Browse Source

Fixed the potential generation of explicit and implicit conversion from the same type.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/547/head
Dimitar Dobrev 11 years ago
parent
commit
a04ac2237a
  1. 49
      src/Generator/Passes/CheckDuplicatedNamesPass.cs
  2. 4
      tests/Basic/Basic.Tests.cs
  3. 8
      tests/Basic/Basic.cpp
  4. 2
      tests/Basic/Basic.h

49
src/Generator/Passes/CheckDuplicatedNamesPass.cs

@ -8,23 +8,18 @@ namespace CppSharp.Passes
{ {
class DeclarationName class DeclarationName
{ {
public Driver Driver { get; set; }
private readonly string Name;
private readonly Dictionary<string, int> methodSignatures; private readonly Dictionary<string, int> methodSignatures;
private int Count; private int Count;
private readonly IDiagnosticConsumer diagnostics;
public DeclarationName(string name, Driver driver) public DeclarationName(IDiagnosticConsumer diagnostics)
{ {
Driver = driver; this.diagnostics = diagnostics;
Name = name;
methodSignatures = new Dictionary<string, int>(); methodSignatures = new Dictionary<string, int>();
} }
public bool UpdateName(Declaration decl) public bool UpdateName(Declaration decl)
{ {
if (decl.Name != Name)
throw new Exception("Invalid name");
var function = decl as Function; var function = decl as Function;
if (function != null) if (function != null)
{ {
@ -57,7 +52,17 @@ namespace CppSharp.Passes
(method.OperatorKind == CXXOperatorKind.Conversion || (method.OperatorKind == CXXOperatorKind.Conversion ||
method.OperatorKind == CXXOperatorKind.ExplicitConversion)) method.OperatorKind == CXXOperatorKind.ExplicitConversion))
@params = @params.Concat(new[] { method.ConversionType.ToString() }); @params = @params.Concat(new[] { method.ConversionType.ToString() });
var signature = string.Format("{0}({1})", Name, string.Join( ", ", @params)); var signature = string.Format("{0}({1})", function.Name, string.Join( ", ", @params));
switch (function.OperatorKind)
{
// C# does not allow an explicit and an implicit operator from the same type
case CXXOperatorKind.Conversion:
signature = signature.Replace("implicit ", "conversion ");
break;
case CXXOperatorKind.ExplicitConversion:
signature = signature.Replace("explicit ", "conversion ");
break;
}
if (Count == 0) if (Count == 0)
Count++; Count++;
@ -70,18 +75,18 @@ namespace CppSharp.Passes
var methodCount = ++methodSignatures[signature]; var methodCount = ++methodSignatures[signature];
if (Count < methodCount+1) if (Count < methodCount + 1)
Count = methodCount+1; Count = methodCount + 1;
if (function.IsOperator) if (function.IsOperator)
{ {
// TODO: turn into a method; append the original type (say, "signed long") of the last parameter to the type so that the user knows which overload is called // TODO: turn into a method; append the original type (say, "signed long") of the last parameter to the type so that the user knows which overload is called
Driver.Diagnostics.Warning("Duplicate operator {0} ignored", function.Name); diagnostics.Warning("Duplicate operator {0} ignored", function.Name);
function.ExplicitlyIgnore(); function.ExplicitlyIgnore();
} }
else if (method != null && method.IsConstructor) else if (method != null && method.IsConstructor)
{ {
Driver.Diagnostics.Warning("Duplicate constructor {0} ignored", function.Name); diagnostics.Warning("Duplicate constructor {0} ignored", function.Name);
function.ExplicitlyIgnore(); function.ExplicitlyIgnore();
} }
else else
@ -184,7 +189,7 @@ namespace CppSharp.Passes
return fields; return fields;
} }
void CheckDuplicate(Declaration decl) private void CheckDuplicate(Declaration decl)
{ {
if (decl.IsDependent || !decl.IsGenerated) if (decl.IsDependent || !decl.IsGenerated)
return; return;
@ -193,10 +198,24 @@ namespace CppSharp.Passes
return; return;
var fullName = decl.QualifiedName; var fullName = decl.QualifiedName;
var function = decl as Function;
if (function != null)
{
switch (function.OperatorKind)
{
// C# does not allow an explicit and an implicit operator from the same type
case CXXOperatorKind.Conversion:
fullName = fullName.Replace("implicit ", "conversion ");
break;
case CXXOperatorKind.ExplicitConversion:
fullName = fullName.Replace("explicit ", "conversion ");
break;
}
}
// If the name is not yet on the map, then add it. // If the name is not yet on the map, then add it.
if (!names.ContainsKey(fullName)) if (!names.ContainsKey(fullName))
names.Add(fullName, new DeclarationName(decl.Name, Driver)); names.Add(fullName, new DeclarationName(Driver.Diagnostics));
if (names[fullName].UpdateName(decl)) if (names[fullName].UpdateName(decl))
{ {

4
tests/Basic/Basic.Tests.cs

@ -13,6 +13,10 @@ public class BasicTests : GeneratorTestFixture
Assert.That(new ChangedAccessOfInheritedProperty().Property, Is.EqualTo(2)); Assert.That(new ChangedAccessOfInheritedProperty().Property, Is.EqualTo(2));
Foo.NestedAbstract a; Foo.NestedAbstract a;
var renamedEmptyEnum = Foo.RenamedEmptyEnum.EmptyEnum1; var renamedEmptyEnum = Foo.RenamedEmptyEnum.EmptyEnum1;
using (var foo = new Foo())
{
Bar bar = foo;
}
} }
[Test] [Test]

8
tests/Basic/Basic.cpp

@ -59,6 +59,14 @@ Bar::Bar()
{ {
} }
Bar::Bar(Foo foo)
{
}
Bar::Bar(const Foo* foo)
{
}
Bar::Item Bar::RetItem1() Bar::Item Bar::RetItem1()
{ {
return Bar::Item1; return Bar::Item1;

2
tests/Basic/Basic.h

@ -73,6 +73,8 @@ struct DLL_API Bar
}; };
Bar(); Bar();
Bar(Foo foo);
explicit Bar(const Foo* foo);
Item RetItem1(); Item RetItem1();
int A; int A;
float B; float B;

Loading…
Cancel
Save