Exemple #1
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);*/
        }
Exemple #2
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);
        }
Exemple #3
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();
        }
        // 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);
        }
Exemple #5
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);
        }
Exemple #6
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);
            }
        }
Exemple #7
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;");
            }
        }
Exemple #8
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);
        }