예제 #1
0
        public void GenerateClassFields(Class @class)
        {
            // Handle the case of struct (value-type) inheritance by adding the base
            // properties to the managed value subtypes.
            if (@class.IsValueType)
            {
                foreach (var @base in @class.Bases.Where(b => b.IsClass && b.Class.IsDeclared))
                {
                    GenerateClassFields(@base.Class);
                }
            }

            Indent();
            // check for value types because some of the ignored fields may back properties;
            // not the case for ref types because the NativePtr pattern is used there
            foreach (var field in @class.Fields.Where(f => !ASTUtils.CheckIgnoreField(f)))
            {
                var property = @class.Properties.FirstOrDefault(p => p.Field == field);
                if (property != null && !property.IsInRefTypeAndBackedByValueClassField())
                {
                    field.Visit(this);
                }
            }
            Unindent();
        }
예제 #2
0
        public void GenerateClassMethods(Class @class)
        {
            PushIndent();

            var staticMethods = new List <Method>();

            foreach (var method in @class.Methods)
            {
                if (ASTUtils.CheckIgnoreMethod(method))
                {
                    continue;
                }

                if (method.IsConstructor)
                {
                    continue;
                }

                if (method.IsStatic)
                {
                    staticMethods.Add(method);
                    continue;
                }

                GenerateMethod(method);
            }

            foreach (var method in staticMethods)
            {
                GenerateMethod(method);
            }

            PopIndent();
        }
        public void SimplestCase()
        {
            // @x = @y + 1
            // @y = @x + 1

            Identifier xident = new Identifier(IdentifierType.InstanceField, "x", null);
            Identifier yident = new Identifier(IdentifierType.InstanceField, "y", null);

            SingleVariableDeclarationStatement xdecl = new SingleVariableDeclarationStatement(xident);
            SingleVariableDeclarationStatement ydecl = new SingleVariableDeclarationStatement(yident);

            VariableReferenceExpression xref = new VariableReferenceExpression(xident);
            VariableReferenceExpression yref = new VariableReferenceExpression(yident);

            BinaryExpression exp1 =
                new BinaryExpression(yref,
                                     new LiteralReferenceExpression("1", LiteralReferenceType.IntLiteral), BinaryOp.Plus);

            xdecl.DependencyExpression = exp1;

            BinaryExpression exp2 =
                new BinaryExpression(xref,
                                     new LiteralReferenceExpression("1", LiteralReferenceType.IntLiteral), BinaryOp.Plus);

            ydecl.DependencyExpression = exp2;

            Assert.IsTrue(ASTUtils.IsCycled(xdecl));
        }
예제 #4
0
 public virtual void VisitClassConstructors(Class @class)
 {
     foreach (var ctor in @class.Constructors.Where(c => !ASTUtils.CheckIgnoreMethod(c)))
     {
         ctor.Visit(this);
     }
 }
예제 #5
0
        public void GenerateClassProperties(Class @class)
        {
            // Handle the case of struct (value-type) inheritance by adding the base
            // properties to the managed value subtypes.
            if (@class.IsValueType)
            {
                foreach (var @base in @class.Bases.Where(b => b.IsClass && b.Class.IsDeclared))
                {
                    GenerateClassProperties(@base.Class);
                }
            }

            PushIndent();
            foreach (var prop in @class.Properties.Where(prop => !ASTUtils.CheckIgnoreProperty(prop)))
            {
                if (prop.IsInRefTypeAndBackedByValueClassField())
                {
                    GenerateField(@class, prop.Field);
                    continue;
                }

                GenerateDeclarationCommon(prop);
                GenerateProperty(prop);
            }
            PopIndent();
        }
예제 #6
0
        private void GenerateClassMethods(Class @class, Class realOwner)
        {
            if (@class.IsValueType)
            {
                foreach (var @base in @class.Bases.Where(b => b.IsClass && !b.Class.Ignore))
                {
                    GenerateClassMethods(@base.Class, realOwner);
                }
            }

            foreach (var method in @class.Methods.Where(m => @class == realOwner || !m.IsOperator))
            {
                if (ASTUtils.CheckIgnoreMethod(method, Options))
                {
                    continue;
                }

                // C++/CLI does not allow special member funtions for value types.
                if (@class.IsValueType && method.IsCopyConstructor)
                {
                    continue;
                }

                // Do not generate constructors or destructors from base classes.
                var declaringClass = method.Namespace as Class;
                if (declaringClass != realOwner && (method.IsConstructor || method.IsDestructor))
                {
                    continue;
                }

                GenerateMethod(method, realOwner);
            }
        }
예제 #7
0
        public override bool VisitFunctionDecl(Function function)
        {
            if (!base.VisitFunctionDecl(function))
            {
                return(false);
            }

            if (function.IsGenerated)
            {
                Action <ClassTemplateSpecialization> add =
                    s =>
                {
                    if (internalSpecializations.Contains(s))
                    {
                        internalSpecializations.Remove(s);
                    }
                    specializations.Add(s);
                };
                ASTUtils.CheckTypeForSpecialization(function.OriginalReturnType.Type,
                                                    function, add, Context.TypeMaps);
                foreach (var parameter in function.Parameters)
                {
                    ASTUtils.CheckTypeForSpecialization(parameter.Type, function,
                                                        add, Context.TypeMaps);
                }
            }

            return(true);
        }
예제 #8
0
        public void GenerateClassConstructors(Class @class, string nativeType)
        {
            PushIndent();

            // Output a default constructor that takes the native pointer.
            WriteLine("{0}({1} native);", SafeIdentifier(@class.Name), nativeType);
            WriteLine("{0}({1} native);", SafeIdentifier(@class.Name), "System::IntPtr");

            foreach (var ctor in @class.Constructors)
            {
                if (ASTUtils.CheckIgnoreMethod(ctor))
                {
                    continue;
                }

                GenerateMethod(ctor);
            }

            if (@class.IsRefType)
            {
                GenerateClassDestructor(@class);
                GenerateClassFinalizer(@class);
            }

            PopIndent();
        }
예제 #9
0
        public override bool VisitFunctionDecl(Function function)
        {
            if (!base.VisitFunctionDecl(function))
            {
                return(false);
            }

            var module = function.TranslationUnit.Module;

            if (function.IsGenerated)
            {
                ASTUtils.CheckTypeForSpecialization(function.OriginalReturnType.Type,
                                                    function, Add, Context.TypeMaps);
                foreach (var parameter in function.Parameters)
                {
                    ASTUtils.CheckTypeForSpecialization(parameter.Type, function,
                                                        Add, Context.TypeMaps);
                }
            }

            if (!NeedsSymbol(function))
            {
                return(false);
            }

            var symbolsCodeGenerator = GetSymbolsCodeGenerator(module);

            return(function.Visit(symbolsCodeGenerator));
        }
예제 #10
0
        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(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);
        }
예제 #11
0
        public void GenerateClassProperties(Class @class)
        {
            // Handle the case of struct (value-type) inheritance by adding the base
            // properties to the managed value subtypes.
            if (@class.IsValueType)
            {
                foreach (var @base in @class.Bases.Where(b => b.IsClass && b.Class.IsDeclared))
                {
                    GenerateClassProperties(@base.Class);
                }
            }

            Indent();
            foreach (var prop in @class.Properties.Where(
                         prop => !ASTUtils.CheckIgnoreProperty(prop) && !TypeIgnored(prop.Type)))
            {
                if (prop.IsInRefTypeAndBackedByValueClassField())
                {
                    prop.Field.Visit(this);
                    continue;
                }

                prop.Visit(this);
            }
            Unindent();
        }
예제 #12
0
        public override bool VisitFieldDecl(Field field)
        {
            if (!VisitDeclaration(field))
            {
                return(false);
            }

            if (ASTUtils.CheckIgnoreField(field))
            {
                return(false);
            }

            var @class = field.Namespace as Class;

            if (@class == null)
            {
                return(false);
            }

            // Check if we already have a synthetized property.
            var existingProp = @class.Properties.FirstOrDefault(property => property.Field == field);

            if (existingProp != null)
            {
                return(false);
            }

            field.GenerationKind = GenerationKind.Internal;

            var prop = new Property
            {
                Name                  = field.Name,
                Namespace             = field.Namespace,
                QualifiedType         = field.QualifiedType,
                Access                = field.Access,
                Field                 = field,
                AssociatedDeclaration = field
            };

            if (Options.GeneratorKind == GeneratorKind.CPlusPlus)
            {
                GenerateAcessorMethods(field, prop);
            }

            // do not rename value-class fields because they would be
            // generated as fields later on even though they are wrapped by properties;
            // that is, in turn, because it's cleaner to write
            // the struct marshalling logic just for properties
            if (!prop.IsInRefTypeAndBackedByValueClassField())
            {
                field.Name = Generator.GeneratedIdentifier(field.Name);
            }

            @class.Properties.Add(prop);

            Diagnostics.Debug($"Property created from field: {field.QualifiedName}");

            return(false);
        }
예제 #13
0
        public override bool VisitMethodDecl(Method method)
        {
            if (!VisitDeclaration(method))
            {
                return(false);
            }

            if (ASTUtils.CheckIgnoreMethod(method, Driver.Options))
            {
                return(false);
            }

            var @class = method.Namespace as Class;

            if (@class == null || @class.IsIncomplete)
            {
                return(false);
            }

            if (method.IsConstructor)
            {
                return(false);
            }

            if (IsGetter(method))
            {
                var name = method.Name.Substring("get".Length);
                var prop = GetOrCreateProperty(@class, name, method.ReturnType);
                prop.GetMethod = method;
                prop.Access    = method.Access;

                // Do not generate the original method now that we know it is a getter.
                method.IsGenerated = false;

                Driver.Diagnostics.Debug("Getter created: {0}::{1}", @class.Name, name);

                return(false);
            }

            if (IsSetter(method) && IsValidSetter(method))
            {
                var name = method.Name.Substring("set".Length);

                var type = method.Parameters[0].QualifiedType;
                var prop = GetOrCreateProperty(@class, name, type);
                prop.SetMethod = method;
                prop.Access    = method.Access;

                // Ignore the original method now that we know it is a setter.
                method.IsGenerated = false;

                Driver.Diagnostics.Debug("Setter created: {0}::{1}", @class.Name, name);

                return(false);
            }

            return(false);
        }
예제 #14
0
        public void GenerateMethod(Method method)
        {
            if (ASTUtils.CheckIgnoreMethod(method, Options))
            {
                return;
            }

            PushBlock(CLIBlockKind.Method, method);

            GenerateDeclarationCommon(method);

            if ((method.IsVirtual || method.IsOverride) && !method.IsOperator)
            {
                Write("virtual ");
            }

            var isBuiltinOperator = method.IsOperator &&
                                    Operators.IsBuiltinOperator(method.OperatorKind);

            if (method.IsStatic || isBuiltinOperator)
            {
                Write("static ");
            }

            if (method.OperatorKind == CXXOperatorKind.ExplicitConversion)
            {
                Write("explicit ");
            }

            if (method.IsConstructor || method.IsDestructor ||
                method.OperatorKind == CXXOperatorKind.Conversion ||
                method.OperatorKind == CXXOperatorKind.ExplicitConversion)
            {
                Write("{0}(", GetMethodName(method));
            }
            else
            {
                Write("{0} {1}(", method.ReturnType, method.Name);
            }

            GenerateMethodParameters(method);

            Write(")");

            if (method.IsOverride)
            {
                Write(" override");
            }

            WriteLine(";");

            if (method.OperatorKind == CXXOperatorKind.EqualEqual)
            {
                GenerateEquals(method, (Class)method.Namespace);
            }

            PopBlock(NewLineKind.BeforeNextBlock);
        }
예제 #15
0
        public override bool VisitFieldDecl(Field field)
        {
            if (!VisitDeclaration(field))
            {
                return(false);
            }

            var @class = field.Namespace as Class;

            if (@class == null)
            {
                return(false);
            }

            if (ASTUtils.CheckIgnoreField(field))
            {
                return(false);
            }

            // Check if we already have a synthetized property.
            var existingProp = @class.Properties.FirstOrDefault(property =>
                                                                property.Name == field.Name &&
                                                                property.QualifiedType == field.QualifiedType);

            if (existingProp != null)
            {
                field.ExplicityIgnored = true;
                return(false);
            }

            field.ExplicityIgnored = true;

            var prop = new Property
            {
                Name          = field.Name,
                Namespace     = field.Namespace,
                QualifiedType = field.QualifiedType,
                Access        = field.Access,
                Field         = field
            };

            // do not rename value-class fields because they would be
            // generated as fields later on even though they are wrapped by properties;
            // that is, in turn, because it's cleaner to write
            // the struct marshalling logic just for properties
            if (!prop.IsInRefTypeAndBackedByValueClassField())
            {
                field.Name = Generator.GeneratedIdentifier(field.Name);
            }

            @class.Properties.Add(prop);

            Log.Debug("Property created from field: {0}::{1}", @class.Name,
                      field.Name);

            return(false);
        }
예제 #16
0
        public override void VisitDeclContextFunctions(DeclarationContext context)
        {
            var functions = context.Functions.Where(f => !ASTUtils.CheckIgnoreFunction(f)).ToList();
            var unique    = functions.GroupBy(m => m.Name);

            foreach (var group in unique)
            {
                GenerateFunctionGroup(group.ToList());
            }
        }
예제 #17
0
        public void GenerateClassMethods(List <Method> methods)
        {
            if (methods.Count == 0)
            {
                return;
            }

            Indent();

            var @class = (Class)methods[0].Namespace;

            if (@class.IsValueType)
            {
                foreach (var @base in @class.Bases.Where(b => b.IsClass && !b.Class.Ignore))
                {
                    GenerateClassMethods(@base.Class.Methods.Where(m => !m.IsOperator).ToList());
                }
            }

            var staticMethods = new List <Method>();

            foreach (var method in methods)
            {
                if (ASTUtils.CheckIgnoreMethod(method) || FunctionIgnored(method))
                {
                    continue;
                }

                if (method.IsConstructor)
                {
                    continue;
                }

                if (method.IsOperator)
                {
                    continue;
                }

                if (method.IsStatic)
                {
                    staticMethods.Add(method);
                    continue;
                }

                method.Visit(this);
            }

            foreach (var method in staticMethods)
            {
                method.Visit(this);
            }

            Unindent();
        }
예제 #18
0
        public virtual void VisitClassMethods(Class @class)
        {
            foreach (var method in @class.Methods.Where(c => !ASTUtils.CheckIgnoreMethod(c)))
            {
                if (method.IsConstructor)
                {
                    continue;
                }

                method.Visit(this);
            }
        }
예제 #19
0
 private void CheckForInternalSpecialization(Declaration container, AST.Type type)
 {
     ASTUtils.CheckTypeForSpecialization(type, container,
                                         specialization =>
     {
         if (!specializations.Contains(specialization))
         {
             internalSpecializations.Add(specialization);
             CheckLayoutFields(specialization);
         }
     }, Context.TypeMaps, true);
 }
예제 #20
0
        public virtual void GenerateClassProperties(Class @class)
        {
            foreach (var property in @class.Properties)
            {
                if (ASTUtils.CheckIgnoreProperty(property) || CppHeaders.TypeIgnored(property.Type))
                {
                    continue;
                }

                property.Visit(this);
            }
        }
예제 #21
0
 private void CheckBasesForSpecialization(Class @class)
 {
     foreach (var @base in @class.Bases.Where(b => b.IsClass))
     {
         var specialization = @base.Class as ClassTemplateSpecialization;
         if (specialization != null && !specialization.IsExplicitlyGenerated &&
             specialization.SpecializationKind != TemplateSpecializationKind.ExplicitSpecialization)
         {
             ASTUtils.CheckTypeForSpecialization(@base.Type, @class, Add, Context.TypeMaps);
         }
         CheckBasesForSpecialization(@base.Class);
     }
 }
예제 #22
0
        public void GenerateClassConstructors(Class @class, string nativeType)
        {
            if (@class.IsStatic)
            {
                return;
            }

            PushIndent();

            // Output a default constructor that takes the native pointer.
            WriteLine("{0}({1} native);", @class.Name, nativeType);
            WriteLine("static {0}^ {1}(::System::IntPtr native);",
                      @class.Name, Helpers.CreateInstanceIdentifier);
            if (@class.IsRefType)
            {
                WriteLine("static {0}^ {1}(::System::IntPtr native, bool {2});",
                          @class.Name, Helpers.CreateInstanceIdentifier, Helpers.OwnsNativeInstanceIdentifier);
            }

            foreach (var ctor in @class.Constructors)
            {
                if (ASTUtils.CheckIgnoreMethod(ctor, Options))
                {
                    continue;
                }

                // C++/CLI does not allow special member funtions for value types.
                if (@class.IsValueType && ctor.IsCopyConstructor)
                {
                    continue;
                }

                GenerateMethod(ctor);
            }

            if (@class.IsRefType)
            {
                var destructor = @class.Destructors
                                 .FirstOrDefault(d => d.Parameters.Count == 0 && d.Access == AccessSpecifier.Public);
                if (destructor != null)
                {
                    GenerateClassDestructor(@class);
                    if (Options.GenerateFinalizers)
                    {
                        GenerateClassFinalizer(@class);
                    }
                }
            }

            PopIndent();
        }
예제 #23
0
        public override bool VisitFieldDecl(Field decl)
        {
            if (ASTUtils.CheckIgnoreField(decl))
            {
                return(false);
            }

            if (!AlreadyVisited(decl))
            {
                CheckDuplicate(decl);
            }

            return(false);
        }
예제 #24
0
 private void CheckBasesForSpecialization(Class @class)
 {
     foreach (var @base in @class.Bases.Where(b => b.IsClass))
     {
         var specialization = @base.Class as ClassTemplateSpecialization;
         if (specialization != null &&
             !ASTUtils.CheckTypeForSpecialization(@base.Type, @class,
                                                  AddSpecialization, Context.TypeMaps))
         {
             CheckForInternalSpecialization(@class, @base.Type);
         }
         CheckBasesForSpecialization(@base.Class);
     }
 }
예제 #25
0
        public void GenerateMethod(Method method)
        {
            if (ASTUtils.CheckIgnoreMethod(method, Options))
            {
                return;
            }

            PushBlock(BlockKind.Method, method);
            GenerateDeclarationCommon(method);

            GenerateMethodSpecifier(method, method.Namespace as Class);
            WriteLine(";");

            PopBlock(NewLineKind.BeforeNextBlock);
        }
예제 #26
0
        public override bool VisitFunctionDecl(Function decl)
        {
            if (!VisitDeclaration(decl))
            {
                return(false);
            }

            if (ASTUtils.CheckIgnoreFunction(decl))
            {
                return(false);
            }

            CheckDuplicate(decl);
            return(false);
        }
예제 #27
0
 private void CheckForInternalSpecialization(Declaration container, AST.Type type)
 {
     ASTUtils.CheckTypeForSpecialization(type, container,
                                         s =>
     {
         if (!specializations.Contains(s))
         {
             internalSpecializations.Add(s);
             foreach (var f in s.Fields)
             {
                 f.Visit(this);
             }
         }
     }, Context.TypeMaps, true);
 }
예제 #28
0
        public override bool VisitVariableDecl(Variable variable)
        {
            if (!base.VisitVariableDecl(variable))
            {
                return(false);
            }

            if (variable.Access == AccessSpecifier.Public)
            {
                ASTUtils.CheckTypeForSpecialization(variable.Type,
                                                    variable, AddSpecialization, Context.TypeMaps);
                return(true);
            }

            return(true);
        }
예제 #29
0
        private void GenerateClassProperties(Class @class, Class realOwner)
        {
            if (@class.IsValueType)
            {
                foreach (var @base in @class.Bases.Where(b => b.IsClass && b.Class.IsDeclared))
                {
                    GenerateClassProperties(@base.Class, realOwner);
                }
            }

            foreach (var property in @class.Properties.Where(
                         p => !ASTUtils.CheckIgnoreProperty(p) && !p.IsInRefTypeAndBackedByValueClassField()))
            {
                GenerateProperty(property, realOwner);
            }
        }
예제 #30
0
        public virtual bool VisitClassDeclContext(Class @class)
        {
            if (!VisitDeclContext(@class))
            {
                return(false);
            }

            foreach (var field in @class.Fields.Where(f => !ASTUtils.CheckIgnoreField(f)))
            {
                field.Visit(this);
            }

            foreach (var property in @class.Properties.Where(p => !ASTUtils.CheckIgnoreProperty(p)))
            {
                property.Visit(this);
            }

            VisitClassConstructors(@class);
            VisitClassMethods(@class);

            foreach (var @event in @class.Events)
            {
                if ([email protected])
                {
                    continue;
                }

                @event.Visit(this);
            }

            foreach (var variable in @class.Variables)
            {
                if (!variable.IsGenerated)
                {
                    continue;
                }

                if (variable.Access != AccessSpecifier.Public)
                {
                    continue;
                }

                variable.Visit(this);
            }

            return(true);
        }