Browse Source

Separated IsTagDecl into TryGetClass and TryGetEnum, added IsClass() and IsEnum().

pull/241/head
marcos henrich 11 years ago
parent
commit
de764599fa
  1. 26
      src/AST/Class.cs
  2. 12
      src/AST/ClassExtensions.cs
  3. 2
      src/AST/PropertyExtensions.cs
  4. 79
      src/AST/TypeExtensions.cs
  5. 2
      src/Generator/AST/ASTRecord.cs
  6. 12
      src/Generator/Generators/CLI/CLIMarshal.cs
  7. 2
      src/Generator/Generators/CLI/CLITypePrinter.cs
  8. 4
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  9. 36
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  10. 4
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  11. 5
      src/Generator/Passes/CheckIgnoredDecls.cs
  12. 2
      src/Generator/Passes/ConstructorToConversionOperatorPass.cs
  13. 2
      src/Generator/Passes/FunctionToInstanceMethodPass.cs

26
src/AST/Class.cs

@ -33,26 +33,9 @@ namespace CppSharp.AST
{ {
get get
{ {
Class @class; Class @class;
if (Type.IsTagDecl(out @class)) Type.TryGetClass(out @class);
return @class; return @class;
var type = Type.Desugar() as TemplateSpecializationType;
if (type == null)
{
TypedefType typedef;
if (Type.IsPointerTo(out typedef))
{
type = (TemplateSpecializationType) typedef.Desugar();
}
else
{
Type.IsPointerTo(out type);
}
}
var templatedClass = ((ClassTemplate) type.Template).TemplatedClass;
return templatedClass.CompleteDeclaration == null ?
templatedClass : (Class) templatedClass.CompleteDeclaration;
} }
} }
@ -60,8 +43,7 @@ namespace CppSharp.AST
{ {
get get
{ {
Class @class; return Type.IsClass();
return Type.IsTagDecl(out @class);
} }
} }
} }

12
src/AST/ClassExtensions.cs

@ -83,9 +83,9 @@ namespace CppSharp.AST
Property property = c.Properties.FirstOrDefault(m => m.Name == propertyName); Property property = c.Properties.FirstOrDefault(m => m.Name == propertyName);
if (property != null) if (property != null)
return property; return property;
Declaration decl;
foreach (var baseClassSpecifier in c.Bases.Where( foreach (var baseClassSpecifier in c.Bases.Where(
b => b.Type.IsTagDecl(out decl) && b.Class.IsDeclared)) b => b.Type.IsClass() && b.Class.IsDeclared))
{ {
property = baseClassSpecifier.Class.GetPropertyByName(propertyName); property = baseClassSpecifier.Class.GetPropertyByName(propertyName);
if (property != null) if (property != null)
@ -102,8 +102,8 @@ namespace CppSharp.AST
property = c.Properties.FirstOrDefault(p => p.SetMethod == method); property = c.Properties.FirstOrDefault(p => p.SetMethod == method);
if (property != null) if (property != null)
return property; return property;
Declaration decl;
foreach (BaseClassSpecifier @base in c.Bases.Where(b => b.Type.IsTagDecl(out decl))) foreach (BaseClassSpecifier @base in c.Bases.Where(b => b.Type.IsClass()))
{ {
property = @base.Class.GetPropertyByConstituentMethod(method); property = @base.Class.GetPropertyByConstituentMethod(method);
if (property != null) if (property != null)
@ -119,8 +119,8 @@ namespace CppSharp.AST
m => string.Compare(m.Name, methodName, StringComparison.OrdinalIgnoreCase) == 0); m => string.Compare(m.Name, methodName, StringComparison.OrdinalIgnoreCase) == 0);
if (method != null) if (method != null)
return method; return method;
Declaration decl;
foreach (BaseClassSpecifier @base in c.Bases.Where(b => b.Type.IsTagDecl(out decl))) foreach (BaseClassSpecifier @base in c.Bases.Where(b => b.Type.IsClass()))
{ {
method = @base.Class.GetMethodByName(methodName); method = @base.Class.GetMethodByName(methodName);
if (method != null) if (method != null)

2
src/AST/PropertyExtensions.cs

@ -14,7 +14,7 @@ namespace CppSharp.AST
type = type ?? p.Field.Type; type = type ?? p.Field.Type;
Class decl; Class decl;
return type.IsTagDecl(out decl) && decl.IsValueType; return type.TryGetClass(out decl) && decl.IsValueType;
} }
} }
} }

79
src/AST/TypeExtensions.cs

@ -90,33 +90,70 @@
if (ptr == null) if (ptr == null)
return false; return false;
return ptr.Pointee.IsPrimitiveType(primitive); return ptr.Pointee.IsPrimitiveType(primitive);
}
public static bool IsPointerTo<T>(this Type t, out T type) where T : Type
{
var pointee = t.GetPointee();
type = pointee as T;
if (type == null)
{
var attributedType = pointee as AttributedType;
if (attributedType != null)
type = attributedType.Modified.Type as T;
}
return type != null;
} }
public static bool IsTagDecl<T>(this Type t, out T decl) where T : Declaration public static bool IsPointerTo<T>(this Type t, out T type) where T : Type
{ {
var tag = t.Desugar() as TagType; var pointee = t.GetPointee();
type = pointee as T;
if (tag == null) if (type == null)
{ {
decl = null; var attributedType = pointee as AttributedType;
return false; if (attributedType != null)
type = attributedType.Modified.Type as T;
} }
return type != null;
}
decl = tag.Declaration as T; public static bool IsClass(this Type t)
return decl != null; {
Class @class;
return t.TryGetClass(out @class);
}
public static bool TryGetClass(this Type t, out Class @class)
{
t = t.Desugar();
var tag = t as TagType;
if (tag != null)
{
@class = tag.Declaration as Class;
return @class != null;
}
var type = t as TemplateSpecializationType;
if (type != null)
{
var templatedClass = ((ClassTemplate)type.Template).TemplatedClass;
@class = templatedClass.CompleteDeclaration == null
? templatedClass
: (Class)templatedClass.CompleteDeclaration;
return @class != null;
}
@class = null;
return false;
}
public static bool IsEnum(this Type t)
{
Enumeration @enum;
return t.TryGetEnum(out @enum);
}
public static bool TryGetEnum(this Type t, out Enumeration @enum)
{
var tag = t.Desugar() as TagType;
if (tag == null)
{
@enum = null;
return false;
}
@enum = tag.Declaration as Enumeration;
return @enum != null;
} }
public static Type Desugar(this Type t) public static Type Desugar(this Type t)

2
src/Generator/AST/ASTRecord.cs

@ -147,7 +147,7 @@ namespace CppSharp.Generators.AST
var field = (Field)ancestors.Pop(); var field = (Field)ancestors.Pop();
Class decl; Class decl;
return field.Type.Desugar().IsTagDecl(out decl) && decl.IsValueType; return field.Type.Desugar().TryGetClass(out decl) && decl.IsValueType;
} }
} }

12
src/Generator/Generators/CLI/CLIMarshal.cs

@ -107,7 +107,7 @@ namespace CppSharp.Generators.CLI
Context.Driver.TypeDatabase.FindTypeMap(pointee, out typeMap); Context.Driver.TypeDatabase.FindTypeMap(pointee, out typeMap);
Class @class; Class @class;
if (pointee.IsTagDecl(out @class) && typeMap == null) if (pointee.TryGetClass(out @class) && typeMap == null)
{ {
var instance = (pointer.IsReference) ? "&" + Context.ReturnVarName var instance = (pointer.IsReference) ? "&" + Context.ReturnVarName
: Context.ReturnVarName; : Context.ReturnVarName;
@ -426,7 +426,7 @@ namespace CppSharp.Generators.CLI
} }
Enumeration @enum; Enumeration @enum;
if (pointee.IsTagDecl(out @enum)) if (pointee.TryGetEnum(out @enum))
{ {
ArgumentPrefix.Write("&"); ArgumentPrefix.Write("&");
Context.Return.Write("(::{0})*{1}", @enum.QualifiedOriginalName, Context.Return.Write("(::{0})*{1}", @enum.QualifiedOriginalName,
@ -434,9 +434,9 @@ namespace CppSharp.Generators.CLI
return true; return true;
} }
Class @class; Class @class;
if (pointee.IsTagDecl(out @class) && @class.IsValueType) if (pointee.TryGetClass(out @class) && @class.IsValueType)
{ {
if (Context.Function == null) if (Context.Function == null)
Context.Return.Write("&"); Context.Return.Write("&");
return pointee.Visit(this, quals); return pointee.Visit(this, quals);
@ -655,7 +655,7 @@ namespace CppSharp.Generators.CLI
Type type; Type type;
Class @class; Class @class;
var isRef = property.Type.IsPointerTo(out type) && var isRef = property.Type.IsPointerTo(out type) &&
!(type.IsTagDecl(out @class) && @class.IsValueType) && !(type.TryGetClass(out @class) && @class.IsValueType) &&
!type.IsPrimitiveType(); !type.IsPrimitiveType();
if (isRef) if (isRef)

2
src/Generator/Generators/CLI/CLITypePrinter.cs

@ -161,7 +161,7 @@ namespace CppSharp.Generators.CLI
} }
Enumeration @enum; Enumeration @enum;
if (pointee.IsTagDecl(out @enum)) if (pointee.TryGetEnum(out @enum))
{ {
var typeName = @enum.Visit(this); var typeName = @enum.Visit(this);
return string.Format("{0}*", typeName); return string.Format("{0}*", typeName);

4
src/Generator/Generators/CSharp/CSharpMarshal.cs

@ -439,7 +439,7 @@ namespace CppSharp.Generators.CSharp
} }
Class @class; Class @class;
if (pointee.IsTagDecl(out @class) && @class.IsValueType) if (pointee.TryGetClass(out @class) && @class.IsValueType)
{ {
if (Context.Parameter.Usage == ParameterUsage.Out) if (Context.Parameter.Usage == ParameterUsage.Out)
{ {
@ -582,7 +582,7 @@ namespace CppSharp.Generators.CSharp
if (type.IsAddress()) if (type.IsAddress())
{ {
Class decl; Class decl;
if (type.IsTagDecl(out decl) && decl.IsValueType) if (type.TryGetClass(out decl) && decl.IsValueType)
Context.Return.Write("{0}.{1}", param, Helpers.InstanceIdentifier); Context.Return.Write("{0}.{1}", param, Helpers.InstanceIdentifier);
else else
Context.Return.Write("{0} == ({2}) null ? global::System.IntPtr.Zero : {0}.{1}", param, Context.Return.Write("{0} == ({2}) null ? global::System.IntPtr.Zero : {0}.{1}", param,

36
src/Generator/Generators/CSharp/CSharpTextTemplate.cs

@ -314,7 +314,7 @@ namespace CppSharp.Generators.CSharp
#region Classes #region Classes
public void GenerateClass(Class @class) public void GenerateClass(Class @class)
{ {
if (@class.IsIncomplete) if (@class.IsIncomplete)
return; return;
@ -661,7 +661,7 @@ namespace CppSharp.Generators.CSharp
Type type; Type type;
Class @class; Class @class;
var isRef = property.Type.IsPointerTo(out type) && var isRef = property.Type.IsPointerTo(out type) &&
!(type.IsTagDecl(out @class) && @class.IsValueType) && !(type.TryGetClass(out @class) && @class.IsValueType) &&
!type.IsPrimitiveType(); !type.IsPrimitiveType();
if (isRef) if (isRef)
@ -704,9 +704,9 @@ namespace CppSharp.Generators.CSharp
public void GenerateClassProlog(Class @class) public void GenerateClassProlog(Class @class)
{ {
if (@class.IsUnion) if (@class.IsUnion)
WriteLine("[StructLayout(LayoutKind.Explicit)]"); WriteLine("[StructLayout(LayoutKind.Explicit)]");
Write(!@class.IsGenerated ? "internal " : Helpers.GetAccess(@class.Access)); Write(!@class.IsGenerated ? "internal " : Helpers.GetAccess(@class.Access));
Write("unsafe "); Write("unsafe ");
if (Driver.Options.GenerateAbstractImpls && @class.IsAbstract) if (Driver.Options.GenerateAbstractImpls && @class.IsAbstract)
@ -766,12 +766,12 @@ namespace CppSharp.Generators.CSharp
} }
} }
private void GenerateClassInternalsField(Field field) private void GenerateClassInternalsField(Field field)
{ {
// we do not support dependent fields yet, see https://github.com/mono/CppSharp/issues/197 // we do not support dependent fields yet, see https://github.com/mono/CppSharp/issues/197
Class @class; Class @class;
if (field.Type.IsDependent && !field.Type.IsPointer() && if (field.Type.IsDependent && !field.Type.IsPointer() &&
!(field.Type.IsTagDecl(out @class) && @class.IsUnion)) !(field.Type.TryGetClass(out @class) && @class.IsUnion))
return; return;
var safeIdentifier = Helpers.SafeIdentifier(field.OriginalName); var safeIdentifier = Helpers.SafeIdentifier(field.OriginalName);
@ -787,14 +787,14 @@ namespace CppSharp.Generators.CSharp
if (field.Expression != null) if (field.Expression != null)
{ {
var fieldValuePrinted = field.Expression.CSharpValue(ExpressionPrinter); var fieldValuePrinted = field.Expression.CSharpValue(ExpressionPrinter);
Write("{0} {1} {2} = {3};", !field.IsGenerated ? "internal" : "public", Write("{0} {1} {2} = {3};", !field.IsGenerated ? "internal" : "public",
fieldTypePrinted.Type, safeIdentifier, fieldValuePrinted); fieldTypePrinted.Type, safeIdentifier, fieldValuePrinted);
} }
else else
{ {
Write("{0} {1} {2};", !field.IsGenerated ? "internal" : "public", Write("{0} {1} {2};", !field.IsGenerated ? "internal" : "public",
fieldTypePrinted.Type, safeIdentifier); fieldTypePrinted.Type, safeIdentifier);
} }
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);
@ -2226,15 +2226,15 @@ namespace CppSharp.Generators.CSharp
var @params = GenerateFunctionParamsMarshal(parameters, function); var @params = GenerateFunctionParamsMarshal(parameters, function);
var originalFunction = function.OriginalFunction ?? function; var originalFunction = function.OriginalFunction ?? function;
if (originalFunction.HasIndirectReturnTypeParameter) if (originalFunction.HasIndirectReturnTypeParameter)
{ {
var indirectRetType = originalFunction.Parameters.First( var indirectRetType = originalFunction.Parameters.First(
parameter => parameter.Kind == ParameterKind.IndirectReturnType); parameter => parameter.Kind == ParameterKind.IndirectReturnType);
Class retClass; Class retClass;
indirectRetType.Type.Desugar().IsTagDecl(out retClass); indirectRetType.Type.Desugar().TryGetClass(out retClass);
WriteLine("var {0} = new {1}.Internal();", GeneratedIdentifier("ret"), WriteLine("var {0} = new {1}.Internal();", GeneratedIdentifier("ret"),
QualifiedIdentifier(retClass.OriginalClass ?? retClass)); QualifiedIdentifier(retClass.OriginalClass ?? retClass));
@ -2337,7 +2337,7 @@ namespace CppSharp.Generators.CSharp
pointee = pointee.Desugar(); pointee = pointee.Desugar();
string @null; string @null;
Class @class; Class @class;
if (pointee.IsTagDecl(out @class) && @class.IsValueType) if (pointee.TryGetClass(out @class) && @class.IsValueType)
{ {
@null = string.Format("new {0}()", pointee); @null = string.Format("new {0}()", pointee);
} }
@ -2468,7 +2468,7 @@ namespace CppSharp.Generators.CSharp
var paramType = param.Type; var paramType = param.Type;
Class @class; Class @class;
if (paramType.Desugar().IsTagDecl(out @class) && @class.IsRefType) if (paramType.Desugar().TryGetClass(out @class) && @class.IsRefType)
{ {
WriteLine("{0} = new {1}();", param.Name, paramType); WriteLine("{0} = new {1}();", param.Name, paramType);
} }

4
src/Generator/Generators/CSharp/CSharpTypePrinter.cs

@ -232,13 +232,13 @@ namespace CppSharp.Generators.CSharp
} }
Enumeration @enum; Enumeration @enum;
if (desugared.IsTagDecl(out @enum)) if (desugared.TryGetEnum(out @enum))
{ {
return @enum.Name + "*"; return @enum.Name + "*";
} }
Class @class; Class @class;
if ((desugared.IsDependent || desugared.IsTagDecl(out @class)) if ((desugared.IsDependent || desugared.TryGetClass(out @class))
&& ContextKind == CSharpTypePrinterContextKind.Native) && ContextKind == CSharpTypePrinterContextKind.Native)
{ {
return "global::System.IntPtr"; return "global::System.IntPtr";

5
src/Generator/Passes/CheckIgnoredDecls.cs

@ -1,4 +1,5 @@
using CppSharp.AST; using System;
using CppSharp.AST;
using CppSharp.AST.Extensions; using CppSharp.AST.Extensions;
using CppSharp.Types; using CppSharp.Types;
@ -125,7 +126,7 @@ namespace CppSharp.Passes
if (param.Kind == ParameterKind.IndirectReturnType) if (param.Kind == ParameterKind.IndirectReturnType)
{ {
Class retClass; Class retClass;
param.Type.Desugar().IsTagDecl(out retClass); param.Type.Desugar().TryGetClass(out retClass);
if (retClass == null) if (retClass == null)
{ {
function.ExplicitlyIgnore(); function.ExplicitlyIgnore();

2
src/Generator/Passes/ConstructorToConversionOperatorPass.cs

@ -27,7 +27,7 @@ namespace CppSharp.Passes
return false; return false;
var qualifiedPointee = parameterType.QualifiedPointee; var qualifiedPointee = parameterType.QualifiedPointee;
Class castFromClass; Class castFromClass;
if (!qualifiedPointee.Type.IsTagDecl(out castFromClass)) if (!qualifiedPointee.Type.TryGetClass(out castFromClass))
return false; return false;
var castToClass = method.OriginalNamespace as Class; var castToClass = method.OriginalNamespace as Class;
if (castToClass == null) if (castToClass == null)

2
src/Generator/Passes/FunctionToInstanceMethodPass.cs

@ -79,7 +79,7 @@ namespace CppSharp.Passes
return true; return true;
} }
return classParam.Type.IsTagDecl(out @class); return classParam.Type.TryGetClass(out @class);
} }
} }
} }

Loading…
Cancel
Save