Browse Source

Fixed the generated C# for indexers in templates.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/890/head
Dimitar Dobrev 8 years ago
parent
commit
e078968cf2
  1. 19
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  2. 34
      src/Generator/Generators/CSharp/CSharpSources.cs
  3. 3
      src/Generator/Passes/SpecializationMethodsWithDependentPointersPass.cs
  4. 25
      tests/CSharp/CSharp.Tests.cs
  5. 33
      tests/CSharp/CSharpTemplates.h

19
src/Generator/Generators/CSharp/CSharpMarshal.cs

@ -167,12 +167,23 @@ namespace CppSharp.Generators.CSharp @@ -167,12 +167,23 @@ namespace CppSharp.Generators.CSharp
return true;
}
if (Context.Context.Options.MarshalCharAsManagedChar && primitive == PrimitiveType.Char)
Context.Return.Write(string.Format("({0}) ", pointer));
if (Context.Context.Options.MarshalCharAsManagedChar &&
primitive == PrimitiveType.Char)
Context.Return.Write($"({pointer}) ");
var type = Context.ReturnType.Type.Desugar(
resolveTemplateSubstitution: false);
if (Context.Function != null &&
Context.Function.OperatorKind == CXXOperatorKind.Subscript &&
Context.ReturnType.Type.Desugar().IsPrimitiveType(primitive))
type.IsPrimitiveType(primitive))
{
var substitute = type as TemplateParameterSubstitutionType;
if (substitute != null)
Context.Return.Write($@"({
substitute.ReplacedParameter.Parameter.Name}) (object) ");
Context.Return.Write("*");
}
Context.Return.Write(Context.ReturnVarName);
return true;
}
@ -732,7 +743,7 @@ namespace CppSharp.Generators.CSharp @@ -732,7 +743,7 @@ namespace CppSharp.Generators.CSharp
}
string param = Context.Parameter.Name;
Type type = Context.Parameter.Type.Desugar(false);
Type type = Context.Parameter.Type.Desugar(resolveTemplateSubstitution: false);
string paramInstance;
Class @interface;
var finalType = type.GetFinalPointee() ?? type;

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

@ -928,28 +928,36 @@ namespace CppSharp.Generators.CSharp @@ -928,28 +928,36 @@ namespace CppSharp.Generators.CSharp
{
Type type;
function.Type.IsPointerTo(out type);
PrimitiveType primitiveType;
var @internal = TypePrinter.PrintNative(function.Namespace);
var ctx = new CSharpMarshalContext(Context)
{
Parameter = new Parameter
{
Name = "value",
QualifiedType = new QualifiedType(type)
},
ReturnType = new QualifiedType(type)
};
var marshal = new CSharpMarshalManagedToNativePrinter(ctx);
type.Visit(marshal);
Write(marshal.Context.Before);
var internalFunction = GetFunctionNativeIdentifier(function);
var @internal = $@"{Helpers.InternalStruct}{
Helpers.GetSuffixForInternal(function.Namespace)}";
if (type.IsPrimitiveType(out primitiveType))
if (type.IsPrimitiveType())
{
WriteLine($@"*{@internal}.{internalFunction}({
GetInstanceParam(function)}, {function.Parameters[0].Name}) = value;");
GetInstanceParam(function)}, {function.Parameters[0].Name}) = {
marshal.Context.Return};");
}
else
{
var typeString = type.ToString();
Class @class;
var isValueType = (type.GetFinalPointee() ?? type).TryGetClass(out @class) &&
@class.IsValueType;
var typeInternal = TypePrinter.PrintNative(type);
var paramMarshal = GenerateFunctionParamMarshal(
function.Parameters[0], 0, function);
WriteLine($@"*({typeString}.{@internal}*) {@internal}.{internalFunction}({
WriteLine($@"*({typeInternal}*) {@internal}.{internalFunction}({
GetInstanceParam(function)}, {(paramMarshal.Context == null ?
paramMarshal.Name : paramMarshal.Context.Return)}) = {
(isValueType ? string.Empty : $@"*({typeString}.{@internal}*) ")}value.{
Helpers.InstanceIdentifier};");
paramMarshal.Name : paramMarshal.Context.Return)}) = {marshal.Context.Return};");
}
}

3
src/Generator/Passes/SpecializationMethodsWithDependentPointersPass.cs

@ -146,7 +146,8 @@ namespace CppSharp.Passes @@ -146,7 +146,8 @@ namespace CppSharp.Passes
var type = qualType.Type.Desugar();
while (type.IsAddress())
{
var pointee = ((PointerType) type).Pointee.Desugar(false);
var pointee = ((PointerType) type).Pointee.Desugar(
resolveTemplateSubstitution: false);
if (pointee.IsAddress())
type = pointee;
else

25
tests/CSharp/CSharp.Tests.cs

@ -739,6 +739,31 @@ public unsafe class CSharpTests : GeneratorTestFixture @@ -739,6 +739,31 @@ public unsafe class CSharpTests : GeneratorTestFixture
Assert.That(IndependentFields<T1>.IndependentConst, Is.EqualTo(15));
}
[Test]
public void TestTemplateWithIndexer()
{
using (var templateWithIndexer = new TemplateWithIndexer<int>())
{
templateWithIndexer[0] = 5;
Assert.That(templateWithIndexer[0], Is.EqualTo(5));
templateWithIndexer["test"] = 15;
Assert.That(templateWithIndexer["test"], Is.EqualTo(15));
}
using (var templateWithIndexer = new TemplateWithIndexer<T1>())
{
using (var t1 = new T1(10))
{
templateWithIndexer[0] = t1;
Assert.That(templateWithIndexer[0].Field, Is.EqualTo(t1.Field));
}
using (var t1 = new T1(15))
{
templateWithIndexer["test"] = t1;
Assert.That(templateWithIndexer["test"].Field, Is.EqualTo(t1.Field));
}
}
}
[Test]
public void TestAbstractImplementatonsInPrimaryAndSecondaryBases()
{

33
tests/CSharp/CSharpTemplates.h

@ -152,6 +152,34 @@ private: @@ -152,6 +152,34 @@ private:
static bool staticField;
};
template <typename T>
class TemplateWithIndexer
{
public:
TemplateWithIndexer();
T& operator[](int i);
T& operator[](const char* string);
private:
T t[1];
};
template <typename T>
TemplateWithIndexer<T>::TemplateWithIndexer()
{
}
template <typename T>
T& TemplateWithIndexer<T>::operator[](int i)
{
return t[0];
}
template <typename T>
T& TemplateWithIndexer<T>::operator[](const char* string)
{
return t[0];
}
template <typename T, typename D>
HasDefaultTemplateArgument<T, D>::HasDefaultTemplateArgument()
{
@ -307,7 +335,8 @@ struct MapResultType<InputSequence<T>, MapFunctor> @@ -307,7 +335,8 @@ struct MapResultType<InputSequence<T>, MapFunctor>
void forceUseSpecializations(IndependentFields<int> _1, IndependentFields<bool> _2,
IndependentFields<T1> _3, IndependentFields<std::string> _4,
VirtualTemplate<int> _5, VirtualTemplate<bool> _6,
HasDefaultTemplateArgument<int, int> _7, DerivedChangesTypeName<T1> _8, std::string s);
HasDefaultTemplateArgument<int, int> _7, DerivedChangesTypeName<T1> _8,
TemplateWithIndexer<int> _9, TemplateWithIndexer<T1> _10, std::string s);
// 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>;
@ -318,3 +347,5 @@ template class DLL_API VirtualTemplate<int>; @@ -318,3 +347,5 @@ template class DLL_API VirtualTemplate<int>;
template class DLL_API VirtualTemplate<bool>;
template class DLL_API HasDefaultTemplateArgument<int, int>;
template class DLL_API DerivedChangesTypeName<T1>;
template class DLL_API TemplateWithIndexer<int>;
template class DLL_API TemplateWithIndexer<T1>;

Loading…
Cancel
Save