Browse Source

Added support for read-only [] operators.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/61/head
Dimitar Dobrev 12 years ago
parent
commit
54c93f4d91
  1. 12
      src/AST/Property.cs
  2. 37
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  3. 60
      src/Generator/Passes/CheckOperatorsOverloads.cs

12
src/AST/Property.cs

@ -1,3 +1,5 @@
using System.Collections.Generic;
namespace CppSharp.AST namespace CppSharp.AST
{ {
/// <summary> /// <summary>
@ -36,6 +38,16 @@ namespace CppSharp.AST
// The field that should be get and set by this property // The field that should be get and set by this property
public Field Field { get; set; } 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) public override T Visit<T>(IDeclVisitor<T> visitor)
{ {
return visitor.VisitProperty(this); return visitor.VisitProperty(this);

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

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

60
src/Generator/Passes/CheckOperatorsOverloads.cs

@ -57,22 +57,48 @@ namespace CppSharp.Passes
if (@operator.SynthKind == FunctionSynthKind.NonMemberOperator) if (@operator.SynthKind == FunctionSynthKind.NonMemberOperator)
continue; continue;
// Handle missing operator parameters if (@operator.OperatorKind == CXXOperatorKind.Subscript)
if (@operator.IsStatic)
@operator.Parameters = @operator.Parameters.Skip(1).ToList();
var type = new PointerType()
{ {
QualifiedPointee = new QualifiedType(new TagType(@class)), CreateIndexer(@class, @operator);
Modifier = PointerType.TypeModifier.LVReference }
}; else
@operator.Parameters.Insert(0, new Parameter
{ {
Name = Generator.GeneratedIdentifier("op"), // Handle missing operator parameters
QualifiedType = new QualifiedType(type), if (@operator.IsStatic)
Kind = ParameterKind.OperatorParameter @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)
{
if (@class.Properties.All(p => p.Parameters.Count == 0 ||
p.Parameters[0].QualifiedType != @operator.Parameters[0].QualifiedType))
{
Property property = new Property
{
Name = "Item",
QualifiedType = @operator.ReturnType,
Access = @operator.Access,
Namespace = @class
};
property.GetMethod = @operator;
property.Parameters.AddRange(@operator.Parameters);
@class.Properties.Add(property);
@operator.IsGenerated = false;
} }
} }
@ -153,6 +179,9 @@ namespace CppSharp.Passes
case CXXOperatorKind.Pipe: case CXXOperatorKind.Pipe:
case CXXOperatorKind.Caret: case CXXOperatorKind.Caret:
// The array indexing operator can be overloaded
case CXXOperatorKind.Subscript:
// The comparison operators can be overloaded // The comparison operators can be overloaded
case CXXOperatorKind.EqualEqual: case CXXOperatorKind.EqualEqual:
case CXXOperatorKind.ExclaimEqual: case CXXOperatorKind.ExclaimEqual:
@ -180,9 +209,6 @@ namespace CppSharp.Passes
case CXXOperatorKind.LessLessEqual: case CXXOperatorKind.LessLessEqual:
case CXXOperatorKind.GreaterGreaterEqual: case CXXOperatorKind.GreaterGreaterEqual:
// The array indexing operator cannot be overloaded
case CXXOperatorKind.Subscript:
// The conditional logical operators cannot be overloaded // The conditional logical operators cannot be overloaded
case CXXOperatorKind.AmpAmp: case CXXOperatorKind.AmpAmp:
case CXXOperatorKind.PipePipe: case CXXOperatorKind.PipePipe:

Loading…
Cancel
Save