diff --git a/src/Generator/AST/Utils.cs b/src/Generator/AST/Utils.cs index ed454281..75a72230 100644 --- a/src/Generator/AST/Utils.cs +++ b/src/Generator/AST/Utils.cs @@ -1,4 +1,6 @@  +using System; + namespace CppSharp.AST { public static class ASTUtils @@ -49,4 +51,116 @@ namespace CppSharp.AST return field.Ignore; } } + + public static class Operators + { + public static string GetOperatorOverloadPair(CXXOperatorKind kind) + { + switch (kind) + { + case CXXOperatorKind.EqualEqual: + return "!="; + case CXXOperatorKind.ExclaimEqual: + return "=="; + + case CXXOperatorKind.Less: + return ">"; + case CXXOperatorKind.Greater: + return "<"; + + case CXXOperatorKind.LessEqual: + return ">="; + case CXXOperatorKind.GreaterEqual: + return "<="; + + default: + throw new NotSupportedException(); + } + } + + public static bool IsBuiltinOperator(CXXOperatorKind kind) + { + bool isBuiltin; + GetOperatorIdentifier(kind, out isBuiltin); + + return isBuiltin; + } + + public static string GetOperatorIdentifier(CXXOperatorKind kind) + { + bool isBuiltin; + return GetOperatorIdentifier(kind, out isBuiltin); + } + + public static string GetOperatorIdentifier(CXXOperatorKind kind, + out bool isBuiltin) + { + isBuiltin = true; + + // These follow the order described in MSDN (Overloadable Operators). + switch (kind) + { + // These unary operators can be overloaded + case CXXOperatorKind.Plus: return "operator +"; + case CXXOperatorKind.Minus: return "operator -"; + case CXXOperatorKind.Exclaim: return "operator !"; + case CXXOperatorKind.Tilde: return "operator ~"; + case CXXOperatorKind.PlusPlus: return "operator ++"; + case CXXOperatorKind.MinusMinus: return "operator --"; + + // These binary operators can be overloaded + case CXXOperatorKind.Star: return "operator *"; + case CXXOperatorKind.Slash: return "operator /"; + case CXXOperatorKind.Percent: return "operator +"; + case CXXOperatorKind.Amp: return "operator &"; + case CXXOperatorKind.Pipe: return "operator |"; + case CXXOperatorKind.Caret: return "operator ^"; + case CXXOperatorKind.LessLess: return "operator <<"; + case CXXOperatorKind.GreaterGreater: return "operator >>"; + + // The comparison operators can be overloaded + case CXXOperatorKind.EqualEqual: return "operator =="; + case CXXOperatorKind.ExclaimEqual: return "operator !="; + case CXXOperatorKind.Less: return "operator <"; + case CXXOperatorKind.Greater: return "operator >"; + case CXXOperatorKind.LessEqual: return "operator <="; + case CXXOperatorKind.GreaterEqual: return "operator >="; + + // Assignment operators cannot be overloaded + case CXXOperatorKind.PlusEqual: + case CXXOperatorKind.MinusEqual: + case CXXOperatorKind.StarEqual: + case CXXOperatorKind.SlashEqual: + case CXXOperatorKind.PercentEqual: + case CXXOperatorKind.AmpEqual: + case CXXOperatorKind.PipeEqual: + case CXXOperatorKind.CaretEqual: + case CXXOperatorKind.LessLessEqual: + case CXXOperatorKind.GreaterGreaterEqual: + + // The array indexing operator cannot be overloaded + case CXXOperatorKind.Subscript: + + // The conditional logical operators cannot be overloaded + case CXXOperatorKind.AmpAmp: + case CXXOperatorKind.PipePipe: + + // These operators cannot be overloaded. + case CXXOperatorKind.Equal: + case CXXOperatorKind.Comma: + case CXXOperatorKind.ArrowStar: + case CXXOperatorKind.Arrow: + case CXXOperatorKind.Call: + case CXXOperatorKind.Conditional: + case CXXOperatorKind.New: + case CXXOperatorKind.Delete: + case CXXOperatorKind.Array_New: + case CXXOperatorKind.Array_Delete: + isBuiltin = false; + return "Operator" + kind.ToString(); + } + + throw new NotSupportedException(); + } + } } diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index 92581e1b..7baddb71 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -1456,14 +1456,13 @@ namespace CppSharp.Generators.CSharp Write("public "); - var isBuiltinOperator = false; - if (method.IsOperator) - GetOperatorIdentifier(method.OperatorKind, out isBuiltinOperator); - if (method.IsVirtual && !method.IsOverride) Write("virtual "); - if (method.IsStatic || (method.IsOperator && isBuiltinOperator)) + var isBuiltinOperator = method.IsOperator && + Operators.IsBuiltinOperator(method.OperatorKind); + + if (method.IsStatic || isBuiltinOperator) Write("static "); if (method.IsOverride) @@ -1525,35 +1524,11 @@ namespace CppSharp.Generators.CSharp PopBlock(NewLineKind.BeforeNextBlock); } - private static string GetOperatorOverloadPair(CXXOperatorKind kind) - { - switch (kind) - { - case CXXOperatorKind.EqualEqual: - return "!="; - case CXXOperatorKind.ExclaimEqual: - return "=="; - - case CXXOperatorKind.Less: - return ">"; - case CXXOperatorKind.Greater: - return "<"; - - case CXXOperatorKind.LessEqual: - return ">="; - case CXXOperatorKind.GreaterEqual: - return "<="; - - default: - throw new NotSupportedException(); - } - } - private void GenerateOperator(Method method, Class @class) { if (method.IsSynthetized) { - var @operator = GetOperatorOverloadPair(method.OperatorKind); + var @operator = Operators.GetOperatorOverloadPair(method.OperatorKind); WriteLine("return !({0} {1} {2});", method.Parameters[0].Name, @operator, method.Parameters[1].Name); @@ -1614,11 +1589,7 @@ namespace CppSharp.Generators.CSharp needsInstance = !method.IsStatic; if (method.IsOperator) - { - bool isBuiltin; - GetOperatorIdentifier(method.OperatorKind, out isBuiltin); - needsInstance &= !isBuiltin; - } + needsInstance &= !Operators.IsBuiltinOperator(method.OperatorKind); } var needsFixedThis = needsInstance && isValueType; @@ -1945,77 +1916,6 @@ namespace CppSharp.Generators.CSharp PopBlock(NewLineKind.BeforeNextBlock); } - public static string GetOperatorIdentifier(CXXOperatorKind kind, - out bool isBuiltin) - { - isBuiltin = true; - - // These follow the order described in MSDN (Overloadable Operators). - switch (kind) - { - // These unary operators can be overloaded - case CXXOperatorKind.Plus: return "operator +"; - case CXXOperatorKind.Minus: return "operator -"; - case CXXOperatorKind.Exclaim: return "operator !"; - case CXXOperatorKind.Tilde: return "operator ~"; - case CXXOperatorKind.PlusPlus: return "operator ++"; - case CXXOperatorKind.MinusMinus: return "operator --"; - - // These binary operators can be overloaded - case CXXOperatorKind.Star: return "operator *"; - case CXXOperatorKind.Slash: return "operator /"; - case CXXOperatorKind.Percent: return "operator +"; - case CXXOperatorKind.Amp: return "operator &"; - case CXXOperatorKind.Pipe: return "operator |"; - case CXXOperatorKind.Caret: return "operator ^"; - case CXXOperatorKind.LessLess: return "operator <<"; - case CXXOperatorKind.GreaterGreater: return "operator >>"; - - // The comparison operators can be overloaded - case CXXOperatorKind.EqualEqual: return "operator =="; - case CXXOperatorKind.ExclaimEqual: return "operator !="; - case CXXOperatorKind.Less: return "operator <"; - case CXXOperatorKind.Greater: return "operator >"; - case CXXOperatorKind.LessEqual: return "operator <="; - case CXXOperatorKind.GreaterEqual: return "operator >="; - - // Assignment operators cannot be overloaded - case CXXOperatorKind.PlusEqual: - case CXXOperatorKind.MinusEqual: - case CXXOperatorKind.StarEqual: - case CXXOperatorKind.SlashEqual: - case CXXOperatorKind.PercentEqual: - case CXXOperatorKind.AmpEqual: - case CXXOperatorKind.PipeEqual: - case CXXOperatorKind.CaretEqual: - case CXXOperatorKind.LessLessEqual: - case CXXOperatorKind.GreaterGreaterEqual: - - // The array indexing operator cannot be overloaded - case CXXOperatorKind.Subscript: - - // The conditional logical operators cannot be overloaded - case CXXOperatorKind.AmpAmp: - case CXXOperatorKind.PipePipe: - - // These operators cannot be overloaded. - case CXXOperatorKind.Equal: - case CXXOperatorKind.Comma: - case CXXOperatorKind.ArrowStar: - case CXXOperatorKind.Arrow: - case CXXOperatorKind.Call: - case CXXOperatorKind.Conditional: - case CXXOperatorKind.New: - case CXXOperatorKind.Delete: - case CXXOperatorKind.Array_New: - case CXXOperatorKind.Array_Delete: - isBuiltin = false; - return "Operator" + kind.ToString(); - } - - throw new NotSupportedException(); - } - public static string GetFunctionIdentifier(Function function) { var identifier = SafeIdentifier(function.Name); @@ -2024,8 +1924,7 @@ namespace CppSharp.Generators.CSharp if (method == null || !method.IsOperator) return identifier; - bool isBuiltin; - identifier = GetOperatorIdentifier(method.OperatorKind, out isBuiltin); + identifier = Operators.GetOperatorIdentifier(method.OperatorKind); return identifier; } diff --git a/src/Generator/Passes/CheckOperatorsOverloads.cs b/src/Generator/Passes/CheckOperatorsOverloads.cs index c6f6a79b..3cfb62ae 100644 --- a/src/Generator/Passes/CheckOperatorsOverloads.cs +++ b/src/Generator/Passes/CheckOperatorsOverloads.cs @@ -87,10 +87,9 @@ namespace CppSharp.Passes if (op.Ignore) continue; - bool isBuiltin; var method = new Method() { - Name = CSharpTextTemplate.GetOperatorIdentifier(missingKind, out isBuiltin), + Name = Operators.GetOperatorIdentifier(missingKind), Namespace = @class, IsSynthetized = true, Kind = CXXMethodKind.Operator,