Fix #2153773 - %nojavaexception - disabling and clearing Java checked exceptions

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@10998 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2008-12-23 07:44:59 +00:00
commit e6f5cdac9f
7 changed files with 85 additions and 4 deletions

View file

@ -1,6 +1,11 @@
Version 1.3.37 (in progress) Version 1.3.37 (in progress)
============================ ============================
2008-12-23: wsfulton
[Java] Fix #2153773 - %nojavaexception was clearing the exception feature
instead of disabling it. Clearing checked Java exceptions also didn't work.
The new %clearjavaexception can be used for clearing the exception feature.
2008-12-22: wsfulton 2008-12-22: wsfulton
Fix #2432801 - Make SwigValueWrapper exception safe for when copy constructors Fix #2432801 - Make SwigValueWrapper exception safe for when copy constructors
throw exceptions. throw exceptions.

View file

@ -1019,6 +1019,20 @@ but this will:
</pre> </pre>
</div> </div>
<p>
SWIG provides macros for disabling and clearing features. Many of these can be found in the <tt>swig.swg</tt> library file.
The typical pattern is to define three macros; one to define the feature itself, one to disable the feature and one to clear the feature.
The three macros below show this for the "except" feature:
</p>
<div class="code">
<pre>
#define %exception %feature("except")
#define %noexception %feature("except","0")
#define %clearexception %feature("except","")
</pre>
</div>
<H3><a name="Customization_features_default_args"></a>11.3.4 Features and default arguments</H3> <H3><a name="Customization_features_default_args"></a>11.3.4 Features and default arguments</H3>

View file

@ -3820,7 +3820,9 @@ public:
In the example above, <tt>java.lang.Exception</tt> is a checked exception class and so ought to be declared in the throws clause of <tt>getitem</tt>. In the example above, <tt>java.lang.Exception</tt> is a checked exception class and so ought to be declared in the throws clause of <tt>getitem</tt>.
Classes can be specified for adding to the throws clause using <tt>%javaexception(classes)</tt> instead of <tt>%exception</tt>, Classes can be specified for adding to the throws clause using <tt>%javaexception(classes)</tt> instead of <tt>%exception</tt>,
where <tt>classes</tt> is a string containing one or more comma separated Java classes. where <tt>classes</tt> is a string containing one or more comma separated Java classes.
The <tt>%nojavaexception</tt> feature is the equivalent to <tt>%noexception</tt> and clears previously declared exception handlers. The <tt>%clearjavaexception</tt> feature is the equivalent to <tt>%clearexception</tt> and clears previously declared exception handlers.
The <tt>%nojavaexception</tt> feature is the equivalent to <tt>%noexception</tt> and disables the exception handler.
See <a href="Customization.html#Customization_clearing_features">Clearing features</a> for the difference on disabling and clearing features.
</p> </p>
<div class="code"> <div class="code">

View file

@ -94,5 +94,20 @@ public class java_throws_runme {
if (!pass) if (!pass)
throw new RuntimeException("Test 7 failed"); throw new RuntimeException("Test 7 failed");
// Test %nojavaexception
NoExceptTest net = new NoExceptTest();
pass = false;
try {
net.exceptionPlease();
pass = true;
}
catch (MyException e) {}
if (!pass)
throw new RuntimeException("Test 8 failed");
net.noExceptionPlease();
} }
} }

View file

@ -143,3 +143,41 @@ try {
} }
%} %}
// Test %nojavaexception
%javaexception("MyException") %{
/* global exception handler */
try {
$action
} catch (MyException) {
jclass excep = jenv->FindClass("java_throws/MyException");
if (excep)
jenv->ThrowNew(excep, "exception message");
return $null;
}
%}
%nojavaexception *::noExceptionPlease();
%nojavaexception NoExceptTest::NoExceptTest();
// Need to handle the checked exception in NoExceptTest.delete()
%typemap(javafinalize) SWIGTYPE %{
protected void finalize() {
try {
delete();
} catch (MyException e) {
throw new RuntimeException(e);
}
}
%}
%inline %{
struct NoExceptTest {
unsigned int noExceptionPlease() { return 123; }
unsigned int exceptionPlease() { return 456; }
~NoExceptTest() {}
};
%}
// Turn global exceptions off (for the implicit destructors)
%nojavaexception;

View file

@ -1191,7 +1191,8 @@ SWIG_PROXY_CONSTRUCTOR(true, true, SWIGTYPE)
#define %javaenum(wrapapproach) %feature("java:enum","wrapapproach") #define %javaenum(wrapapproach) %feature("java:enum","wrapapproach")
#define %javamethodmodifiers %feature("java:methodmodifiers") #define %javamethodmodifiers %feature("java:methodmodifiers")
#define %javaexception(exceptionclasses) %feature("except",throws=exceptionclasses) #define %javaexception(exceptionclasses) %feature("except",throws=exceptionclasses)
#define %nojavaexception %feature("except","",throws="") #define %nojavaexception %feature("except","0",throws="")
#define %clearjavaexception %feature("except","",throws="")
%pragma(java) jniclassclassmodifiers="class" %pragma(java) jniclassclassmodifiers="class"
%pragma(java) moduleclassmodifiers="public class" %pragma(java) moduleclassmodifiers="public class"

View file

@ -70,6 +70,7 @@ class JAVA:public Language {
String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
String *imclass_directors; // Intermediate class director code String *imclass_directors; // Intermediate class director code
String *destructor_call; //C++ destructor call if any String *destructor_call; //C++ destructor call if any
String *destructor_throws_clause; //C++ destructor throws clause if any
// Director method stuff: // Director method stuff:
List *dmethods_seq; List *dmethods_seq;
@ -141,6 +142,7 @@ public:
imclass_cppcasts_code(NULL), imclass_cppcasts_code(NULL),
imclass_directors(NULL), imclass_directors(NULL),
destructor_call(NULL), destructor_call(NULL),
destructor_throws_clause(NULL),
dmethods_seq(NULL), dmethods_seq(NULL),
dmethods_table(NULL), dmethods_table(NULL),
n_dmethods(0), n_dmethods(0),
@ -1654,7 +1656,7 @@ public:
else else
Replaceall(destruct, "$jnicall", "throw new UnsupportedOperationException(\"C++ destructor does not have public access\")"); Replaceall(destruct, "$jnicall", "throw new UnsupportedOperationException(\"C++ destructor does not have public access\")");
if (*Char(destruct)) if (*Char(destruct))
Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " void ", destruct_methodname, "() ", destruct, "\n", NIL); Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " void ", destruct_methodname, "()", destructor_throws_clause, " ", destruct, "\n", NIL);
} }
/* Insert directordisconnect typemap, if this class has directors enabled */ /* Insert directordisconnect typemap, if this class has directors enabled */
@ -1761,6 +1763,7 @@ public:
Clear(proxy_class_code); Clear(proxy_class_code);
destructor_call = NewString(""); destructor_call = NewString("");
destructor_throws_clause = NewString("");
proxy_class_constants_code = NewString(""); proxy_class_constants_code = NewString("");
} }
@ -1819,6 +1822,8 @@ public:
proxy_class_name = NULL; proxy_class_name = NULL;
Delete(destructor_call); Delete(destructor_call);
destructor_call = NULL; destructor_call = NULL;
Delete(destructor_throws_clause);
destructor_throws_clause = NULL;
Delete(proxy_class_constants_code); Delete(proxy_class_constants_code);
proxy_class_constants_code = NULL; proxy_class_constants_code = NULL;
} }
@ -2336,6 +2341,7 @@ public:
if (proxy_flag) { if (proxy_flag) {
Printv(destructor_call, imclass_name, ".", Swig_name_destroy(symname), "(swigCPtr)", NIL); Printv(destructor_call, imclass_name, ".", Swig_name_destroy(symname), "(swigCPtr)", NIL);
generateThrowsClause(n, destructor_throws_clause);
} }
return SWIG_OK; return SWIG_OK;
} }
@ -2870,7 +2876,7 @@ public:
String *throws_attribute = NewStringf("%s:throws", attribute); String *throws_attribute = NewStringf("%s:throws", attribute);
String *throws = Getattr(parameter, throws_attribute); String *throws = Getattr(parameter, throws_attribute);
if (throws) { if (throws && Len(throws) > 0) {
String *throws_list = Getattr(n, "java:throwslist"); String *throws_list = Getattr(n, "java:throwslist");
if (!throws_list) { if (!throws_list) {
throws_list = NewList(); throws_list = NewList();