diff options
Diffstat (limited to 'Source/Modules/csharp.cxx')
-rw-r--r-- | Source/Modules/csharp.cxx | 232 |
1 files changed, 168 insertions, 64 deletions
diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 6b9219750..9197b4b17 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -53,7 +53,6 @@ class CSHARP:public Language { String *proxy_class_code; String *module_class_code; String *proxy_class_name; // proxy class name - String *full_proxy_class_name;// fully qualified proxy class name when using nspace feature, otherwise same as proxy_class_name String *full_imclass_name; // fully qualified intermediary class name when using nspace feature, otherwise same as imclass_name String *variable_name; //Name of a variable being wrapped String *proxy_class_constants_code; @@ -87,6 +86,7 @@ class CSHARP:public Language { int n_directors; int first_class_dmethod; int curr_class_dmethod; + int nesting_depth; enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum }; @@ -125,7 +125,6 @@ public: proxy_class_code(NULL), module_class_code(NULL), proxy_class_name(NULL), - full_proxy_class_name(NULL), full_imclass_name(NULL), variable_name(NULL), proxy_class_constants_code(NULL), @@ -156,7 +155,8 @@ public: n_dmethods(0), n_directors(0), first_class_dmethod(0), - curr_class_dmethod(0) { + curr_class_dmethod(0), + nesting_depth(0){ /* for now, multiple inheritance in directors is disabled, this should be easy to implement though */ director_multiple_inheritance = 0; @@ -179,7 +179,13 @@ public: proxyname = Getattr(n, "proxyname"); if (!proxyname) { String *nspace = Getattr(n, "sym:nspace"); - String *symname = Getattr(n, "sym:name"); + String *symname = Copy(Getattr(n, "sym:name")); + if (symname && !GetFlag(n, "feature:flatnested")) { + for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) { + Push(symname, "."); + Push(symname, Getattr(outer_class, "sym:name")); + } + } if (nspace) { if (namespce) proxyname = NewStringf("%s.%s.%s", namespce, nspace, symname); @@ -190,12 +196,33 @@ public: } Setattr(n, "proxyname", proxyname); Delete(proxyname); + Delete(symname); } } } return proxyname; } + /* ----------------------------------------------------------------------------- + * directorClassName() + * ----------------------------------------------------------------------------- */ + + String *directorClassName(Node *n) { + String *dirclassname; + const char *attrib = "director:classname"; + + if (!(dirclassname = Getattr(n, attrib))) { + String *classname = getClassPrefix(); + + dirclassname = NewStringf("SwigDirector_%s", classname); + Setattr(n, attrib, dirclassname); + } + else + dirclassname = Copy(dirclassname); + + return dirclassname; + } + /* ------------------------------------------------------------ * main() * ------------------------------------------------------------ */ @@ -1025,7 +1052,7 @@ public: */ if (proxy_flag && wrapping_member_flag && !enum_constant_flag) { // Capitalize the first letter in the variable in the getter/setter function name - bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) != 0; + bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) != 0; String *getter_setter_name = NewString(""); if (!getter_flag) @@ -1589,6 +1616,7 @@ public: String *c_baseclassname = NULL; 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"); // Inheritance from pure C# classes Node *attributes = NewHash(); @@ -1648,7 +1676,8 @@ public: // Pure C# interfaces const String *pure_interfaces = typemapLookup(n, derived ? "csinterfaces_derived" : "csinterfaces", typemap_lookup_type, WARN_NONE); // Start writing the proxy class - Printv(proxy_class_def, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements + if (!has_outerclass) + Printv(proxy_class_def, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements "\n", NIL); // Class attributes @@ -1719,7 +1748,7 @@ public: Printf(proxy_class_code, " if (SwigDerivedClassHasMethod(\"%s\", swigMethodTypes%s))\n", method, methid); Printf(proxy_class_code, " swigDelegate%s = new SwigDelegate%s_%s(SwigDirector%s);\n", methid, proxy_class_name, methid, overname); } - String *director_connect_method_name = Swig_name_member(getNSpace(), proxy_class_name, "director_connect"); + String *director_connect_method_name = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect"); Printf(proxy_class_code, " %s.%s(swigCPtr", imclass_name, director_connect_method_name); for (i = first_class_dmethod; i < curr_class_dmethod; ++i) { UpcallData *udata = Getitem(dmethods_seq, i); @@ -1795,7 +1824,7 @@ public: // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy) if (derived) { String *smartptr = Getattr(n, "feature:smartptr"); - String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, smartptr != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); + String *upcast_method = Swig_name_member(getNSpace(), getClassPrefix(), smartptr != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); String *wname = Swig_name_wrapper(upcast_method); Printv(imclass_cppcasts_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL); @@ -1846,11 +1875,35 @@ public: String *nspace = getNSpace(); File *f_proxy = NULL; + // save class local variables + String *old_proxy_class_name = proxy_class_name; + String *old_full_imclass_name = full_imclass_name; + String *old_destructor_call = destructor_call; + String *old_proxy_class_constants_code = proxy_class_constants_code; + String *old_proxy_class_def = proxy_class_def; + String *old_proxy_class_code = proxy_class_code; + if (proxy_flag) { proxy_class_name = NewString(Getattr(n, "sym:name")); + 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")) { + Push(outerClassesPrefix, "::"); + Push(outerClassesPrefix, Getattr(outer, "sym:name")); + } + String *fnspace = nspace ? NewStringf("%s::%s", nspace, outerClassesPrefix) : outerClassesPrefix; + if (!addSymbol(proxy_class_name, n, fnspace)) + return SWIG_ERROR; + if (nspace) + Delete(fnspace); + Delete(outerClassesPrefix); + } + else { + if (!addSymbol(proxy_class_name, n, nspace)) + return SWIG_ERROR; + } if (!nspace) { - full_proxy_class_name = NewStringf("%s", proxy_class_name); 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); @@ -1863,36 +1916,34 @@ public: } } else { if (namespce) { - full_proxy_class_name = NewStringf("%s.%s.%s", namespce, nspace, proxy_class_name); full_imclass_name = NewStringf("%s.%s", namespce, imclass_name); } else { - full_proxy_class_name = NewStringf("%s.%s", nspace, proxy_class_name); full_imclass_name = NewStringf("%s", imclass_name); } } - if (!addSymbol(proxy_class_name, n, nspace)) - return SWIG_ERROR; - - String *output_directory = outputDirectory(nspace); - String *filen = NewStringf("%s%s.cs", output_directory, proxy_class_name); - f_proxy = NewFile(filen, "w", SWIG_output_files()); - if (!f_proxy) { - FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - filen = NULL; - - // Start writing out the proxy class file - emitBanner(f_proxy); - - addOpenNamespace(nspace, f_proxy); + // inner class doesn't need this prologue + if (!Getattr(n, "nested:outer")) { + String *output_directory = outputDirectory(nspace); + String *filen = NewStringf("%s%s.cs", output_directory, proxy_class_name); + f_proxy = NewFile(filen, "w", SWIG_output_files()); + if (!f_proxy) { + FileErrorDisplay(filen); + SWIG_exit(EXIT_FAILURE); + } + Append(filenames_list, Copy(filen)); + Delete(filen); + filen = NULL; - Clear(proxy_class_def); - Clear(proxy_class_code); + // Start writing out the proxy class file + emitBanner(f_proxy); + addOpenNamespace(nspace, f_proxy); + } + else + ++nesting_depth; + proxy_class_def = NewString(""); + proxy_class_code = NewString(""); destructor_call = NewString(""); proxy_class_constants_code = NewString(""); } @@ -1903,7 +1954,7 @@ public: emitProxyClassDefAndCPPCasts(n); - String *csclazzname = Swig_name_member(getNSpace(), proxy_class_name, ""); // mangled full proxy class name + String *csclazzname = Swig_name_member(getNSpace(), getClassPrefix(), ""); // mangled full proxy class name Replaceall(proxy_class_def, "$csclassname", proxy_class_name); Replaceall(proxy_class_code, "$csclassname", proxy_class_name); @@ -1924,17 +1975,36 @@ public: Replaceall(proxy_class_def, "$dllimport", dllimport); Replaceall(proxy_class_code, "$dllimport", dllimport); Replaceall(proxy_class_constants_code, "$dllimport", dllimport); - - Printv(f_proxy, proxy_class_def, proxy_class_code, NIL); + bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested"); + if (!has_outerclass) + Printv(f_proxy, proxy_class_def, proxy_class_code, NIL); + else { + Swig_offset_string(proxy_class_def, nesting_depth); + Append(old_proxy_class_code, proxy_class_def); + Swig_offset_string(proxy_class_code, nesting_depth); + Append(old_proxy_class_code, proxy_class_code); + } // Write out all the constants - if (Len(proxy_class_constants_code) != 0) - Printv(f_proxy, proxy_class_constants_code, NIL); - - Printf(f_proxy, "}\n"); - addCloseNamespace(nspace, f_proxy); - Delete(f_proxy); - f_proxy = NULL; + if (Len(proxy_class_constants_code) != 0) { + if (!has_outerclass) + Printv(f_proxy, proxy_class_constants_code, NIL); + else { + Swig_offset_string(proxy_class_constants_code, nesting_depth); + Append(old_proxy_class_code, proxy_class_constants_code); + } + } + if (!has_outerclass) { + Printf(f_proxy, "}\n"); + addCloseNamespace(nspace, f_proxy); + Delete(f_proxy); + f_proxy = NULL; + } else { + for (int i = 0; i < nesting_depth; ++i) + Append(old_proxy_class_code, " "); + Append(old_proxy_class_code, "}\n\n"); + --nesting_depth; + } /* Output the downcast method, if necessary. Note: There's no other really good place to put this code, since Abstract Base Classes (ABCs) can and should have @@ -1971,17 +2041,18 @@ public: Delete(csclazzname); Delete(proxy_class_name); - proxy_class_name = NULL; - Delete(full_proxy_class_name); - full_proxy_class_name = NULL; + proxy_class_name = old_proxy_class_name; Delete(full_imclass_name); - full_imclass_name = NULL; + full_imclass_name = old_full_imclass_name; Delete(destructor_call); - destructor_call = NULL; + destructor_call = old_destructor_call; Delete(proxy_class_constants_code); - proxy_class_constants_code = NULL; + proxy_class_constants_code = old_proxy_class_constants_code; + Delete(proxy_class_def); + proxy_class_def = old_proxy_class_def; + Delete(proxy_class_code); + proxy_class_code = old_proxy_class_code; } - return SWIG_OK; } @@ -1994,7 +2065,7 @@ public: if (proxy_flag) { String *overloaded_name = getOverloadedName(n); - String *intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, overloaded_name); + String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name); Setattr(n, "proxyfuncname", Getattr(n, "sym:name")); Setattr(n, "imfuncname", intermediary_function_name); proxyClassFunctionHandler(n); @@ -2014,7 +2085,7 @@ public: if (proxy_flag) { String *overloaded_name = getOverloadedName(n); - String *intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, overloaded_name); + String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name); Setattr(n, "proxyfuncname", Getattr(n, "sym:name")); Setattr(n, "imfuncname", intermediary_function_name); proxyClassFunctionHandler(n); @@ -2094,7 +2165,7 @@ public: if (wrapping_member_flag && !enum_constant_flag) { // Properties - setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) == 0); + setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) == 0); if (setter_flag) Swig_typemap_attach_parms("csvarin", l, NULL); } @@ -2264,7 +2335,7 @@ public: Node *explicit_n = Getattr(n, "explicitcallnode"); if (explicit_n) { String *ex_overloaded_name = getOverloadedName(explicit_n); - String *ex_intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, ex_overloaded_name); + String *ex_intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), ex_overloaded_name); String *ex_imcall = Copy(imcall); Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name); @@ -3376,14 +3447,21 @@ public: // Output the director connect method: String *norm_name = SwigType_namestr(Getattr(n, "name")); - String *swig_director_connect = Swig_name_member(getNSpace(), proxy_class_name, "director_connect"); + String *dirclassname = directorClassName(n); + String *swig_director_connect = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect"); String *wname = Swig_name_wrapper(swig_director_connect); String *sym_name = Getattr(n, "sym:name"); String *qualified_classname = Copy(sym_name); String *nspace = getNSpace(); String *dirClassName = directorClassName(n); String *smartptr = Getattr(n, "feature:smartptr"); + if (!GetFlag(n, "feature:flatnested")) { + for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) { + Push(qualified_classname, "."); + Push(qualified_classname, Getattr(outer_class, "sym:name")); + } + } if (nspace) Insert(qualified_classname, 0, NewStringf("%s.", nspace)); @@ -3415,7 +3493,7 @@ public: Printf(code_wrap->def, ", "); if (i != first_class_dmethod) Printf(code_wrap->code, ", "); - Printf(code_wrap->def, "%s::SWIG_Callback%s_t callback%s", dirClassName, methid, methid); + Printf(code_wrap->def, "%s::SWIG_Callback%s_t callback%s", dirclassname, methid, methid); Printf(code_wrap->code, "callback%s", methid); Printf(imclass_class_code, ", %s.SwigDelegate%s_%s delegate%s", qualified_classname, sym_name, methid, methid); } @@ -3432,7 +3510,7 @@ public: Delete(wname); Delete(swig_director_connect); Delete(qualified_classname); - Delete(dirClassName); + Delete(dirclassname); } /* --------------------------------------------------------------- @@ -3485,7 +3563,7 @@ 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(), classname, overloaded_name)); + imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name)); qualified_return = SwigType_rcaststr(returntype, "c_result"); @@ -3931,6 +4009,7 @@ public: Delete(proxy_method_types); Delete(callback_def); Delete(callback_code); + Delete(dirclassname); DelWrapper(w); return status; @@ -3970,13 +4049,11 @@ public: String *basetype = Getattr(parent, "classtype"); String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 0); String *call = Swig_csuperclass_call(0, basetype, superparms); - String *classtype = SwigType_namestr(Getattr(n, "name")); Printf(f_directors, "%s::%s : %s, %s {\n", dirclassname, target, call, Getattr(parent, "director:ctor")); Printf(f_directors, " swig_init_callbacks();\n"); Printf(f_directors, "}\n\n"); - Delete(classtype); Delete(target); Delete(call); } @@ -4047,6 +4124,29 @@ public: return Language::classDirectorInit(n); } + int classDeclaration(Node *n) { + String *old_director_callback_typedefs = director_callback_typedefs; + String *old_director_callbacks = director_callbacks; + String *old_director_delegate_callback = director_delegate_callback; + String *old_director_delegate_definitions = director_delegate_definitions; + String *old_director_delegate_instances = director_delegate_instances; + String *old_director_method_types = director_method_types; + String *old_director_connect_parms = director_connect_parms; + + int ret = Language::classDeclaration(n); + + // these variables are deleted in emitProxyClassDefAndCPPCasts, hence no Delete here + director_callback_typedefs = old_director_callback_typedefs; + director_callbacks = old_director_callbacks; + director_delegate_callback = old_director_delegate_callback; + director_delegate_definitions = old_director_delegate_definitions; + director_delegate_instances = old_director_delegate_instances; + director_method_types = old_director_method_types; + director_connect_parms = old_director_connect_parms; + + return ret; + } + /* ---------------------------------------------------------------------- * classDirectorDestructor() * ---------------------------------------------------------------------- */ @@ -4079,7 +4179,7 @@ public: int classDirectorEnd(Node *n) { int i; - String *director_classname = directorClassName(n); + String *dirclassname = directorClassName(n); Wrapper *w = NewWrapper(); @@ -4089,7 +4189,7 @@ public: Printf(f_directors_h, " void swig_connect_director("); - Printf(w->def, "void %s::swig_connect_director(", director_classname); + Printf(w->def, "void %s::swig_connect_director(", dirclassname); for (i = first_class_dmethod; i < curr_class_dmethod; ++i) { UpcallData *udata = Getitem(dmethods_seq, i); @@ -4116,7 +4216,7 @@ public: Printf(f_directors_h, "};\n\n"); Printf(w->code, "}\n\n"); - Printf(w->code, "void %s::swig_init_callbacks() {\n", director_classname); + Printf(w->code, "void %s::swig_init_callbacks() {\n", dirclassname); for (i = first_class_dmethod; i < curr_class_dmethod; ++i) { UpcallData *udata = Getitem(dmethods_seq, i); String *overname = Getattr(udata, "overname"); @@ -4127,6 +4227,7 @@ public: Wrapper_print(w, f_directors); DelWrapper(w); + Delete(dirclassname); return Language::classDirectorEnd(n); } @@ -4159,8 +4260,8 @@ public: String *base = Getattr(n, "classtype"); String *class_ctor = NewString("Swig::Director()"); - String *directorname = directorClassName(n); - String *declaration = Swig_class_declaration(n, directorname); + String *dirclassname = directorClassName(n); + String *declaration = Swig_class_declaration(n, dirclassname); Printf(declaration, " : public %s, public Swig::Director", base); @@ -4168,9 +4269,12 @@ public: Setattr(n, "director:decl", declaration); Setattr(n, "director:ctor", class_ctor); - Delete(directorname); + Delete(dirclassname); } + bool nestedClassesSupported() const { + return true; + } }; /* class CSHARP */ /* ----------------------------------------------------------------------------- |