Browse Source

Added explicit implementation of interface properties (when necessary).

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/68/head
Dimitar Dobrev 12 years ago
parent
commit
068cf51165
  1. 15
      src/AST/Class.cs
  2. 25
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  3. 14
      src/Generator/Passes/MultipleInheritancePass.cs
  4. 6
      tests/CSharpTemp/CSharpTemp.Tests.cs

15
src/AST/Class.cs

@ -219,6 +219,21 @@ namespace CppSharp.AST @@ -219,6 +219,21 @@ namespace CppSharp.AST
select rootBaseMethod ?? baseMethod).FirstOrDefault();
}
public Property GetRootBaseProperty(Property @override)
{
return (from @base in Bases
let baseMethod = (
from property in @base.Class.Properties
where
property.Name == @override.Name &&
property.Parameters.Count == @override.Parameters.Count &&
property.Parameters.SequenceEqual(@override.Parameters,
new ParameterTypeComparer())
select property).FirstOrDefault()
let rootBaseMethod = @base.Class.GetRootBaseProperty(@override)
select rootBaseMethod ?? baseMethod).FirstOrDefault();
}
public override T Visit<T>(IDeclVisitor<T> visitor)
{
return visitor.VisitClassDecl(this);

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

@ -869,16 +869,17 @@ namespace CppSharp.Generators.CSharp @@ -869,16 +869,17 @@ namespace CppSharp.Generators.CSharp
Type type;
returnType.Type.IsPointerTo(out type);
PrimitiveType primitiveType;
string internalFunction = GetFunctionNativeIdentifier(function);
if (type.IsPrimitiveType(out primitiveType))
{
string internalFunction = GetFunctionNativeIdentifier(function);
WriteLine("*Internal.{0}({1}, {2}) = value;", internalFunction,
Helpers.InstanceIdentifier, function.Parameters[0].Name);
}
else
{
WriteLine("*({0}.Internal*) this[{1}].{2} = *({0}.Internal*) value.{2};",
type.ToString(), function.Parameters[0].Name, Helpers.InstanceIdentifier);
WriteLine("*({0}.Internal*) Internal.{1}({2}, {3}) = *({0}.Internal*) value.{2};",
type.ToString(), internalFunction,
Helpers.InstanceIdentifier, function.Parameters[0].Name);
}
}
@ -1008,9 +1009,13 @@ namespace CppSharp.Generators.CSharp @@ -1008,9 +1009,13 @@ namespace CppSharp.Generators.CSharp
var type = prop.Type;
if (prop.Parameters.Count > 0 && prop.Type.IsPointerToPrimitiveType())
type = ((PointerType) prop.Type).Pointee;
WriteLine("{0} {1} {2}",
prop.Access == AccessSpecifier.Public ? "public" : "protected",
type, GetPropertyName(prop));
// explicit impl
if (prop.Name.Contains('.'))
WriteLine("{0} {1}", type, GetPropertyName(prop));
else
WriteLine("{0} {1} {2}",
prop.Access == AccessSpecifier.Public ? "public" : "protected",
type, GetPropertyName(prop));
WriteStartBraceIndent();
if (prop.Field != null)
@ -1037,8 +1042,12 @@ namespace CppSharp.Generators.CSharp @@ -1037,8 +1042,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));
// check for explicit interface implementations
var indexOfDot = prop.Name.IndexOf('.');
string name = prop.Name.Substring(prop.Name.IndexOf('.') + 1);
return prop.Name.Substring(0, indexOfDot + 1) +
(prop.Parameters.Count == 0 ? SafeIdentifier(name)
: string.Format("this[{0}]", FormatMethodParameters(prop.Parameters)));
}
private void GenerateVariable(Class @class, Type type, Variable variable)

14
src/Generator/Passes/MultipleInheritancePass.cs

@ -64,9 +64,17 @@ namespace CppSharp.Passes @@ -64,9 +64,17 @@ namespace CppSharp.Passes
@class.Methods.Add(impl);
}
@interface.Properties.AddRange(@base.Properties.Where(p => !p.Ignore));
@class.Properties.AddRange(
from property in @interface.Properties
select new Property(property) { Namespace = @class });
foreach (var property in @interface.Properties)
{
var impl = new Property(property)
{
Namespace = @class
};
var rootBaseProperty = @class.GetRootBaseProperty(property);
if (rootBaseProperty != null && !rootBaseProperty.Ignore)
impl.Name = @interface.Name + "." + impl.Name;
@class.Properties.Add(impl);
}
@interface.Events.AddRange(@base.Events);
if (@base.Bases.All(b => b.Class != @interface))
@base.Bases.Add(new BaseClassSpecifier { Type = new TagType(@interface) });

6
tests/CSharpTemp/CSharpTemp.Tests.cs

@ -36,6 +36,10 @@ public class CSharpTempTests @@ -36,6 +36,10 @@ public class CSharpTempTests
{
Baz baz = new Baz();
Assert.That(baz.method(), Is.EqualTo(1));
Assert.That(((IBar) baz).method(), Is.EqualTo(2));
var bar = (IBar) baz;
Assert.That(bar.method(), Is.EqualTo(2));
Assert.That(baz[0], Is.EqualTo(50));
bar[0] = new Foo { A = 1000 };
Assert.That(bar[0].A, Is.EqualTo(1000));
}
}
Loading…
Cancel
Save