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)
============================
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
Fix #2432801 - Make SwigValueWrapper exception safe for when copy constructors
throw exceptions.

View file

@ -1019,6 +1019,20 @@ but this will:
</pre>
</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>

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>.
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.
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>
<div class="code">

View file

@ -94,5 +94,20 @@ public class java_throws_runme {
if (!pass)
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 %javamethodmodifiers %feature("java:methodmodifiers")
#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) 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_directors; // Intermediate class director code
String *destructor_call; //C++ destructor call if any
String *destructor_throws_clause; //C++ destructor throws clause if any
// Director method stuff:
List *dmethods_seq;
@ -141,6 +142,7 @@ public:
imclass_cppcasts_code(NULL),
imclass_directors(NULL),
destructor_call(NULL),
destructor_throws_clause(NULL),
dmethods_seq(NULL),
dmethods_table(NULL),
n_dmethods(0),
@ -1654,7 +1656,7 @@ public:
else
Replaceall(destruct, "$jnicall", "throw new UnsupportedOperationException(\"C++ destructor does not have public access\")");
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 */
@ -1761,6 +1763,7 @@ public:
Clear(proxy_class_code);
destructor_call = NewString("");
destructor_throws_clause = NewString("");
proxy_class_constants_code = NewString("");
}
@ -1819,6 +1822,8 @@ public:
proxy_class_name = NULL;
Delete(destructor_call);
destructor_call = NULL;
Delete(destructor_throws_clause);
destructor_throws_clause = NULL;
Delete(proxy_class_constants_code);
proxy_class_constants_code = NULL;
}
@ -2336,6 +2341,7 @@ public:
if (proxy_flag) {
Printv(destructor_call, imclass_name, ".", Swig_name_destroy(symname), "(swigCPtr)", NIL);
generateThrowsClause(n, destructor_throws_clause);
}
return SWIG_OK;
}
@ -2870,7 +2876,7 @@ public:
String *throws_attribute = NewStringf("%s:throws", attribute);
String *throws = Getattr(parameter, throws_attribute);
if (throws) {
if (throws && Len(throws) > 0) {
String *throws_list = Getattr(n, "java:throwslist");
if (!throws_list) {
throws_list = NewList();