diff --git a/src/AST/Expression.cs b/src/AST/Expression.cs index e5b71728..5a9a2898 100644 --- a/src/AST/Expression.cs +++ b/src/AST/Expression.cs @@ -31,8 +31,7 @@ namespace CppSharp.AST { var printAsHex = IsHexadecimal && Type.IsUnsigned; var format = printAsHex ? "x" : string.Empty; - var value = Type.IsUnsigned ? Value.ToString(format) : - ((long)Value).ToString(format); + var value = Value.ToString(format); return printAsHex ? "0x" + value : value; } @@ -66,6 +65,7 @@ namespace CppSharp.AST { public CallExpr() { + Class = StatementClass.Call; Arguments = new List(); } @@ -81,6 +81,7 @@ namespace CppSharp.AST { public CXXConstructExpr() { + Class = StatementClass.ConstructorReference; Arguments = new List(); } diff --git a/src/AST/Statement.cs b/src/AST/Statement.cs index 712acb5d..2f55888b 100644 --- a/src/AST/Statement.cs +++ b/src/AST/Statement.cs @@ -5,6 +5,7 @@ Any, BinaryOperator, DeclarationReference, + Call, ConstructorReference, CXXOperatorCall, ImplicitCast, diff --git a/src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs b/src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs index 84a450ff..6ff5ccf2 100644 --- a/src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs +++ b/src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs @@ -1,5 +1,7 @@ -using CppSharp.AST; +using System.Linq; +using CppSharp.AST; using CppSharp.Types; +using Type = CppSharp.AST.Type; namespace CppSharp.Generators.CSharp { @@ -21,20 +23,52 @@ namespace CppSharp.Generators.CSharp } } - public class CSharpExpressionPrinter : IExpressionPrinter, - IExpressionVisitor + + public class CSharpExpressionPrinter : IExpressionPrinter { + public CSharpExpressionPrinter(CSharpTypePrinter typePrinter) + { + this.typePrinter = typePrinter; + } + public CSharpExpressionPrinterResult VisitExpression(Expression expr) { - return new CSharpExpressionPrinterResult() + switch (expr.Class) { - Value = expr.ToString(), - }; + case StatementClass.Call: + var callExpr = (CallExpr) expr; + switch (callExpr.Declaration.GenerationKind) + { + case GenerationKind.Generate: + case GenerationKind.Link: + return new CSharpExpressionPrinterResult + { + Value = string.Format("{0}.{1}({2})", + typePrinter.VisitDeclaration(callExpr.Declaration.Namespace), + callExpr.Declaration.Name, + string.Join(", ", callExpr.Arguments.Select(VisitExpression))) + }; + case GenerationKind.Internal: + // a non-ctor can only be internal if it's been converted to a property + return new CSharpExpressionPrinterResult + { + Value = string.Format("{0}.{1}", + typePrinter.VisitDeclaration(callExpr.Declaration.Namespace), + callExpr.Declaration.Name) + }; + default: + return new CSharpExpressionPrinterResult { Value = expr.String }; + } + default: + return new CSharpExpressionPrinterResult { Value = expr.String }; + } } public string ToString(Type type) { throw new System.NotImplementedException(); } + + private readonly CSharpTypePrinter typePrinter; } } \ No newline at end of file diff --git a/src/Generator/Generators/CSharp/CSharpGenerator.cs b/src/Generator/Generators/CSharp/CSharpGenerator.cs index 2b492697..f9f77b21 100644 --- a/src/Generator/Generators/CSharp/CSharpGenerator.cs +++ b/src/Generator/Generators/CSharp/CSharpGenerator.cs @@ -12,7 +12,7 @@ namespace CppSharp.Generators.CSharp public CSharpGenerator(Driver driver) : base(driver) { typePrinter = new CSharpTypePrinter(driver); - expressionPrinter = new CSharpExpressionPrinter(); + expressionPrinter = new CSharpExpressionPrinter(typePrinter); CppSharp.AST.Type.TypePrinterDelegate += type => type.Visit(typePrinter).Type; } diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index 53e6e171..bfbd3689 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -2065,7 +2065,7 @@ namespace CppSharp.Generators.CSharp string.Join(", ", method.Parameters.Where( p => p.Kind == ParameterKind.Regular).Select( - p => p.Ignore ? p.DefaultArgument.String : p.Name))); + p => p.Ignore ? ExpressionPrinter.VisitExpression(p.DefaultArgument).Value : p.Name))); } if (method.IsPure) @@ -2145,11 +2145,11 @@ namespace CppSharp.Generators.CSharp PopBlock(NewLineKind.BeforeNextBlock); } - private static string OverloadParamNameWithDefValue(Parameter p, ref int index) + private string OverloadParamNameWithDefValue(Parameter p, ref int index) { - return (p.Type.IsPointerToPrimitiveType() && p.Usage == ParameterUsage.InOut && p.HasDefaultValue) + return p.Type.IsPointerToPrimitiveType() && p.Usage == ParameterUsage.InOut && p.HasDefaultValue ? "ref param" + index++ - : p.DefaultArgument.String; + : ExpressionPrinter.VisitExpression(p.DefaultArgument).Value; } private void GenerateOverloadCall(Function function) @@ -2745,7 +2745,7 @@ namespace CppSharp.Generators.CSharp select string.Format("{0}{1} {2}", GetParameterUsage(param.Usage), typeName, param.Name + (param.DefaultArgument == null || !Options.GenerateDefaultValuesForArguments ? - string.Empty : " = " + param.DefaultArgument.String))); + string.Empty : " = " + ExpressionPrinter.VisitExpression(param.DefaultArgument)))); } #endregion diff --git a/src/Generator/Passes/HandleDefaultParamValuesPass.cs b/src/Generator/Passes/HandleDefaultParamValuesPass.cs index 8fe0e1ef..4613cff1 100644 --- a/src/Generator/Passes/HandleDefaultParamValuesPass.cs +++ b/src/Generator/Passes/HandleDefaultParamValuesPass.cs @@ -66,6 +66,9 @@ namespace CppSharp.Passes if (CheckForDefaultPointer(desugared, ref result)) return true; + if (expression.Class == StatementClass.Call) + return expression.Declaration.Ignore ? false : (bool?) null; + var defaultConstruct = CheckForDefaultConstruct(desugared, expression, ref result); if (defaultConstruct != false) return defaultConstruct; diff --git a/tests/CSharp/CSharp.Tests.cs b/tests/CSharp/CSharp.Tests.cs index 3b13416a..3b78f24e 100644 --- a/tests/CSharp/CSharp.Tests.cs +++ b/tests/CSharp/CSharp.Tests.cs @@ -197,6 +197,8 @@ public class CSharpTests : GeneratorTestFixture methodsWithDefaultValues.DefaultIntExpressionWithEnum(); methodsWithDefaultValues.DefaultCtorWithMoreThanOneArg(); methodsWithDefaultValues.DefaultWithRefManagedLong(); + methodsWithDefaultValues.DefaultWithFunctionCall(); + methodsWithDefaultValues.DefaultWithPropertyCall(); } } @@ -238,10 +240,14 @@ public class CSharpTests : GeneratorTestFixture public void TestImplicitCtor() { Foo foo = new Foo { A = 10 }; - MethodsWithDefaultValues m = foo; - Assert.AreEqual(foo.A, m.A); - MethodsWithDefaultValues m1 = 5; - Assert.AreEqual(5, m1.A); + using (MethodsWithDefaultValues m = foo) + { + Assert.AreEqual(foo.A, m.A); + } + using (MethodsWithDefaultValues m1 = 5) + { + Assert.AreEqual(5, m1.A); + } } [Test] diff --git a/tests/CSharp/CSharp.cpp b/tests/CSharp/CSharp.cpp index 09e11389..d9f8b2c6 100644 --- a/tests/CSharp/CSharp.cpp +++ b/tests/CSharp/CSharp.cpp @@ -43,6 +43,16 @@ void Foo::setNoParams() const int Foo::rename; +int Foo::makeFunctionCall() +{ + return 1; +} + +int Foo::propertyCall() +{ + return 1; +} + const Foo& Bar::operator[](int i) const { return m_foo; @@ -484,6 +494,14 @@ void MethodsWithDefaultValues::defaultWithRefManagedLong(long long* i) { } +void MethodsWithDefaultValues::defaultWithFunctionCall(int f) +{ +} + +void MethodsWithDefaultValues::defaultWithPropertyCall(int f) +{ +} + int MethodsWithDefaultValues::getA() { return m_foo.A; diff --git a/tests/CSharp/CSharp.h b/tests/CSharp/CSharp.h index c8500bfd..5519abe7 100644 --- a/tests/CSharp/CSharp.h +++ b/tests/CSharp/CSharp.h @@ -17,6 +17,8 @@ public: void setNoParams(); static const int rename = 5; + static int makeFunctionCall(); + static int propertyCall(); protected: int P; @@ -364,6 +366,8 @@ public: void defaultCtorWithMoreThanOneArg(QMargins m = QMargins(0, 0, 0, 0)); void defaultWithComplexArgs(const QRect& rectangle = QRect(QPoint(0, 0), QSize(-1, -1))); void defaultWithRefManagedLong(long long* i = 0); + void defaultWithFunctionCall(int f = Foo::makeFunctionCall()); + void defaultWithPropertyCall(int f = Foo::propertyCall()); int getA(); private: Foo m_foo;