~ubuntu-branches/ubuntu/oneiric/swig1.3/oneiric

« back to all changes in this revision

Viewing changes to Source/Modules/csharp.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-12-06 10:27:08 UTC
  • mfrom: (1.2.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20071206102708-t37t62i45n595w0e
Tags: 1.3.33-2ubuntu1
* Merge with Debian; remaining changes:
  - Drop support for pike.
  - Use python2.5 instead of python2.4.
  - Clean Runtime/ as well.
  - Force a few environment variables.
* debian/Rules (clean): Remove Lib/ocaml/swigp4.ml.

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 * C# language module for SWIG.
8
8
 * ----------------------------------------------------------------------------- */
9
9
 
10
 
char cvsroot_csharp_cxx[] = "$Header: /cvsroot/swig/SWIG/Source/Modules/csharp.cxx,v 1.103 2006/11/15 23:45:47 wsfulton Exp $";
 
10
char cvsroot_csharp_cxx[] = "$Id: csharp.cxx 10099 2007-11-10 21:10:17Z wsfulton $";
11
11
 
12
12
#include "swigmod.h"
13
13
#include <limits.h>             // for INT_MAX
85
85
 
86
86
  enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum };
87
87
 
 
88
  static Parm *NewParmFromNode(SwigType *type, const String_or_char *name, Node *n) {
 
89
    Parm *p = NewParm(type, name);
 
90
    Setfile(p, Getfile(n));
 
91
    Setline(p, Getline(n));
 
92
    return p;
 
93
  }
 
94
 
88
95
public:
89
96
 
90
97
  /* -----------------------------------------------------------------------------
273
280
    String *outfile = Getattr(n, "outfile");
274
281
    String *outfile_h = Getattr(n, "outfile_h");
275
282
 
 
283
    if (!outfile) {
 
284
      Printf(stderr, "Unable to determine outfile\n");
 
285
      SWIG_exit(EXIT_FAILURE);
 
286
    }
 
287
 
276
288
    f_runtime = NewFile(outfile, "w");
277
289
    if (!f_runtime) {
278
290
      FileErrorDisplay(outfile);
280
292
    }
281
293
 
282
294
    if (directorsEnabled()) {
 
295
      if (!outfile_h) {
 
296
        Printf(stderr, "Unable to determine outfile_h\n");
 
297
        SWIG_exit(EXIT_FAILURE);
 
298
      }
283
299
      f_runtime_h = NewFile(outfile_h, "w");
284
300
      if (!f_runtime_h) {
285
301
        FileErrorDisplay(outfile_h);
359
375
        Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h));
360
376
    }
361
377
 
362
 
    String *wrapper_name = NewString("");
363
 
 
364
 
    Printf(wrapper_name, "CSharp_%%f", imclass_name);
365
 
    Swig_name_register((char *) "wrapper", Char(wrapper_name));
 
378
    Swig_name_register((char *) "wrapper", (char *) "CSharp_%f");
366
379
    if (old_variable_names) {
367
380
      Swig_name_register((char *) "set", (char *) "set_%v");
368
381
      Swig_name_register((char *) "get", (char *) "get_%v");
369
382
    }
370
383
 
371
 
    Delete(wrapper_name);
372
 
 
373
384
    Printf(f_wrappers, "\n#ifdef __cplusplus\n");
374
385
    Printf(f_wrappers, "extern \"C\" {\n");
375
386
    Printf(f_wrappers, "#endif\n\n");
912
923
        Replaceall(tm, "$source", "result");    /* deprecated */
913
924
        Replaceall(tm, "$target", "jresult");   /* deprecated */
914
925
        Replaceall(tm, "$result", "jresult");
 
926
 
 
927
        if (GetFlag(n, "feature:new"))
 
928
          Replaceall(tm, "$owner", "1");
 
929
        else
 
930
          Replaceall(tm, "$owner", "0");
 
931
 
915
932
        Printf(f->code, "%s", tm);
916
933
        null_attribute = Getattr(n, "tmap:out:null");
917
934
        if (Len(tm))
1456
1473
    String *typemap_lookup_type = Getattr(n, "classtypeobj");
1457
1474
    bool feature_director = Swig_directorclass(n) ? true : false;
1458
1475
 
1459
 
    /* Deal with inheritance */
1460
 
    List *baselist = Getattr(n, "bases");
1461
 
    if (baselist) {
1462
 
      Iterator base = First(baselist);
1463
 
      while (base.item && GetFlag(base.item, "feature:ignore")) {
1464
 
        base = Next(base);
1465
 
      }
1466
 
      if (base.item) {
1467
 
        c_baseclassname = Getattr(base.item, "name");
1468
 
        baseclass = Copy(getProxyName(c_baseclassname));
1469
 
        if (baseclass)
1470
 
          c_baseclass = SwigType_namestr(Getattr(base.item, "name"));
1471
 
        base = Next(base);
1472
 
        /* Warn about multiple inheritance for additional base class(es) */
1473
 
        while (base.item) {
1474
 
          if (GetFlag(base.item, "feature:ignore")) {
1475
 
            base = Next(base);
1476
 
            continue;
1477
 
          }
1478
 
          String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0);
1479
 
          String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0);
1480
 
          Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, input_file, line_number,
1481
 
                       "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#.\n", proxyclassname, baseclassname);
1482
 
          base = Next(base);
1483
 
        }
1484
 
      }
1485
 
    }
1486
1476
    // Inheritance from pure C# classes
1487
1477
    Node *attributes = NewHash();
1488
1478
    const String *pure_baseclass = typemapLookup("csbase", typemap_lookup_type, WARN_NONE, attributes);
 
1479
    bool purebase_replace = GetFlag(attributes, "tmap:csbase:replace") ? true : false;
 
1480
    Delete(attributes);
 
1481
 
 
1482
    // C++ inheritance
 
1483
    if (!purebase_replace) {
 
1484
      List *baselist = Getattr(n, "bases");
 
1485
      if (baselist) {
 
1486
        Iterator base = First(baselist);
 
1487
        while (base.item && GetFlag(base.item, "feature:ignore")) {
 
1488
          base = Next(base);
 
1489
        }
 
1490
        if (base.item) {
 
1491
          c_baseclassname = Getattr(base.item, "name");
 
1492
          baseclass = Copy(getProxyName(c_baseclassname));
 
1493
          if (baseclass)
 
1494
            c_baseclass = SwigType_namestr(Getattr(base.item, "name"));
 
1495
          base = Next(base);
 
1496
          /* Warn about multiple inheritance for additional base class(es) */
 
1497
          while (base.item) {
 
1498
            if (GetFlag(base.item, "feature:ignore")) {
 
1499
              base = Next(base);
 
1500
              continue;
 
1501
            }
 
1502
            String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0);
 
1503
            String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0);
 
1504
            Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, input_file, line_number,
 
1505
                         "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#.\n", proxyclassname, baseclassname);
 
1506
            base = Next(base);
 
1507
          }
 
1508
        }
 
1509
      }
 
1510
    }
 
1511
 
1489
1512
    const String *wanted_base = baseclass ? baseclass : pure_baseclass;
1490
1513
    bool derived = baseclass && getProxyName(c_baseclassname);
1491
1514
 
1492
 
    if (GetFlag(attributes, "tmap:csbase:replace")) {
 
1515
    if (purebase_replace) {
1493
1516
      wanted_base = pure_baseclass;
1494
 
      derived = *Char(wanted_base) ? true : false;
 
1517
      derived = false;
1495
1518
      Delete(baseclass);
1496
1519
      baseclass = NULL;
1497
1520
    } else if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) {
1498
1521
      Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, input_file, line_number,
1499
 
                   "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#.\n", typemap_lookup_type, pure_baseclass);
 
1522
                   "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#. Perhaps you need the replace attribute in the csbase typemap?\n", typemap_lookup_type, pure_baseclass);
1500
1523
    }
 
1524
 
1501
1525
    // Pure C# interfaces
1502
1526
    const String *pure_interfaces = typemapLookup(derived ? "csinterfaces_derived" : "csinterfaces", typemap_lookup_type, WARN_NONE);
1503
1527
    // Start writing the proxy class
1532
1556
      destruct_methodname = Getattr(attributes, "tmap:csdestruct:methodname");
1533
1557
      destruct_methodmodifiers = Getattr(attributes, "tmap:csdestruct:methodmodifiers");
1534
1558
    }
1535
 
    if (*Char(tm)) {
 
1559
    if (tm && *Char(tm)) {
1536
1560
      if (!destruct_methodname) {
1537
1561
        Swig_error(input_file, line_number, "No methodname attribute defined in csdestruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name);
1538
1562
      }
1563
1587
      // put this in classDirectorEnd ???
1564
1588
      Printf(proxy_class_code, "  private void SwigDirectorConnect() {\n");
1565
1589
 
1566
 
      for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) {
 
1590
      int i;
 
1591
      for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
1567
1592
        UpcallData *udata = Getitem(dmethods_seq, i);
1568
1593
        String *method = Getattr(udata, "method");
1569
1594
        String *methid = Getattr(udata, "class_methodidx");
 
1595
        String *overname = Getattr(udata, "overname");
1570
1596
        Printf(proxy_class_code, "    if (SwigDerivedClassHasMethod(\"%s\", swigMethodTypes%s))\n", method, methid);
1571
 
        Printf(proxy_class_code, "      swigDelegate%s = new SwigDelegate%s_%s(SwigDirector%s);\n", methid, proxy_class_name, methid, method);
 
1597
        Printf(proxy_class_code, "      swigDelegate%s = new SwigDelegate%s_%s(SwigDirector%s);\n", methid, proxy_class_name, methid, overname);
1572
1598
      }
1573
1599
      Printf(proxy_class_code, "    %s.%s_director_connect(swigCPtr", imclass_name, proxy_class_name);
1574
 
      for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) {
 
1600
      for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
1575
1601
        UpcallData *udata = Getitem(dmethods_seq, i);
1576
1602
        String *methid = Getattr(udata, "class_methodidx");
1577
1603
        Printf(proxy_class_code, ", swigDelegate%s", methid);
1847
1873
    String *return_type = NewString("");
1848
1874
    String *function_code = NewString("");
1849
1875
    bool setter_flag = false;
 
1876
    String *pre_code = NewString("");
 
1877
    String *post_code = NewString("");
1850
1878
 
1851
1879
    if (!proxy_flag)
1852
1880
      return;
1889
1917
    if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
1890
1918
      // Properties
1891
1919
      setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(Swig_name_member(proxy_class_name, variable_name))) == 0);
 
1920
      if (setter_flag)
 
1921
        Swig_typemap_attach_parms("csvarin", l, NULL);
1892
1922
    }
1893
1923
 
1894
1924
    /* Start generating the proxy function */
1929
1959
      Printf(function_code, "static ");
1930
1960
    Printf(function_code, "%s %s(", return_type, proxy_function_name);
1931
1961
 
1932
 
    Printv(imcall, imclass_name, ".", intermediary_function_name, "(", NIL);
 
1962
    Printv(imcall, imclass_name, ".$imfuncname(", NIL);
1933
1963
    if (!static_flag)
1934
1964
      Printf(imcall, "swigCPtr");
1935
1965
 
1976
2006
        if ((tm = Getattr(p, "tmap:csin"))) {
1977
2007
          substituteClassname(pt, tm);
1978
2008
          Replaceall(tm, "$csinput", arg);
 
2009
          String *pre = Getattr(p, "tmap:csin:pre");
 
2010
          if (pre) {
 
2011
            substituteClassname(pt, pre);
 
2012
            Replaceall(pre, "$csinput", arg);
 
2013
            if (Len(pre_code) > 0)
 
2014
              Printf(pre_code, "\n");
 
2015
            Printv(pre_code, pre, NIL);
 
2016
          }
 
2017
          String *post = Getattr(p, "tmap:csin:post");
 
2018
          if (post) {
 
2019
            substituteClassname(pt, post);
 
2020
            Replaceall(post, "$csinput", arg);
 
2021
            if (Len(post_code) > 0)
 
2022
              Printf(post_code, "\n");
 
2023
            Printv(post_code, post, NIL);
 
2024
          }
1979
2025
          Printv(imcall, tm, NIL);
1980
2026
        } else {
1981
2027
          Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0));
1998
2044
 
1999
2045
    // Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in proxy class)
2000
2046
    if ((tm = Swig_typemap_lookup_new("csout", n, "", 0))) {
 
2047
      excodeSubstitute(n, tm, "csout", n);
 
2048
      bool is_pre_code = Len(pre_code) > 0;
 
2049
      bool is_post_code = Len(post_code) > 0;
 
2050
      if (is_pre_code || is_post_code) {
 
2051
        Replaceall(tm, "\n ", "\n   "); // add extra indentation to code in typemap
 
2052
        if (is_post_code) {
 
2053
          Insert(tm, 0, "\n    try ");
 
2054
          Printv(tm, " finally {\n", post_code, "\n    }", NIL);
 
2055
        } else {
 
2056
          Insert(tm, 0, "\n    ");
 
2057
        }
 
2058
        if (is_pre_code) {
 
2059
          Insert(tm, 0, pre_code);
 
2060
          Insert(tm, 0, "\n");
 
2061
        }
 
2062
        Insert(tm, 0, "{");
 
2063
        Printf(tm, "\n  }");
 
2064
      }
2001
2065
      if (GetFlag(n, "feature:new"))
2002
2066
        Replaceall(tm, "$owner", "true");
2003
2067
      else
2012
2076
        String *ex_intermediary_function_name = Swig_name_member(proxy_class_name, ex_overloaded_name);
2013
2077
 
2014
2078
        String *ex_imcall = Copy(imcall);
2015
 
        Replaceall(ex_imcall, intermediary_function_name, ex_intermediary_function_name);
 
2079
        Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name);
 
2080
        Replaceall(imcall, "$imfuncname", intermediary_function_name);
2016
2081
 
2017
2082
        String *excode = NewString("");
2018
2083
        if (!Cmp(return_type, "void"))
2024
2089
        Printv(imcall, excode, NIL);
2025
2090
        Delete(ex_overloaded_name);
2026
2091
        Delete(excode);
 
2092
      } else {
 
2093
        Replaceall(imcall, "$imfuncname", intermediary_function_name);
2027
2094
      }
2028
2095
      Replaceall(tm, "$imcall", imcall);
2029
 
      excodeSubstitute(n, tm, "csout", n);
2030
2096
    } else {
2031
2097
      Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
2032
2098
    }
2041
2107
          SwigType *pt = Getattr(p, "type");
2042
2108
          if ((tm = Getattr(p, "tmap:cstype"))) {
2043
2109
            substituteClassname(pt, tm);
2044
 
            variable_type = tm;
 
2110
            String *cstypeout = Getattr(p, "tmap:cstype:out");  // the type in the cstype typemap's out attribute overrides the type in the typemap
 
2111
            variable_type = cstypeout ? cstypeout : tm;
2045
2112
          } else {
2046
2113
            Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarin typemap defined for %s\n", SwigType_str(pt, 0));
2047
2114
          }
2058
2125
 
2059
2126
      if (setter_flag) {
2060
2127
        // Setter method
2061
 
        Swig_typemap_attach_parms("csvarin", l, NULL);
2062
2128
        p = last_parm;          // (last parameter is the only parameter for properties)
2063
2129
        SwigType *pt = Getattr(p, "type");
2064
2130
        if ((tm = Getattr(p, "tmap:csvarin"))) {
2090
2156
      Printv(proxy_class_code, function_code, NIL);
2091
2157
    }
2092
2158
 
 
2159
    Delete(pre_code);
 
2160
    Delete(post_code);
2093
2161
    Delete(function_code);
2094
2162
    Delete(return_type);
2095
2163
    Delete(imcall);
2106
2174
    Parm *p;
2107
2175
    int i;
2108
2176
    String *function_code = NewString("");
 
2177
    String *helper_code = NewString(""); // Holds code for the constructor helper method generated only when the csin typemap has code in the pre or post attributes
 
2178
    String *helper_args = NewString("");
 
2179
    String *pre_code = NewString("");
 
2180
    String *post_code = NewString("");
 
2181
    String *im_return_type = NewString("");
2109
2182
    bool feature_director = (parentNode(n) && Swig_directorclass(n));
2110
2183
 
2111
2184
    Language::constructorHandler(n);
2120
2193
      String *imcall = NewString("");
2121
2194
 
2122
2195
      const String *csattributes = Getattr(n, "feature:cs:attributes");
2123
 
      if (csattributes)
 
2196
      if (csattributes) {
2124
2197
        Printf(function_code, "  %s\n", csattributes);
 
2198
        Printf(helper_code, "  %s\n", csattributes);
 
2199
      }
2125
2200
      const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
2126
2201
      methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
 
2202
 
 
2203
      tm = Getattr(n, "tmap:imtype"); // typemaps were attached earlier to the node
 
2204
      String *imtypeout = Getattr(n, "tmap:imtype:out");        // the type in the imtype typemap's out attribute overrides the type in the typemap
 
2205
      if (imtypeout)
 
2206
        tm = imtypeout;
 
2207
      Printf(im_return_type, "%s", tm);
 
2208
 
2127
2209
      Printf(function_code, "  %s %s(", methodmods, proxy_class_name);
 
2210
      Printf(helper_code, "  static private %s SwigConstruct%s(", im_return_type, proxy_class_name);
 
2211
 
2128
2212
      Printv(imcall, imclass_name, ".", mangled_overname, "(", NIL);
2129
2213
 
2130
2214
      /* Attach the non-standard typemaps to the parameter list */
2167
2251
          Printf(imcall, ", ");
2168
2252
 
2169
2253
        String *arg = makeParameterName(n, p, i, false);
 
2254
        String *cshin = 0;
2170
2255
 
2171
2256
        // Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class)
2172
2257
        if ((tm = Getattr(p, "tmap:csin"))) {
2173
2258
          substituteClassname(pt, tm);
2174
2259
          Replaceall(tm, "$csinput", arg);
 
2260
          String *pre = Getattr(p, "tmap:csin:pre");
 
2261
          if (pre) {
 
2262
            substituteClassname(pt, pre);
 
2263
            Replaceall(pre, "$csinput", arg);
 
2264
            if (Len(pre_code) > 0)
 
2265
              Printf(pre_code, "\n");
 
2266
            Printv(pre_code, pre, NIL);
 
2267
          }
 
2268
          String *post = Getattr(p, "tmap:csin:post");
 
2269
          if (post) {
 
2270
            substituteClassname(pt, post);
 
2271
            Replaceall(post, "$csinput", arg);
 
2272
            if (Len(post_code) > 0)
 
2273
              Printf(post_code, "\n");
 
2274
            Printv(post_code, post, NIL);
 
2275
          }
 
2276
          cshin = Getattr(p, "tmap:csin:cshin");
 
2277
          if (cshin)
 
2278
            Replaceall(cshin, "$csinput", arg);
2175
2279
          Printv(imcall, tm, NIL);
2176
2280
        } else {
2177
2281
          Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0));
2178
2282
        }
2179
2283
 
2180
2284
        /* Add parameter to proxy function */
2181
 
        if (gencomma)
 
2285
        if (gencomma) {
2182
2286
          Printf(function_code, ", ");
 
2287
          Printf(helper_code, ", ");
 
2288
          Printf(helper_args, ", ");
 
2289
        }
2183
2290
        Printf(function_code, "%s %s", param_type, arg);
 
2291
        Printf(helper_code, "%s %s", param_type, arg);
 
2292
        Printf(helper_args, "%s", cshin ? cshin : arg);
2184
2293
        ++gencomma;
2185
2294
 
 
2295
        Delete(cshin);
2186
2296
        Delete(arg);
2187
2297
        Delete(param_type);
2188
2298
        p = Getattr(p, "tmap:in:next");
2191
2301
      Printf(imcall, ")");
2192
2302
 
2193
2303
      Printf(function_code, ")");
 
2304
      Printf(helper_code, ")");
2194
2305
 
2195
2306
      /* Insert the csconstruct typemap, doing the replacement for $directorconnect, as needed */
2196
2307
      Hash *attributes = NewHash();
2214
2325
        Printv(function_code, " ", construct_tm, NIL);
2215
2326
      }
2216
2327
 
2217
 
      Replaceall(function_code, "$imcall", imcall);
2218
2328
      excodeSubstitute(n, function_code, "csconstruct", attributes);
 
2329
 
 
2330
      bool is_pre_code = Len(pre_code) > 0;
 
2331
      bool is_post_code = Len(post_code) > 0;
 
2332
      if (is_pre_code || is_post_code) {
 
2333
        Printf(helper_code, " {\n");
 
2334
        if (is_pre_code) {
 
2335
          Printv(helper_code, pre_code, "\n", NIL);
 
2336
        }
 
2337
        if (is_post_code) {
 
2338
          Printf(helper_code, "    try {\n");
 
2339
          Printv(helper_code, "      return ", imcall, ";\n", NIL);
 
2340
          Printv(helper_code, "    } finally {\n", post_code, "\n    }", NIL);
 
2341
        } else {
 
2342
          Printv(helper_code, "    return ", imcall, ";", NIL);
 
2343
        }
 
2344
        Printf(helper_code, "\n  }\n");
 
2345
        String *helper_name = NewStringf("%s.SwigConstruct%s(%s)", proxy_class_name, proxy_class_name, helper_args);
 
2346
        String *im_outattribute = Getattr(n, "tmap:imtype:outattributes");
 
2347
        if (im_outattribute)
 
2348
          Printf(proxy_class_code, "  %s\n", im_outattribute);
 
2349
        Printv(proxy_class_code, helper_code, "\n", NIL);
 
2350
        Replaceall(function_code, "$imcall", helper_name);
 
2351
        Delete(helper_name);
 
2352
      } else {
 
2353
        Replaceall(function_code, "$imcall", imcall);
 
2354
      }
 
2355
 
2219
2356
      Printv(proxy_class_code, function_code, "\n", NIL);
2220
2357
 
 
2358
      Delete(helper_args);
 
2359
      Delete(im_return_type);
 
2360
      Delete(pre_code);
 
2361
      Delete(post_code);
2221
2362
      Delete(construct_tm);
2222
2363
      Delete(attributes);
2223
2364
      Delete(overloaded_name);
2333
2474
    String *overloaded_name = getOverloadedName(n);
2334
2475
    String *func_name = NULL;
2335
2476
    bool setter_flag = false;
 
2477
    String *pre_code = NewString("");
 
2478
    String *post_code = NewString("");
2336
2479
 
2337
2480
    if (l) {
2338
2481
      if (SwigType_type(Getattr(l, "type")) == T_VOID) {
2366
2509
        Printf(func_name, "get");
2367
2510
      Putc(toupper((int) *Char(variable_name)), func_name);
2368
2511
      Printf(func_name, "%s", Char(variable_name) + 1);
 
2512
      if (setter_flag)
 
2513
        Swig_typemap_attach_parms("csvarin", l, NULL);
2369
2514
    } else {
2370
2515
      func_name = Copy(Getattr(n, "sym:name"));
2371
2516
    }
2418
2563
      if ((tm = Getattr(p, "tmap:csin"))) {
2419
2564
        substituteClassname(pt, tm);
2420
2565
        Replaceall(tm, "$csinput", arg);
 
2566
        String *pre = Getattr(p, "tmap:csin:pre");
 
2567
        if (pre) {
 
2568
          substituteClassname(pt, pre);
 
2569
          Replaceall(pre, "$csinput", arg);
 
2570
          if (Len(pre_code) > 0)
 
2571
            Printf(pre_code, "\n");
 
2572
          Printv(pre_code, pre, NIL);
 
2573
        }
 
2574
        String *post = Getattr(p, "tmap:csin:post");
 
2575
        if (post) {
 
2576
          substituteClassname(pt, post);
 
2577
          Replaceall(post, "$csinput", arg);
 
2578
          if (Len(post_code) > 0)
 
2579
            Printf(post_code, "\n");
 
2580
          Printv(post_code, post, NIL);
 
2581
        }
2421
2582
        Printv(imcall, tm, NIL);
2422
2583
      } else {
2423
2584
        Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0));
2439
2600
 
2440
2601
    // Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in module class)
2441
2602
    if ((tm = Swig_typemap_lookup_new("csout", n, "", 0))) {
 
2603
      excodeSubstitute(n, tm, "csout", n);
 
2604
      bool is_pre_code = Len(pre_code) > 0;
 
2605
      bool is_post_code = Len(post_code) > 0;
 
2606
      if (is_pre_code || is_post_code) {
 
2607
        Replaceall(tm, "\n ", "\n   "); // add extra indentation to code in typemap
 
2608
        if (is_post_code) {
 
2609
          Insert(tm, 0, "\n    try ");
 
2610
          Printv(tm, " finally {\n", post_code, "\n    }", NIL);
 
2611
        } else {
 
2612
          Insert(tm, 0, "\n    ");
 
2613
        }
 
2614
        if (is_pre_code) {
 
2615
          Insert(tm, 0, pre_code);
 
2616
          Insert(tm, 0, "\n");
 
2617
        }
 
2618
        Insert(tm, 0, "{");
 
2619
        Printf(tm, "\n  }");
 
2620
      }
2442
2621
      if (GetFlag(n, "feature:new"))
2443
2622
        Replaceall(tm, "$owner", "true");
2444
2623
      else
2445
2624
        Replaceall(tm, "$owner", "false");
2446
2625
      substituteClassname(t, tm);
2447
2626
      Replaceall(tm, "$imcall", imcall);
2448
 
      excodeSubstitute(n, tm, "csout", n);
2449
2627
    } else {
2450
2628
      Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
2451
2629
    }
2460
2638
          SwigType *pt = Getattr(p, "type");
2461
2639
          if ((tm = Getattr(p, "tmap:cstype"))) {
2462
2640
            substituteClassname(pt, tm);
2463
 
            variable_type = tm;
 
2641
            String *cstypeout = Getattr(p, "tmap:cstype:out");  // the type in the cstype typemap's out attribute overrides the type in the typemap
 
2642
            variable_type = cstypeout ? cstypeout : tm;
2464
2643
          } else {
2465
2644
            Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarin typemap defined for %s\n", SwigType_str(pt, 0));
2466
2645
          }
2477
2656
 
2478
2657
      if (setter_flag) {
2479
2658
        // Setter method
2480
 
        Swig_typemap_attach_parms("csvarin", l, NULL);
2481
2659
        p = last_parm;          // (last parameter is the only parameter for properties)
2482
2660
        SwigType *pt = Getattr(p, "type");
2483
2661
        if ((tm = Getattr(p, "tmap:csvarin"))) {
2484
2662
          substituteClassname(pt, tm);
 
2663
          Replaceall(tm, "$csinput", "value");
2485
2664
          Replaceall(tm, "$imcall", imcall);
2486
2665
          excodeSubstitute(n, tm, "csvarin", p);
2487
2666
          Printf(module_class_code, "%s", tm);
2509
2688
      Printv(module_class_code, function_code, NIL);
2510
2689
    }
2511
2690
 
 
2691
    Delete(pre_code);
 
2692
    Delete(post_code);
2512
2693
    Delete(function_code);
2513
2694
    Delete(return_type);
2514
2695
    Delete(imcall);
2696
2877
    String *arg = 0;
2697
2878
    String *pn = Getattr(p, "name");
2698
2879
    if (setter) {
2699
 
      // Note that in C# property setter names must always be called 'value'
 
2880
      // Note that in C# properties, the input variable name is always called 'value'
2700
2881
      arg = NewString("value");
2701
2882
    } else {
2702
2883
      // Use C parameter name unless it is a duplicate or an empty parameter name
3004
3185
      if (!is_void && !ignored_method) {
3005
3186
        if (!SwigType_isclass(returntype)) {
3006
3187
          if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
3007
 
            Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), NIL);
 
3188
            String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
 
3189
            Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
 
3190
            Delete(construct_result);
3008
3191
          } else {
3009
3192
            String *base_typename = SwigType_base(returntype);
3010
3193
            String *resolved_typename = SwigType_typedef_resolve_all(base_typename);
3054
3237
        String *imtypeout = Getattr(tp, "tmap:imtype:out");     // the type in the imtype typemap's out attribute overrides the type in the typemap
3055
3238
        if (imtypeout)
3056
3239
          tm = imtypeout;
3057
 
        Printf(callback_def, "  private %s SwigDirector%s(", tm, symname);
 
3240
        Printf(callback_def, "  private %s SwigDirector%s(", tm, overloaded_name);
3058
3241
        if (!ignored_method)
3059
3242
          Printf(director_delegate_definitions, "  public delegate %s", tm);
3060
3243
      } else {
3067
3250
 
3068
3251
        if (!is_void && !ignored_method) {
3069
3252
          String *jretval_decl = NewStringf("%s jresult", c_ret_type);
3070
 
          Wrapper_add_localv(w, "jresult", jretval_decl, " = 0", NIL);
 
3253
          Wrapper_add_localv(w, "jresult", jretval_decl, "= 0", NIL);
3071
3254
          Delete(jretval_decl);
3072
3255
        }
3073
3256
      } else {
3164
3347
            && (tm = Getattr(p, "tmap:directorin"))) {
3165
3348
 
3166
3349
          Replaceall(tm, "$input", arg);
 
3350
          Replaceall(tm, "$owner", "0");
3167
3351
 
3168
3352
          if (Len(tm))
3169
3353
            if (!ignored_method)
3573
3757
   * ------------------------------------------------------------ */
3574
3758
 
3575
3759
  int classDirectorEnd(Node *n) {
 
3760
    int i;
3576
3761
    String *director_classname = directorClassName(n);
3577
3762
 
3578
3763
    Wrapper *w = NewWrapper();
3585
3770
 
3586
3771
    Printf(w->def, "void %s::swig_connect_director(", director_classname);
3587
3772
 
3588
 
    for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) {
 
3773
    for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
3589
3774
      UpcallData *udata = Getitem(dmethods_seq, i);
3590
3775
      String *methid = Getattr(udata, "class_methodidx");
3591
3776
      String *overname = Getattr(udata, "overname");
3611
3796
    Printf(w->code, "}\n\n");
3612
3797
 
3613
3798
    Printf(w->code, "void %s::swig_init_callbacks() {\n", director_classname);
3614
 
    for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) {
 
3799
    for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
3615
3800
      UpcallData *udata = Getitem(dmethods_seq, i);
3616
3801
      String *overname = Getattr(udata, "overname");
3617
3802
      Printf(w->code, "swig_callback%s = 0;\n", overname);