Browse Source

Merge pull request #61 from ddobrev/master

Read-only support for operator []
pull/62/merge
João Matos 12 years ago
parent
commit
c242c5d807
  1. 12
      src/AST/Property.cs
  2. 5
      src/Generator/Driver.cs
  3. 37
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  4. 8
      src/Generator/Passes/CheckAmbiguousFunctions.cs
  5. 58
      src/Generator/Passes/CheckOperatorsOverloads.cs
  6. 7
      tests/Basic/Basic.Tests.cs
  7. 4
      tests/Basic/Basic.h
  8. 21
      tests/CSharpTemp/CSharpTemp.Tests.cs
  9. 12
      tests/CSharpTemp/CSharpTemp.cpp
  10. 22
      tests/CSharpTemp/CSharpTemp.cs
  11. 15
      tests/CSharpTemp/CSharpTemp.h
  12. 2
      tests/CSharpTemp/premake4.lua
  13. 8
      tests/UTF16/UTF16.Tests.cs
  14. 13
      tests/UTF16/UTF16.cpp
  15. 4
      tests/UTF16/UTF16.h

12
src/AST/Property.cs

@ -1,3 +1,5 @@ @@ -1,3 +1,5 @@
using System.Collections.Generic;
namespace CppSharp.AST
{
/// <summary>
@ -36,6 +38,16 @@ namespace CppSharp.AST @@ -36,6 +38,16 @@ namespace CppSharp.AST
// The field that should be get and set by this property
public Field Field { get; set; }
private readonly List<Parameter> parameters = new List<Parameter>();
/// <summary>
/// Only applicable to index ([]) properties.
/// </summary>
public List<Parameter> Parameters
{
get { return parameters; }
}
public override T Visit<T>(IDeclVisitor<T> visitor)
{
return visitor.VisitProperty(this);

5
src/Generator/Driver.cs

@ -134,15 +134,16 @@ namespace CppSharp @@ -134,15 +134,16 @@ namespace CppSharp
TranslationUnitPasses.AddPass(new ResolveIncompleteDeclsPass());
TranslationUnitPasses.AddPass(new CleanInvalidDeclNamesPass());
TranslationUnitPasses.AddPass(new CheckIgnoredDeclsPass());
TranslationUnitPasses.AddPass(new GenerateInlinesCodePass());
if (Options.IsCSharpGenerator)
TranslationUnitPasses.AddPass(new GenerateInlinesCodePass());
library.SetupPasses(this);
TranslationUnitPasses.AddPass(new FindSymbolsPass());
TranslationUnitPasses.AddPass(new MoveOperatorToClassPass());
TranslationUnitPasses.AddPass(new CheckAmbiguousFunctions());
TranslationUnitPasses.AddPass(new CheckOperatorsOverloadsPass());
TranslationUnitPasses.AddPass(new CheckVirtualOverrideReturnCovariance());
TranslationUnitPasses.AddPass(new CheckAmbiguousFunctions());
Generator.SetupPasses();
TranslationUnitPasses.AddPass(new FieldToPropertyPass());

37
src/Generator/Generators/CSharp/CSharpTextTemplate.cs

@ -893,14 +893,12 @@ namespace CppSharp.Generators.CSharp @@ -893,14 +893,12 @@ namespace CppSharp.Generators.CSharp
private void GenerateClassProperties(Class @class)
{
foreach (var prop in @class.Properties)
foreach (var prop in @class.Properties.Where(p => !p.Ignore))
{
if (prop.Ignore) continue;
PushBlock(CSharpBlockKind.Property);
WriteLine("{0} {1} {2}",
prop.Access == AccessSpecifier.Public ? "public" : "protected",
prop.Type, SafeIdentifier(prop.Name));
prop.Type, GetPropertyName(prop));
WriteStartBraceIndent();
if (prop.Field != null)
@ -925,6 +923,12 @@ namespace CppSharp.Generators.CSharp @@ -925,6 +923,12 @@ namespace CppSharp.Generators.CSharp
}
}
private string GetPropertyName(Property prop)
{
return prop.Parameters.Count == 0 ? SafeIdentifier(prop.Name)
: string.Format("this[{0}]", FormatMethodParameters(prop.Parameters));
}
private void GenerateVariable(Class @class, Type type, Variable variable)
{
PushBlock(CSharpBlockKind.Variable);
@ -1469,7 +1473,7 @@ namespace CppSharp.Generators.CSharp @@ -1469,7 +1473,7 @@ namespace CppSharp.Generators.CSharp
var functionName = GetFunctionIdentifier(function);
Write("public static {0} {1}(", function.OriginalReturnType, functionName);
GenerateMethodParameters(function);
Write(FormatMethodParameters(function.Parameters));
WriteLine(")");
WriteStartBraceIndent();
@ -1517,7 +1521,7 @@ namespace CppSharp.Generators.CSharp @@ -1517,7 +1521,7 @@ namespace CppSharp.Generators.CSharp
else
Write("{0} {1}(", method.OriginalReturnType, functionName);
GenerateMethodParameters(method);
Write(FormatMethodParameters(method.Parameters));
Write(")");
@ -1938,23 +1942,14 @@ namespace CppSharp.Generators.CSharp @@ -1938,23 +1942,14 @@ namespace CppSharp.Generators.CSharp
}
}
private void GenerateMethodParameters(Function function)
private string FormatMethodParameters(IEnumerable<Parameter> @params)
{
var @params = new List<string>();
for (var i = 0; i < function.Parameters.Count; ++i)
{
var param = function.Parameters[i];
if (param.Kind == ParameterKind.IndirectReturnType)
continue;
var typeName = param.CSharpType(TypePrinter);
@params.Add(string.Format("{0}{1} {2}", GetParameterUsage(param.Usage),
return string.Join(", ",
from param in @params
where param.Kind != ParameterKind.IndirectReturnType
let typeName = param.CSharpType(this.TypePrinter)
select string.Format("{0}{1} {2}", GetParameterUsage(param.Usage),
typeName, SafeIdentifier(param.Name)));
}
Write(string.Join(", ", @params));
}
#endregion

8
src/Generator/Passes/CheckAmbiguousFunctions.cs

@ -23,14 +23,6 @@ namespace CppSharp.Passes @@ -23,14 +23,6 @@ namespace CppSharp.Passes
/// </summary>
public class CheckAmbiguousFunctions : TranslationUnitPass
{
public override bool VisitMethodDecl(Method method)
{
if (method.Kind != CXXMethodKind.Normal)
return false;
return base.VisitMethodDecl(method);
}
public override bool VisitFunctionDecl(AST.Function function)
{
if (AlreadyVisited(function))

58
src/Generator/Passes/CheckOperatorsOverloads.cs

@ -44,7 +44,7 @@ namespace CppSharp.Passes @@ -44,7 +44,7 @@ namespace CppSharp.Passes
private void CheckInvalidOperators(Class @class)
{
foreach (var @operator in @class.Operators)
foreach (var @operator in @class.Operators.Where(o => !o.Ignore))
{
if (!IsValidOperatorOverload(@operator))
{
@ -57,25 +57,47 @@ namespace CppSharp.Passes @@ -57,25 +57,47 @@ namespace CppSharp.Passes
if (@operator.SynthKind == FunctionSynthKind.NonMemberOperator)
continue;
// Handle missing operator parameters
if (@operator.IsStatic)
@operator.Parameters = @operator.Parameters.Skip(1).ToList();
var type = new PointerType()
if (@operator.OperatorKind == CXXOperatorKind.Subscript)
{
QualifiedPointee = new QualifiedType(new TagType(@class)),
Modifier = PointerType.TypeModifier.LVReference
};
@operator.Parameters.Insert(0, new Parameter
CreateIndexer(@class, @operator);
}
else
{
Name = Generator.GeneratedIdentifier("op"),
QualifiedType = new QualifiedType(type),
Kind = ParameterKind.OperatorParameter
});
// Handle missing operator parameters
if (@operator.IsStatic)
@operator.Parameters = @operator.Parameters.Skip(1).ToList();
var type = new PointerType()
{
QualifiedPointee = new QualifiedType(new TagType(@class)),
Modifier = PointerType.TypeModifier.LVReference
};
@operator.Parameters.Insert(0, new Parameter
{
Name = Generator.GeneratedIdentifier("op"),
QualifiedType = new QualifiedType(type),
Kind = ParameterKind.OperatorParameter
});
}
}
}
private static void CreateIndexer(Class @class, Method @operator)
{
Property property = new Property
{
Name = "Item",
QualifiedType = @operator.ReturnType,
Access = @operator.Access,
Namespace = @class,
GetMethod = @operator
};
property.Parameters.AddRange(@operator.Parameters);
@class.Properties.Add(property);
@operator.IsGenerated = false;
}
static void HandleMissingOperatorOverloadPair(Class @class, CXXOperatorKind op1,
CXXOperatorKind op2)
{
@ -153,6 +175,9 @@ namespace CppSharp.Passes @@ -153,6 +175,9 @@ namespace CppSharp.Passes
case CXXOperatorKind.Pipe:
case CXXOperatorKind.Caret:
// The array indexing operator can be overloaded
case CXXOperatorKind.Subscript:
// The comparison operators can be overloaded
case CXXOperatorKind.EqualEqual:
case CXXOperatorKind.ExclaimEqual:
@ -180,9 +205,6 @@ namespace CppSharp.Passes @@ -180,9 +205,6 @@ namespace CppSharp.Passes
case CXXOperatorKind.LessLessEqual:
case CXXOperatorKind.GreaterGreaterEqual:
// The array indexing operator cannot be overloaded
case CXXOperatorKind.Subscript:
// The conditional logical operators cannot be overloaded
case CXXOperatorKind.AmpAmp:
case CXXOperatorKind.PipePipe:

7
tests/Basic/Basic.Tests.cs

@ -117,13 +117,6 @@ public class BasicTests @@ -117,13 +117,6 @@ public class BasicTests
Assert.AreEqual(abstractFoo.pureFunction2(), 15);
}
[Test, Ignore]
public void TestPropertyAccessModifier()
{
Assert.That(typeof(Foo2).GetProperty("P",
BindingFlags.Instance | BindingFlags.NonPublic), Is.Not.Null);
}
[Test]
public void TestANSI()
{

4
tests/Basic/Basic.h

@ -29,10 +29,6 @@ public: @@ -29,10 +29,6 @@ public:
Foo2 operator<<(signed int i);
Foo2 operator<<(signed long l);
// TODO: uncomment when the C++/CLI back-end supports protected members
//protected:
// int P;
};
struct DLL_API Bar

21
tests/CSharpTemp/CSharpTemp.Tests.cs

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
using System.Reflection;
using NUnit.Framework;
using Foo = CSharpTemp.Foo;
[TestFixture]
public class CSharpTempTests
{
[Test]
public void TestIndexer()
{
var foo = new Foo();
Assert.That(foo[0], Is.EqualTo(5));
}
[Test]
public void TestPropertyAccessModifier()
{
Assert.That(typeof(Foo).GetProperty("P",
BindingFlags.Instance | BindingFlags.NonPublic), Is.Not.Null);
}
}

12
tests/CSharpTemp/CSharpTemp.cpp

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
#include "CSharpTemp.h"
// TODO: move this, it has nothing to do with Unicode, it's here only not to break the CLI branch
int Foo::operator[](int i) const
{
return 5;
}
int Foo::operator[](int i)
{
return 5;
}

22
tests/CSharpTemp/CSharpTemp.cs

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
using CppSharp.Generators;
using CppSharp.Utils;
namespace CppSharp.Tests
{
public class CSharpTempTests : LibraryTest
{
public CSharpTempTests(LanguageGeneratorKind kind)
: base("CSharpTemp", kind)
{
}
static class Program
{
public static void Main(string[] args)
{
ConsoleDriver.Run(new CSharpTempTests(LanguageGeneratorKind.CSharp));
}
}
}
}

15
tests/CSharpTemp/CSharpTemp.h

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
#if defined(_MSC_VER)
#define DLL_API __declspec(dllexport)
#else
#define DLL_API
#endif
class DLL_API Foo
{
public:
int operator[](int i) const;
int operator[](int i);
protected:
int P;
};

2
tests/CSharpTemp/premake4.lua

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
group "Tests/CSharpTemp"
SetupTestCSharp("CSharpTemp")

8
tests/UTF16/UTF16.Tests.cs

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
using NUnit.Framework;
using UTF16;
using System;
using NUnit.Framework;
using Foo = UTF16.Foo;
[TestFixture]
public class UTF16Tests
@ -11,5 +12,8 @@ public class UTF16Tests @@ -11,5 +12,8 @@ public class UTF16Tests
const string georgia = "საქართველო";
foo.Unicode = georgia;
Assert.That(foo.Unicode, Is.EqualTo(georgia));
// TODO: move this, it has nothing to do with Unicode, it's here only not to break the CLI branch
Assert.That(foo[0], Is.EqualTo(5));
}
}

13
tests/UTF16/UTF16.cpp

@ -1 +1,12 @@ @@ -1 +1,12 @@
#include "UTF16.h"
#include "UTF16.h"
// TODO: move this, it has nothing to do with Unicode, it's here only not to break the CLI branch
int Foo::operator[](int i) const
{
return 5;
}
int Foo::operator[](int i)
{
return 5;
}

4
tests/UTF16/UTF16.h

@ -8,6 +8,10 @@ class DLL_API Foo @@ -8,6 +8,10 @@ class DLL_API Foo
{
public:
const char* Unicode;
// TODO: move this, it has nothing to do with Unicode, it's here only not to break the CLI branch
int operator[](int i) const;
int operator[](int i);
};
DLL_API int FooCallFoo(Foo* foo);

Loading…
Cancel
Save