Browse Source

Deprecated ExplicityIgnored use ExplicitlyIgnore(). Getting ExplicityIgnored and setting ExplicityIgnored to false don't make much sense anymore.

Conflicts:
	src/Generator/Passes/CheckOperatorsOverloads.cs
pull/228/merge
marcos henrich 12 years ago committed by triton
parent
commit
7125109e3f
  1. 20
      src/AST/Declaration.cs
  2. 4
      src/CppParser/Bindings/ParserGen.cs
  3. 8
      src/Generator.Tests/Passes/TestPasses.cs
  4. 14
      src/Generator/Library.cs
  5. 8
      src/Generator/Passes/CheckAmbiguousFunctions.cs
  6. 4
      src/Generator/Passes/CheckDuplicatedNamesPass.cs
  7. 38
      src/Generator/Passes/CheckIgnoredDecls.cs
  8. 12
      src/Generator/Passes/CheckMacrosPass.cs
  9. 484
      src/Generator/Passes/CheckOperatorsOverloads.cs
  10. 6
      src/Generator/Passes/CleanInvalidDeclNamesPass.cs
  11. 2
      src/Generator/Passes/FindSymbolsPass.cs
  12. 2
      src/Generator/Passes/FunctionToInstanceMethodPass.cs
  13. 2
      src/Generator/Passes/FunctionToStaticMethodPass.cs
  14. 4
      src/Generator/Passes/MoveFunctionToClassPass.cs
  15. 2
      src/Generator/Passes/MoveOperatorToClassPass.cs

20
src/AST/Declaration.cs

@ -192,9 +192,6 @@ namespace CppSharp.AST @@ -192,9 +192,6 @@ namespace CppSharp.AST
{
get
{
if(ExplicityIgnored)
return GenerationKind.None;
if (generationKind.HasValue)
return generationKind.Value;
@ -244,13 +241,24 @@ namespace CppSharp.AST @@ -244,13 +241,24 @@ namespace CppSharp.AST
}
}
public bool ExplicityIgnored { get; set; }
public void ExplicitlyIgnore()
{
GenerationKind = GenerationKind.None;
}
[Obsolete("Replace set by ExplicitlyIgnore(). Replace get by GenerationKind == GenerationKind.None.")]
public bool ExplicityIgnored
{
get { return GenerationKind == GenerationKind.None; }
set { if (value) ExplicitlyIgnore(); }
}
[Obsolete("Replace set by ExplicityIgnored. Replace get by IsGenerated, IsInternal or IsDeclared.")]
[Obsolete("Replace set by ExplicitlyIgnore(). Replace get by GenerationKind == GenerationKind.None.")]
public virtual bool Ignore
{
get { return GenerationKind == GenerationKind.None; }
set { ExplicityIgnored = value; }
set { if (value) ExplicitlyIgnore(); }
}
public AccessSpecifier Access { get; set; }

4
src/CppParser/Bindings/ParserGen.cs

@ -150,7 +150,7 @@ namespace CppSharp @@ -150,7 +150,7 @@ namespace CppSharp
if (!IsStdType(field.QualifiedType)) return false;
field.ExplicityIgnored = true;
field.ExplicitlyIgnore();
return true;
}
@ -161,7 +161,7 @@ namespace CppSharp @@ -161,7 +161,7 @@ namespace CppSharp
if (function.Parameters.Any(param => IsStdType(param.QualifiedType)))
{
function.ExplicityIgnored = true;
function.ExplicitlyIgnore();
return false;
}

8
src/Generator.Tests/Passes/TestPasses.cs

@ -55,13 +55,13 @@ namespace CppSharp.Generator.Tests.Passes @@ -55,13 +55,13 @@ namespace CppSharp.Generator.Tests.Passes
{
var c = AstContext.Class("Foo");
Assert.IsFalse(AstContext.Function("FooStart").ExplicityIgnored);
Assert.IsTrue(AstContext.Function("FooStart").IsGenerated);
Assert.IsNull(c.Method("Start"));
passBuilder.AddPass(new FunctionToStaticMethodPass());
passBuilder.RunPasses(pass => pass.VisitLibrary(AstContext));
Assert.IsTrue(AstContext.Function("FooStart").ExplicityIgnored);
Assert.IsFalse(AstContext.Function("FooStart").IsGenerated);
Assert.IsNotNull(c.Method("Start"));
}
@ -105,8 +105,8 @@ namespace CppSharp.Generator.Tests.Passes @@ -105,8 +105,8 @@ namespace CppSharp.Generator.Tests.Passes
public void TestIgnoringMethod()
{
AstContext.IgnoreClassMethodWithName("Foo", "toIgnore");
Assert.IsTrue(AstContext.FindClass("Foo").First().Methods.Find(
m => m.Name == "toIgnore").ExplicityIgnored);
Assert.IsFalse(AstContext.FindClass("Foo").First().Methods.Find(
m => m.Name == "toIgnore").IsGenerated);
}
}
}

14
src/Generator/Library.cs

@ -54,7 +54,7 @@ namespace CppSharp @@ -54,7 +54,7 @@ namespace CppSharp
{
Enumeration @enum = context.GetEnumWithMatchingItem(pattern);
if (@enum != null)
@enum.ExplicityIgnored = true;
@enum.ExplicitlyIgnore();
}
public static void SetNameOfEnumWithMatchingItem(this ASTContext context, string pattern,
@ -184,7 +184,7 @@ namespace CppSharp @@ -184,7 +184,7 @@ namespace CppSharp
public static void IgnoreClassWithName(this ASTContext context, string name)
{
foreach (var @class in context.FindClass(name))
@class.ExplicityIgnored = true;
@class.ExplicitlyIgnore();
}
public static void SetClassAsOpaque(this ASTContext context, string name)
@ -270,7 +270,7 @@ namespace CppSharp @@ -270,7 +270,7 @@ namespace CppSharp
public static void IgnoreFunctionWithName(this ASTContext context, string name)
{
foreach (var function in context.FindFunction(name))
function.ExplicityIgnored = true;
function.ExplicitlyIgnore();
}
public static void IgnoreFunctionWithPattern(this ASTContext context, string pattern)
@ -280,7 +280,7 @@ namespace CppSharp @@ -280,7 +280,7 @@ namespace CppSharp
foreach (var function in unit.Functions)
{
if (Regex.Match(function.Name, pattern).Success)
function.ExplicityIgnored = true;
function.ExplicitlyIgnore();
}
}
}
@ -299,7 +299,7 @@ namespace CppSharp @@ -299,7 +299,7 @@ namespace CppSharp
where method.Name == name
select method)
{
method.ExplicityIgnored = true;
method.ExplicitlyIgnore();
}
}
@ -308,7 +308,7 @@ namespace CppSharp @@ -308,7 +308,7 @@ namespace CppSharp
foreach (var @class in context.FindClass(name))
{
foreach (var classField in @class.Fields.FindAll(f => f.Name == field))
classField.ExplicityIgnored = true;
classField.ExplicitlyIgnore();
}
}
@ -334,7 +334,7 @@ namespace CppSharp @@ -334,7 +334,7 @@ namespace CppSharp
foreach (var unit in units)
{
unit.ExplicityIgnored = true;
unit.ExplicitlyIgnore();
}
}

8
src/Generator/Passes/CheckAmbiguousFunctions.cs

@ -88,9 +88,9 @@ namespace CppSharp.Passes @@ -88,9 +88,9 @@ namespace CppSharp.Passes
}
if (function.Parameters.Count > overload.Parameters.Count)
overload.ExplicityIgnored = true;
overload.ExplicitlyIgnore();
else
function.ExplicityIgnored = true;
function.ExplicitlyIgnore();
return true;
}
@ -104,13 +104,13 @@ namespace CppSharp.Passes @@ -104,13 +104,13 @@ namespace CppSharp.Passes
if (method1.IsConst && !method2.IsConst)
{
method1.ExplicityIgnored = true;
method1.ExplicitlyIgnore();
return false;
}
if (method2.IsConst && !method1.IsConst)
{
method2.ExplicityIgnored = true;
method2.ExplicitlyIgnore();
return false;
}
}

4
src/Generator/Passes/CheckDuplicatedNamesPass.cs

@ -72,12 +72,12 @@ namespace CppSharp.Passes @@ -72,12 +72,12 @@ namespace CppSharp.Passes
{
// 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.EmitWarning("Duplicate operator {0} ignored", function.Name);
function.ExplicityIgnored = true;
function.ExplicitlyIgnore();
}
else if (method != null && method.IsConstructor)
{
Driver.Diagnostics.EmitWarning("Duplicate constructor {0} ignored", function.Name);
function.ExplicityIgnored = true;
function.ExplicitlyIgnore();
}
else
function.Name += methodCount.ToString(CultureInfo.InvariantCulture);

38
src/Generator/Passes/CheckIgnoredDecls.cs

@ -33,20 +33,20 @@ namespace CppSharp.Passes @@ -33,20 +33,20 @@ namespace CppSharp.Passes
if (AlreadyVisited(decl))
return false;
if (decl.ExplicityIgnored)
if (decl.GenerationKind == GenerationKind.None)
return true;
if (!CheckDeclarationAccess(decl))
{
Log.Debug("Decl '{0}' was ignored due to invalid access",
decl.Name);
decl.ExplicityIgnored = true;
decl.ExplicitlyIgnore();
return true;
}
if (decl.IsDependent)
{
decl.ExplicityIgnored = true;
decl.ExplicitlyIgnore();
Log.Debug("Decl '{0}' was ignored due to dependent context",
decl.Name);
return true;
@ -66,7 +66,7 @@ namespace CppSharp.Passes @@ -66,7 +66,7 @@ namespace CppSharp.Passes
if (!HasInvalidType(type, out msg))
return false;
field.ExplicityIgnored = true;
field.ExplicitlyIgnore();
var @class = (Class)field.Namespace;
@ -89,7 +89,7 @@ namespace CppSharp.Passes @@ -89,7 +89,7 @@ namespace CppSharp.Passes
string msg;
if (HasInvalidType(ret.Type, out msg))
{
function.ExplicityIgnored = true;
function.ExplicitlyIgnore();
Log.Debug("Function '{0}' was ignored due to {1} return decl",
function.Name, msg);
return false;
@ -99,7 +99,7 @@ namespace CppSharp.Passes @@ -99,7 +99,7 @@ namespace CppSharp.Passes
{
if (HasInvalidDecl(param, out msg))
{
function.ExplicityIgnored = true;
function.ExplicitlyIgnore();
Log.Debug("Function '{0}' was ignored due to {1} param",
function.Name, msg);
return false;
@ -107,7 +107,7 @@ namespace CppSharp.Passes @@ -107,7 +107,7 @@ namespace CppSharp.Passes
if (HasInvalidType(param.Type, out msg))
{
function.ExplicityIgnored = true;
function.ExplicitlyIgnore();
Log.Debug("Function '{0}' was ignored due to {1} param",
function.Name, msg);
return false;
@ -116,7 +116,7 @@ namespace CppSharp.Passes @@ -116,7 +116,7 @@ namespace CppSharp.Passes
var decayedType = param.Type.Desugar() as DecayedType;
if (decayedType != null)
{
function.ExplicityIgnored = true;
function.ExplicitlyIgnore();
Log.Debug("Function '{0}' was ignored due to unsupported decayed type param",
function.Name);
return false;
@ -128,7 +128,7 @@ namespace CppSharp.Passes @@ -128,7 +128,7 @@ namespace CppSharp.Passes
param.Type.Desugar().IsTagDecl(out retClass);
if (retClass == null)
{
function.ExplicityIgnored = true;
function.ExplicitlyIgnore();
Log.Debug(
"Function '{0}' was ignored due to an indirect return param not of a tag type",
function.Name);
@ -161,7 +161,7 @@ namespace CppSharp.Passes @@ -161,7 +161,7 @@ namespace CppSharp.Passes
"Virtual method '{0}' was ignored due to ignored base '{1}'",
method.QualifiedOriginalName, ignoredBase.Name);
method.ExplicityIgnored = true;
method.ExplicitlyIgnore();
return false;
}
@ -174,7 +174,7 @@ namespace CppSharp.Passes @@ -174,7 +174,7 @@ namespace CppSharp.Passes
"Virtual method '{0}' was ignored due to ignored override '{1}'",
method.QualifiedOriginalName, baseOverride.Name);
method.ExplicityIgnored = true;
method.ExplicitlyIgnore();
return false;
}
}
@ -217,7 +217,7 @@ namespace CppSharp.Passes @@ -217,7 +217,7 @@ namespace CppSharp.Passes
string msg;
if (HasInvalidType(typedef.Type, out msg))
{
typedef.ExplicityIgnored = true;
typedef.ExplicitlyIgnore();
Log.Debug("Typedef '{0}' was ignored due to {1} type",
typedef.Name, msg);
return false;
@ -234,7 +234,7 @@ namespace CppSharp.Passes @@ -234,7 +234,7 @@ namespace CppSharp.Passes
string msg;
if (HasInvalidDecl(property, out msg))
{
property.ExplicityIgnored = true;
property.ExplicitlyIgnore();
Log.Debug("Property '{0}' was ignored due to {1} decl",
property.Name, msg);
return false;
@ -242,7 +242,7 @@ namespace CppSharp.Passes @@ -242,7 +242,7 @@ namespace CppSharp.Passes
if (HasInvalidType(property.Type, out msg))
{
property.ExplicityIgnored = true;
property.ExplicitlyIgnore();
Log.Debug("Property '{0}' was ignored due to {1} type",
property.Name, msg);
return false;
@ -259,7 +259,7 @@ namespace CppSharp.Passes @@ -259,7 +259,7 @@ namespace CppSharp.Passes
string msg;
if (HasInvalidDecl(variable, out msg))
{
variable.ExplicityIgnored = true;
variable.ExplicitlyIgnore();
Log.Debug("Variable '{0}' was ignored due to {1} decl",
variable.Name, msg);
return false;
@ -267,7 +267,7 @@ namespace CppSharp.Passes @@ -267,7 +267,7 @@ namespace CppSharp.Passes
if (HasInvalidType(variable.Type, out msg))
{
variable.ExplicityIgnored = true;
variable.ExplicitlyIgnore();
Log.Debug("Variable '{0}' was ignored due to {1} type",
variable.Name, msg);
return false;
@ -284,7 +284,7 @@ namespace CppSharp.Passes @@ -284,7 +284,7 @@ namespace CppSharp.Passes
string msg;
if (HasInvalidDecl(@event, out msg))
{
@event.ExplicityIgnored = true;
@event.ExplicitlyIgnore();
Log.Debug("Event '{0}' was ignored due to {1} decl",
@event.Name, msg);
return false;
@ -294,7 +294,7 @@ namespace CppSharp.Passes @@ -294,7 +294,7 @@ namespace CppSharp.Passes
{
if (HasInvalidDecl(param, out msg))
{
@event.ExplicityIgnored = true;
@event.ExplicitlyIgnore();
Log.Debug("Event '{0}' was ignored due to {1} param",
@event.Name, msg);
return false;
@ -302,7 +302,7 @@ namespace CppSharp.Passes @@ -302,7 +302,7 @@ namespace CppSharp.Passes
if (HasInvalidType(param.Type, out msg))
{
@event.ExplicityIgnored = true;
@event.ExplicitlyIgnore();
Log.Debug("Event '{0}' was ignored due to {1} param",
@event.Name, msg);
return false;

12
src/Generator/Passes/CheckMacrosPass.cs

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
using System;
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST;
@ -74,7 +74,7 @@ namespace CppSharp.Passes @@ -74,7 +74,7 @@ namespace CppSharp.Passes
e.Location != MacroLocation.ClassBody &&
e.Location != MacroLocation.FunctionBody &&
e.Location != MacroLocation.FunctionParameters))
decl.ExplicityIgnored = true;
decl.ExplicitlyIgnore();
if (expansions.Any(e => e.Text == Prefix + "_IGNORE_GEN" &&
e.Location != MacroLocation.ClassBody &&
@ -89,7 +89,7 @@ namespace CppSharp.Passes @@ -89,7 +89,7 @@ namespace CppSharp.Passes
if (expansions.Any(e => e.Text == Prefix + "_IGNORE_FILE"))
{
unit.ExplicityIgnored = true;
unit.ExplicitlyIgnore();
}
return base.VisitTranslationUnit(unit);
@ -149,7 +149,7 @@ namespace CppSharp.Passes @@ -149,7 +149,7 @@ namespace CppSharp.Passes
if (expansions.Any(e => e.Text == Prefix + "_HASHCODE"
|| e.Text == Prefix + "_EQUALS"))
method.ExplicityIgnored = true;
method.ExplicitlyIgnore();
return base.VisitMethodDecl(method);
}
@ -184,7 +184,7 @@ namespace CppSharp.Passes @@ -184,7 +184,7 @@ namespace CppSharp.Passes
var setMethod = property.SetMethod;
if (setMethod != null)
property.SetMethod.ExplicityIgnored = true;
property.SetMethod.ExplicitlyIgnore();
}
return base.VisitProperty(property);

484
src/Generator/Passes/CheckOperatorsOverloads.cs

@ -1,102 +1,102 @@ @@ -1,102 +1,102 @@
using System.Linq;
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators;
namespace CppSharp.Passes
{
/// <summary>
/// Checks for missing operator overloads required by C#.
/// </summary>
class CheckOperatorsOverloadsPass : TranslationUnitPass
{
public CheckOperatorsOverloadsPass()
{
ClearVisitedDeclarations = false;
}
public override bool VisitClassDecl(Class @class)
{
if (@class.CompleteDeclaration != null)
return VisitClassDecl(@class.CompleteDeclaration as Class);
if (!VisitDeclarationContext(@class))
return false;
// Check for C++ operators that cannot be represented in C#.
CheckInvalidOperators(@class);
if (Driver.Options.IsCSharpGenerator)
{
// The comparison operators, if overloaded, must be overloaded in pairs;
// that is, if == is overloaded, != must also be overloaded. The reverse
// is also true, and similar for < and >, and for <= and >=.
HandleMissingOperatorOverloadPair(@class, CXXOperatorKind.EqualEqual,
CXXOperatorKind.ExclaimEqual);
HandleMissingOperatorOverloadPair(@class, CXXOperatorKind.Less,
CXXOperatorKind.Greater);
HandleMissingOperatorOverloadPair(@class, CXXOperatorKind.LessEqual,
CXXOperatorKind.GreaterEqual);
}
return false;
}
private void CheckInvalidOperators(Class @class)
{
foreach (var @operator in @class.Operators.Where(o => o.IsGenerated))
{
if (!IsValidOperatorOverload(@operator))
{
Driver.Diagnostics.Debug(DiagnosticId.InvalidOperatorOverload,
"Invalid operator overload {0}::{1}",
@class.OriginalName, @operator.OperatorKind);
@operator.ExplicityIgnored = true;
continue;
}
if (@operator.SynthKind == FunctionSynthKind.NonMemberOperator)
continue;
if (@operator.OperatorKind == CXXOperatorKind.Subscript)
{
CreateIndexer(@class, @operator);
}
else
{
// Handle missing operator parameters
if (@operator.IsStatic)
@operator.Parameters = @operator.Parameters.Skip(1).ToList();
var type = new PointerType()
{
QualifiedPointee = new QualifiedType(new TagType(@class)),
Modifier = PointerType.TypeModifier.LVReference
};
@operator.Parameters.Insert(0, new Parameter
{
Name = Generator.GeneratedIdentifier("op"),
QualifiedType = new QualifiedType(type),
Kind = ParameterKind.OperatorParameter
});
}
}
}
void CreateIndexer(Class @class, Method @operator)
{
var property = new Property
{
Name = "Item",
QualifiedType = @operator.ReturnType,
Access = @operator.Access,
Namespace = @class,
GetMethod = @operator
};
using System.Linq;
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators;
namespace CppSharp.Passes
{
/// <summary>
/// Checks for missing operator overloads required by C#.
/// </summary>
class CheckOperatorsOverloadsPass : TranslationUnitPass
{
public CheckOperatorsOverloadsPass()
{
ClearVisitedDeclarations = false;
}
public override bool VisitClassDecl(Class @class)
{
if (@class.CompleteDeclaration != null)
return VisitClassDecl(@class.CompleteDeclaration as Class);
if (!VisitDeclarationContext(@class))
return false;
// Check for C++ operators that cannot be represented in C#.
CheckInvalidOperators(@class);
if (Driver.Options.IsCSharpGenerator)
{
// The comparison operators, if overloaded, must be overloaded in pairs;
// that is, if == is overloaded, != must also be overloaded. The reverse
// is also true, and similar for < and >, and for <= and >=.
HandleMissingOperatorOverloadPair(@class, CXXOperatorKind.EqualEqual,
CXXOperatorKind.ExclaimEqual);
HandleMissingOperatorOverloadPair(@class, CXXOperatorKind.Less,
CXXOperatorKind.Greater);
HandleMissingOperatorOverloadPair(@class, CXXOperatorKind.LessEqual,
CXXOperatorKind.GreaterEqual);
}
return false;
}
private void CheckInvalidOperators(Class @class)
{
foreach (var @operator in @class.Operators.Where(o => o.IsGenerated))
{
if (!IsValidOperatorOverload(@operator))
{
Driver.Diagnostics.Debug(DiagnosticId.InvalidOperatorOverload,
"Invalid operator overload {0}::{1}",
@class.OriginalName, @operator.OperatorKind);
@operator.ExplicitlyIgnore();
continue;
}
if (@operator.SynthKind == FunctionSynthKind.NonMemberOperator)
continue;
if (@operator.OperatorKind == CXXOperatorKind.Subscript)
{
CreateIndexer(@class, @operator);
}
else
{
// Handle missing operator parameters
if (@operator.IsStatic)
@operator.Parameters = @operator.Parameters.Skip(1).ToList();
var type = new PointerType()
{
QualifiedPointee = new QualifiedType(new TagType(@class)),
Modifier = PointerType.TypeModifier.LVReference
};
@operator.Parameters.Insert(0, new Parameter
{
Name = Generator.GeneratedIdentifier("op"),
QualifiedType = new QualifiedType(type),
Kind = ParameterKind.OperatorParameter
});
}
}
}
void CreateIndexer(Class @class, Method @operator)
{
var property = new Property
{
Name = "Item",
QualifiedType = @operator.ReturnType,
Access = @operator.Access,
Namespace = @class,
GetMethod = @operator
};
if (!@operator.ReturnType.Qualifiers.IsConst && @operator.ReturnType.Type.IsAddress())
property.SetMethod = @operator;
@ -114,148 +114,148 @@ namespace CppSharp.Passes @@ -114,148 +114,148 @@ namespace CppSharp.Passes
}
property.Parameters.AddRange(@operator.Parameters);
@class.Properties.Add(property);
@operator.GenerationKind = GenerationKind.Internal;
}
static void HandleMissingOperatorOverloadPair(Class @class, CXXOperatorKind op1,
CXXOperatorKind op2)
{
foreach (var op in @class.Operators.Where(
o => o.OperatorKind == op1 || o.OperatorKind == op2).ToList())
{
int index;
var missingKind = CheckMissingOperatorOverloadPair(@class, out index, op1, op2,
op.Parameters.Last().Type);
if (missingKind == CXXOperatorKind.None || !op.IsGenerated)
continue;
var method = new Method()
{
Name = Operators.GetOperatorIdentifier(missingKind),
Namespace = @class,
IsSynthetized = true,
Kind = CXXMethodKind.Operator,
OperatorKind = missingKind,
ReturnType = op.ReturnType,
Parameters = op.Parameters
};
@class.Methods.Insert(index, method);
}
}
static CXXOperatorKind CheckMissingOperatorOverloadPair(Class @class,
out int index, CXXOperatorKind op1, CXXOperatorKind op2, Type type)
{
var first = @class.Operators.FirstOrDefault(o => o.OperatorKind == op1 &&
o.Parameters.Last().Type.Equals(type));
var second = @class.Operators.FirstOrDefault(o => o.OperatorKind == op2 &&
o.Parameters.Last().Type.Equals(type));
var hasFirst = first != null;
var hasSecond = second != null;
if (hasFirst && (!hasSecond || !second.IsGenerated))
{
index = @class.Methods.IndexOf(first);
return op2;
}
if (hasSecond && (!hasFirst || !first.IsGenerated))
{
index = @class.Methods.IndexOf(second);
return op1;
}
index = 0;
return CXXOperatorKind.None;
}
static bool IsValidOperatorOverload(Method @operator)
{
// These follow the order described in MSDN (Overloadable Operators).
switch (@operator.OperatorKind)
{
// These unary operators can be overloaded
case CXXOperatorKind.Plus:
case CXXOperatorKind.Minus:
case CXXOperatorKind.Exclaim:
case CXXOperatorKind.Tilde:
// These binary operators can be overloaded
case CXXOperatorKind.Slash:
case CXXOperatorKind.Percent:
case CXXOperatorKind.Amp:
case CXXOperatorKind.Pipe:
case CXXOperatorKind.Caret:
// The array indexing operator can be overloaded
case CXXOperatorKind.Subscript:
// The conversion operator can be overloaded
case CXXOperatorKind.Conversion:
return true;
// The comparison operators can be overloaded if their return type is bool
case CXXOperatorKind.EqualEqual:
case CXXOperatorKind.ExclaimEqual:
case CXXOperatorKind.Less:
case CXXOperatorKind.Greater:
case CXXOperatorKind.LessEqual:
case CXXOperatorKind.GreaterEqual:
return @operator.ReturnType.Type.IsPrimitiveType(PrimitiveType.Bool);
// Only prefix operators can be overloaded
case CXXOperatorKind.PlusPlus:
case CXXOperatorKind.MinusMinus:
return @operator.Parameters.Count == 0;
// Bitwise shift operators can only be overloaded if the second parameter is int
case CXXOperatorKind.LessLess:
case CXXOperatorKind.GreaterGreater:
PrimitiveType primitiveType;
return @operator.Parameters.Last().Type.IsPrimitiveType(out primitiveType) &&
primitiveType == PrimitiveType.Int32;
// No parameters means the dereference operator - cannot be overloaded
case CXXOperatorKind.Star:
return @operator.Parameters.Count > 0;
// 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 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:
default:
return false;
}
}
}
}
@operator.GenerationKind = GenerationKind.Internal;
}
static void HandleMissingOperatorOverloadPair(Class @class, CXXOperatorKind op1,
CXXOperatorKind op2)
{
foreach (var op in @class.Operators.Where(
o => o.OperatorKind == op1 || o.OperatorKind == op2).ToList())
{
int index;
var missingKind = CheckMissingOperatorOverloadPair(@class, out index, op1, op2,
op.Parameters.Last().Type);
if (missingKind == CXXOperatorKind.None || !op.IsGenerated)
continue;
var method = new Method()
{
Name = Operators.GetOperatorIdentifier(missingKind),
Namespace = @class,
IsSynthetized = true,
Kind = CXXMethodKind.Operator,
OperatorKind = missingKind,
ReturnType = op.ReturnType,
Parameters = op.Parameters
};
@class.Methods.Insert(index, method);
}
}
static CXXOperatorKind CheckMissingOperatorOverloadPair(Class @class,
out int index, CXXOperatorKind op1, CXXOperatorKind op2, Type type)
{
var first = @class.Operators.FirstOrDefault(o => o.OperatorKind == op1 &&
o.Parameters.Last().Type.Equals(type));
var second = @class.Operators.FirstOrDefault(o => o.OperatorKind == op2 &&
o.Parameters.Last().Type.Equals(type));
var hasFirst = first != null;
var hasSecond = second != null;
if (hasFirst && (!hasSecond || !second.IsGenerated))
{
index = @class.Methods.IndexOf(first);
return op2;
}
if (hasSecond && (!hasFirst || !first.IsGenerated))
{
index = @class.Methods.IndexOf(second);
return op1;
}
index = 0;
return CXXOperatorKind.None;
}
static bool IsValidOperatorOverload(Method @operator)
{
// These follow the order described in MSDN (Overloadable Operators).
switch (@operator.OperatorKind)
{
// These unary operators can be overloaded
case CXXOperatorKind.Plus:
case CXXOperatorKind.Minus:
case CXXOperatorKind.Exclaim:
case CXXOperatorKind.Tilde:
// These binary operators can be overloaded
case CXXOperatorKind.Slash:
case CXXOperatorKind.Percent:
case CXXOperatorKind.Amp:
case CXXOperatorKind.Pipe:
case CXXOperatorKind.Caret:
// The array indexing operator can be overloaded
case CXXOperatorKind.Subscript:
// The conversion operator can be overloaded
case CXXOperatorKind.Conversion:
return true;
// The comparison operators can be overloaded if their return type is bool
case CXXOperatorKind.EqualEqual:
case CXXOperatorKind.ExclaimEqual:
case CXXOperatorKind.Less:
case CXXOperatorKind.Greater:
case CXXOperatorKind.LessEqual:
case CXXOperatorKind.GreaterEqual:
return @operator.ReturnType.Type.IsPrimitiveType(PrimitiveType.Bool);
// Only prefix operators can be overloaded
case CXXOperatorKind.PlusPlus:
case CXXOperatorKind.MinusMinus:
return @operator.Parameters.Count == 0;
// Bitwise shift operators can only be overloaded if the second parameter is int
case CXXOperatorKind.LessLess:
case CXXOperatorKind.GreaterGreater:
PrimitiveType primitiveType;
return @operator.Parameters.Last().Type.IsPrimitiveType(out primitiveType) &&
primitiveType == PrimitiveType.Int32;
// No parameters means the dereference operator - cannot be overloaded
case CXXOperatorKind.Star:
return @operator.Parameters.Count > 0;
// 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 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:
default:
return false;
}
}
}
}

6
src/Generator/Passes/CleanInvalidDeclNamesPass.cs

@ -36,7 +36,7 @@ namespace CppSharp.Passes @@ -36,7 +36,7 @@ namespace CppSharp.Passes
if (decl is Class && string.IsNullOrWhiteSpace(decl.Name))
{
decl.Name = "_";
decl.ExplicityIgnored = true;
decl.ExplicitlyIgnore();
return false;
}
@ -107,10 +107,10 @@ namespace CppSharp.Passes @@ -107,10 +107,10 @@ namespace CppSharp.Passes
// so we ignore the class and process just the typedef.
if (@class != null)
typedef.ExplicityIgnored = true;
typedef.ExplicitlyIgnore();
if (typedef.Type == null)
typedef.ExplicityIgnored = true;
typedef.ExplicitlyIgnore();
return base.VisitTypedefDecl(typedef);
}

2
src/Generator/Passes/FindSymbolsPass.cs

@ -15,7 +15,7 @@ namespace CppSharp.Passes @@ -15,7 +15,7 @@ namespace CppSharp.Passes
if (mangledDecl != null && !(method != null && (method.IsPure || method.IsSynthetized)) &&
!VisitMangledDeclaration(mangledDecl))
{
decl.ExplicityIgnored = true;
decl.ExplicitlyIgnore();
return false;
}

2
src/Generator/Passes/FunctionToInstanceMethodPass.cs

@ -39,7 +39,7 @@ namespace CppSharp.Passes @@ -39,7 +39,7 @@ namespace CppSharp.Passes
return false;
function.Name = function.Name.Substring(@class.Name.Length);
function.ExplicityIgnored = true;
function.ExplicitlyIgnore();
// Create a new fake method so it acts as an instance method.
var method = new Method

2
src/Generator/Passes/FunctionToStaticMethodPass.cs

@ -33,7 +33,7 @@ namespace CppSharp.Passes @@ -33,7 +33,7 @@ namespace CppSharp.Passes
// Clean up the name of the function now that it will be a static method.
var name = function.Name.Substring(@class.Name.Length);
function.ExplicityIgnored = true;
function.ExplicitlyIgnore();
// Create a new fake method so it acts as a static method.
var method = new Method

4
src/Generator/Passes/MoveFunctionToClassPass.cs

@ -24,7 +24,7 @@ namespace CppSharp.Passes @@ -24,7 +24,7 @@ namespace CppSharp.Passes
}
if (function.IsOperator)
function.ExplicityIgnored = true;
function.ExplicitlyIgnore();
return true;
}
@ -49,7 +49,7 @@ namespace CppSharp.Passes @@ -49,7 +49,7 @@ namespace CppSharp.Passes
IsStatic = true
};
function.ExplicityIgnored = true;
function.ExplicitlyIgnore();
if (method.OperatorKind != CXXOperatorKind.None)
{

2
src/Generator/Passes/MoveOperatorToClassPass.cs

@ -38,7 +38,7 @@ namespace CppSharp.Passes @@ -38,7 +38,7 @@ namespace CppSharp.Passes
IsStatic = true
};
function.ExplicityIgnored = true;
function.ExplicitlyIgnore();
@class.Methods.Add(method);

Loading…
Cancel
Save