Esempio n. 1
0
        private bool GenerateClassConstructorBase(Class @class, Method method = null)
        {
            var hasBase = @class.HasBase && @class.Bases[0].IsClass && @class.Bases[0].Class.IsGenerated;

            if (!hasBase)
            {
                return(false);
            }

            if ([email protected])
            {
                Indent();

                var baseClass = @class.Bases[0].Class;
                Write($": {QualifiedIdentifier(baseClass)}(");

                // We cast the value to the base class type since otherwise there
                // could be ambiguous call to overloaded constructors.
                CTypePrinter.PushContext(TypePrinterContextKind.Native);
                var nativeTypeName = baseClass.Visit(CTypePrinter);
                CTypePrinter.PopContext();
                Write($"({nativeTypeName}*)");

                WriteLine("{0})", method != null ? "nullptr" : ClassCtorInstanceParamIdentifier);

                Unindent();
            }

            return(true);
        }
Esempio n. 2
0
        public void GenerateFunction(Function function, DeclarationContext @namespace)
        {
            if (!function.IsGenerated || CLIHeaders.FunctionIgnored(function))
            {
                return;
            }

            GenerateDeclarationCommon(function);

            var classSig = string.Format("{0}::{1}", QualifiedIdentifier(@namespace),
                                         TranslationUnit.FileNameWithoutExtension);

            Write("{0} {1}::{2}(", function.ReturnType, classSig,
                  function.Name);

            for (var i = 0; i < function.Parameters.Count; ++i)
            {
                var param = function.Parameters[i];
                Write("{0}", CTypePrinter.VisitParameter(param));
                if (i < function.Parameters.Count - 1)
                {
                    Write(", ");
                }
            }

            WriteLine(")");
            WriteOpenBraceAndIndent();

            GenerateFunctionCall(function);

            UnindentAndWriteCloseBrace();
        }
Esempio n. 3
0
        public void GenerateClassNativeField(Class @class)
        {
            PushBlock();

            var nativeInstanceField = new Field()
            {
                Name          = Helpers.InstanceIdentifier,
                QualifiedType = new QualifiedType(new PointerType(new QualifiedType(new TagType(@class)))),
                Namespace     = @class
            };

            Indent();
            CTypePrinter.PushContext(TypePrinterContextKind.Native);
            nativeInstanceField.Visit(this);
            CTypePrinter.PopContext();
            Unindent();

            PopBlock(NewLineKind.BeforeNextBlock);

            /*var nativeInstanceProperty = new Property()
             * {
             *  Name = Helpers.InstanceIdentifier,
             *  QualifiedType =
             * };
             *
             * nativeInstanceProperty.Visit(this);*/
        }
Esempio n. 4
0
        public string GenerateParametersList(List <Parameter> parameters)
        {
            var types = new List <string>();

            foreach (var param in parameters)
            {
                types.Add(CTypePrinter.VisitParameter(param).ToString());
            }
            return(string.Join(", ", types));
        }
Esempio n. 5
0
        public override bool VisitEnumDecl(Enumeration @enum)
        {
            if (!VisitDeclaration(@enum))
            {
                return(false);
            }

            PushBlock();

            var enumName = Options.GeneratorKind != GeneratorKind.CPlusPlus ?
                           CGenerator.QualifiedName(@enum) : @enum.Name;

            Write($"typedef enum {enumName}");

            if (Options.GeneratorKind == GeneratorKind.CPlusPlus)
            {
                var typeName = CTypePrinter.VisitPrimitiveType(
                    @enum.BuiltinType.Type, new TypeQualifiers());

                if (@enum.BuiltinType.Type != PrimitiveType.Int)
                {
                    Write($" : {typeName}");
                }
            }

            NewLine();
            WriteStartBraceIndent();

            foreach (var item in @enum.Items)
            {
                var enumItemName = Options.GeneratorKind != GeneratorKind.CPlusPlus ?
                                   $"{@enum.QualifiedName}_{item.Name}" : item.Name;

                Write(enumItemName);

                if (item.ExplicitValue)
                {
                    Write($" = {@enum.GetItemValueAsString(item)}");
                }

                if (item != @enum.Items.Last())
                {
                    WriteLine(",");
                }
            }

            NewLine();
            PopIndent();
            WriteLine($"}} {enumName};");

            PopBlock(NewLineKind.BeforeNextBlock);

            return(true);
        }
Esempio n. 6
0
        public void GenerateClassConstructors(Class @class, string nativeType)
        {
            if (@class.IsStatic)
            {
                return;
            }

            Indent();

            var classNativeName = @class.Visit(CTypePrinter);

            CTypePrinter.PushContext(TypePrinterContextKind.Native);
            var classManagedName = @class.Visit(CTypePrinter);

            CTypePrinter.PopContext();

            WriteLine($"{@class.Name}({classManagedName}* native);");
            NewLine();

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

                ctor.Visit(this);
            }

            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);
                    }
                }
            }

            Unindent();
        }
Esempio n. 7
0
        public void GenerateMethodParameters(Method method)
        {
            for (var i = 0; i < method.Parameters.Count; ++i)
            {
                if (method.Conversion == MethodConversionKind.FunctionToInstanceMethod &&
                    i == 0)
                {
                    continue;
                }

                var param = method.Parameters[i];
                Write("{0}", CTypePrinter.VisitParameter(param));
                if (i < method.Parameters.Count - 1)
                {
                    Write(", ");
                }
            }
        }
Esempio n. 8
0
        public override string GetMethodIdentifier(Function function,
                                                   TypePrinterContextKind context = TypePrinterContextKind.Managed)
        {
            string id;

            if (function is Method method)
            {
                var @class = method.Namespace as Class;
                CTypePrinter.PushScope(TypePrintScopeKind.Qualified);
                id = $"{QualifiedIdentifier(@class)}::{base.GetMethodIdentifier(method, context)}";
                CTypePrinter.PopScope();
                return(id);
            }

            CTypePrinter.PushScope(TypePrintScopeKind.Qualified);
            id = base.GetMethodIdentifier(function);
            CTypePrinter.PopScope();
            return(id);
        }
Esempio n. 9
0
        public bool GenerateTypedef(TypedefNameDecl typedef)
        {
            if (!typedef.IsGenerated)
            {
                return(false);
            }

            var functionType = typedef.Type as FunctionType;

            if (functionType != null || typedef.Type.IsPointerTo(out functionType))
            {
                PushBlock(BlockKind.Typedef, typedef);
                GenerateDeclarationCommon(typedef);

                var insideClass = typedef.Namespace is Class;

                var attributedType    = typedef.Type.GetPointee().Desugar();
                var callingConvention = attributedType == null && functionType != null
                    ? functionType.CallingConvention
                    : ((FunctionType)attributedType).CallingConvention;
                var interopCallConv = callingConvention.ToInteropCallConv();
                if (interopCallConv != System.Runtime.InteropServices.CallingConvention.Winapi)
                {
                    WriteLine("[System::Runtime::InteropServices::UnmanagedFunctionPointer" +
                              "(System::Runtime::InteropServices::CallingConvention::{0})] ",
                              interopCallConv);
                }

                var visibility = !insideClass ? "public " : string.Empty;
                var result     = CTypePrinter.VisitDelegate(functionType);
                result.Name = typedef.Name;
                WriteLine($"{visibility}{result};");

                PopBlock(NewLineKind.BeforeNextBlock);

                return(true);
            }

            return(false);
        }
Esempio n. 10
0
        public override bool VisitFunctionDecl(Function function)
        {
            if (!function.IsGenerated || CppHeaders.FunctionIgnored(function))
            {
                return(false);
            }

            PushBlock(BlockKind.Function, function);

            GenerateDeclarationCommon(function);

            var returnType = function.ReturnType.Visit(CTypePrinter);

            var name = function.Visit(CTypePrinter);

            Write($"{returnType} ({name})(");

            for (var i = 0; i < function.Parameters.Count; ++i)
            {
                var param = function.Parameters[i];
                Write($"{CTypePrinter.VisitParameter(param)}");
                if (i < function.Parameters.Count - 1)
                {
                    Write(", ");
                }
            }

            WriteLine(")");
            WriteOpenBraceAndIndent();

            GenerateFunctionCall(function);

            UnindentAndWriteCloseBrace();

            PopBlock(NewLineKind.BeforeNextBlock);

            return(true);
        }
Esempio n. 11
0
        // Generate an external instance storage location for external bindings.
        public virtual void GenerateExternalDataFields(Class @class)
        {
            PushBlock();

            var voidPtrType           = new PointerType(new QualifiedType(new BuiltinType(PrimitiveType.Void)));
            var externalInstanceField = new Field()
            {
                Name          = Generator.GeneratedIdentifier("ExternalInstance"),
                QualifiedType = new QualifiedType(voidPtrType),
                Namespace     = @class
            };

            Indent();
            CTypePrinter.PushContext(TypePrinterContextKind.Native);
            externalInstanceField.Visit(this);
            CTypePrinter.PopContext();

            var externalDataField = new Field()
            {
                Name          = Generator.GeneratedIdentifier("ExternalData"),
                QualifiedType = new QualifiedType(new ArrayType
                {
                    QualifiedType = new QualifiedType(voidPtrType),
                    SizeType      = ArrayType.ArraySize.Constant,
                    Size          = 2
                }),
                Namespace = @class
            };

            CTypePrinter.PushContext(TypePrinterContextKind.Native);
            var result = externalDataField.Visit(CTypePrinter);

            CTypePrinter.PopContext();
            Unindent();

            PopBlock(NewLineKind.BeforeNextBlock);
        }
Esempio n. 12
0
        public override bool VisitTypedefNameDecl(TypedefNameDecl typedef)
        {
            if (!typedef.IsGenerated)
            {
                return(false);
            }

            var functionType = typedef.Type as FunctionType;

            if (functionType != null || typedef.Type.IsPointerTo(out functionType))
            {
                PushBlock(BlockKind.Typedef, typedef);
                GenerateDeclarationCommon(typedef);

                var @delegate = string.Format(CTypePrinter.VisitDelegate(functionType), typedef.Name);
                WriteLine($"{@delegate};");

                PopBlock(NewLineKind.BeforeNextBlock);

                return(true);
            }

            return(false);
        }
Esempio n. 13
0
 public QuickJSModule(BindingContext context, Module module)
     : base(context, module.Units.GetGenerated())
 {
     this.module = module;
     CTypePrinter.PushContext(TypePrinterContextKind.Managed);
 }
Esempio n. 14
0
 public QuickJSSources(BindingContext context, IEnumerable <TranslationUnit> units)
     : base(context, units)
 {
     CTypePrinter.PushContext(TypePrinterContextKind.Managed);
 }
Esempio n. 15
0
 public NAPIModule(BindingContext context, Module module)
     : base(context, module.Units.GetGenerated())
 {
     CTypePrinter.PushContext(TypePrinterContextKind.Managed);
 }
Esempio n. 16
0
 public CppHeaders(BindingContext context, IEnumerable <TranslationUnit> units)
     : base(context, units)
 {
     CTypePrinter.PushContext(TypePrinterContextKind.Managed);
 }
Esempio n. 17
0
        private void GenerateEventInvoke(Event @event)
        {
            var invokeId = $"event_invoke_{@event.OriginalName}";

            PushBlock();
            {
                CTypePrinter.PushContext(TypePrinterContextKind.Native);
                var functionType = @event.Type as FunctionType;
                var retType      = functionType.ReturnType.Visit(CTypePrinter);
                CTypePrinter.PopContext();

                Write($"{retType} {invokeId}(");

                var @params = new List <string>();
                foreach (var param in @event.Parameters)
                {
                    CTypePrinter.PushContext(TypePrinterContextKind.Native);
                    var paramType = param.Type.Visit(CTypePrinter);
                    CTypePrinter.PopContext();

                    @params.Add($"{paramType} {param.Name}");
                }

                Write(string.Join(", ", @params));
                WriteLine(")");
                WriteOpenBraceAndIndent();

                WriteLine($"JSValue event = JS_Interop_FindEvent(&events, {@event.GlobalId});");
                WriteLine($"if (JS_IsUndefined(event))");

                var isVoidReturn = functionType.ReturnType.Type.IsPrimitiveType(PrimitiveType.Void);
                if (isVoidReturn)
                {
                    WriteLineIndent($"return;");
                }
                else
                {
                    var defaultValuePrinter = new CppDefaultValuePrinter(Context);
                    var defaultValue        = functionType.ReturnType.Visit(defaultValuePrinter);
                    WriteLineIndent($"return {defaultValue};");
                }
                NewLine();

                // Marshal the arguments.
                var marshalers = new List <MarshalPrinter <MarshalContext> >();
                foreach (var param in @event.Parameters)
                {
                    var ctx = new MarshalContext(Context, CurrentIndentation)
                    {
                        ArgName       = param.Name,
                        ReturnVarName = param.Name,
                        ReturnType    = param.QualifiedType,
                        Parameter     = param
                    };

                    var marshal = GetMarshalNativeToManagedPrinter(ctx);
                    marshalers.Add(marshal);

                    param.Visit(marshal);

                    if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                    {
                        Write(marshal.Context.Before);
                    }
                }

                var args = marshalers.Select(m => m.Context.Return.ToString());
                WriteLine($"JSValueConst argv[] = {{ { string.Join(", ", args)} }};");
                WriteLine($"auto data = (JS_SignalContext*) JS_GetOpaque(event, 0);");
                WriteLine($"JSValue ret = JS_Call(ctx, data->function, JS_UNDEFINED, {@event.Parameters.Count}, argv);");
                WriteLine($"JS_FreeValue(ctx, ret);");

                //WriteLine($"{@class.QualifiedOriginalName}* instance = data->instance;");

/*
 *
 *              if (!isVoidReturn)
 *              {
 *                  CTypePrinter.PushContext(TypePrinterContextKind.Native);
 *                  var returnType = function.ReturnType.Visit(CTypePrinter);
 *                  CTypePrinter.PopContext();
 *
 *                  Write($"{returnType} {Helpers.ReturnIdentifier} = ");
 *              }
 *
 *              var @class = function.Namespace as Class;
 */

                UnindentAndWriteCloseBrace();
            }
            PopBlock(NewLineKind.BeforeNextBlock);
        }
Esempio n. 18
0
        public override bool VisitClassDecl(Class @class)
        {
            CTypePrinter.PushContext(TypePrinterContextKind.Native);
            var typeName = @class.Visit(CTypePrinter);

            WriteLine($"class _{@class.Name} : public {typeName}");
            WriteLine("{");
            WriteLine("public:");
            NewLine();
            Indent();

            Class         = @class;
            UniqueMethods = new HashSet <Method>();

            foreach (var component in @class.Layout.Layout.Components)
            {
                var method = component.Method;
                if (method == null)
                {
                    continue;
                }

                if (!method.IsVirtual || (method.GenerationKind == GenerationKind.None))
                {
                    continue;
                }

                if (!UniqueMethods.Add(method))
                {
                    continue;
                }

                if (!ShouldVisitMethod(method))
                {
                    continue;
                }

                method = new Method(component.Method)
                {
                    IsOverride = true
                };

                if (method.IsConstructor || method.IsDestructor)
                {
                    continue;
                }

                UniqueMethods.Add(method);

                method.Visit(this);
            }

            Unindent();
            WriteLine("};");

            CTypePrinter.PopContext();

            Class         = null;
            UniqueMethods = null;

            return(true);
        }
Esempio n. 19
0
        public void GenerateFunctionCall(Function function)
        {
            var @params = GenerateFunctionParamsMarshal(function.Parameters, function);

            var needsReturn = !function.ReturnType.Type.IsPrimitiveType(PrimitiveType.Void);

            if (needsReturn)
            {
                CTypePrinter.PushContext(TypePrinterContextKind.Native);
                var returnType = function.ReturnType.Visit(CTypePrinter);
                CTypePrinter.PopContext();

                Write($"{returnType} {Helpers.ReturnIdentifier} = ");
            }

            var method = function as Method;
            var @class = function.Namespace as Class;

            var property = method?.AssociatedDeclaration as Property;
            var field    = property?.Field;

            if (field != null)
            {
                Write($"((::{@class.QualifiedOriginalName}*){Helpers.InstanceIdentifier})->");
                Write($"{field.OriginalName}");

                var isGetter = property.GetMethod == method;
                if (isGetter)
                {
                    WriteLine(";");
                }
                else
                {
                    WriteLine($" = {@params[0].Name};");
                }
            }
            else
            {
                if (IsNativeFunctionOrStaticMethod(function))
                {
                    Write($"::{function.QualifiedOriginalName}(");
                }
                else
                {
                    if (IsNativeMethod(function))
                    {
                        Write($"((::{@class.QualifiedOriginalName}*){Helpers.InstanceIdentifier})->");
                    }

                    Write($"{base.GetMethodIdentifier(function, TypePrinterContextKind.Native)}(");
                }

                GenerateFunctionParams(@params);
                WriteLine(");");
            }

            foreach (var paramInfo in @params)
            {
                var param = paramInfo.Param;
                if (param.Usage != ParameterUsage.Out && param.Usage != ParameterUsage.InOut)
                {
                    continue;
                }

                if (param.Type.IsPointer() && !param.Type.GetFinalPointee().IsPrimitiveType())
                {
                    param.QualifiedType = new QualifiedType(param.Type.GetFinalPointee());
                }

                var nativeVarName = paramInfo.Name;

                var ctx = new MarshalContext(Context, CurrentIndentation)
                {
                    ArgName       = nativeVarName,
                    ReturnVarName = nativeVarName,
                    ReturnType    = param.QualifiedType
                };

                var marshal = new CppMarshalNativeToManagedPrinter(ctx);
                param.Visit(marshal);

                if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                {
                    Write(marshal.Context.Before);
                }

                WriteLine($"{param.Name} = {marshal.Context.Return};");
            }

            if (needsReturn)
            {
                GenerateFunctionCallReturnMarshal(function);
            }
        }
Esempio n. 20
0
        public virtual void GenerateFunctionCall(Function function)
        {
            var @params      = GenerateFunctionParamsMarshal(function.Parameters, function);
            var method       = function as Method;
            var isVoidReturn = function.ReturnType.Type.IsPrimitiveType(PrimitiveType.Void);

            PushBlock();
            {
                if (!isVoidReturn)
                {
                    CTypePrinter.PushContext(TypePrinterContextKind.Native);
                    var returnType = function.ReturnType.Visit(CTypePrinter);
                    CTypePrinter.PopContext();

                    Write($"{returnType} {Helpers.ReturnIdentifier} = ");
                }

                var @class   = function.Namespace as Class;
                var property = method?.AssociatedDeclaration as Property;
                var field    = property?.Field;
                if (field != null)
                {
                    Write($"instance->{field.OriginalName}");

                    var isGetter = property.GetMethod == method;
                    if (isGetter)
                    {
                        WriteLine(";");
                    }
                    else
                    {
                        WriteLine($" = {@params[0].Name};");
                    }
                }
                else
                {
                    if (method != null && method.IsConstructor)
                    {
                        Write($"instance = new {@class.QualifiedOriginalName}(");
                    }
                    else if (IsNativeFunctionOrStaticMethod(function))
                    {
                        Write($"::{function.QualifiedOriginalName}(");
                    }
                    else
                    {
                        if (function.IsNativeMethod())
                        {
                            Write($"instance->");
                        }

                        Write($"{base.GetMethodIdentifier(function, TypePrinterContextKind.Native)}(");
                    }

                    GenerateFunctionParams(@params);
                    WriteLine(");");
                }
            }
            PopBlock(NewLineKind.IfNotEmpty);

            GenerateFunctionParamsMarshalCleanups(@params);

            var isCtor      = method != null && method.IsConstructor;
            var needsReturn = !isVoidReturn || (this is QuickJSInvokes && !isCtor);

            if (needsReturn)
            {
                NewLine();
                GenerateFunctionCallReturnMarshal(function);
            }

            if (isCtor)
            {
                WriteLine("goto wrap;");
            }
        }