Browse Source

Fixed the generated C# when a template is used with different type arguments.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/890/head
Dimitar Dobrev 9 years ago
parent
commit
38ed4ab472
  1. 14
      src/Generator/Generators/CSharp/CSharpSources.cs
  2. 16
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  3. 8
      tests/CSharp/CSharpTemplates.h

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

@ -641,10 +641,16 @@ namespace CppSharp.Generators.CSharp
if (@class.NeedsBase) if (@class.NeedsBase)
{ {
bases.AddRange( foreach (var @base in @class.Bases.Where(b => b.IsClass))
from @base in @class.Bases {
where @base.IsClass var typeMaps = new List<System.Type>();
select @base.Class.Visit(TypePrinter).Type); var keys = new List<string>();
this.DisableTypeMap(@base.Class, typeMaps, keys);
var printedBase = @base.Type.Desugar().Visit(TypePrinter);
bases.Add(printedBase.Type);
for (int i = 0; i < typeMaps.Count; i++)
Context.TypeMaps.TypeMaps.Add(keys[i], typeMaps[i]);
}
} }
if (@class.IsGenerated) if (@class.IsGenerated)

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

@ -342,7 +342,8 @@ namespace CppSharp.Generators.CSharp
if (!TypeMapDatabase.FindTypeMap(template, out typeMap)) if (!TypeMapDatabase.FindTypeMap(template, out typeMap))
{ {
if (ContextKind == TypePrinterContextKind.Managed && if (ContextKind == TypePrinterContextKind.Managed &&
decl == template.Template.TemplatedDecl) decl == template.Template.TemplatedDecl &&
template.Arguments.All(IsValid))
return $@"{VisitDeclaration(decl)}<{string.Join(", ", return $@"{VisitDeclaration(decl)}<{string.Join(", ",
template.Arguments.Select(VisitTemplateArgument))}>"; template.Arguments.Select(VisitTemplateArgument))}>";
return decl.Visit(this); return decl.Visit(this);
@ -395,7 +396,9 @@ namespace CppSharp.Generators.CSharp
public override TypePrinterResult VisitInjectedClassNameType( public override TypePrinterResult VisitInjectedClassNameType(
InjectedClassNameType injected, TypeQualifiers quals) InjectedClassNameType injected, TypeQualifiers quals)
{ {
return injected.Class.Visit(this); return injected.InjectedSpecializationType.Type != null ?
injected.InjectedSpecializationType.Visit(this) :
injected.Class.Visit(this);
} }
public override TypePrinterResult VisitDependentNameType(DependentNameType dependent, public override TypePrinterResult VisitDependentNameType(DependentNameType dependent,
@ -776,6 +779,15 @@ namespace CppSharp.Generators.CSharp
return typePrinterResult; return typePrinterResult;
} }
private static bool IsValid(TemplateArgument a)
{
if (a.Type.Type == null)
return true;
var templateParam = a.Type.Type.Desugar() as TemplateParameterType;
// HACK: TemplateParameterType.Parameter is null in some corner cases, see the parser
return templateParam == null || templateParam.Parameter != null;
}
private CSharpExpressionPrinter expressionPrinter => new CSharpExpressionPrinter(this); private CSharpExpressionPrinter expressionPrinter => new CSharpExpressionPrinter(this);
} }
} }

8
tests/CSharp/CSharpTemplates.h

@ -92,6 +92,11 @@ int IndependentFields<T>::getIndependent()
return independent; return independent;
} }
template <typename X>
class DerivedChangesTypeName : public IndependentFields<X>
{
};
template <typename T> template <typename T>
class DLL_API DependentValueFields class DLL_API DependentValueFields
{ {
@ -302,7 +307,7 @@ struct MapResultType<InputSequence<T>, MapFunctor>
void forceUseSpecializations(IndependentFields<int> _1, IndependentFields<bool> _2, void forceUseSpecializations(IndependentFields<int> _1, IndependentFields<bool> _2,
IndependentFields<T1> _3, IndependentFields<std::string> _4, IndependentFields<T1> _3, IndependentFields<std::string> _4,
VirtualTemplate<int> _5, VirtualTemplate<bool> _6, VirtualTemplate<int> _5, VirtualTemplate<bool> _6,
HasDefaultTemplateArgument<int, int> _7, std::string s); HasDefaultTemplateArgument<int, int> _7, DerivedChangesTypeName<T1> _8, std::string s);
// force the symbols for the template instantiations because we do not have the auto-compilation for the generated C++ source // force the symbols for the template instantiations because we do not have the auto-compilation for the generated C++ source
template class DLL_API IndependentFields<int>; template class DLL_API IndependentFields<int>;
@ -312,3 +317,4 @@ template class DLL_API IndependentFields<std::string>;
template class DLL_API VirtualTemplate<int>; template class DLL_API VirtualTemplate<int>;
template class DLL_API VirtualTemplate<bool>; template class DLL_API VirtualTemplate<bool>;
template class DLL_API HasDefaultTemplateArgument<int, int>; template class DLL_API HasDefaultTemplateArgument<int, int>;
template class DLL_API DerivedChangesTypeName<T1>;

Loading…
Cancel
Save