Browse Source

Fixed handling of property indexers in the CLI generator.

pull/219/merge
triton 11 years ago
parent
commit
e95a2929a8
  1. 3
      src/Generator.Tests/GeneratorTest.cs
  2. 28
      src/Generator/Generators/CLI/CLIHeadersTemplate.cs
  3. 41
      src/Generator/Generators/CLI/CLISourcesTemplate.cs
  4. 18
      src/Generator/Passes/CheckOperatorsOverloads.cs
  5. 7
      tests/Basic/Basic.Tests.cs
  6. 9
      tests/Basic/Basic.h

3
src/Generator.Tests/GeneratorTest.cs

@ -30,8 +30,9 @@ namespace CppSharp.Utils @@ -30,8 +30,9 @@ namespace CppSharp.Utils
options.OutputDir = Path.Combine(GetOutputDirectory(), "gen", name);
options.SharedLibraryName = name + ".Native";
options.GenerateLibraryNamespace = true;
options.Quiet = true;
options.Quiet = false;
options.IgnoreParseWarnings = true;
options.Verbose = true;
driver.Diagnostics.EmitMessage("");
driver.Diagnostics.EmitMessage("Generating bindings for {0} ({1})",

28
src/Generator/Generators/CLI/CLIHeadersTemplate.cs

@ -621,6 +621,22 @@ namespace CppSharp.Generators.CLI @@ -621,6 +621,22 @@ namespace CppSharp.Generators.CLI
PopIndent();
}
public void GenerateIndexer(Property property)
{
var type = property.QualifiedType.Visit(TypePrinter);
WriteLine("property {0} default[int]", type);
WriteStartBraceIndent();
if (property.HasGetter)
WriteLine("{0} get(int index);", type);
if (property.HasSetter)
WriteLine("void set(int index, {0});", type);
WriteCloseBraceIndent();
}
public void GenerateProperty(Property property)
{
if (!(property.HasGetter || property.HasSetter))
@ -629,16 +645,24 @@ namespace CppSharp.Generators.CLI @@ -629,16 +645,24 @@ namespace CppSharp.Generators.CLI
PushBlock(CLIBlockKind.Property, property);
var type = property.QualifiedType.Visit(TypePrinter);
if (property.IsIndexer)
{
GenerateIndexer(property);
}
else
{
WriteLine("property {0} {1}", type, property.Name);
WriteStartBraceIndent();
if(property.HasGetter)
if (property.HasGetter)
WriteLine("{0} get();", type);
if(property.HasSetter)
if (property.HasSetter)
WriteLine("void set({0});", type);
WriteCloseBraceIndent();
}
PopBlock(NewLineKind.BeforeNextBlock);
}

41
src/Generator/Generators/CLI/CLISourcesTemplate.cs

@ -312,7 +312,6 @@ namespace CppSharp.Generators.CLI @@ -312,7 +312,6 @@ namespace CppSharp.Generators.CLI
if (property.Ignore) return;
PushBlock(CLIBlockKind.Property);
var @class = property.Namespace as Class;
if (property.Field != null)
{
@ -343,15 +342,23 @@ namespace CppSharp.Generators.CLI @@ -343,15 +342,23 @@ namespace CppSharp.Generators.CLI
if (decl == null)
return;
WriteLine("void {0}::{1}::set({2} value)", QualifiedIdentifier(@class),
name, type);
var method = decl as Method;
var isIndexer = method != null &&
method.OperatorKind == CXXOperatorKind.Subscript;
var args = new List<string>();
if (isIndexer)
args.Add("int index");
args.Add(string.Format("{0} value", type));
WriteLine("void {0}::{1}::set({2})", QualifiedIdentifier(@class),
name, string.Join(", ", args));
WriteStartBraceIndent();
if (decl is Function)
if (decl is Function && !isIndexer)
{
var func = decl as Function;
if(func.Parameters[0].Name != "value")
WriteLine("auto {0} = value;", func.Parameters[0].Name);
GenerateFunctionCall(func, @class);
}
else
@ -386,6 +393,9 @@ namespace CppSharp.Generators.CLI @@ -386,6 +393,9 @@ namespace CppSharp.Generators.CLI
variable = string.Format("((::{0}*)NativePtr)->{1}",
@class.QualifiedOriginalName, decl.OriginalName);
if (isIndexer)
variable += "(index)";
if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
Write(marshal.Context.SupportBefore);
@ -402,8 +412,17 @@ namespace CppSharp.Generators.CLI @@ -402,8 +412,17 @@ namespace CppSharp.Generators.CLI
if (decl == null)
return;
WriteLine("{0} {1}::{2}::get()", type, QualifiedIdentifier(@class),
name);
var method = decl as Method;
var isIndexer = method != null &&
method.OperatorKind == CXXOperatorKind.Subscript;
var args = new List<string>();
if (isIndexer)
args.Add("int index");
WriteLine("{0} {1}::{2}::get({3})", type, QualifiedIdentifier(@class),
name, string.Join(", ", args));
WriteStartBraceIndent();
if (decl is Function)
@ -855,7 +874,8 @@ namespace CppSharp.Generators.CLI @@ -855,7 +874,8 @@ namespace CppSharp.Generators.CLI
var typeName = method.ConversionType.Visit(typePrinter);
WriteLine("({0}) {1};", typeName, @params[0].Name);
}
else if (function.IsOperator)
else if (function.IsOperator &&
function.OperatorKind != CXXOperatorKind.Subscript)
{
var opName = function.Name.Replace("operator", "").Trim();
@ -865,8 +885,7 @@ namespace CppSharp.Generators.CLI @@ -865,8 +885,7 @@ namespace CppSharp.Generators.CLI
WriteLine("{0} {1};", opName, @params[0].Name);
break;
case CXXOperatorArity.Binary:
WriteLine("{0} {1} {2};", @params[0].Name, opName,
@params[1].Name);
WriteLine("{0} {1} {2};", @params[0].Name, opName, @params[1].Name);
break;
}
}

18
src/Generator/Passes/CheckOperatorsOverloads.cs

@ -86,9 +86,9 @@ namespace CppSharp.Passes @@ -86,9 +86,9 @@ namespace CppSharp.Passes
}
}
private static void CreateIndexer(Class @class, Method @operator)
void CreateIndexer(Class @class, Method @operator)
{
Property property = new Property
var property = new Property
{
Name = "Item",
QualifiedType = @operator.ReturnType,
@ -96,9 +96,21 @@ namespace CppSharp.Passes @@ -96,9 +96,21 @@ namespace CppSharp.Passes
Namespace = @class,
GetMethod = @operator
};
property.Parameters.AddRange(@operator.Parameters);
if (!@operator.ReturnType.Qualifiers.IsConst && @operator.ReturnType.Type.IsAddress())
property.SetMethod = @operator;
// C++/CLI uses "default" as the indexer property name.
if (Driver.Options.IsCLIGenerator)
property.Name = "default";
property.GetMethod.Parameters[0].Name = "index";
if (property.SetMethod != null)
property.SetMethod.Parameters[0].Name = "index";
property.Parameters.AddRange(@operator.Parameters);
@class.Properties.Add(property);
@operator.IsGenerated = false;
}

7
tests/Basic/Basic.Tests.cs

@ -218,5 +218,12 @@ public class BasicTests : GeneratorTestFixture @@ -218,5 +218,12 @@ public class BasicTests : GeneratorTestFixture
Assert.That(foo2.testCharMarshalling(c), Is.EqualTo(c));
Assert.Catch<ArgumentException>(() => foo2.testCharMarshalling('ж'));
}
[Test]
public unsafe void TestIndexers()
{
var someStruct = new SomeStruct();
Assert.That(someStruct[0], Is.EqualTo(1));
}
}

9
tests/Basic/Basic.h

@ -304,11 +304,12 @@ struct EmptyNamedNestedEnum @@ -304,11 +304,12 @@ struct EmptyNamedNestedEnum
};
typedef unsigned long foo_t;
typedef struct SomeStruct
typedef DLL_API struct SomeStruct
{
const foo_t& operator[](int i) const { return p[i]; }
foo_t& operator[](int i) { return p[i]; }
foo_t* p;
SomeStruct() : p(1) {}
const foo_t& operator[](int i) const { return p; }
foo_t operator[](int i) { return p; }
foo_t p;
}
SomeStruct;

Loading…
Cancel
Save