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);*/ }
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); }
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); }
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); }
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); } }
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;"); } }
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); }