From fcb93169a202f59ad0289242e4a2bb4b765f0ea8 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 10:06:09 +0100 Subject: [PATCH 01/23] Added OriginalNamespace to Declaration and now QualifiedOriginalName uses it. --- src/AST/Declaration.cs | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/AST/Declaration.cs b/src/AST/Declaration.cs index a9c9fa67..94f85ecc 100644 --- a/src/AST/Declaration.cs +++ b/src/AST/Declaration.cs @@ -38,10 +38,24 @@ namespace CppSharp.AST /// public abstract class Declaration : INamedDecl { + + private DeclarationContext @namespace; + public DeclarationContext OriginalNamespace; + // Namespace the declaration is contained in. - public DeclarationContext Namespace; + public DeclarationContext Namespace + { + get { return @namespace; } + set + { + @namespace = value; + if (OriginalNamespace == null) + OriginalNamespace = @namespace; + } + } private string name; + public virtual string OriginalName { get; set;} // Name of the declaration. public virtual string Name @@ -66,17 +80,14 @@ namespace CppSharp.AST } } - // Name of the declaration. - public virtual string OriginalName { get; set;} - public string QualifiedOriginalName { get { - if (Namespace == null) + if (OriginalNamespace == null) return OriginalName; - return Namespace.IsRoot ? OriginalName - : string.Format("{0}::{1}", Namespace.QualifiedOriginalName, OriginalName); + return OriginalNamespace.IsRoot ? OriginalName + : string.Format("{0}::{1}", OriginalNamespace.QualifiedOriginalName, OriginalName); } } From c02b7bf3a856877907218fa6b893d8a9a397a703 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 10:09:17 +0100 Subject: [PATCH 02/23] Added Field to Property Declaration so now we can generate the property from a field instead of get or set methods. --- src/AST/Property.cs | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/AST/Property.cs b/src/AST/Property.cs index 8367cc07..1b8b93a2 100644 --- a/src/AST/Property.cs +++ b/src/AST/Property.cs @@ -5,11 +5,6 @@ namespace CppSharp.AST /// public class Property : Declaration, ITypedDecl { - public Property() - { - - } - public Type Type { get { return QualifiedType.Type; } @@ -17,17 +12,12 @@ namespace CppSharp.AST public QualifiedType QualifiedType { get; set; } - public Method GetMethod - { - get; - set; - } + public Method GetMethod { get; set; } - public Method SetMethod - { - get; - set; - } + public Method SetMethod { get; set; } + + // The field that should be get and set by this property + public Field Field { get; set; } public override T Visit(IDeclVisitor visitor) { From 379cf32f1de8a8b9ea698e0c8a8cdae6ebc0bb75 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 10:12:19 +0100 Subject: [PATCH 03/23] Added FieldToPropertyPass, all non ignored fields can now be transformed into properties before generation. --- src/Generator/Passes/FieldToPropertyPass.cs | 33 +++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/Generator/Passes/FieldToPropertyPass.cs diff --git a/src/Generator/Passes/FieldToPropertyPass.cs b/src/Generator/Passes/FieldToPropertyPass.cs new file mode 100644 index 00000000..f2151256 --- /dev/null +++ b/src/Generator/Passes/FieldToPropertyPass.cs @@ -0,0 +1,33 @@ +using CppSharp.AST; + +namespace CppSharp.Passes +{ + public class FieldToPropertyPass : TranslationUnitPass + { + public override bool VisitFieldDecl(Field field) + { + var @class = field.Namespace as Class; + if (@class == null) + return false; + + if (@class.IsValueType) + return false; + + if (ASTUtils.CheckIgnoreField(@class,field)) + return false; + + var prop = new Property() + { + Name = field.Name, + Namespace = field.Namespace, + QualifiedType = field.QualifiedType, + Field = field + }; + @class.Properties.Add(prop); + + field.ExplicityIgnored = true; + + return false; + } + } +} From 78ab63086acd4b6eb792c101b467788c77688ad6 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 10:17:07 +0100 Subject: [PATCH 04/23] CLIHeadersTemplate.cs now always tries to generate properties even when it is a value class. This is done because now fields should be converted to properties with FieldToPropertyPass. --- src/Generator/Generators/CLI/CLIHeadersTemplate.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs index 49bf6f25..1c0c8fbf 100644 --- a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs +++ b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs @@ -213,9 +213,7 @@ namespace CppSharp.Generators.CLI GenerateClassFields(@class); - // Generate a property for each field if class is not value type - if (@class.IsRefType) - GenerateClassProperties(@class); + GenerateClassProperties(@class); GenerateClassEvents(@class); GenerateClassMethods(@class); From 06aba88fbbe7b2a891e6bf58f9d8e3e2bcd5b8a6 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 10:22:04 +0100 Subject: [PATCH 05/23] Modified GetterSetterToPropertyPass more complex properties are supported. Now even if we only have a getter or a setter a property is created. Trying to convert multiple setter with same name and different types is an issue, so we check before creating a setter for a matching getter or the non existence of more setters. --- .../Passes/GetterSetterToPropertyPass.cs | 102 +++++++++++++----- 1 file changed, 75 insertions(+), 27 deletions(-) diff --git a/src/Generator/Passes/GetterSetterToPropertyPass.cs b/src/Generator/Passes/GetterSetterToPropertyPass.cs index 6fa6e2a3..a3c26349 100644 --- a/src/Generator/Passes/GetterSetterToPropertyPass.cs +++ b/src/Generator/Passes/GetterSetterToPropertyPass.cs @@ -1,4 +1,6 @@ using System; +using System.Diagnostics; +using System.Linq; using CppSharp.AST; namespace CppSharp.Passes @@ -44,51 +46,97 @@ namespace CppSharp.Passes return !isRetVoid && isGetter && method.Parameters.Count == 0; } + Property GetOrCreateProperty(Class @class, string name, QualifiedType type) + { + var prop = @class.Properties.FirstOrDefault(property => property.Name == name + && property.QualifiedType.Equals(type)); + + var prop2 = @class.Properties.FirstOrDefault(property => property.Name == name); + + if (prop == null && prop2 != null) + Driver.Diagnostics.EmitWarning(DiagnosticId.PropertySynthetized, + "Property {0}::{1} already exist with type {2}", @class.Name, name, type.Type.ToString()); + + if (prop != null) + return prop; + + prop = new Property + { + Name = name, + Namespace = @class, + QualifiedType = type + }; + + @class.Properties.Add(prop); + return prop; + } + public override bool VisitMethodDecl(Method method) { - //var expansions = method.PreprocessedEntities.OfType(); - //if (expansions.Any(e => e.Text.Contains("ACCESSOR"))) - // System.Diagnostics.Debugger.Break(); + if (AlreadyVisited(method)) + return false; - if (!IsGetter(method)) + if (ASTUtils.CheckIgnoreMethod(null, method)) return false; var @class = method.Namespace as Class; - foreach (var classMethod in @class.Methods) + + if (@class == null || @class.IsIncomplete) + return false; + + if (IsGetter(method)) { - if (!IsSetter(classMethod)) - continue; + var name = method.Name.Substring("get".Length); + var prop = GetOrCreateProperty(@class, name, method.ReturnType); + prop.GetMethod = method; - if (classMethod.Parameters[0].Type.Equals(method.ReturnType.Type)) - continue; + // Do not generate the original method now that we know it is a getter. + method.IsGenerated = false; - var getName = method.Name.Substring("get".Length); - var setName = classMethod.Name.Substring("set".Length); + Driver.Diagnostics.EmitMessage(DiagnosticId.PropertySynthetized, + "Getter created: {0}::{1}", @class.Name, name); - if (getName != setName) - continue; + return false; + } - // We found a compatible pair of methods, create a property. - var prop = new Property - { - Name = getName, - Namespace = @class, - QualifiedType = method.ReturnType - }; + if (IsSetter(method) && IsValidSetter(method)) + { + var name = method.Name.Substring("set".Length); - // Ignore the original methods now that we have a property. - method.ExplicityIgnored = true; - classMethod.ExplicityIgnored = true; + var type = method.Parameters[0].QualifiedType; + var prop = GetOrCreateProperty(@class, name, type); + prop.SetMethod = method; - @class.Properties.Add(prop); + // Ignore the original method now that we know it is a setter. + method.IsGenerated = false; Driver.Diagnostics.EmitMessage(DiagnosticId.PropertySynthetized, - "Getter/setter property created: {0}::{1}", @class.Name, - getName); - return true; + "Setter created: {0}::{1}", @class.Name, name); + + return false; } return false; } + + // Check if a matching getter exist or no other setter exists. + private bool IsValidSetter(Method method) + { + var @class = method.Namespace as Class; + var name = method.Name.Substring("set".Length); + + if (method.Parameters.Count == 0) + return false; + + var type = method.Parameters[0].Type; + + var getter = @class.Methods.FirstOrDefault(m => m.Name == "Get" + name && m.Type.Equals(type)); + + var otherSetter = @class.Methods.FirstOrDefault(m => m.Name == method.Name + && m.Parameters.Count == 1 + && !m.Parameters[0].Type.Equals(type)); + + return getter != null || otherSetter == null; + } } } From 61986172e76ae48654f88945dafe56766dab938f Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 10:28:03 +0100 Subject: [PATCH 06/23] CLIHeaderTemplate an CLISourcesTemplate now take care of properties with only a getter or s setter, and properties using fields that for now always have a getter and a setter. --- .../Generators/CLI/CLIHeadersTemplate.cs | 26 ++-- .../Generators/CLI/CLISourcesTemplate.cs | 146 +++++++++++------- 2 files changed, 98 insertions(+), 74 deletions(-) diff --git a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs index 1c0c8fbf..0d35e9b6 100644 --- a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs +++ b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs @@ -475,39 +475,33 @@ namespace CppSharp.Generators.CLI public void GenerateClassProperties(Class @class) { - PushIndent(); - foreach (var field in @class.Fields) - { - if (ASTUtils.CheckIgnoreField(@class, field)) - continue; - - GenerateDeclarationCommon(field); - GenerateProperty(field); - } - PopIndent(); - PushIndent(); foreach (var prop in @class.Properties) { if (prop.Ignore) continue; GenerateDeclarationCommon(prop); - GenerateProperty(prop); + var isGetter = prop.GetMethod != null || prop.Field != null; + var isSetter = prop.SetMethod != null || prop.Field != null; + GenerateProperty(prop, isGetter, isSetter); } PopIndent(); } - public void GenerateProperty(T decl) + public void GenerateProperty(T decl, bool isGetter = true, bool isSetter = true) where T : Declaration, ITypedDecl { + if (!(isGetter || isSetter)) + return; + PushBlock(CLIBlockKind.Property, decl); var type = decl.Type.Visit(TypePrinter, decl.QualifiedType.Qualifiers); WriteLine("property {0} {1}", type, decl.Name); WriteStartBraceIndent(); - WriteLine("{0} get();", type); - WriteLine("void set({0});", type); + if(isGetter) WriteLine("{0} get();", type); + if(isSetter) WriteLine("void set({0});", type); WriteCloseBraceIndent(); PopBlock(); @@ -518,8 +512,6 @@ namespace CppSharp.Generators.CLI if (method.Ignore) return; if (method.Access != AccessSpecifier.Public) - return; - PushBlock(CLIBlockKind.Method, method); GenerateDeclarationCommon(method); diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index 944c03a6..2a5bf296 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -154,16 +154,11 @@ namespace CppSharp.Generators.CLI WriteCloseBraceIndent(); PopBlock(NewLineKind.BeforeNextBlock); } - - foreach (var field in @class.Fields) - { - if (ASTUtils.CheckIgnoreField(@class, field)) - continue; - - GenerateFieldProperty(field); - } } + foreach (var property in @class.Properties) + GenerateProperty(property); + foreach (var @event in @class.Events) { if (@event.Ignore) @@ -239,82 +234,119 @@ namespace CppSharp.Generators.CLI printer.Context = oldCtx; } - private void GenerateFieldProperty(Field field) + private void GenerateProperty(Property property) { - var @class = field.Class; + if (property.Ignore) return; + + PushBlock(CLIBlockKind.Property); + var @class = property.Namespace as Class; - GeneratePropertyGetter(field, @class); - GeneratePropertySetter(field, @class); + if (property.Field != null) + { + GeneratePropertyGetter(property.Field, @class, property.Name, property.Type); + GeneratePropertySetter(property.Field, @class, property.Name, property.Type); + } + else + { + GeneratePropertyGetter(property.GetMethod, @class, property.Name, property.Type); + GeneratePropertySetter(property.SetMethod, @class, property.Name, property.Type); + } + PopBlock(); } - private void GeneratePropertySetter(T decl, Class @class) + private void GeneratePropertySetter(T decl, Class @class, string name, Type type) where T : Declaration, ITypedDecl { + if (decl == null) + return; + WriteLine("void {0}::{1}::set({2} value)", QualifiedIdentifier(@class), - decl.Name, decl.Type); + name, type); WriteStartBraceIndent(); - var param = new Parameter - { - Name = "value", - QualifiedType = decl.QualifiedType - }; + if (decl is Function) + { + var func = decl as Function; + if(func.Parameters[0].Name != "value") + WriteLine("auto {0} = value;", func.Parameters[0].Name); + GenerateFunctionCall(func, @class); + } + else + { + var param = new Parameter + { + Name = "value", + QualifiedType = decl.QualifiedType + }; - var ctx = new MarshalContext(Driver) - { - Parameter = param, - ArgName = param.Name, - }; + var ctx = new MarshalContext(Driver) + { + Parameter = param, + ArgName = param.Name, + }; - var marshal = new CLIMarshalManagedToNativePrinter(ctx); - param.Visit(marshal); + var marshal = new CLIMarshalManagedToNativePrinter(ctx); + param.Visit(marshal); - string variable; - if (decl is Variable) - variable = string.Format("::{0}::{1}", - @class.QualifiedOriginalName, decl.OriginalName); - else - variable = string.Format("((::{0}*)NativePtr)->{1}", - @class.QualifiedOriginalName, decl.OriginalName); + string variable; + if (decl is Variable) + variable = string.Format("::{0}::{1}", + @class.QualifiedOriginalName, decl.OriginalName); + else + variable = string.Format("((::{0}*)NativePtr)->{1}", + @class.QualifiedOriginalName, decl.OriginalName); - if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) - Write(marshal.Context.SupportBefore); + if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) + Write(marshal.Context.SupportBefore); - WriteLine("{0} = {1};", variable, marshal.Context.Return); + WriteLine("{0} = {1};", variable, marshal.Context.Return); + } WriteCloseBraceIndent(); NewLine(); } - private void GeneratePropertyGetter(T decl, Class @class) + private void GeneratePropertyGetter(T decl, Class @class, string name, Type type) where T : Declaration, ITypedDecl { - WriteLine("{0} {1}::{2}::get()", decl.Type, QualifiedIdentifier(@class), - decl.Name); + if (decl == null) + return; + + WriteLine("{0} {1}::{2}::get()", type, QualifiedIdentifier(@class), + name); WriteStartBraceIndent(); - string variable; - if (decl is Variable) - variable = string.Format("::{0}::{1}", - @class.QualifiedOriginalName, decl.OriginalName); + if (decl is Function) + { + var func = decl as Function; + GenerateFunctionCall(func, @class); + } else - variable = string.Format("((::{0}*)NativePtr)->{1}", + { + string variable; + if (decl is Variable) + variable = string.Format("::{0}::{1}", @class.QualifiedOriginalName, decl.OriginalName); + else + variable = string.Format("((::{0}*)NativePtr)->{1}", + @class.QualifiedOriginalName, decl.OriginalName); - var ctx = new MarshalContext(Driver) - { - ArgName = decl.Name, - ReturnVarName = variable, - ReturnType = decl.QualifiedType - }; + var ctx = new MarshalContext(Driver) + { + ArgName = decl.Name, + ReturnVarName = variable, + ReturnType = decl.QualifiedType + }; - var marshal = new CLIMarshalNativeToManagedPrinter(ctx); - decl.Visit(marshal); + var marshal = new CLIMarshalNativeToManagedPrinter(ctx); + decl.Visit(marshal); - if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) - Write(marshal.Context.SupportBefore); + if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) + Write(marshal.Context.SupportBefore); - WriteLine("return {0};", marshal.Context.Return); + WriteLine("return {0};", marshal.Context.Return); + } + WriteCloseBraceIndent(); NewLine(); @@ -428,10 +460,10 @@ namespace CppSharp.Generators.CLI private void GenerateVariable(Variable variable, Class @class) { - GeneratePropertyGetter(variable, @class); + GeneratePropertyGetter(variable, @class, variable.Name, variable.Type); if (!variable.QualifiedType.Qualifiers.IsConst) - GeneratePropertySetter(variable, @class); + GeneratePropertySetter(variable, @class, variable.Name, variable.Type); } private void GenerateClassConstructor(Class @class, bool isIntPtr) From c28723c0b6dddbfed53e08cab14b7c67c451c979 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 10:36:27 +0100 Subject: [PATCH 07/23] Added support to emit messages without DiagnosticId. --- src/Generator/Diagnostics.cs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/Generator/Diagnostics.cs b/src/Generator/Diagnostics.cs index b3719440..84452491 100644 --- a/src/Generator/Diagnostics.cs +++ b/src/Generator/Diagnostics.cs @@ -72,6 +72,42 @@ namespace CppSharp consumer.Emit(diagInfo); } + + public static void EmitMessage(this IDiagnosticConsumer consumer, + string msg, params object[] args) + { + var diagInfo = new DiagnosticInfo + { + Kind = DiagnosticKind.Message, + Message = string.Format(msg, args) + }; + + consumer.Emit(diagInfo); + } + + public static void EmitWarning(this IDiagnosticConsumer consumer, + string msg, params object[] args) + { + var diagInfo = new DiagnosticInfo + { + Kind = DiagnosticKind.Warning, + Message = string.Format(msg, args) + }; + + consumer.Emit(diagInfo); + } + + public static void EmitError(this IDiagnosticConsumer consumer, + string msg, params object[] args) + { + var diagInfo = new DiagnosticInfo + { + Kind = DiagnosticKind.Error, + Message = string.Format(msg, args) + }; + + consumer.Emit(diagInfo); + } } public class TextDiagnosticPrinter : IDiagnosticConsumer From 9ba1707616e5476dbfe5995b3573c381b8ac4e30 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 10:43:53 +0100 Subject: [PATCH 08/23] Added Equality operator to AST Types. This was needed because GetterSetterToPropertyPass has to match a getter return type with a setter parameter type. --- src/AST/Type.cs | 163 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 143 insertions(+), 20 deletions(-) diff --git a/src/AST/Type.cs b/src/AST/Type.cs index 18b5b2f9..bcf2b258 100644 --- a/src/AST/Type.cs +++ b/src/AST/Type.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; namespace CppSharp.AST { @@ -162,6 +163,14 @@ namespace CppSharp.AST { return Type.ToString(); } + + public override bool Equals(object obj) + { + if (!(obj is QualifiedType)) return false; + + var type = (QualifiedType) obj; + return Type.Equals(type.Type) && Qualifiers.Equals(type.Qualifiers); + } } /// @@ -184,6 +193,14 @@ namespace CppSharp.AST { return visitor.VisitTagType(this, quals); } + + public override bool Equals(object obj) + { + var type = obj as TagType; + if (type == null) return false; + + return Declaration.Equals(type.Declaration); + } } /// @@ -216,6 +233,18 @@ namespace CppSharp.AST { return visitor.VisitArrayType(this, quals); } + + public override bool Equals(object obj) + { + var type = obj as ArrayType; + if (type == null) return false; + var equals = Type.Equals(type.Type) && SizeType.Equals(type.SizeType); + + if (SizeType == ArraySize.Constant) + equals &= Size.Equals(type.Size); + + return equals; + } } /// @@ -238,6 +267,14 @@ namespace CppSharp.AST { return visitor.VisitFunctionType(this, quals); } + + public override bool Equals(object obj) + { + var type = obj as FunctionType; + if (type == null) return false; + + return ReturnType.Equals(type.ReturnType) && Parameters.SequenceEqual(type.Parameters); + } } /// @@ -281,6 +318,15 @@ namespace CppSharp.AST { return visitor.VisitPointerType(this, QualifiedPointee.Qualifiers); } + + public override bool Equals(object obj) + { + var type = obj as PointerType; + if (type == null) return false; + + return QualifiedPointee.Equals(type.QualifiedPointee) + && Modifier == type.Modifier; + } } /// @@ -299,6 +345,14 @@ namespace CppSharp.AST { return visitor.VisitMemberPointerType(this, quals); } + + public override bool Equals(object obj) + { + var pointer = obj as MemberPointerType; + if (pointer == null) return false; + + return Pointee.Equals(pointer.Pointee); + } } /// @@ -317,6 +371,15 @@ namespace CppSharp.AST { return visitor.VisitTypedefType(this, quals); } + + public override bool Equals(object obj) + { + var typedef = obj as TypedefType; + if (typedef == null) return false; + + var t = Declaration.Equals(typedef.Declaration); + return t; + } } /// @@ -337,6 +400,14 @@ namespace CppSharp.AST { return visitor.VisitDecayedType(this, quals); } + + public override bool Equals(object obj) + { + var decay = obj as DecayedType; + if (decay == null) return false; + + return Original.Equals(decay.Original); + } } /// @@ -382,6 +453,28 @@ namespace CppSharp.AST public QualifiedType Type; public Declaration Declaration; public long Integral; + + public override bool Equals(object obj) + { + if (!(obj is TemplateArgument)) return false; + var arg = (TemplateArgument) obj; + + if (Kind != arg.Kind) return false; + + switch (Kind) + { + case ArgumentKind.Type: + return Type.Equals(arg.Type); + case ArgumentKind.Declaration: + return Declaration.Equals(arg.Declaration); + case ArgumentKind.Integral: + return Integral.Equals(arg.Integral); + case ArgumentKind.Expression: + return true; + default: + throw new Exception("Unknowed TemplateArgument Kind"); + } + } } /// @@ -405,6 +498,15 @@ namespace CppSharp.AST { return visitor.VisitTemplateSpecializationType(this, quals); } + + public override bool Equals(object obj) + { + var type = obj as TemplateSpecializationType; + if (type == null) return false; + + return Arguments.SequenceEqual(type.Arguments) + && Template.Equals(type.Template); + } } /// @@ -412,18 +514,21 @@ namespace CppSharp.AST /// public class TemplateParameterType : Type { - public TemplateParameterType() - { - } - public TemplateParameter Parameter; - public Template Template; public override T Visit(ITypeVisitor visitor, TypeQualifiers quals = new TypeQualifiers()) { return visitor.VisitTemplateParameterType(this, quals); } + + public override bool Equals(object obj) + { + var type = obj as TemplateParameterType; + if (type == null) return false; + + return Parameter.Equals(type.Parameter); + } } /// @@ -431,11 +536,6 @@ namespace CppSharp.AST /// public class TemplateParameterSubstitutionType : Type { - public TemplateParameterSubstitutionType() - { - - } - public QualifiedType Replacement; public override T Visit(ITypeVisitor visitor, @@ -443,6 +543,14 @@ namespace CppSharp.AST { return visitor.VisitTemplateParameterSubstitutionType(this, quals); } + + public override bool Equals(object obj) + { + var type = obj as TemplateParameterSubstitutionType; + if (type == null) return false; + + return Replacement.Equals(type.Replacement); + } } /// @@ -451,11 +559,6 @@ namespace CppSharp.AST /// public class InjectedClassNameType : Type { - public InjectedClassNameType() - { - - } - public TemplateSpecializationType TemplateSpecialization; public Class Class; @@ -464,6 +567,15 @@ namespace CppSharp.AST { return visitor.VisitInjectedClassNameType(this, quals); } + + public override bool Equals(object obj) + { + var type = obj as InjectedClassNameType; + if (type == null) return false; + + return TemplateSpecialization.Equals(type.TemplateSpecialization) + && Class.Equals(type.Class); + } } /// @@ -471,11 +583,6 @@ namespace CppSharp.AST /// public class DependentNameType : Type { - public DependentNameType() - { - - } - public override T Visit(ITypeVisitor visitor, TypeQualifiers quals = new TypeQualifiers()) { @@ -500,6 +607,14 @@ namespace CppSharp.AST { return visitor.VisitCILType(this, quals); } + + public override bool Equals(object obj) + { + var type = obj as CILType; + if (type == null) return false; + + return Type == type.Type; + } } #region Primitives @@ -567,6 +682,14 @@ namespace CppSharp.AST { return visitor.VisitBuiltinType(this, quals); } + + public override bool Equals(object obj) + { + var type = obj as BuiltinType; + if (type == null) return false; + + return Type == type.Type; + } } #endregion From dc8ecc9d2e49459b0e4a56c91a68f83ae8fbb660 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 10:52:12 +0100 Subject: [PATCH 09/23] Removed unnecessary override keyword from interface method implementations. --- src/Generator/Generators/CLI/CLIHeadersTemplate.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs index 0d35e9b6..dc3274c3 100644 --- a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs +++ b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs @@ -248,8 +248,8 @@ namespace CppSharp.Generators.CLI PushIndent(); WriteLine("property System::IntPtr Instance"); WriteStartBraceIndent(); - WriteLine("virtual System::IntPtr get() override;"); - WriteLine("virtual void set(System::IntPtr instance) override;"); + WriteLine("virtual System::IntPtr get();"); + WriteLine("virtual void set(System::IntPtr instance);"); WriteCloseBraceIndent(); NewLine(); From 3bd0086ac69906aeafc44fb29d9ae7849204f25d Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 10:58:29 +0100 Subject: [PATCH 10/23] Fixed methods generated by FunctionToInstanceMethodPass and FunctionToStaticMethodPass, to use parent class Namespace and keep function Namespace as OriginalNamespace. --- src/Generator/Passes/FunctionToInstanceMethodPass.cs | 1 + src/Generator/Passes/FunctionToStaticMethodPass.cs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Generator/Passes/FunctionToInstanceMethodPass.cs b/src/Generator/Passes/FunctionToInstanceMethodPass.cs index 3b48a1e2..4810d217 100644 --- a/src/Generator/Passes/FunctionToInstanceMethodPass.cs +++ b/src/Generator/Passes/FunctionToInstanceMethodPass.cs @@ -44,6 +44,7 @@ namespace CppSharp.Passes var method = new Method() { Namespace = @class, + OriginalNamespace = function.Namespace, Name = function.Name, OriginalName = function.OriginalName, Mangled = function.Mangled, diff --git a/src/Generator/Passes/FunctionToStaticMethodPass.cs b/src/Generator/Passes/FunctionToStaticMethodPass.cs index cdc02baf..f7bc833b 100644 --- a/src/Generator/Passes/FunctionToStaticMethodPass.cs +++ b/src/Generator/Passes/FunctionToStaticMethodPass.cs @@ -33,7 +33,8 @@ namespace CppSharp.Passes // Create a new fake method so it acts as a static method. var method = new Method() { - Namespace = @class.Namespace, + Namespace = @class, + OriginalNamespace = function.Namespace, Name = name, OriginalName = function.OriginalName, Mangled = function.Mangled, From 12daa4980ce0575c7f7d794c21a7070a9a67a75f Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 11:13:36 +0100 Subject: [PATCH 11/23] Added CheckDuplicatedNamesPass that check all class members names for duplicated names. When a non function member has an already used name a number is append to its name. When a method is found with a know signature a number is append to its name. The appended number for each method overload is independently incremented, others members appended number start at the most overloaded method count which is then incremented with each non function member sharing the same name. --- src/Generator/Driver.cs | 2 +- .../Passes/CheckAmbiguousOverloads.cs | 146 ------------------ .../Passes/CheckDuplicatedNamesPass.cs | 145 +++++++++++++++++ .../Passes/DuplicatedNamesCheckerPass.cs | 68 -------- 4 files changed, 146 insertions(+), 215 deletions(-) delete mode 100644 src/Generator/Passes/CheckAmbiguousOverloads.cs create mode 100644 src/Generator/Passes/CheckDuplicatedNamesPass.cs delete mode 100644 src/Generator/Passes/DuplicatedNamesCheckerPass.cs diff --git a/src/Generator/Driver.cs b/src/Generator/Driver.cs index c0cf56b3..809dc833 100644 --- a/src/Generator/Driver.cs +++ b/src/Generator/Driver.cs @@ -132,7 +132,7 @@ namespace CppSharp Passes.CleanInvalidDeclNames(); Passes.CheckIgnoredDecls(); Passes.CheckFlagEnums(); - Passes.CheckAmbiguousOverloads(); + Passes.CheckDuplicateNames(); Generator.SetupPasses(Passes); } diff --git a/src/Generator/Passes/CheckAmbiguousOverloads.cs b/src/Generator/Passes/CheckAmbiguousOverloads.cs deleted file mode 100644 index ae6922d5..00000000 --- a/src/Generator/Passes/CheckAmbiguousOverloads.cs +++ /dev/null @@ -1,146 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using CppSharp.AST; -using CppSharp.Generators; - -namespace CppSharp.Passes -{ - struct OverloadSignature - { - public string Return; - public List Parameters; - public Function Function; - - public OverloadSignature(Function function) - { - Function = function; - - Return = function.ReturnType.ToString(); - Parameters = new List(); - - foreach (var param in function.Parameters) - { - var paramType = param.Type.ToString(); - Parameters.Add(paramType); - } - } - - public static bool IsAmbiguous(OverloadSignature overload1, - OverloadSignature overload2, Class @class) - { - if (overload1.Function == overload2.Function) - return false; - - if (ASTUtils.CheckIgnoreFunction(@class, overload1.Function)) - return false; - - if (ASTUtils.CheckIgnoreFunction(@class, overload2.Function)) - return false; - - // TODO: Default parameters? - if (overload1.Parameters.Count != overload2.Parameters.Count) - return false; - - if (overload1.Parameters.Count == 0) - return true; - - for (var i = 0; i < overload1.Parameters.Count; i++) - { - if (overload1.Parameters[i] != overload2.Parameters[i]) - return false; - } - - return true; - } - }; - - public class CheckAmbiguousOverloads : TranslationUnitPass - { - private readonly ISet visited; - - public CheckAmbiguousOverloads() - { - visited = new HashSet(); - Options.VisitNamespaceEnums = false; - Options.VisitNamespaceTemplates = false; - Options.VisitNamespaceTypedefs = false; - Options.VisitNamespaceEvents = false; - Options.VisitNamespaceVariables = false; - - Options.VisitClassBases = false; - Options.VisitClassFields = false; - Options.VisitClassProperties = false; - } - - public override bool VisitClassDecl(Class @class) - { - visited.Clear(); - return base.VisitClassDecl(@class); - } - - public override bool VisitMethodDecl(Method method) - { - CheckOverloads(method); - return false; - } - - public override bool VisitFunctionDecl(Function function) - { - CheckOverloads(function); - return false; - } - - private bool CheckOverloads(Function function) - { - if (visited.Contains(function)) - return false; - - if (function.Ignore) - return false; - - var overloads = function.Namespace.GetFunctionOverloads(function); - var signatures = overloads.Select(fn => new OverloadSignature(fn)).ToList(); - - foreach (var sig1 in signatures) - { - visited.Add(sig1.Function); - - if (sig1.Function.Ignore) - continue; - - foreach (var sig2 in signatures) - { - if (sig2.Function.Ignore) - continue; - - var @class = function.Namespace as Class; - if (!OverloadSignature.IsAmbiguous(sig1, sig2, @class)) - continue; - - Driver.Diagnostics.EmitWarning(DiagnosticId.AmbiguousOverload, - "Overload {0} is ambiguous, renaming automatically", - sig1.Function.QualifiedOriginalName); - - RenameOverload(sig1.Function); - return false; - } - } - - return true; - } - - public void RenameOverload(Function function) - { - function.Name = function.Name + "0"; - } - } - - public static class CheckAmbiguousOverloadsExtensions - { - public static void CheckAmbiguousOverloads(this PassBuilder builder) - { - var pass = new CheckAmbiguousOverloads(); - builder.AddPass(pass); - } - } -} diff --git a/src/Generator/Passes/CheckDuplicatedNamesPass.cs b/src/Generator/Passes/CheckDuplicatedNamesPass.cs new file mode 100644 index 00000000..6453ec67 --- /dev/null +++ b/src/Generator/Passes/CheckDuplicatedNamesPass.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using CppSharp.AST; + +namespace CppSharp.Passes +{ + class DeclarationName + { + private readonly string Name; + private readonly Dictionary methodSignatures; + private int Count; + + public DeclarationName(string name) + { + Name = name; + methodSignatures = new Dictionary(); + } + + public bool UpdateName(Declaration decl) + { + if (decl.Name != Name) + throw new Exception("Invalid name"); + + var method = decl as Method; + if (method != null) + { + return UpdateName(method); + } + + var count = Count++; + if (count == 0) + return false; + + decl.Name += count.ToString(CultureInfo.InvariantCulture); + return true; + } + + private bool UpdateName(Method method) + { + var @params = method.Parameters.Select(p => p.QualifiedType.ToString()); + var signature = string.Format("{0}({1})", Name,string.Join( ", ", @params)); + + if (Count == 0) + Count++; + + if (!methodSignatures.ContainsKey(signature)) + { + methodSignatures.Add(signature, 0); + return false; + } + + var methodCount = ++methodSignatures[signature]; + + if (Count < methodCount+1) + Count = methodCount+1; + + method.Name += methodCount.ToString(CultureInfo.InvariantCulture); + return true; + } + } + + public class CheckDuplicatedNamesPass : TranslationUnitPass + { + private readonly IDictionary names; + + public CheckDuplicatedNamesPass() + { + names = new Dictionary(); + } + + public override bool VisitFieldDecl(Field decl) + { + if (ASTUtils.CheckIgnoreField(null, decl)) + return false; + + if(!AlreadyVisited(decl)) + CheckDuplicate(decl); + return false; + } + + public override bool VisitProperty(Property decl) + { + if(!AlreadyVisited(decl)) + CheckDuplicate(decl); + return false; + } + + public override bool VisitMethodDecl(Method decl) + { + if (ASTUtils.CheckIgnoreMethod(null, decl)) + return false; + + if(!AlreadyVisited(decl)) + CheckDuplicate(decl); + return false; + } + + public override bool VisitClassDecl(Class @class) + { + if (AlreadyVisited(@class) || @class.IsIncomplete) + return false; + + // In order to DeclarationName works, we visit methods first. + foreach (var method in @class.Methods) + VisitMethodDecl(method); + + foreach (var field in @class.Fields) + VisitFieldDecl(field); + + foreach (var property in @class.Properties) + VisitProperty(property); + + return false; + } + + void CheckDuplicate(Declaration decl) + { + if (decl.IsDependent || decl.Ignore) + return; + + if (string.IsNullOrWhiteSpace(decl.Name)) + return; + + var fullName = decl.QualifiedName; + + // If the name is not yet on the map, then add it. + if (!names.ContainsKey(fullName)) + names.Add(fullName, new DeclarationName(decl.Name)); + + if (names[fullName].UpdateName(decl)) + Driver.Diagnostics.EmitWarning("Duplicate name {0}, renamed to {1}", fullName, decl.Name); + } + } + + public static class CheckDuplicateNamesExtensions + { + public static void CheckDuplicateNames(this PassBuilder builder) + { + var pass = new CheckDuplicatedNamesPass(); + builder.AddPass(pass); + } + } +} diff --git a/src/Generator/Passes/DuplicatedNamesCheckerPass.cs b/src/Generator/Passes/DuplicatedNamesCheckerPass.cs deleted file mode 100644 index 3424cad2..00000000 --- a/src/Generator/Passes/DuplicatedNamesCheckerPass.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections.Generic; -using CppSharp.AST; - -namespace CppSharp.Passes -{ - public class DuplicatedNamesCheckerPass : TranslationUnitPass - { - private readonly IDictionary names; - - public DuplicatedNamesCheckerPass() - { - names = new Dictionary(); - } - - public override bool VisitClassDecl(Class @class) - { - if (@class.Ignore) return false; - - names.Clear(); - return base.VisitClassDecl(@class); - } - - public override bool VisitDeclaration(Declaration decl) - { - if (AlreadyVisited(decl)) - return true; - - Visited.Add(decl); - - CheckDuplicate(decl); - return base.VisitDeclaration(decl); - } - - public override bool VisitParameterDecl(Parameter parameter) - { - return true; - } - - void CheckDuplicate(Declaration decl) - { - if (string.IsNullOrWhiteSpace(decl.Name)) - return; - - Declaration duplicate; - - // If the name is not yet on the map, then add it. - if (!names.TryGetValue(decl.Name, out duplicate)) - { - names[decl.Name] = decl; - return; - } - - // Else we found a duplicate name and need to change it. - Console.WriteLine("Found a duplicate named declaration: {0}", - decl.Name); - } - } - - public static class CheckDuplicateNamesExtensions - { - public static void CheckDuplicateNames(this PassBuilder builder) - { - var pass = new DuplicatedNamesCheckerPass(); - builder.AddPass(pass); - } - } -} From 5c7bbe1bc0171b396ae6692e5d1e54b6175e2e95 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 11:19:35 +0100 Subject: [PATCH 12/23] Added CheckIgnoreDecls to the to pre passes, so user added passes already have some declarations ignored. --- src/Generator/Driver.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Generator/Driver.cs b/src/Generator/Driver.cs index 809dc833..b1bcbe84 100644 --- a/src/Generator/Driver.cs +++ b/src/Generator/Driver.cs @@ -125,6 +125,7 @@ namespace CppSharp Passes.CleanUnit(Options); Passes.SortDeclarations(); Passes.ResolveIncompleteDecls(); + Passes.CheckIgnoredDecls(); } public void AddPostPasses() From ca569eb334ecc93e9dfa7c3f8d3cc73304cae965 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 11:25:20 +0100 Subject: [PATCH 13/23] Better template function generation, less manual fixes are needed after generation. --- .../Generators/CLI/CLIHeadersTemplate.cs | 18 ++++++++++----- .../Generators/CLI/CLISourcesTemplate.cs | 22 ++++++++++++------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs index dc3274c3..0bafd45d 100644 --- a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs +++ b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs @@ -271,9 +271,6 @@ namespace CppSharp.Generators.CLI var function = functionTemplate.TemplatedFunction; - var typeNames = template.Parameters.Select( - param => "typename " + param.Name).ToList(); - var typeCtx = new CLITypePrinterContext() { Kind = TypePrinterContextKind.Template, @@ -284,10 +281,19 @@ namespace CppSharp.Generators.CLI var typePrinter = new CLITypePrinter(Driver, typeCtx); var retType = function.ReturnType.Type.Visit(typePrinter, - function.ReturnType.Qualifiers); + function.ReturnType.Qualifiers).Split('<')[0]; + + var typeNamesStr = ""; + var paramNamesStr = ""; + var paramNames = template.Parameters.Select(param => param.Name).ToList(); + if (paramNames.Any()) + { + typeNamesStr = "typename " + string.Join(", typename ", paramNames); + paramNamesStr = string.Join(", ", paramNames); + } - WriteLine("generic<{0}>", string.Join(", ", typeNames)); - WriteLine("{0} {1}({2});", retType, SafeIdentifier(function.Name), + WriteLine("generic<{0}>", typeNamesStr); + WriteLine("{0}<{1}> {2}({3});", retType, paramNamesStr, SafeIdentifier(function.Name), GenerateParametersList(function.Parameters)); } PopIndent(); diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index 2a5bf296..2e71244c 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -204,9 +204,6 @@ namespace CppSharp.Generators.CLI var function = template.TemplatedFunction; - var typeNames = template.Parameters.Select( - param => "typename " + param.Name).ToList(); - var typeCtx = new CLITypePrinterContext() { Kind = TypePrinterContextKind.Template, @@ -217,12 +214,21 @@ namespace CppSharp.Generators.CLI var typePrinter = new CLITypePrinter(Driver, typeCtx); var retType = function.ReturnType.Type.Visit(typePrinter, - function.ReturnType.Qualifiers); + function.ReturnType.Qualifiers).Split('<')[0]; + + var typeNamesStr = ""; + var paramNamesStr = ""; + var paramNames = template.Parameters.Select(param => param.Name).ToList(); + if (paramNames.Any()) + { + typeNamesStr = "typename " + string.Join(", typename ", paramNames); + paramNamesStr = string.Join(", ", paramNames); + } - WriteLine("generic<{0}>", string.Join(", ", typeNames)); - WriteLine("{0} {1}::{2}({3})", retType, QualifiedIdentifier(@class), - SafeIdentifier(function.Name), - GenerateParametersList(function.Parameters)); + WriteLine("generic<{0}>", typeNamesStr); + WriteLine("{0}<{1}> {2}::{3}({4});", retType, paramNamesStr, + QualifiedIdentifier(@class), SafeIdentifier(function.Name), + GenerateParametersList(function.Parameters)); WriteStartBraceIndent(); From 777de80c3bf151b4b9c4a5d5016f209b75ec53dd Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 11:26:42 +0100 Subject: [PATCH 14/23] Resolved ambiguous type Type. --- src/Generator/Generators/CLI/CLISourcesTemplate.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index 2e71244c..fd1eaae0 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using CppSharp.AST; using CppSharp.Types; +using Type = CppSharp.AST.Type; namespace CppSharp.Generators.CLI { From 57ce9d449daf28842141cce454dd1e21eb162665 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 11:29:19 +0100 Subject: [PATCH 15/23] Removed class parameter from CheckIgnoreFunction, CheckIgnoreMethod and CheckIgnoreField. --- src/Generator/AST/Utils.cs | 17 ++++++++--------- .../Generators/CLI/CLIHeadersTemplate.cs | 7 +++---- .../Generators/CSharp/CSharpTextTemplate.cs | 9 +++++---- .../Passes/CheckDuplicatedNamesPass.cs | 4 ++-- src/Generator/Passes/FieldToPropertyPass.cs | 2 +- .../Passes/GetterSetterToPropertyPass.cs | 2 +- 6 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/Generator/AST/Utils.cs b/src/Generator/AST/Utils.cs index 2f8c2b48..ed454281 100644 --- a/src/Generator/AST/Utils.cs +++ b/src/Generator/AST/Utils.cs @@ -3,23 +3,24 @@ namespace CppSharp.AST { public static class ASTUtils { - public static bool CheckIgnoreFunction(Class @class, Function function) + public static bool CheckIgnoreFunction(Function function) { if (function.Ignore) return true; if (function is Method) - return CheckIgnoreMethod(@class, function as Method); + return CheckIgnoreMethod(function as Method); return false; } - public static bool CheckIgnoreMethod(Class @class, Method method) + public static bool CheckIgnoreMethod(Method method) { if (method.Ignore) return true; var isEmptyCtor = method.IsConstructor && method.Parameters.Count == 0; - if (@class.IsValueType && isEmptyCtor) + var @class = method.Namespace as Class; + if (@class != null && @class.IsValueType && isEmptyCtor) return true; if (method.IsCopyConstructor || method.IsMoveConstructor) @@ -40,14 +41,12 @@ namespace CppSharp.AST return false; } - public static bool CheckIgnoreField(Class @class, Field field) + public static bool CheckIgnoreField(Field field) { - if (field.Ignore) return true; - - if (field.Access != AccessSpecifier.Public) + if (field.Access != AccessSpecifier.Public) return true; - return false; + return field.Ignore; } } } diff --git a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs index 0bafd45d..5d4dcd96 100644 --- a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs +++ b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs @@ -350,7 +350,7 @@ namespace CppSharp.Generators.CLI PushIndent(); foreach (var field in @class.Fields) { - if (ASTUtils.CheckIgnoreField(@class, field)) continue; + if (ASTUtils.CheckIgnoreField(field)) continue; GenerateDeclarationCommon(field); if (@class.IsUnion) @@ -405,7 +405,7 @@ namespace CppSharp.Generators.CLI var staticMethods = new List(); foreach (var method in @class.Methods) { - if (ASTUtils.CheckIgnoreMethod(@class, method)) + if (ASTUtils.CheckIgnoreMethod(method)) continue; if (method.IsConstructor) @@ -515,9 +515,8 @@ namespace CppSharp.Generators.CLI public void GenerateMethod(Method method) { - if (method.Ignore) return; + if (ASTUtils.CheckIgnoreMethod(method)) return; - if (method.Access != AccessSpecifier.Public) PushBlock(CLIBlockKind.Method, method); GenerateDeclarationCommon(method); diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index e55bde5d..06426324 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -384,7 +384,7 @@ namespace CppSharp.Generators.CSharp foreach (var method in @class.Methods) { - if (ASTUtils.CheckIgnoreMethod(@class, method)) + if (ASTUtils.CheckIgnoreMethod(method)) continue; if (method.IsConstructor) @@ -432,7 +432,7 @@ namespace CppSharp.Generators.CSharp foreach (var field in @class.Fields) { - if (ASTUtils.CheckIgnoreField(@class, field)) continue; + if (ASTUtils.CheckIgnoreField(field)) continue; var nativeField = string.Format("{0}->{1}", Helpers.GeneratedIdentifier("ptr"), field.OriginalName); @@ -582,6 +582,7 @@ namespace CppSharp.Generators.CSharp foreach (var field in @class.Fields) { + if (ASTUtils.CheckIgnoreField(field)) continue; GenerateClassField(@class, isInternal, field); } } @@ -794,7 +795,7 @@ namespace CppSharp.Generators.CSharp var staticMethods = new List(); foreach (var method in @class.Methods) { - if (ASTUtils.CheckIgnoreMethod(@class, method)) + if (ASTUtils.CheckIgnoreMethod(method)) continue; if (method.IsConstructor) @@ -985,7 +986,7 @@ namespace CppSharp.Generators.CSharp foreach (var ctor in @class.Constructors) { - if (ASTUtils.CheckIgnoreMethod(@class, ctor)) + if (ASTUtils.CheckIgnoreMethod(ctor)) continue; GenerateMethod(ctor, @class); diff --git a/src/Generator/Passes/CheckDuplicatedNamesPass.cs b/src/Generator/Passes/CheckDuplicatedNamesPass.cs index 6453ec67..cfb86ea4 100644 --- a/src/Generator/Passes/CheckDuplicatedNamesPass.cs +++ b/src/Generator/Passes/CheckDuplicatedNamesPass.cs @@ -72,7 +72,7 @@ namespace CppSharp.Passes public override bool VisitFieldDecl(Field decl) { - if (ASTUtils.CheckIgnoreField(null, decl)) + if (ASTUtils.CheckIgnoreField(decl)) return false; if(!AlreadyVisited(decl)) @@ -89,7 +89,7 @@ namespace CppSharp.Passes public override bool VisitMethodDecl(Method decl) { - if (ASTUtils.CheckIgnoreMethod(null, decl)) + if (ASTUtils.CheckIgnoreMethod(decl)) return false; if(!AlreadyVisited(decl)) diff --git a/src/Generator/Passes/FieldToPropertyPass.cs b/src/Generator/Passes/FieldToPropertyPass.cs index f2151256..2997e1d6 100644 --- a/src/Generator/Passes/FieldToPropertyPass.cs +++ b/src/Generator/Passes/FieldToPropertyPass.cs @@ -13,7 +13,7 @@ namespace CppSharp.Passes if (@class.IsValueType) return false; - if (ASTUtils.CheckIgnoreField(@class,field)) + if (ASTUtils.CheckIgnoreField(field)) return false; var prop = new Property() diff --git a/src/Generator/Passes/GetterSetterToPropertyPass.cs b/src/Generator/Passes/GetterSetterToPropertyPass.cs index a3c26349..8039611f 100644 --- a/src/Generator/Passes/GetterSetterToPropertyPass.cs +++ b/src/Generator/Passes/GetterSetterToPropertyPass.cs @@ -76,7 +76,7 @@ namespace CppSharp.Passes if (AlreadyVisited(method)) return false; - if (ASTUtils.CheckIgnoreMethod(null, method)) + if (ASTUtils.CheckIgnoreMethod(method)) return false; var @class = method.Namespace as Class; From feef6ee80d084478fdc808f62dec35bdd938e840 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 12:04:10 +0100 Subject: [PATCH 16/23] Removed class parameter from CheckIgnoreFunction, CheckIgnoreMethod and CheckIgnoreField from recent commits. --- src/Generator/Generators/CLI/CLISourcesTemplate.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index fd1eaae0..83343ab8 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -125,7 +125,7 @@ namespace CppSharp.Generators.CLI foreach (var method in @class.Methods) { - if (ASTUtils.CheckIgnoreMethod(@class, method)) + if (ASTUtils.CheckIgnoreMethod(method)) continue; GenerateDeclarationCommon(method); @@ -522,7 +522,7 @@ namespace CppSharp.Generators.CLI foreach (var field in @class.Fields) { - if (ASTUtils.CheckIgnoreField(@class, field)) continue; + if (ASTUtils.CheckIgnoreField(field)) continue; var nativeField = string.Format("{0}{1}", nativeVar, field.OriginalName); @@ -660,7 +660,7 @@ namespace CppSharp.Generators.CLI foreach (var field in @class.Fields) { - if (ASTUtils.CheckIgnoreField(@class, field)) continue; + if (ASTUtils.CheckIgnoreField(field)) continue; var varName = string.Format("_native.{0}", field.OriginalName); From a45dbc7655c3aa089685a80074cf90a42c00253c Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 13:15:32 +0100 Subject: [PATCH 17/23] Fix template function generation. Return type should be created in TypePrinter. --- src/Generator/Generators/CLI/CLIHeadersTemplate.cs | 8 ++------ src/Generator/Generators/CLI/CLISourcesTemplate.cs | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs index 5d4dcd96..4d21dac1 100644 --- a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs +++ b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs @@ -281,19 +281,15 @@ namespace CppSharp.Generators.CLI var typePrinter = new CLITypePrinter(Driver, typeCtx); var retType = function.ReturnType.Type.Visit(typePrinter, - function.ReturnType.Qualifiers).Split('<')[0]; + function.ReturnType.Qualifiers); var typeNamesStr = ""; - var paramNamesStr = ""; var paramNames = template.Parameters.Select(param => param.Name).ToList(); if (paramNames.Any()) - { typeNamesStr = "typename " + string.Join(", typename ", paramNames); - paramNamesStr = string.Join(", ", paramNames); - } WriteLine("generic<{0}>", typeNamesStr); - WriteLine("{0}<{1}> {2}({3});", retType, paramNamesStr, SafeIdentifier(function.Name), + WriteLine("{0} {1}({2});", retType, SafeIdentifier(function.Name), GenerateParametersList(function.Parameters)); } PopIndent(); diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index 83343ab8..c8fa8214 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -215,19 +215,15 @@ namespace CppSharp.Generators.CLI var typePrinter = new CLITypePrinter(Driver, typeCtx); var retType = function.ReturnType.Type.Visit(typePrinter, - function.ReturnType.Qualifiers).Split('<')[0]; + function.ReturnType.Qualifiers); var typeNamesStr = ""; - var paramNamesStr = ""; var paramNames = template.Parameters.Select(param => param.Name).ToList(); if (paramNames.Any()) - { typeNamesStr = "typename " + string.Join(", typename ", paramNames); - paramNamesStr = string.Join(", ", paramNames); - } WriteLine("generic<{0}>", typeNamesStr); - WriteLine("{0}<{1}> {2}::{3}({4});", retType, paramNamesStr, + WriteLine("{0} {1}::{2}({3})", retType, QualifiedIdentifier(@class), SafeIdentifier(function.Name), GenerateParametersList(function.Parameters)); From ddfcf291df9579a62383bef635d41593b7068fe4 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Tue, 30 Jul 2013 15:18:49 +0100 Subject: [PATCH 18/23] CLI generator needs first function parameter. --- src/Generator/Passes/FunctionToInstanceMethodPass.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Generator/Passes/FunctionToInstanceMethodPass.cs b/src/Generator/Passes/FunctionToInstanceMethodPass.cs index 4810d217..1daccdb7 100644 --- a/src/Generator/Passes/FunctionToInstanceMethodPass.cs +++ b/src/Generator/Passes/FunctionToInstanceMethodPass.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using CppSharp.AST; +using CppSharp.Generators; namespace CppSharp.Passes { @@ -51,13 +52,16 @@ namespace CppSharp.Passes Access = AccessSpecifier.Public, Kind = CXXMethodKind.Normal, ReturnType = function.ReturnType, - Parameters = function.Parameters.Skip(1).ToList(), + Parameters = function.Parameters, CallingConvention = function.CallingConvention, IsVariadic = function.IsVariadic, IsInline = function.IsInline, Conversion = MethodConversionKind.FunctionToInstanceMethod }; + if (Driver.Options.GeneratorKind == LanguageGeneratorKind.CSharp) + method.Parameters = method.Parameters.Skip(0).ToList(); + @class.Methods.Add(method); Console.WriteLine("Instance method: {0}::{1}", @class.Name, From b1390894e0671fb93fb107fbfcf99667578b1469 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Fri, 2 Aug 2013 10:44:25 +0100 Subject: [PATCH 19/23] Added missing new lines. --- src/Generator/Passes/CheckDuplicatedNamesPass.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Generator/Passes/CheckDuplicatedNamesPass.cs b/src/Generator/Passes/CheckDuplicatedNamesPass.cs index cfb86ea4..0d98bdc8 100644 --- a/src/Generator/Passes/CheckDuplicatedNamesPass.cs +++ b/src/Generator/Passes/CheckDuplicatedNamesPass.cs @@ -77,6 +77,7 @@ namespace CppSharp.Passes if(!AlreadyVisited(decl)) CheckDuplicate(decl); + return false; } @@ -84,6 +85,7 @@ namespace CppSharp.Passes { if(!AlreadyVisited(decl)) CheckDuplicate(decl); + return false; } @@ -94,6 +96,7 @@ namespace CppSharp.Passes if(!AlreadyVisited(decl)) CheckDuplicate(decl); + return false; } From 83ac0cdf715a81359dccd5046c0acb8c1b2e8a5d Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Fri, 2 Aug 2013 10:47:15 +0100 Subject: [PATCH 20/23] Changed comment --- src/Generator/Passes/CheckDuplicatedNamesPass.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Generator/Passes/CheckDuplicatedNamesPass.cs b/src/Generator/Passes/CheckDuplicatedNamesPass.cs index 0d98bdc8..1f9b2b95 100644 --- a/src/Generator/Passes/CheckDuplicatedNamesPass.cs +++ b/src/Generator/Passes/CheckDuplicatedNamesPass.cs @@ -105,7 +105,8 @@ namespace CppSharp.Passes if (AlreadyVisited(@class) || @class.IsIncomplete) return false; - // In order to DeclarationName works, we visit methods first. + // DeclarationName should always process methods first, + // so we visit methods first. foreach (var method in @class.Methods) VisitMethodDecl(method); From b0d9e8b0883faad576230b59b4776cd4795c5e1e Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Fri, 2 Aug 2013 10:48:43 +0100 Subject: [PATCH 21/23] Fixed FunctionToInstanceMethodPass not skipping first method parameter. --- src/Generator/Passes/FunctionToInstanceMethodPass.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generator/Passes/FunctionToInstanceMethodPass.cs b/src/Generator/Passes/FunctionToInstanceMethodPass.cs index 1daccdb7..e169947d 100644 --- a/src/Generator/Passes/FunctionToInstanceMethodPass.cs +++ b/src/Generator/Passes/FunctionToInstanceMethodPass.cs @@ -60,7 +60,7 @@ namespace CppSharp.Passes }; if (Driver.Options.GeneratorKind == LanguageGeneratorKind.CSharp) - method.Parameters = method.Parameters.Skip(0).ToList(); + method.Parameters = method.Parameters.Skip(1).ToList(); @class.Methods.Add(method); From 90efc99083567c5a0a49ea7e0ed64af89401420d Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Fri, 2 Aug 2013 16:58:49 +0100 Subject: [PATCH 22/23] CheckIgnoreField has only one parameter now --- src/Generator/Generators/CSharp/CSharpTextTemplate.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index 06426324..7af14831 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -589,7 +589,7 @@ namespace CppSharp.Generators.CSharp private void GenerateClassField(Class @class, bool isInternal, Field field) { - if (ASTUtils.CheckIgnoreField(@class, field)) return; + if (ASTUtils.CheckIgnoreField(field)) return; PushBlock(CSharpBlockKind.Field); From 0c97842a8bdfe2b27b3f56c50fd45e384ac96b77 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Fri, 2 Aug 2013 17:00:18 +0100 Subject: [PATCH 23/23] Check if clang SVN_REVISION is greater than 187409 before trying to use MicrosoftVFTableContext. --- src/Parser/Parser.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index f89719ae..256f026c 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -463,6 +463,7 @@ void Parser::WalkVTable(clang::CXXRecordDecl* RD, CppSharp::AST::Class^ C) { case TargetCXXABI::Microsoft: { +#if SVN_REVISION >= 187409 MicrosoftVFTableContext VTContext(*AST); auto VFPtrs = VTContext.getVFPtrOffsets(RD); @@ -481,6 +482,7 @@ void Parser::WalkVTable(clang::CXXRecordDecl* RD, CppSharp::AST::Class^ C) C->Layout->VFTables->Add(Info); break; } +#endif } case TargetCXXABI::GenericItanium: {