mirror of https://github.com/mono/CppSharp.git
27 changed files with 335 additions and 289 deletions
@ -0,0 +1,132 @@
@@ -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<Method> FindOperator(this Class c, CXXOperatorKind kind) |
||||
{ |
||||
return c.Operators.Where(method => method.OperatorKind == kind); |
||||
} |
||||
|
||||
public static IEnumerable<Method> FindMethodByOriginalName(this Class c, string name) |
||||
{ |
||||
return c.Methods.Where(method => method.OriginalName == name); |
||||
} |
||||
|
||||
public static IEnumerable<Variable> FindVariableByOriginalName(this Class c, string originalName) |
||||
{ |
||||
return c.Variables.Where(v => v.OriginalName == originalName); |
||||
} |
||||
|
||||
public static IEnumerable<Function> 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<T> FindHierarchy<T>(this Class c, Func<Class, IEnumerable<T>> 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<T>(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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,20 @@
@@ -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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,159 @@
@@ -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<T>(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<T>(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; |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue