Browse Source

Changed the C#-printing of template specialisation types to use their arguments.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/859/head
Dimitar Dobrev 8 years ago
parent
commit
762d3803d7
  1. 7
      src/Generator.Tests/AST/TestAST.cs
  2. 55
      src/Generator/Generators/CSharp/CSharpSources.cs
  3. 43
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs

7
src/Generator.Tests/AST/TestAST.cs

@ -516,8 +516,11 @@ namespace CppSharp.Generator.Tests.AST @@ -516,8 +516,11 @@ namespace CppSharp.Generator.Tests.AST
[Test]
public void TestDependentNameType()
{
var template = AstContext.FindDecl<ClassTemplate>("TestSpecializationArguments").First();
Assert.That(template.TemplatedClass.Fields[0].Type.ToString(),
var template = AstContext.FindDecl<ClassTemplate>(
"TestSpecializationArguments").First();
var type = template.TemplatedClass.Fields[0].Type.Visit(
new CSharpTypePrinter(Driver.Context));
Assert.That($"{type}",
Is.EqualTo("global::Test.TestTemplateClass<T>.NestedInTemplate"));
}
}

55
src/Generator/Generators/CSharp/CSharpSources.cs

@ -344,9 +344,11 @@ namespace CppSharp.Generators.CSharp @@ -344,9 +344,11 @@ namespace CppSharp.Generators.CSharp
WriteLine("protected int {0};", Helpers.PointerAdjustmentIdentifier);
// use interfaces if any - derived types with a secondary base this class must be compatible with the map
var @interface = @class.Namespace.Classes.Find(c => c.OriginalClass == @class);
var dict = string.Format("global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, {0}>",
(@interface ?? @class).Visit(TypePrinter));
var @interface = @class.Namespace.Classes.FirstOrDefault(
c => c.IsInterface && c.OriginalClass == @class);
var printedClass = (@interface ?? @class).Visit(TypePrinter);
var dict = $@"global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, {
printedClass}{printedClass.NameSuffix}>";
WriteLine("internal static readonly {0} NativeToManagedMap = new {0}();", dict);
WriteLine("protected void*[] __OriginalVTables;");
}
@ -1169,6 +1171,7 @@ namespace CppSharp.Generators.CSharp @@ -1169,6 +1171,7 @@ namespace CppSharp.Generators.CSharp
}
GenerateDeclarationCommon(prop);
var printedType = prop.Type.Visit(TypePrinter);
if (prop.ExplicitInterfaceImpl == null)
{
Write(Helpers.GetAccess(GetValidPropertyAccess(prop)));
@ -1190,12 +1193,12 @@ namespace CppSharp.Generators.CSharp @@ -1190,12 +1193,12 @@ namespace CppSharp.Generators.CSharp
if (prop.IsVirtual && !isOverride && !prop.IsPure)
Write("virtual ");
WriteLine("{0} {1}", prop.Type, GetPropertyName(prop));
WriteLine($"{printedType}{printedType.NameSuffix} {GetPropertyName(prop)}");
}
else
{
WriteLine("{0} {1}.{2}", prop.Type, prop.ExplicitInterfaceImpl.Name,
GetPropertyName(prop));
WriteLine($@"{printedType}{printedType.NameSuffix} {
prop.ExplicitInterfaceImpl.Name}.{GetPropertyName(prop)}");
}
WriteStartBraceIndent();
@ -1613,7 +1616,9 @@ namespace CppSharp.Generators.CSharp @@ -1613,7 +1616,9 @@ namespace CppSharp.Generators.CSharp
WriteLineIndent("throw new global::System.Exception(\"No managed instance was found\");");
NewLine();
WriteLine("var {0} = ({1}) NativeToManagedMap[instance];", Helpers.TargetIdentifier, @class.Visit(TypePrinter));
var printedClass = @class.Visit(TypePrinter);
WriteLine($@"var {Helpers.TargetIdentifier} = ({printedClass}{
printedClass.NameSuffix}) NativeToManagedMap[instance];");
WriteLine("if ({0}.{1})", Helpers.TargetIdentifier, Helpers.OwnsNativeInstanceIdentifier);
WriteLineIndent("{0}.SetupVTables();", Helpers.TargetIdentifier);
GenerateVTableManagedCall(method);
@ -1828,15 +1833,16 @@ namespace CppSharp.Generators.CSharp @@ -1828,15 +1833,16 @@ namespace CppSharp.Generators.CSharp
var @base = @class.GetNonIgnoredRootBase();
// Use interfaces if any - derived types with a this class as a seconary base, must be compatible with the map
var @interface = @base.Namespace.Classes.Find(c => c.OriginalClass == @base);
var @interface = @base.Namespace.Classes.FirstOrDefault(
c => c.IsInterface && c.OriginalClass == @base);
WriteLine("if ({0} == IntPtr.Zero)", Helpers.InstanceIdentifier);
WriteLineIndent("return;");
// The local var must be of the exact type in the object map because of TryRemove
WriteLine("{0} {1};",
(@interface ?? (@base.IsAbstractImpl ? @base.BaseClass : @base)).Visit(TypePrinter),
Helpers.DummyIdentifier);
var printedClass = (@interface ?? (
@base.IsAbstractImpl ? @base.BaseClass : @base)).Visit(TypePrinter);
WriteLine($"{printedClass}{printedClass.NameSuffix} {Helpers.DummyIdentifier};");
WriteLine("NativeToManagedMap.TryRemove({0}, out {1});",
Helpers.InstanceIdentifier, Helpers.DummyIdentifier);
TypePrinter.PushContext(TypePrinterContextKind.Native);
@ -1911,13 +1917,15 @@ namespace CppSharp.Generators.CSharp @@ -1911,13 +1917,15 @@ namespace CppSharp.Generators.CSharp
}
var suffix = @class.IsAbstract ? "Internal" : string.Empty;
var ctorCall = $"{@class.Visit(TypePrinter)}{suffix}";
var printedClass = @class.Visit(TypePrinter);
var ctorCall = $"{printedClass}{printedClass.NameSuffix}{suffix}";
if (!@class.IsAbstractImpl)
{
PushBlock(BlockKind.Method);
WriteLine("internal static {0}{1} {2}(global::System.IntPtr native, bool skipVTables = false)",
WriteLine("internal static {0}{1}{2} {3}(global::System.IntPtr native, bool skipVTables = false)",
@class.NeedsBase && !@class.BaseClass.IsInterface ? "new " : string.Empty,
@class.Visit(TypePrinter), Helpers.CreateInstanceIdentifier);
printedClass, printedClass.NameSuffix, Helpers.CreateInstanceIdentifier);
WriteStartBraceIndent();
WriteLine("return new {0}(native.ToPointer(), skipVTables);", ctorCall);
WriteCloseBraceIndent();
@ -2118,7 +2126,10 @@ namespace CppSharp.Generators.CSharp @@ -2118,7 +2126,10 @@ namespace CppSharp.Generators.CSharp
method.ExplicitInterfaceImpl.Name, functionName);
else if (method.OperatorKind == CXXOperatorKind.Conversion ||
method.OperatorKind == CXXOperatorKind.ExplicitConversion)
Write("{0} {1}(", functionName, method.OriginalReturnType);
{
var printedType = method.OriginalReturnType.Visit(TypePrinter);
Write($"{functionName} {printedType}{printedType.NameSuffix}(");
}
else
Write("{0} {1}(", method.OriginalReturnType, functionName);
@ -2427,11 +2438,15 @@ namespace CppSharp.Generators.CSharp @@ -2427,11 +2438,15 @@ namespace CppSharp.Generators.CSharp
method.Parameters[0].Type.IsPrimitiveTypeConvertibleToRef() ?
"ref *" : string.Empty,
method.Parameters[0].Name);
var printedType = method.ConversionType.Visit(TypePrinter);
if (@interface != null)
WriteLine("return new {0}(({2}) {1});",
method.ConversionType, paramName, @interface.Name);
{
var printedInterface = @interface.Visit(TypePrinter);
WriteLine($@"return new {printedType}{printedType.NameSuffix}(({
printedInterface}{printedInterface.NameSuffix}) {paramName});");
}
else
WriteLine("return new {0}({1});", method.ConversionType, paramName);
WriteLine($"return new {printedType}{printedType.NameSuffix}({paramName});");
}
else
{
@ -2508,8 +2523,8 @@ namespace CppSharp.Generators.CSharp @@ -2508,8 +2523,8 @@ namespace CppSharp.Generators.CSharp
TypePrinter.PopContext();
}
var functionName = string.Format("{0}.{1}", @internal,
GetFunctionNativeIdentifier(function.OriginalFunction ?? function));
var nativeFunction = GetFunctionNativeIdentifier(function);
var functionName = $"{@internal}.{nativeFunction}";
GenerateFunctionCall(functionName, parameters, function, returnType);
}

43
src/Generator/Generators/CSharp/CSharpTypePrinter.cs

@ -7,6 +7,7 @@ using Type = CppSharp.AST.Type; @@ -7,6 +7,7 @@ using Type = CppSharp.AST.Type;
using ParserTargetInfo = CppSharp.Parser.ParserTargetInfo;
using System.Linq;
using System.Text;
using System.Globalization;
namespace CppSharp.Generators.CSharp
{
@ -339,7 +340,13 @@ namespace CppSharp.Generators.CSharp @@ -339,7 +340,13 @@ namespace CppSharp.Generators.CSharp
TypeMap typeMap;
if (!TypeMapDatabase.FindTypeMap(template, out typeMap))
{
if (ContextKind == TypePrinterContextKind.Managed &&
decl == template.Template.TemplatedDecl)
return $@"{decl.Visit(this)}<{string.Join(", ",
template.Arguments.Select(VisitTemplateArgument))}>";
return decl.Visit(this);
}
typeMap.Declaration = decl;
typeMap.Type = template;
@ -542,8 +549,12 @@ namespace CppSharp.Generators.CSharp @@ -542,8 +549,12 @@ namespace CppSharp.Generators.CSharp
if (ContextKind == TypePrinterContextKind.Native)
return $"{VisitDeclaration(@class.OriginalClass ?? @class)}.{Helpers.InternalStruct}";
return $@"{VisitDeclaration(@class)}{(@class.IsDependent ? $@"<{
string.Join(", ", @class.TemplateParameters.Select(p => p.Name))}>" : string.Empty)}";
var typePrinterResult = new TypePrinterResult();
typePrinterResult.Type = VisitDeclaration(@class).Type;
if (@class.IsDependent)
typePrinterResult.NameSuffix = $@"<{
string.Join(", ", @class.TemplateParameters.Select(p => p.Name))}>";
return typePrinterResult;
}
public override TypePrinterResult VisitClassTemplateSpecializationDecl(
@ -552,7 +563,18 @@ namespace CppSharp.Generators.CSharp @@ -552,7 +563,18 @@ namespace CppSharp.Generators.CSharp
if (ContextKind == TypePrinterContextKind.Native)
return $@"{VisitClassDecl(specialization)}{
Helpers.GetSuffixForInternal(specialization)}";
return VisitClassDecl(specialization);
if (specialization.IsExplicitlyGenerated)
return $"{VisitClassDecl(specialization)}";
var args = string.Join(", ", specialization.Arguments.Select(VisitTemplateArgument));
return $"{VisitClassDecl(specialization)}<{args}>";
}
private TypePrinterResult VisitTemplateArgument(TemplateArgument a)
{
if (a.Type.Type == null)
return a.Integral.ToString(CultureInfo.InvariantCulture);
var type = a.Type.Type.Desugar();
return type.IsPointerToPrimitiveType() ? "global::System.IntPtr" : type.Visit(this);
}
public override TypePrinterResult VisitParameterDecl(Parameter parameter)
@ -626,13 +648,20 @@ namespace CppSharp.Generators.CSharp @@ -626,13 +648,20 @@ namespace CppSharp.Generators.CSharp
public override TypePrinterResult VisitParameter(Parameter param, bool hasName)
{
var usage = ContextKind == TypePrinterContextKind.Native ?
string.Empty : GetParameterUsage(param.Usage);
var type = param.QualifiedType.Visit(this);
var printedType = param.Type.Visit(this, param.QualifiedType.Qualifiers);
var type = $"{printedType}{printedType.NameSuffix}";
var name = param.Name;
if (ContextKind == TypePrinterContextKind.Native)
return $"{type} {name}";
var usage = GetParameterUsage(param.Usage);
if (param.DefaultArgument == null || !Options.GenerateDefaultValuesForArguments)
return $"{usage}{type} {name}";
return $"{usage}{type} {name} = {expressionPrinter.VisitParameter(param)}";
var defaultValue = expressionPrinter.VisitParameter(param);
return $"{usage}{type} {name} = {defaultValue}";
}
public override TypePrinterResult VisitDelegate(FunctionType function)

Loading…
Cancel
Save