Browse Source

Fixed overloading of operators with parameters mapped to the same type.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1159/head
Dimitar Dobrev 8 years ago committed by João Matos
parent
commit
b0db304523
  1. 46
      src/Generator/Passes/CheckAmbiguousFunctions.cs
  2. 10
      tests/Common/Common.Tests.cs
  3. 17
      tests/Common/Common.cpp
  4. 4
      tests/Common/Common.h

46
src/Generator/Passes/CheckAmbiguousFunctions.cs

@ -1,8 +1,10 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using CppSharp.AST; using CppSharp.AST;
using CppSharp.AST.Extensions; using CppSharp.AST.Extensions;
using CppSharp.Types; using CppSharp.Types;
using CppSharp.Generators;
namespace CppSharp.Passes namespace CppSharp.Passes
{ {
@ -68,13 +70,16 @@ namespace CppSharp.Passes
private bool CheckDefaultParametersForAmbiguity(Function function, Function overload) private bool CheckDefaultParametersForAmbiguity(Function function, Function overload)
{ {
var commonParameters = Math.Min(function.Parameters.Count, overload.Parameters.Count); List<Parameter> functionParams = RemoveOperatorParams(function);
List<Parameter> overloadParams = RemoveOperatorParams(overload);
var commonParameters = Math.Min(functionParams.Count, overloadParams.Count);
var i = 0; var i = 0;
for (; i < commonParameters; ++i) for (; i < commonParameters; ++i)
{ {
AST.Type funcType = GetFinalType(function.Parameters[i]); AST.Type funcType = GetFinalType(functionParams[i]);
AST.Type overloadType = GetFinalType(overload.Parameters[i]); AST.Type overloadType = GetFinalType(overloadParams[i]);
AST.Type funcPointee = funcType.GetFinalPointee() ?? funcType; AST.Type funcPointee = funcType.GetFinalPointee() ?? funcType;
AST.Type overloadPointee = overloadType.GetFinalPointee() ?? overloadType; AST.Type overloadPointee = overloadType.GetFinalPointee() ?? overloadType;
@ -85,21 +90,21 @@ namespace CppSharp.Passes
return false; return false;
} }
for (; i < function.Parameters.Count; ++i) for (; i < functionParams.Count; ++i)
{ {
var funcParam = function.Parameters[i]; var funcParam = functionParams[i];
if (!funcParam.HasDefaultValue) if (!funcParam.HasDefaultValue)
return false; return false;
} }
for (; i < overload.Parameters.Count; ++i) for (; i < overloadParams.Count; ++i)
{ {
var overloadParam = overload.Parameters[i]; var overloadParam = overloadParams[i];
if (!overloadParam.HasDefaultValue) if (!overloadParam.HasDefaultValue)
return false; return false;
} }
if (function.Parameters.Count > overload.Parameters.Count) if (functionParams.Count > overloadParams.Count)
overload.ExplicitlyIgnore(); overload.ExplicitlyIgnore();
else else
function.ExplicitlyIgnore(); function.ExplicitlyIgnore();
@ -107,6 +112,31 @@ namespace CppSharp.Passes
return true; return true;
} }
private List<Parameter> RemoveOperatorParams(Function function)
{
var functionParams = new List<Parameter>(function.Parameters);
if (!function.IsOperator ||
(Context.Options.GeneratorKind != GeneratorKind.CLI &&
Context.Options.GeneratorKind != GeneratorKind.CSharp))
return functionParams;
// C++ operators in a class have no class param unlike C#
// but we need to be able to compare them to free operators.
Parameter param = functionParams.Find(p => p.Kind == ParameterKind.Regular);
if (param != null)
{
AST.Type type = param.Type.Desugar();
type = (type.GetFinalPointee() ?? type).Desugar();
Class @class;
if (type.TryGetClass(out @class) &&
function.Namespace == @class)
functionParams.Remove(param);
}
return functionParams;
}
private AST.Type GetFinalType(Parameter parameter) private AST.Type GetFinalType(Parameter parameter)
{ {
TypeMap typeMap; TypeMap typeMap;

10
tests/Common/Common.Tests.cs

@ -632,10 +632,13 @@ public class CommonTests : GeneratorTestFixture
var bar = new Bar { A = 5, B = 5.5f }; var bar = new Bar { A = 5, B = 5.5f };
Assert.IsTrue(bar == bar); Assert.IsTrue(bar == bar);
Assert.IsFalse(new Bar { A = 5, B = 5.6f } == bar); Assert.IsFalse(new Bar { A = 5, B = 5.6f } == bar);
#if !__MonoCS__
using (var differentConstOverloads = new DifferentConstOverloads()) using (var differentConstOverloads = new DifferentConstOverloads())
{ {
Assert.IsTrue(differentConstOverloads != null); DifferentConstOverloads other = null;
Assert.IsTrue(differentConstOverloads != other);
} }
#endif
#pragma warning restore 1718 #pragma warning restore 1718
} }
@ -654,7 +657,10 @@ public class CommonTests : GeneratorTestFixture
{ {
var differentConstOverloads = new DifferentConstOverloads(); var differentConstOverloads = new DifferentConstOverloads();
Assert.IsTrue(differentConstOverloads == new DifferentConstOverloads()); Assert.IsTrue(differentConstOverloads == new DifferentConstOverloads());
Assert.IsFalse(differentConstOverloads == 5); Assert.IsTrue(differentConstOverloads == 5);
Assert.IsFalse(differentConstOverloads == 4);
Assert.IsTrue(differentConstOverloads == "abcde");
Assert.IsFalse(differentConstOverloads == "abcd");
} }
[Test] [Test]

17
tests/Common/Common.cpp

@ -652,6 +652,11 @@ DifferentConstOverloads::DifferentConstOverloads() : i(5)
{ {
} }
int DifferentConstOverloads::getI() const
{
return i;
}
bool DifferentConstOverloads::operator ==(const DifferentConstOverloads& other) bool DifferentConstOverloads::operator ==(const DifferentConstOverloads& other)
{ {
return i == other.i; return i == other.i;
@ -664,7 +669,17 @@ bool DifferentConstOverloads::operator !=(const DifferentConstOverloads& other)
bool DifferentConstOverloads::operator ==(int number) const bool DifferentConstOverloads::operator ==(int number) const
{ {
return false; return i == number;
}
bool DifferentConstOverloads::operator ==(std::string s) const
{
return i == s.length();
}
bool operator ==(const DifferentConstOverloads& d, const char* s)
{
return d.getI() == strlen(s);
} }
int HasVirtualProperty::getProperty() int HasVirtualProperty::getProperty()

4
tests/Common/Common.h

@ -900,13 +900,17 @@ class DLL_API DifferentConstOverloads
{ {
public: public:
DifferentConstOverloads(); DifferentConstOverloads();
int getI() const;
bool operator ==(const DifferentConstOverloads& other); bool operator ==(const DifferentConstOverloads& other);
bool operator !=(const DifferentConstOverloads& other); bool operator !=(const DifferentConstOverloads& other);
bool operator ==(int number) const; bool operator ==(int number) const;
bool operator ==(std::string s) const;
private: private:
int i; int i;
}; };
DLL_API bool operator ==(const DifferentConstOverloads& d, const char* s);
class TestNamingAnonymousTypesInUnion class TestNamingAnonymousTypesInUnion
{ {
public: public:

Loading…
Cancel
Save