From d3e963ff19eac61ee584a94063b757574ab407c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98ystein=20Krog?= Date: Sat, 15 Mar 2014 17:51:38 +0100 Subject: [PATCH 1/3] Move helper methods in Type out from class and into extension class TypeExtensions --- src/AST/Class.cs | 1 + src/AST/Method.cs | 2 + src/AST/Property.cs | 1 + src/AST/Type.cs | 154 ----------------- src/AST/TypeExtensions.cs | 159 ++++++++++++++++++ src/Generator/AST/ASTRecord.cs | 1 + .../Generators/CLI/CLIHeadersTemplate.cs | 1 + src/Generator/Generators/CLI/CLIMarshal.cs | 1 + .../Generators/CLI/CLISourcesTemplate.cs | 1 + .../Generators/CLI/CLITypePrinter.cs | 1 + .../Generators/CLI/CLITypeReferences.cs | 1 + .../Generators/CSharp/CSharpMarshal.cs | 1 + .../Generators/CSharp/CSharpTextTemplate.cs | 3 +- .../Generators/CSharp/CSharpTypePrinter.cs | 1 + src/Generator/Passes/CheckIgnoredDecls.cs | 1 + .../Passes/CheckOperatorsOverloads.cs | 1 + src/Generator/Passes/CheckStaticClass.cs | 1 + .../CheckVirtualOverrideReturnCovariance.cs | 1 + .../Passes/FunctionToInstanceMethodPass.cs | 1 + .../GetterSetterToPropertyAdvancedPass.cs | 1 + .../Passes/GetterSetterToPropertyPass.cs | 1 + src/Generator/Passes/RenamePass.cs | 1 + src/Generator/Types/ITypePrinter.cs | 1 + src/Generator/Types/TypeMap.cs | 1 + src/Generator/Types/Types.cs | 1 + 25 files changed, 184 insertions(+), 155 deletions(-) create mode 100644 src/AST/TypeExtensions.cs diff --git a/src/AST/Class.cs b/src/AST/Class.cs index 5336a28f..50557d57 100644 --- a/src/AST/Class.cs +++ b/src/AST/Class.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using CppSharp.AST.Extensions; namespace CppSharp.AST { diff --git a/src/AST/Method.cs b/src/AST/Method.cs index 964b694d..77d72b8e 100644 --- a/src/AST/Method.cs +++ b/src/AST/Method.cs @@ -1,3 +1,5 @@ +using CppSharp.AST.Extensions; + namespace CppSharp.AST { public enum CXXMethodKind diff --git a/src/AST/Property.cs b/src/AST/Property.cs index 3bb65261..0d045578 100644 --- a/src/AST/Property.cs +++ b/src/AST/Property.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using CppSharp.AST.Extensions; namespace CppSharp.AST { diff --git a/src/AST/Type.cs b/src/AST/Type.cs index c51cb6df..5fa4fb89 100644 --- a/src/AST/Type.cs +++ b/src/AST/Type.cs @@ -13,160 +13,6 @@ namespace CppSharp.AST public bool IsDependent { get; set; } - public bool IsPrimitiveType() - { - PrimitiveType type; - return IsPrimitiveType(out type); - } - - public bool IsPrimitiveType(out PrimitiveType primitive) - { - var builtin = this as BuiltinType; - if (builtin != null) - { - primitive = builtin.Type; - return true; - } - - primitive = PrimitiveType.Null; - return false; - } - - public bool IsPrimitiveType(PrimitiveType primitive) - { - PrimitiveType type; - if (!IsPrimitiveType(out type)) - return false; - - return primitive == type; - } - - public bool IsEnumType() - { - var tag = this as TagType; - - if (tag == null) - return false; - - return tag.Declaration is Enumeration; - } - - public bool IsAddress() - { - return IsPointer() || IsReference(); - } - - public bool IsPointer() - { - var functionPointer = this as MemberPointerType; - if (functionPointer != null) - return true; - var pointer = this as PointerType; - if (pointer == null) - return false; - return pointer.Modifier == PointerType.TypeModifier.Pointer; - } - - public bool IsReference() - { - var pointer = this as PointerType; - if (pointer == null) - return false; - return pointer.IsReference; - } - - public bool IsPointerToPrimitiveType() - { - var ptr = this as PointerType; - if (ptr == null) - return false; - PrimitiveType primitiveType; - return ptr.Pointee.IsPrimitiveType(out primitiveType); - } - - public bool IsPointerToPrimitiveType(out PrimitiveType primitive) - { - var ptr = this as PointerType; - if (ptr == null) - { - primitive = PrimitiveType.Null; - return false; - } - return ptr.Pointee.IsPrimitiveType(out primitive); - } - - public bool IsPointerToPrimitiveType(PrimitiveType primitive) - { - var ptr = this as PointerType; - if (ptr == null) - return false; - return ptr.Pointee.IsPrimitiveType(primitive); - } - - public bool IsPointerTo(out T type) where T : Type - { - var ptr = this as PointerType; - - if (ptr == null) - { - var functionPointer = this as MemberPointerType; - if (functionPointer != null) - { - type = functionPointer.Pointee as T; - return type != null; - } - type = null; - return false; - } - - type = ptr.Pointee as T; - return type != null; - } - - public bool IsTagDecl(out T decl) where T : Declaration - { - var tag = this as TagType; - - if (tag == null) - { - decl = null; - return false; - } - - decl = tag.Declaration as T; - return decl != null; - } - - public Type Desugar() - { - var type = this as TypedefType; - - if (type != null) - { - var decl = type.Declaration.Type; - - if (decl != null) - return decl.Desugar(); - } - - return this; - } - - public Type SkipPointerRefs() - { - var type = this as PointerType; - - if (type != null) - { - var pointee = type.Pointee; - - if (type.IsReference()) - return pointee.Desugar().SkipPointerRefs(); - } - - return this; - } - public abstract T Visit(ITypeVisitor visitor, TypeQualifiers quals = new TypeQualifiers()); diff --git a/src/AST/TypeExtensions.cs b/src/AST/TypeExtensions.cs new file mode 100644 index 00000000..1b4d7bc6 --- /dev/null +++ b/src/AST/TypeExtensions.cs @@ -0,0 +1,159 @@ +namespace CppSharp.AST.Extensions +{ + public static class TypeExtensions + { + public static bool IsPrimitiveType(this Type t) + { + PrimitiveType type; + return t.IsPrimitiveType(out type); + } + + public static bool IsPrimitiveType(this Type t, out PrimitiveType primitive) + { + var builtin = t as BuiltinType; + if (builtin != null) + { + primitive = builtin.Type; + return true; + } + + primitive = PrimitiveType.Null; + return false; + } + + public static bool IsPrimitiveType(this Type t, PrimitiveType primitive) + { + PrimitiveType type; + if (!t.IsPrimitiveType(out type)) + return false; + + return primitive == type; + } + + public static bool IsEnumType(this Type t) + { + var tag = t as TagType; + + if (tag == null) + return false; + + return tag.Declaration is Enumeration; + } + + public static bool IsAddress(this Type t) + { + return t.IsPointer() || t.IsReference(); + } + + public static bool IsPointer(this Type t) + { + var functionPointer = t as MemberPointerType; + if (functionPointer != null) + return true; + var pointer = t as PointerType; + if (pointer == null) + return false; + return pointer.Modifier == PointerType.TypeModifier.Pointer; + } + + public static bool IsReference(this Type t) + { + var pointer = t as PointerType; + if (pointer == null) + return false; + return pointer.IsReference; + } + + public static bool IsPointerToPrimitiveType(this Type t) + { + var ptr = t as PointerType; + if (ptr == null) + return false; + PrimitiveType primitiveType; + return ptr.Pointee.IsPrimitiveType(out primitiveType); + } + + public static bool IsPointerToPrimitiveType(this Type t, out PrimitiveType primitive) + { + var ptr = t as PointerType; + if (ptr == null) + { + primitive = PrimitiveType.Null; + return false; + } + return ptr.Pointee.IsPrimitiveType(out primitive); + } + + public static bool IsPointerToPrimitiveType(this Type t, PrimitiveType primitive) + { + var ptr = t as PointerType; + if (ptr == null) + return false; + return ptr.Pointee.IsPrimitiveType(primitive); + } + + public static bool IsPointerTo(this Type t, out T type) where T : Type + { + var ptr = t as PointerType; + + if (ptr == null) + { + var functionPointer = t as MemberPointerType; + if (functionPointer != null) + { + type = functionPointer.Pointee as T; + return type != null; + } + type = null; + return false; + } + + type = ptr.Pointee as T; + return type != null; + } + + public static bool IsTagDecl(this Type t, out T decl) where T : Declaration + { + var tag = t as TagType; + + if (tag == null) + { + decl = null; + return false; + } + + decl = tag.Declaration as T; + return decl != null; + } + + public static Type Desugar(this Type t) + { + var type = t as TypedefType; + + if (type != null) + { + var decl = type.Declaration.Type; + + if (decl != null) + return decl.Desugar(); + } + + return t; + } + + public static Type SkipPointerRefs(this Type t) + { + var type = t as PointerType; + + if (type != null) + { + var pointee = type.Pointee; + + if (type.IsReference()) + return pointee.Desugar().SkipPointerRefs(); + } + + return t; + } + } +} \ No newline at end of file diff --git a/src/Generator/AST/ASTRecord.cs b/src/Generator/AST/ASTRecord.cs index 4e3b816f..6d50494e 100644 --- a/src/Generator/AST/ASTRecord.cs +++ b/src/Generator/AST/ASTRecord.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using CppSharp.AST; +using CppSharp.AST.Extensions; using Type = CppSharp.AST.Type; namespace CppSharp.Generators.AST diff --git a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs index b6a50ba2..041cc651 100644 --- a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs +++ b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using CppSharp.AST; +using CppSharp.AST.Extensions; using CppSharp.Generators.CSharp; using CppSharp.Types; diff --git a/src/Generator/Generators/CLI/CLIMarshal.cs b/src/Generator/Generators/CLI/CLIMarshal.cs index 632f495e..890a0c2a 100644 --- a/src/Generator/Generators/CLI/CLIMarshal.cs +++ b/src/Generator/Generators/CLI/CLIMarshal.cs @@ -1,6 +1,7 @@ using System; using System.Text; using CppSharp.AST; +using CppSharp.AST.Extensions; using CppSharp.Types; using Delegate = CppSharp.AST.Delegate; using Type = CppSharp.AST.Type; diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index e257f4e6..abde1896 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.IO; using System.Linq; using CppSharp.AST; +using CppSharp.AST.Extensions; using CppSharp.Generators.CSharp; using CppSharp.Types; using Type = CppSharp.AST.Type; diff --git a/src/Generator/Generators/CLI/CLITypePrinter.cs b/src/Generator/Generators/CLI/CLITypePrinter.cs index 00a9bb83..8fc1645d 100644 --- a/src/Generator/Generators/CLI/CLITypePrinter.cs +++ b/src/Generator/Generators/CLI/CLITypePrinter.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using CppSharp.AST; +using CppSharp.AST.Extensions; using CppSharp.Types; using Type = CppSharp.AST.Type; diff --git a/src/Generator/Generators/CLI/CLITypeReferences.cs b/src/Generator/Generators/CLI/CLITypeReferences.cs index 0e56447d..90129523 100644 --- a/src/Generator/Generators/CLI/CLITypeReferences.cs +++ b/src/Generator/Generators/CLI/CLITypeReferences.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using CppSharp.AST; +using CppSharp.AST.Extensions; using CppSharp.Generators.AST; using CppSharp.Types; diff --git a/src/Generator/Generators/CSharp/CSharpMarshal.cs b/src/Generator/Generators/CSharp/CSharpMarshal.cs index 8624beb7..c96dd291 100644 --- a/src/Generator/Generators/CSharp/CSharpMarshal.cs +++ b/src/Generator/Generators/CSharp/CSharpMarshal.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using CppSharp.AST; +using CppSharp.AST.Extensions; using CppSharp.Types; using Type = CppSharp.AST.Type; diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index 0f428367..c6564434 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -6,7 +6,8 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Web.Util; -using CppSharp.AST; +using CppSharp.AST; +using CppSharp.AST.Extensions; using CppSharp.Types; using CppSharp.Utils; using Attribute = CppSharp.AST.Attribute; diff --git a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs index 81937138..9b5521fa 100644 --- a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs +++ b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using CppSharp.AST; +using CppSharp.AST.Extensions; using CppSharp.Types; using Type = CppSharp.AST.Type; diff --git a/src/Generator/Passes/CheckIgnoredDecls.cs b/src/Generator/Passes/CheckIgnoredDecls.cs index f300d555..fc90c237 100644 --- a/src/Generator/Passes/CheckIgnoredDecls.cs +++ b/src/Generator/Passes/CheckIgnoredDecls.cs @@ -1,4 +1,5 @@ using CppSharp.AST; +using CppSharp.AST.Extensions; using CppSharp.Types; namespace CppSharp.Passes diff --git a/src/Generator/Passes/CheckOperatorsOverloads.cs b/src/Generator/Passes/CheckOperatorsOverloads.cs index 99e19b33..d629c265 100644 --- a/src/Generator/Passes/CheckOperatorsOverloads.cs +++ b/src/Generator/Passes/CheckOperatorsOverloads.cs @@ -1,5 +1,6 @@ using System.Linq; using CppSharp.AST; +using CppSharp.AST.Extensions; using CppSharp.Generators; namespace CppSharp.Passes diff --git a/src/Generator/Passes/CheckStaticClass.cs b/src/Generator/Passes/CheckStaticClass.cs index 92485a08..04a2c4cb 100644 --- a/src/Generator/Passes/CheckStaticClass.cs +++ b/src/Generator/Passes/CheckStaticClass.cs @@ -1,5 +1,6 @@ using System.Linq; using CppSharp.AST; +using CppSharp.AST.Extensions; namespace CppSharp.Passes { diff --git a/src/Generator/Passes/CheckVirtualOverrideReturnCovariance.cs b/src/Generator/Passes/CheckVirtualOverrideReturnCovariance.cs index 05ad5520..829c7714 100644 --- a/src/Generator/Passes/CheckVirtualOverrideReturnCovariance.cs +++ b/src/Generator/Passes/CheckVirtualOverrideReturnCovariance.cs @@ -1,4 +1,5 @@ using CppSharp.AST; +using CppSharp.AST.Extensions; namespace CppSharp.Passes { diff --git a/src/Generator/Passes/FunctionToInstanceMethodPass.cs b/src/Generator/Passes/FunctionToInstanceMethodPass.cs index 022efcae..6355c8c8 100644 --- a/src/Generator/Passes/FunctionToInstanceMethodPass.cs +++ b/src/Generator/Passes/FunctionToInstanceMethodPass.cs @@ -1,5 +1,6 @@ using System.Linq; using CppSharp.AST; +using CppSharp.AST.Extensions; using CppSharp.Generators; namespace CppSharp.Passes diff --git a/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs b/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs index d2efaf2f..a4b32b75 100644 --- a/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs +++ b/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Reflection; using System.Text; using CppSharp.AST; +using CppSharp.AST.Extensions; using Type = CppSharp.AST.Type; namespace CppSharp.Passes diff --git a/src/Generator/Passes/GetterSetterToPropertyPass.cs b/src/Generator/Passes/GetterSetterToPropertyPass.cs index 73f6280c..3d843162 100644 --- a/src/Generator/Passes/GetterSetterToPropertyPass.cs +++ b/src/Generator/Passes/GetterSetterToPropertyPass.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using CppSharp.AST; +using CppSharp.AST.Extensions; namespace CppSharp.Passes { diff --git a/src/Generator/Passes/RenamePass.cs b/src/Generator/Passes/RenamePass.cs index 54ede31e..0f1ed1b1 100644 --- a/src/Generator/Passes/RenamePass.cs +++ b/src/Generator/Passes/RenamePass.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; using CppSharp.AST; +using CppSharp.AST.Extensions; namespace CppSharp.Passes { diff --git a/src/Generator/Types/ITypePrinter.cs b/src/Generator/Types/ITypePrinter.cs index 873f01eb..14758e45 100644 --- a/src/Generator/Types/ITypePrinter.cs +++ b/src/Generator/Types/ITypePrinter.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using CppSharp.AST; +using CppSharp.AST.Extensions; namespace CppSharp.Types { diff --git a/src/Generator/Types/TypeMap.cs b/src/Generator/Types/TypeMap.cs index 5571b3c4..cfceaa38 100644 --- a/src/Generator/Types/TypeMap.cs +++ b/src/Generator/Types/TypeMap.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using CppSharp.AST; +using CppSharp.AST.Extensions; using CppSharp.Generators; using CppSharp.Generators.AST; using CppSharp.Generators.CLI; diff --git a/src/Generator/Types/Types.cs b/src/Generator/Types/Types.cs index 871ee015..3549fb63 100644 --- a/src/Generator/Types/Types.cs +++ b/src/Generator/Types/Types.cs @@ -1,4 +1,5 @@ using CppSharp.AST; +using CppSharp.AST.Extensions; using CppSharp.Types; namespace CppSharp From fb127211ecdf8736dd48de38bf68fe9f9a0fced7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98ystein=20Krog?= Date: Sat, 15 Mar 2014 18:05:00 +0100 Subject: [PATCH 2/3] Move helper methods in Property out from class and into extension class PropertyExtensions --- src/AST/Property.cs | 13 ------------- src/AST/PropertyExtensions.cs | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 src/AST/PropertyExtensions.cs diff --git a/src/AST/Property.cs b/src/AST/Property.cs index 0d045578..0c477c26 100644 --- a/src/AST/Property.cs +++ b/src/AST/Property.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using CppSharp.AST.Extensions; namespace CppSharp.AST { @@ -106,17 +105,5 @@ namespace CppSharp.AST return visitor.VisitProperty(this); } - public bool IsInRefTypeAndBackedByValueClassField() - { - if (Field == null || ((Class) Namespace).IsRefType) - return false; - - Type type; - Field.Type.IsPointerTo(out type); - type = type ?? Field.Type; - - Class decl; - return type.IsTagDecl(out decl) && decl.IsValueType; - } } } \ No newline at end of file diff --git a/src/AST/PropertyExtensions.cs b/src/AST/PropertyExtensions.cs new file mode 100644 index 00000000..2d1a9a66 --- /dev/null +++ b/src/AST/PropertyExtensions.cs @@ -0,0 +1,20 @@ +using CppSharp.AST.Extensions; + +namespace CppSharp.AST +{ + public static class PropertyExtensions + { + public static bool IsInRefTypeAndBackedByValueClassField(this Property p) + { + if (p.Field == null || ((Class) p.Namespace).IsRefType) + return false; + + Type type; + p.Field.Type.IsPointerTo(out type); + type = type ?? p.Field.Type; + + Class decl; + return type.IsTagDecl(out decl) && decl.IsValueType; + } + } +} \ No newline at end of file From e0812abbd76b0afff9f61ff20bbfc30d10051b81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98ystein=20Krog?= Date: Sat, 15 Mar 2014 18:12:57 +0100 Subject: [PATCH 3/3] Move helper methods in Class out from class and into extension class ClassExtensions --- src/AST/Class.cs | 122 ---------------------------------- src/AST/ClassExtensions.cs | 132 +++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 122 deletions(-) create mode 100644 src/AST/ClassExtensions.cs diff --git a/src/AST/Class.cs b/src/AST/Class.cs index 50557d57..b075ef58 100644 --- a/src/AST/Class.cs +++ b/src/AST/Class.cs @@ -199,128 +199,6 @@ namespace CppSharp.AST } } - public IEnumerable FindOperator(CXXOperatorKind kind) - { - return Operators.Where(method => method.OperatorKind == kind); - } - - public IEnumerable FindMethodByOriginalName(string name) - { - return Methods.Where(method => method.OriginalName == name); - } - - public IEnumerable FindVariableByOriginalName(string originalName) - { - return Variables.Where(v => v.OriginalName == originalName); - } - - public override IEnumerable GetFunctionOverloads(Function function) - { - if (function.IsOperator) - return FindOperator(function.OperatorKind); - return Methods.Where(method => method.Name == function.Name); - } - - public IEnumerable FindHierarchy(Func> func) - where T : Declaration - { - foreach (var elem in func(this)) - yield return elem; - - foreach (var @base in Bases) - { - if (!@base.IsClass) continue; - foreach(var elem in @base.Class.FindHierarchy(func)) - yield return elem; - } - } - - public Method GetRootBaseMethod(Method @override, bool onlyFirstBase = false) - { - return (from @base in Bases - where @base.IsClass && (!onlyFirstBase || !@base.Class.IsInterface) - let baseMethod = ( - from method in @base.Class.Methods - where - method.Name == @override.Name && - method.ReturnType == @override.ReturnType && - method.Parameters.Count == @override.Parameters.Count && - method.Parameters.SequenceEqual(@override.Parameters, - new ParameterTypeComparer()) - select method).FirstOrDefault() - let rootBaseMethod = @base.Class.GetRootBaseMethod(@override) ?? baseMethod - where rootBaseMethod != null || onlyFirstBase - select rootBaseMethod).FirstOrDefault(); - } - - public Property GetRootBaseProperty(Property @override, bool onlyFirstBase = false) - { - return (from @base in Bases - where (!onlyFirstBase || !@base.Class.IsInterface) && @base.IsClass - let baseProperty = ( - from property in @base.Class.Properties - where - property.Name == @override.Name && - property.Parameters.Count == @override.Parameters.Count && - property.Parameters.SequenceEqual(@override.Parameters, - new ParameterTypeComparer()) - select property).FirstOrDefault() - let rootBaseProperty = @base.Class.GetRootBaseProperty(@override) ?? baseProperty - where rootBaseProperty != null || onlyFirstBase - select rootBaseProperty).FirstOrDefault(); - } - - public Property GetPropertyByName(string propertyName) - { - Property property = Properties.FirstOrDefault(m => m.Name == propertyName); - if (property != null) - return property; - Declaration decl; - foreach (var baseClassSpecifier in Bases.Where( - b => b.Type.IsTagDecl(out decl) && !b.Class.Ignore)) - { - property = baseClassSpecifier.Class.GetPropertyByName(propertyName); - if (property != null) - return property; - } - return null; - } - - public Property GetPropertyByConstituentMethod(Method method) - { - var property = Properties.FirstOrDefault(p => p.GetMethod == method); - if (property != null) - return property; - property = Properties.FirstOrDefault(p => p.SetMethod == method); - if (property != null) - return property; - Declaration decl; - foreach (BaseClassSpecifier @base in Bases.Where(b => b.Type.IsTagDecl(out decl))) - { - property = @base.Class.GetPropertyByConstituentMethod(method); - if (property != null) - return property; - } - return null; - } - - public Method GetMethodByName(string methodName) - { - var method = Methods.FirstOrDefault( - // HACK: because of the non-shared v-table entries bug one copy may have been renamed and the other not - m => string.Compare(m.Name, methodName, StringComparison.OrdinalIgnoreCase) == 0); - if (method != null) - return method; - Declaration decl; - foreach (BaseClassSpecifier @base in Bases.Where(b => b.Type.IsTagDecl(out decl))) - { - method = @base.Class.GetMethodByName(methodName); - if (method != null) - return method; - } - return null; - } - public override T Visit(IDeclVisitor visitor) { return visitor.VisitClassDecl(this); diff --git a/src/AST/ClassExtensions.cs b/src/AST/ClassExtensions.cs new file mode 100644 index 00000000..88b2e779 --- /dev/null +++ b/src/AST/ClassExtensions.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using CppSharp.AST.Extensions; + +namespace CppSharp.AST +{ + public static class ClassExtensions + { + public static IEnumerable FindOperator(this Class c, CXXOperatorKind kind) + { + return c.Operators.Where(method => method.OperatorKind == kind); + } + + public static IEnumerable FindMethodByOriginalName(this Class c, string name) + { + return c.Methods.Where(method => method.OriginalName == name); + } + + public static IEnumerable FindVariableByOriginalName(this Class c, string originalName) + { + return c.Variables.Where(v => v.OriginalName == originalName); + } + + public static IEnumerable GetFunctionOverloads(this Class c, Function function) + { + if (function.IsOperator) + return c.FindOperator(function.OperatorKind); + return c.Methods.Where(method => method.Name == function.Name); + } + + public static IEnumerable FindHierarchy(this Class c, Func> func) + where T : Declaration + { + foreach (var elem in func(c)) + yield return elem; + + foreach (var @base in c.Bases) + { + if (!@base.IsClass) continue; + foreach(var elem in @base.Class.FindHierarchy(func)) + yield return elem; + } + } + + public static Method GetRootBaseMethod(this Class c, Method @override, bool onlyFirstBase = false) + { + return (from @base in c.Bases + where @base.IsClass && (!onlyFirstBase || !@base.Class.IsInterface) + let baseMethod = ( + from method in @base.Class.Methods + where + method.Name == @override.Name && + method.ReturnType == @override.ReturnType && + method.Parameters.Count == @override.Parameters.Count && + method.Parameters.SequenceEqual(@override.Parameters, + new ParameterTypeComparer()) + select method).FirstOrDefault() + let rootBaseMethod = @base.Class.GetRootBaseMethod(@override) ?? baseMethod + where rootBaseMethod != null || onlyFirstBase + select rootBaseMethod).FirstOrDefault(); + } + + public static Property GetRootBaseProperty(this Class c, Property @override, bool onlyFirstBase = false) + { + return (from @base in c.Bases + where (!onlyFirstBase || !@base.Class.IsInterface) && @base.IsClass + let baseProperty = ( + from property in @base.Class.Properties + where + property.Name == @override.Name && + property.Parameters.Count == @override.Parameters.Count && + property.Parameters.SequenceEqual(@override.Parameters, + new ParameterTypeComparer()) + select property).FirstOrDefault() + let rootBaseProperty = @base.Class.GetRootBaseProperty(@override) ?? baseProperty + where rootBaseProperty != null || onlyFirstBase + select rootBaseProperty).FirstOrDefault(); + } + + public static Property GetPropertyByName(this Class c, string propertyName) + { + Property property = c.Properties.FirstOrDefault(m => m.Name == propertyName); + if (property != null) + return property; + Declaration decl; + foreach (var baseClassSpecifier in c.Bases.Where( + b => b.Type.IsTagDecl(out decl) && !b.Class.Ignore)) + { + property = baseClassSpecifier.Class.GetPropertyByName(propertyName); + if (property != null) + return property; + } + return null; + } + + public static Property GetPropertyByConstituentMethod(this Class c, Method method) + { + var property = c.Properties.FirstOrDefault(p => p.GetMethod == method); + if (property != null) + return property; + property = c.Properties.FirstOrDefault(p => p.SetMethod == method); + if (property != null) + return property; + Declaration decl; + foreach (BaseClassSpecifier @base in c.Bases.Where(b => b.Type.IsTagDecl(out decl))) + { + property = @base.Class.GetPropertyByConstituentMethod(method); + if (property != null) + return property; + } + return null; + } + + public static Method GetMethodByName(this Class c, string methodName) + { + var method = c.Methods.FirstOrDefault( + // HACK: because of the non-shared v-table entries bug one copy may have been renamed and the other not + m => string.Compare(m.Name, methodName, StringComparison.OrdinalIgnoreCase) == 0); + if (method != null) + return method; + Declaration decl; + foreach (BaseClassSpecifier @base in c.Bases.Where(b => b.Type.IsTagDecl(out decl))) + { + method = @base.Class.GetMethodByName(methodName); + if (method != null) + return method; + } + return null; + } + } +} \ No newline at end of file