aboutsummaryrefslogtreecommitdiff
path: root/Source/Modules/csharp.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Modules/csharp.cxx')
-rw-r--r--Source/Modules/csharp.cxx371
1 files changed, 229 insertions, 142 deletions
diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx
index 17100b330..b0103f3c1 100644
--- a/Source/Modules/csharp.cxx
+++ b/Source/Modules/csharp.cxx
@@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
*
* csharp.cxx
*
@@ -12,8 +12,8 @@
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
-#include <limits.h> // for INT_MAX
#include "cparse.h"
+#include <limits.h> // for INT_MAX
#include <ctype.h>
/* Hash type used for upcalls from C/C++ */
@@ -59,6 +59,7 @@ class CSHARP:public Language {
String *variable_name; //Name of a variable being wrapped
String *proxy_class_constants_code;
String *module_class_constants_code;
+ String *common_begin_code;
String *enum_code;
String *dllimport; // DllImport attribute name
String *namespce; // Optional namespace name
@@ -134,6 +135,7 @@ public:
variable_name(NULL),
proxy_class_constants_code(NULL),
module_class_constants_code(NULL),
+ common_begin_code(NULL),
enum_code(NULL),
dllimport(NULL),
namespce(NULL),
@@ -166,7 +168,7 @@ public:
/* for now, multiple inheritance in directors is disabled, this
should be easy to implement though */
director_multiple_inheritance = 0;
- director_language = 1;
+ directorLanguage();
}
/* -----------------------------------------------------------------------------
@@ -288,7 +290,8 @@ public:
virtual int top(Node *n) {
// Get any options set in the module directive
- Node *optionsnode = Getattr(Getattr(n, "module"), "options");
+ Node *module = Getattr(n, "module");
+ Node *optionsnode = Getattr(module, "options");
if (optionsnode) {
if (Getattr(optionsnode, "imclassname"))
@@ -308,6 +311,9 @@ public:
allow_dirprot();
}
allow_allprotected(GetFlag(optionsnode, "allprotected"));
+ common_begin_code = Getattr(optionsnode, "csbegin");
+ if (common_begin_code)
+ Printf(common_begin_code, "\n");
}
/* Initialize all of the output files */
@@ -316,24 +322,24 @@ public:
if (!outfile) {
Printf(stderr, "Unable to determine outfile\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
- if (directorsEnabled()) {
+ if (Swig_directors_enabled()) {
if (!outfile_h) {
Printf(stderr, "Unable to determine outfile_h\n");
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
if (!f_runtime_h) {
FileErrorDisplay(outfile_h);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
}
@@ -369,9 +375,9 @@ public:
}
// module class and intermediary classes are always created
- if (!addSymbol(imclass_name, n))
+ if (!addSymbol(imclass_name, module))
return SWIG_ERROR;
- if (!addSymbol(module_class_name, n))
+ if (!addSymbol(module_class_name, module))
return SWIG_ERROR;
imclass_class_code = NewString("");
@@ -399,9 +405,9 @@ public:
Swig_banner(f_begin);
- Printf(f_runtime, "\n\n#ifndef SWIGCSHARP\n#define SWIGCSHARP\n#endif\n\n");
+ Swig_obligatory_macros(f_runtime, "CSHARP");
- if (directorsEnabled()) {
+ if (Swig_directors_enabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
/* Emit initial director header and director code: */
@@ -444,7 +450,7 @@ public:
/* Emit code */
Language::top(n);
- if (directorsEnabled()) {
+ if (Swig_directors_enabled()) {
// Insert director runtime into the f_runtime file (make it occur before %header section)
Swig_insert_file("director_common.swg", f_runtime);
Swig_insert_file("director.swg", f_runtime);
@@ -608,7 +614,7 @@ public:
Dump(f_runtime, f_begin);
Dump(f_header, f_begin);
- if (directorsEnabled()) {
+ if (Swig_directors_enabled()) {
Dump(f_directors, f_begin);
Dump(f_directors_h, f_runtime_h);
@@ -649,6 +655,7 @@ public:
Printf(f, "//\n");
Swig_banner_target_lang(f, "//");
Printf(f, "//------------------------------------------------------------------------------\n\n");
+ Printv(f, common_begin_code, NIL);
}
/* -----------------------------------------------------------------------------
@@ -670,7 +677,7 @@ public:
f_single_out = NewFile(filen, "w", SWIG_output_files());
if (!f_single_out) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filen));
Delete(filen);
@@ -684,7 +691,7 @@ public:
File *f = NewFile(filen, "w", SWIG_output_files());
if (!f) {
FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filen));
Delete(filen);
@@ -901,8 +908,6 @@ public:
// Get typemap for this argument
if ((tm = Getattr(p, "tmap:in"))) {
canThrow(n, "in", p);
- Replaceall(tm, "$source", arg); /* deprecated */
- Replaceall(tm, "$target", ln); /* deprecated */
Replaceall(tm, "$arg", arg); /* deprecated? */
Replaceall(tm, "$input", arg);
Setattr(p, "emit:input", arg);
@@ -921,7 +926,6 @@ public:
for (p = l; p;) {
if ((tm = Getattr(p, "tmap:check"))) {
canThrow(n, "check", p);
- Replaceall(tm, "$target", Getattr(p, "lname")); /* deprecated */
Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
Replaceall(tm, "$input", Getattr(p, "emit:input"));
Printv(f->code, tm, "\n", NIL);
@@ -935,7 +939,6 @@ public:
for (p = l; p;) {
if ((tm = Getattr(p, "tmap:freearg"))) {
canThrow(n, "freearg", p);
- Replaceall(tm, "$source", Getattr(p, "emit:input")); /* deprecated */
Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
Replaceall(tm, "$input", Getattr(p, "emit:input"));
Printv(cleanup, tm, "\n", NIL);
@@ -949,8 +952,6 @@ public:
for (p = l; p;) {
if ((tm = Getattr(p, "tmap:argout"))) {
canThrow(n, "argout", p);
- Replaceall(tm, "$source", Getattr(p, "emit:input")); /* deprecated */
- Replaceall(tm, "$target", Getattr(p, "lname")); /* deprecated */
Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
Replaceall(tm, "$result", "jresult");
Replaceall(tm, "$input", Getattr(p, "emit:input"));
@@ -982,8 +983,6 @@ public:
/* Return value if necessary */
if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
canThrow(n, "out", n);
- Replaceall(tm, "$source", Swig_cresult_name()); /* deprecated */
- Replaceall(tm, "$target", "jresult"); /* deprecated */
Replaceall(tm, "$result", "jresult");
if (GetFlag(n, "feature:new"))
@@ -1011,7 +1010,6 @@ public:
if (GetFlag(n, "feature:new")) {
if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
canThrow(n, "newfree", n);
- Replaceall(tm, "$source", Swig_cresult_name()); /* deprecated */
Printf(f->code, "%s\n", tm);
}
}
@@ -1020,7 +1018,6 @@ public:
if (!native_function_flag) {
if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
canThrow(n, "ret", n);
- Replaceall(tm, "$source", Swig_cresult_name()); /* deprecated */
Printf(f->code, "%s\n", tm);
}
}
@@ -1180,21 +1177,6 @@ public:
return SWIG_NOWRAP;
String *nspace = Getattr(n, "sym:nspace"); // NSpace/getNSpace() only works during Language::enumDeclaration call
- if (proxy_flag && !is_wrapping_class()) {
- // Global enums / enums in a namespace
- assert(!full_imclass_name);
-
- if (!nspace) {
- full_imclass_name = NewStringf("%s", imclass_name);
- } else {
- if (namespce) {
- full_imclass_name = NewStringf("%s.%s", namespce, imclass_name);
- } else {
- full_imclass_name = NewStringf("%s", imclass_name);
- }
- }
- }
-
enum_code = NewString("");
String *symname = Getattr(n, "sym:name");
String *constants_code = (proxy_flag && is_wrapping_class())? proxy_class_constants_code : module_class_constants_code;
@@ -1208,9 +1190,29 @@ public:
if (!addSymbol(symname, n, scope))
return SWIG_ERROR;
- // Pure C# baseclass and interfaces
- const String *pure_baseclass = typemapLookup(n, "csbase", typemap_lookup_type, WARN_NONE);
- const String *pure_interfaces = typemapLookup(n, "csinterfaces", typemap_lookup_type, WARN_NONE);
+ // Enum base (underlying enum type)
+ Node *attributes = NewHash();
+ const String *pure_baseclass = typemapLookup(n, "csbase", typemap_lookup_type, WARN_NONE, attributes);
+ bool purebase_replace = GetFlag(attributes, "tmap:csbase:replace") ? true : false;
+ Delete(attributes);
+
+ const String *baseclass = NULL;
+ if (!purebase_replace) {
+ String *underlying_enum_type = Getattr(n, "enumbase");
+ if (underlying_enum_type) {
+ baseclass = typemapLookup(n, "cstype", underlying_enum_type, WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF);
+ }
+ }
+
+ const String *wanted_base = baseclass ? baseclass : pure_baseclass;
+
+ if (purebase_replace) {
+ wanted_base = pure_baseclass;
+ } else if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) {
+ Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
+ "Warning for %s, enum base %s ignored. Multiple enum bases is not supported in C# enums. "
+ "Perhaps you need the 'replace' attribute in the csbase typemap?\n", typemap_lookup_type, pure_baseclass);
+ }
// Class attributes
const String *csattributes = typemapLookup(n, "csattributes", typemap_lookup_type, WARN_NONE);
@@ -1219,8 +1221,7 @@ public:
// Emit the enum
Printv(enum_code, typemapLookup(n, "csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers (enum modifiers really)
- " ", symname, (*Char(pure_baseclass) || *Char(pure_interfaces)) ? " : " : "", pure_baseclass, ((*Char(pure_baseclass)) && *Char(pure_interfaces)) ? // Interfaces
- ", " : "", pure_interfaces, " {\n", NIL);
+ " ", symname, *Char(wanted_base) ? " : " : "", wanted_base, " {\n", NIL);
Delete(scope);
} else {
// Wrap C++ enum with integers - just indicate start of enum with a comment, no comment for anonymous enums of any sort
@@ -1228,9 +1229,29 @@ public:
Printf(constants_code, " // %s \n", symname);
}
+ if (proxy_flag && !is_wrapping_class()) {
+ // Global enums / enums in a namespace
+ assert(!full_imclass_name);
+
+ if (!nspace) {
+ full_imclass_name = NewStringf("%s", imclass_name);
+ } else {
+ if (namespce) {
+ full_imclass_name = NewStringf("%s.%s", namespce, imclass_name);
+ } else {
+ full_imclass_name = NewStringf("%s", imclass_name);
+ }
+ }
+ }
+
// Emit each enum item
Language::enumDeclaration(n);
+ if (proxy_flag && !is_wrapping_class()) {
+ Delete(full_imclass_name);
+ full_imclass_name = 0;
+ }
+
if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
// Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum
// Finish the enum declaration
@@ -1282,11 +1303,6 @@ public:
Delete(enum_code);
enum_code = NULL;
-
- if (proxy_flag && !is_wrapping_class()) {
- Delete(full_imclass_name);
- full_imclass_name = 0;
- }
}
return SWIG_OK;
}
@@ -1709,12 +1725,12 @@ public:
* addInterfaceNameAndUpcasts()
* ----------------------------------------------------------------------------- */
- void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, String *c_classname) {
- List *keys = Keys(base_list);
- for (Iterator it = First(keys); it.item; it = Next(it)) {
- Node *base = Getattr(base_list, it.item);
- String *c_baseclass = SwigType_namestr(Getattr(base, "name"));
+ void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, List *base_list, SwigType *c_classname) {
+ for (Iterator it = First(base_list); it.item; it = Next(it)) {
+ Node *base = it.item;
+ SwigType *c_baseclassname = Getattr(base, "name");
String *interface_name = Getattr(base, "interface:name");
+ SwigType *bsmart = Getattr(base, "smart");
if (Len(interface_list))
Append(interface_list, ", ");
Append(interface_list, interface_name);
@@ -1733,14 +1749,12 @@ public:
Replaceall(cptr_method_name, "$interfacename", interface_name);
String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name);
- upcastsCode(smart, upcast_method_name, c_classname, c_baseclass);
+ upcastsCode(smart, bsmart, upcast_method_name, c_classname, c_baseclassname);
Delete(upcast_method_name);
Delete(cptr_method_name);
Delete(interface_code);
- Delete(c_baseclass);
}
- Delete(keys);
}
/* -----------------------------------------------------------------------------
@@ -1749,7 +1763,7 @@ public:
* Add code for C++ casting to base class
* ----------------------------------------------------------------------------- */
- void upcastsCode(SwigType *smart, String *upcast_method_name, String *c_classname, String *c_baseclass) {
+ void upcastsCode(SwigType *smart, SwigType *bsmart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) {
String *wname = Swig_name_wrapper(upcast_method_name);
Printv(imclass_cppcasts_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL);
@@ -1758,27 +1772,31 @@ public:
Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
if (smart) {
- SwigType *bsmart = Copy(smart);
- SwigType *rclassname = SwigType_typedef_resolve_all(c_classname);
- SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass);
- Replaceall(bsmart, rclassname, rbaseclass);
- Delete(rclassname);
- Delete(rbaseclass);
- String *smartnamestr = SwigType_namestr(smart);
- String *bsmartnamestr = SwigType_namestr(bsmart);
- Printv(upcasts_code,
- "SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n",
- " return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n"
- "}\n", "\n", NIL);
- Delete(bsmartnamestr);
- Delete(smartnamestr);
- Delete(bsmart);
+ if (bsmart) {
+ String *smartnamestr = SwigType_namestr(smart);
+ String *bsmartnamestr = SwigType_namestr(bsmart);
+
+ Printv(upcasts_code,
+ "SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n",
+ " return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n"
+ "}\n", "\n", NIL);
+
+ Delete(bsmartnamestr);
+ Delete(smartnamestr);
+ }
} else {
+ String *classname = SwigType_namestr(c_classname);
+ String *baseclassname = SwigType_namestr(c_baseclassname);
+
Printv(upcasts_code,
- "SWIGEXPORT ", c_baseclass, " * SWIGSTDCALL ", wname, "(", c_classname, " *jarg1) {\n",
- " return (", c_baseclass, " *)jarg1;\n"
+ "SWIGEXPORT ", baseclassname, " * SWIGSTDCALL ", wname, "(", classname, " *jarg1) {\n",
+ " return (", baseclassname, " *)jarg1;\n"
"}\n", "\n", NIL);
+
+ Delete(baseclassname);
+ Delete(classname);
}
+
Delete(wname);
}
@@ -1787,16 +1805,16 @@ public:
* ----------------------------------------------------------------------------- */
void emitProxyClassDefAndCPPCasts(Node *n) {
- String *c_classname = SwigType_namestr(Getattr(n, "name"));
- String *c_baseclass = NULL;
+ SwigType *c_classname = Getattr(n, "name");
+ SwigType *c_baseclassname = NULL;
String *baseclass = NULL;
- String *c_baseclassname = NULL;
String *interface_list = NewStringEmpty();
String *interface_upcasts = NewStringEmpty();
SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
bool feature_director = Swig_directorclass(n) ? true : false;
bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested");
- SwigType *smart = Swig_cparse_smartptr(n);
+ SwigType *smart = Getattr(n, "smart");
+ SwigType *bsmart = 0;
// Inheritance from pure C# classes
Node *attributes = NewHash();
@@ -1811,13 +1829,15 @@ public:
if (baselist) {
Iterator base = First(baselist);
while (base.item) {
- if (!(GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface"))) {
- String *baseclassname = Getattr(base.item, "name");
+ if (!(GetFlag(base.item, "feature:ignore") || GetFlag(base.item, "feature:interface"))) {
+ SwigType *baseclassname = Getattr(base.item, "name");
if (!c_baseclassname) {
- c_baseclassname = baseclassname;
- baseclass = Copy(getProxyName(baseclassname));
- if (baseclass)
- c_baseclass = SwigType_namestr(baseclassname);
+ String *name = getProxyName(baseclassname);
+ if (name) {
+ c_baseclassname = baseclassname;
+ baseclass = name;
+ bsmart = Getattr(base.item, "smart");
+ }
} else {
/* Warn about multiple inheritance for additional base class(es) */
String *proxyclassname = Getattr(n, "classtypeobj");
@@ -1829,11 +1849,11 @@ public:
}
}
}
- Hash *interface_bases = Getattr(n, "interface:bases");
+ List *interface_bases = Getattr(n, "interface:bases");
if (interface_bases)
addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname);
- bool derived = baseclass && getProxyName(c_baseclassname);
+ bool derived = baseclass != 0;
if (derived && purebase_notderived)
pure_baseclass = empty_string;
const String *wanted_base = baseclass ? baseclass : pure_baseclass;
@@ -1841,7 +1861,6 @@ public:
if (purebase_replace) {
wanted_base = pure_baseclass;
derived = false;
- Delete(baseclass);
baseclass = NULL;
if (purebase_notderived)
Swig_error(Getfile(n), Getline(n), "The csbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type);
@@ -1969,9 +1988,32 @@ public:
// Only emit if there is at least one director method
Printf(proxy_class_code, "\n");
Printf(proxy_class_code, " private bool SwigDerivedClassHasMethod(string methodName, global::System.Type[] methodTypes) {\n");
- Printf(proxy_class_code,
- " global::System.Reflection.MethodInfo methodInfo = this.GetType().GetMethod(methodName, global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance, null, methodTypes, null);\n");
- Printf(proxy_class_code, " bool hasDerivedMethod = methodInfo.DeclaringType.IsSubclassOf(typeof(%s));\n", proxy_class_name);
+ Printf(proxy_class_code, " global::System.Reflection.MethodInfo[] methodInfos = this.GetType().GetMethods(\n");
+ Printf(proxy_class_code, " global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance);\n");
+ Printf(proxy_class_code, " foreach (global::System.Reflection.MethodInfo methodInfo in methodInfos) {\n");
+ Printf(proxy_class_code, " if (methodInfo.DeclaringType == null)\n");
+ Printf(proxy_class_code, " continue;\n\n");
+ Printf(proxy_class_code, " if (methodInfo.Name != methodName)\n");
+ Printf(proxy_class_code, " continue;\n\n");
+ Printf(proxy_class_code, " var parameters = methodInfo.GetParameters();\n");
+ Printf(proxy_class_code, " if (parameters.Length != methodTypes.Length)\n");
+ Printf(proxy_class_code, " continue;\n\n");
+ Printf(proxy_class_code, " bool parametersMatch = true;\n");
+ Printf(proxy_class_code, " for (var i = 0; i < parameters.Length; i++) {\n");
+ Printf(proxy_class_code, " if (parameters[i].ParameterType != methodTypes[i]) {\n");
+ Printf(proxy_class_code, " parametersMatch = false;\n");
+ Printf(proxy_class_code, " break;\n");
+ Printf(proxy_class_code, " }\n");
+ Printf(proxy_class_code, " }\n\n");
+ Printf(proxy_class_code, " if (!parametersMatch)\n");
+ Printf(proxy_class_code, " continue;\n\n");
+ Printf(proxy_class_code, " if (methodInfo.IsVirtual && (methodInfo.DeclaringType.IsSubclassOf(typeof(%s))) &&\n", proxy_class_name);
+ Printf(proxy_class_code, " methodInfo.DeclaringType != methodInfo.GetBaseDefinition().DeclaringType) {\n");
+ Printf(proxy_class_code, " return true;\n");
+ Printf(proxy_class_code, " }\n");
+ Printf(proxy_class_code, " }\n\n");
+ Printf(proxy_class_code, " return false;\n");
+
/* Could add this code to cover corner case where the GetMethod() returns a method which allows type
* promotion, eg it will return foo(double), if looking for foo(int).
if (hasDerivedMethod) {
@@ -1991,7 +2033,7 @@ public:
}
}
*/
- Printf(proxy_class_code, " return hasDerivedMethod;\n");
+ //Printf(proxy_class_code, " return hasDerivedMethod;\n");
Printf(proxy_class_code, " }\n");
}
@@ -2032,12 +2074,9 @@ public:
if (derived) {
String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
- upcastsCode(smart, upcast_method_name, c_classname, c_baseclass);
+ upcastsCode(smart, bsmart, upcast_method_name, c_classname, c_baseclassname);
Delete(upcast_method_name);
}
-
- Delete(smart);
- Delete(baseclass);
}
/* ----------------------------------------------------------------------
@@ -2046,11 +2085,12 @@ public:
void emitInterfaceDeclaration(Node *n, String *interface_name, File *f_interface) {
Printv(f_interface, typemapLookup(n, "csimports", Getattr(n, "classtypeobj"), WARN_NONE), "\n", NIL);
- Printf(f_interface, "public interface %s", interface_name);
+ Printv(f_interface, typemapLookup(n, "csinterfacemodifiers", Getattr(n, "classtypeobj"), WARN_CSHARP_TYPEMAP_INTERFACEMODIFIERS_UNDEF), NIL);
+ Printf(f_interface, " %s", interface_name);
if (List *baselist = Getattr(n, "bases")) {
String *bases = 0;
for (Iterator base = First(baselist); base.item; base = Next(base)) {
- if (GetFlag(base.item, "feature:ignore") || !Getattr(base.item, "feature:interface"))
+ if (GetFlag(base.item, "feature:ignore") || !GetFlag(base.item, "feature:interface"))
continue; // TODO: warn about skipped non-interface bases
String *base_iname = Getattr(base.item, "interface:name");
if (!bases)
@@ -2101,7 +2141,7 @@ public:
if (proxy_flag) {
proxy_class_name = NewString(Getattr(n, "sym:name"));
- String *interface_name = Getattr(n, "feature:interface") ? Getattr(n, "interface:name") : 0;
+ String *interface_name = GetFlag(n, "feature:interface") ? Getattr(n, "interface:name") : 0;
if (Node *outer = Getattr(n, "nested:outer")) {
String *outerClassesPrefix = Copy(Getattr(outer, "sym:name"));
for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) {
@@ -2127,12 +2167,12 @@ public:
full_imclass_name = NewStringf("%s", imclass_name);
if (Cmp(proxy_class_name, imclass_name) == 0) {
Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
if (Cmp(proxy_class_name, module_class_name) == 0) {
Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
} else {
if (namespce) {
@@ -2157,7 +2197,7 @@ public:
destructor_call = NewString("");
proxy_class_constants_code = NewString("");
- if (Getattr(n, "feature:interface")) {
+ if (GetFlag(n, "feature:interface")) {
interface_class_code = NewString("");
String *output_directory = outputDirectory(nspace);
f_interface = getOutputFile(output_directory, interface_name);
@@ -2260,6 +2300,31 @@ public:
return SWIG_OK;
}
+ void printArgumentDeclaration(Node *n, Parm *p, String *param_type, String *arg, String *code)
+ {
+ String *specifiedoverridekey = NewString("feature:cs:defaultargs:");
+ Append(specifiedoverridekey, arg);
+ String *specifiedoverridevalue = Getattr(n, specifiedoverridekey);
+ if (specifiedoverridevalue) {
+ Printf(code, "%s %s=%s", param_type, arg, specifiedoverridevalue);
+ } else {
+ String *cppvalue = NULL;
+ //if they've not specified defaultargs, then fall back to
+ //the normal default handling of specifying one overload per possible
+ //set of arguments. If they have, then use the default argument from
+ //c++ as a literal csharp expression.
+ if (Getattr(n, "feature:cs:defaultargs"))
+ cppvalue = Getattr(p, "value");
+ if (cppvalue)
+ Printf(code, "%s %s=%s", param_type, arg, cppvalue);
+ else
+ Printf(code, "%s %s", param_type, arg);
+ }
+ Delete(specifiedoverridekey);
+ }
+
+
+
/* ----------------------------------------------------------------------
* memberfunctionHandler()
* ---------------------------------------------------------------------- */
@@ -2328,7 +2393,7 @@ public:
String *pre_code = NewString("");
String *post_code = NewString("");
String *terminator_code = NewString("");
- bool is_interface = Getattr(parentNode(n), "feature:interface") != 0
+ bool is_interface = GetFlag(parentNode(n), "feature:interface") && !checkAttribute(n, "kind", "variable")
&& !static_flag && Getattr(n, "interface:owner") == 0;
if (!proxy_flag)
@@ -2338,6 +2403,9 @@ public:
if (Getattr(n, "overload:ignore"))
return;
+ if (Getattr(n, "feature:cs:defaultargs") && Getattr(n, "defaultargs"))
+ return;
+
// Don't generate proxy method for additional explicitcall method used in directors
if (GetFlag(n, "explicitcall"))
return;
@@ -2422,7 +2490,6 @@ public:
Printf(imcall, "swigCPtr");
emit_mark_varargs(l);
-
int gencomma = !static_flag;
/* Output each parameter */
@@ -2501,9 +2568,9 @@ public:
Printf(interface_class_code, ", ");
}
gencomma = 2;
- Printf(function_code, "%s %s", param_type, arg);
+ printArgumentDeclaration(n, p, param_type, arg, function_code);
if (is_interface)
- Printf(interface_class_code, "%s %s", param_type, arg);
+ printArgumentDeclaration(n, p, param_type, arg, interface_class_code);
Delete(arg);
Delete(param_type);
@@ -2558,8 +2625,8 @@ public:
Replaceall(imcall, "$imfuncname", intermediary_function_name);
String *excode = NewString("");
Node *directorNode = Getattr(n, "directorNode");
- if (directorNode) {
- UpcallData *udata = Getattr(directorNode, "upcalldata");
+ UpcallData *udata = directorNode ? Getattr(directorNode, "upcalldata") : 0;
+ if (udata) {
String *methid = Getattr(udata, "class_methodidx");
if (!Cmp(return_type, "void"))
@@ -2577,6 +2644,7 @@ public:
} else {
Replaceall(imcall, "$imfuncname", intermediary_function_name);
}
+ Replaceall(tm, "$imfuncname", intermediary_function_name);
Replaceall(tm, "$imcall", imcall);
} else {
Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
@@ -2608,6 +2676,8 @@ public:
const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
if (!methodmods)
methodmods = (is_public(n) ? public_string : protected_string);
+
+ // Start property declaration
Printf(proxy_class_code, " %s %s%s %s {", methodmods, static_flag ? "static " : "", variable_type, variable_name);
}
generate_property_declaration_flag = false;
@@ -2620,6 +2690,7 @@ public:
if ((tm = Swig_typemap_lookup("csvarin", variable_parm, "", 0))) {
substituteClassname(cvariable_type, tm);
Replaceall(tm, "$csinput", "value");
+ Replaceall(tm, "$imfuncname", intermediary_function_name);
Replaceall(tm, "$imcall", imcall);
excodeSubstitute(n, tm, "csvarin", variable_parm);
Printf(proxy_class_code, "%s", tm);
@@ -2634,6 +2705,7 @@ public:
else
Replaceall(tm, "$owner", "false");
substituteClassname(t, tm);
+ Replaceall(tm, "$imfuncname", intermediary_function_name);
Replaceall(tm, "$imcall", imcall);
excodeSubstitute(n, tm, "csvarout", n);
Printf(proxy_class_code, "%s", tm);
@@ -2680,6 +2752,9 @@ public:
if (Getattr(n, "overload:ignore"))
return SWIG_OK;
+ if (Getattr(n, "feature:cs:defaultargs") && Getattr(n, "defaultargs"))
+ return SWIG_OK;
+
if (proxy_flag) {
String *overloaded_name = getOverloadedName(n);
String *mangled_overname = Swig_name_construct(getNSpace(), overloaded_name);
@@ -2788,7 +2863,7 @@ public:
Printf(helper_code, ", ");
Printf(helper_args, ", ");
}
- Printf(function_code, "%s %s", param_type, arg);
+ printArgumentDeclaration(n, p, param_type, arg, function_code);
Printf(helper_code, "%s %s", param_type, arg);
Printf(helper_args, "%s", cshin ? cshin : arg);
++gencomma;
@@ -2908,6 +2983,7 @@ public:
variable_wrapper_flag = false;
generate_property_declaration_flag = false;
+ // End property declaration
Printf(proxy_class_code, "\n }\n\n");
return SWIG_OK;
@@ -2919,8 +2995,6 @@ public:
virtual int staticmembervariableHandler(Node *n) {
- bool static_const_member_flag = (Getattr(n, "value") == 0);
-
generate_property_declaration_flag = true;
variable_name = Getattr(n, "sym:name");
wrapping_member_flag = true;
@@ -2930,8 +3004,10 @@ public:
static_flag = false;
generate_property_declaration_flag = false;
- if (static_const_member_flag)
+ if (!GetFlag(n, "wrappedasconstant")) {
+ // End property declaration
Printf(proxy_class_code, "\n }\n\n");
+ }
return SWIG_OK;
}
@@ -2957,7 +3033,7 @@ public:
/* A C# HandleRef is used for all classes in the SWIG intermediary class.
* The intermediary class methods are thus mangled when overloaded to give
* a unique name. */
- String *overloaded_name = NewStringf("%s", Getattr(n, "sym:name"));
+ String *overloaded_name = Copy(Getattr(n, "sym:name"));
if (Getattr(n, "sym:overloaded")) {
Printv(overloaded_name, Getattr(n, "sym:overname"), NIL);
@@ -2988,6 +3064,9 @@ public:
String *post_code = NewString("");
String *terminator_code = NewString("");
+ if (Getattr(n, "feature:cs:defaultargs") && Getattr(n, "defaultargs"))
+ return;
+
if (l) {
if (SwigType_type(Getattr(l, "type")) == T_VOID) {
l = nextSibling(l);
@@ -3107,7 +3186,7 @@ public:
if (gencomma >= 2)
Printf(function_code, ", ");
gencomma = 2;
- Printf(function_code, "%s %s", param_type, arg);
+ printArgumentDeclaration(n, p, param_type, arg, function_code);
p = Getattr(p, "tmap:in:next");
Delete(arg);
@@ -3146,6 +3225,7 @@ public:
else
Replaceall(tm, "$owner", "false");
substituteClassname(t, tm);
+ Replaceall(tm, "$imfuncname", overloaded_name);
Replaceall(tm, "$imcall", imcall);
} else {
Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
@@ -3184,6 +3264,7 @@ public:
if ((tm = Getattr(p, "tmap:csvarin"))) {
substituteClassname(pt, tm);
Replaceall(tm, "$csinput", "value");
+ Replaceall(tm, "$imfuncname", overloaded_name);
Replaceall(tm, "$imcall", imcall);
excodeSubstitute(n, tm, "csvarin", p);
Printf(module_class_code, "%s", tm);
@@ -3198,6 +3279,7 @@ public:
else
Replaceall(tm, "$owner", "false");
substituteClassname(t, tm);
+ Replaceall(tm, "$imfuncname", overloaded_name);
Replaceall(tm, "$imcall", imcall);
excodeSubstitute(n, tm, "csvarout", n);
Printf(module_class_code, "%s", tm);
@@ -3665,7 +3747,7 @@ public:
if (newdir_error) {
Printf(stderr, "%s\n", newdir_error);
Delete(newdir_error);
- SWIG_exit(EXIT_FAILURE);
+ Exit(EXIT_FAILURE);
}
Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0);
Delete(nspace_subdirectory);
@@ -3729,7 +3811,8 @@ public:
String *qualified_classname = Copy(sym_name);
String *nspace = getNSpace();
String *dirClassName = directorClassName(n);
- String *smartptr = Getattr(n, "feature:smartptr");
+ SwigType *smart = Getattr(n, "smart");
+ String *smartptr = smart ? SwigType_namestr(smart) : 0;
if (!GetFlag(n, "feature:flatnested")) {
for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) {
@@ -3798,7 +3881,7 @@ public:
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
SwigType *returntype = Getattr(n, "type");
- String *overloaded_name = getOverloadedName(n);
+ String *overloaded_name = 0;
String *storage = Getattr(n, "storage");
String *value = Getattr(n, "value");
String *decl = Getattr(n, "decl");
@@ -3820,7 +3903,6 @@ public:
String *qualified_name = NewStringf("%s::%s", dirclassname, name);
SwigType *c_ret_type = NULL;
String *jupcall_args = NewString("");
- String *imclass_dmethod;
String *callback_typedef_parms = NewString("");
String *delegate_parms = NewString("");
String *proxy_method_types = NewString("");
@@ -3834,7 +3916,8 @@ public:
// we're consistent with the sym:overload name in functionWrapper. (?? when
// does the overloaded method name get set?)
- imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name));
+ if (!ignored_method)
+ overloaded_name = getOverloadedName(n);
qualified_return = SwigType_rcaststr(returntype, "c_result");
@@ -3887,28 +3970,28 @@ public:
}
}
- /* Create the intermediate class wrapper */
- tm = Swig_typemap_lookup("imtype", n, "", 0);
- if (tm) {
- String *imtypeout = Getattr(n, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap
- if (imtypeout)
- tm = imtypeout;
- const String *im_directoroutattributes = Getattr(n, "tmap:imtype:directoroutattributes");
- if (im_directoroutattributes) {
- Printf(callback_def, " %s\n", im_directoroutattributes);
- if (!ignored_method)
- Printf(director_delegate_definitions, " %s\n", im_directoroutattributes);
- }
+ if (!ignored_method) {
+ /* Create the intermediate class wrapper */
+ tm = Swig_typemap_lookup("imtype", n, "", 0);
+ if (tm) {
+ String *imtypeout = Getattr(n, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap
+ if (imtypeout)
+ tm = imtypeout;
+ const String *im_directoroutattributes = Getattr(n, "tmap:imtype:directoroutattributes");
+ if (im_directoroutattributes) {
+ Printf(callback_def, " %s\n", im_directoroutattributes);
+ if (!ignored_method)
+ Printf(director_delegate_definitions, " %s\n", im_directoroutattributes);
+ }
- Printf(callback_def, " private %s SwigDirectorMethod%s(", tm, overloaded_name);
- if (!ignored_method) {
+ Printf(callback_def, " private %s SwigDirectorMethod%s(", tm, overloaded_name);
const String *csdirectordelegatemodifiers = Getattr(n, "feature:csdirectordelegatemodifiers");
String *modifiers = (csdirectordelegatemodifiers ? NewStringf("%s%s", csdirectordelegatemodifiers, Len(csdirectordelegatemodifiers) > 0 ? " " : "") : NewStringf("public "));
Printf(director_delegate_definitions, " %sdelegate %s", modifiers, tm);
Delete(modifiers);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(returntype, 0));
}
- } else {
- Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(returntype, 0));
}
if ((c_ret_type = Swig_typemap_lookup("ctype", n, "", 0))) {
@@ -4064,11 +4147,10 @@ public:
/* Get the C# parameter type */
if ((tm = Getattr(p, "tmap:cstype"))) {
substituteClassname(pt, tm);
- if (Strncmp(tm, "ref ", 4) == 0) {
- Replace(tm, "ref ", "", DOH_REPLACE_FIRST);
+ int flags = DOH_REPLACE_FIRST | DOH_REPLACE_ID_BEGIN | DOH_REPLACE_NOCOMMENT;
+ if (Replace(tm, "ref ", "", flags) || Replace(tm, "ref\t", "", flags)) {
Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm);
- } else if (Strncmp(tm, "out ", 4) == 0) {
- Replace(tm, "out ", "", DOH_REPLACE_FIRST);
+ } else if (Replace(tm, "out ", "", flags) || Replace(tm, "out\t", "", flags)) {
Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm);
} else {
Printf(proxy_method_types, "typeof(%s)", tm);
@@ -4267,6 +4349,8 @@ public:
if (!ignored_method) {
/* Emit the actual upcall through */
+ String *member_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name);
+ String *imclass_dmethod = NewStringf("SwigDirector_%s", member_name);
UpcallData *udata = addUpcallMethod(imclass_dmethod, symname, decl, overloaded_name);
String *methid = Getattr(udata, "class_methodidx");
Setattr(n, "upcalldata", udata);
@@ -4282,6 +4366,9 @@ public:
Printf(director_delegate_instances, " private SwigDelegate%s_%s swigDelegate%s;\n", classname, methid, methid);
Printf(director_method_types, " private static global::System.Type[] swigMethodTypes%s = new global::System.Type[] { %s };\n", methid, proxy_method_types);
Printf(director_connect_parms, "SwigDirector%s%s delegate%s", classname, methid, methid);
+
+ Delete(imclass_dmethod);
+ Delete(member_name);
}
Delete(pre_code);