public static bool RequiresABITranslation(AST.IVariable arg) { var ctx = arg.Context; if (arg.IsArray && ctx == AST.VariableContext.Member) { return(true); } if (arg.Type.IsPrimitive) { return(false); } if (arg.Type.IsVoid) { return(false); } if (arg.Type.IsString) { return(ctx == AST.VariableContext.Member); } if (arg.Type.IsEnum) { return(false); } if (arg.Type.IsObject) { return(true); } if (arg.Type.IsDelegate) { return(true); } if (arg.Type.IsStruct) { var argStruct = arg.Type as AST.Struct; foreach (var field in argStruct.Fields) { if (RequiresABITranslation(field)) { return(true); } } return(false); } if (arg.Type.Origin == TypeOrigin.Managed) { return(false); } return(true); }
public static bool RequiresABITranslation(AST.IVariable arg) { var ctx = arg.Context; if (arg.Type == BasicTypes.IUnknown) { return(ctx == AST.VariableContext.Ref || ctx == AST.VariableContext.Out); } if (arg.IsArray) { return(true); } if (arg.Type.IsPrimitive) { return(ctx == AST.VariableContext.Ref || ctx == AST.VariableContext.Out); } if (arg.Type.IsVoid) { return(false); } if (arg.Type.IsString) { return(true); } if (arg.Type.IsEnum) { return(ctx == AST.VariableContext.Ref || ctx == AST.VariableContext.Out); } if (arg.Type.IsStruct) { if (ctx == AST.VariableContext.Ref || ctx == AST.VariableContext.Out) { return(true); } var argStruct = arg.Type as AST.Struct; foreach (var field in argStruct.Fields) { if (RequiresABITranslation(field)) { return(true); } } return(false); } if (arg.Type.Origin == TypeOrigin.Native) { return(false); } return(true); }
public static string GenerateConverter(AST.IVariable v, VariableContext ctx, bool isCallback) { var requiresTranslation = CsRender.RequiresABITranslation(v); var channels = GetChannels(v); if (v.IsArray) { return(null); } if (v.IsRef && v.Type.IsObject) { return(null); } if (!requiresTranslation) { return(NoTranslation[TranslationIndex(ctx, isCallback)]); } else { if (channels == null) { return(_Replacer.Replace(BasicTranslation[TranslationIndex(ctx, isCallback)], m => { var label = m.Groups["Label"]; var format = m.Groups["Format"]; if (!label.Success) { return m.Value; } if (label.Value == "ToABI") { string fmt = format.Success ? format.Value.Replace("$", "{0}") : "{0}"; return ToABI[v.Type.ConstructType].Replace("{0}", fmt); } else if (label.Value == "FromABI") { string fmt = format.Success ? format.Value.Replace("$", "{0}") : "{0}"; return FromABI[v.Type.ConstructType].Replace("{0}", fmt); } else { return m.Value; } })); } } return(null); }
public override string TypeName(AST.IVariable t, bool?abi = null) { if (t.IsArray) { var prefix = ""; if (abi.HasValue && abi.Value != WorkingABINamespace && (t.Type.Origin == TypeOrigin.Gluon || t.Type.Origin == TypeOrigin.Managed)) { prefix = (abi.Value ? "ABI::" : "CS::"); } return(prefix + "Array<" + GetParameterType(t.Type.ToVariable(), abi) + ">"); } return(TypeName(t.Type, abi)); }
public void WriteWrappedMemberCall(string callName, bool isStatic, AST.IVariable retType, params AST.Parameter[] args) { AST.Parameter ctxarg = null; if (!isStatic) { ctxarg = new AST.Parameter() { Type = BasicTypes.IntPtr, Name = "IPtr", Context = AST.VariableContext.In } } ; Line("Check();"); WriteWrappedCall(false, MemberCallScope(isStatic) + callName, retType, ctxarg, args); }
public override void ParameterType(AST.IVariable arg, bool?abi = null) { var t = arg.Type; var isOut = arg.IsOut; string adorn = arg.IsRef ? "ref " : isOut ? "out " : ""; string attr = MarshalParameter(arg, CurrentListSize); if (attr != null) { Code("[{0}] {1}{2}", attr, adorn, TypeName(arg)); } else { Code("{0}{1}", adorn, TypeName(arg)); } }
public static string[] GetChannels(AST.IVariable v) { if (v.IsArray) { return new string[] { "Ptr", "Count" } } ; else if (v.Type.IsDelegate) { return new string[] { "Fn", "Ctx" } } ; else { return(null); } }
public override string TypeName(AST.IVariable v, bool?abi = null) { var useabi = RequiresABITranslation(v) && (abi ?? Strata == ApiStrata.ABI); if (v.IsVoid) { return("void"); } var t = v.Type; if (useabi && v.Context == AST.VariableContext.Member) { if (v.IsArray) { return("ArrayBlob"); } else if (t.IsString) { return("IntPtr"); } else if (t.IsDelegate) { return("DelegateBlob"); } } if (v.IsArray) { if (useabi && v.Type.IsDelegate) { return("DelegateBlob[]"); } else { return(TypeName(t, abi) + "[]"); } } else { return(TypeName(t, abi)); } }
public static AST.Parameter InContext(this AST.IVariable v, AST.VariableContext newContext, string newName = null) { var p = new AST.Parameter(); p.Context = newContext; p.Name = newName ?? v.Name; p.Type = v.Type; p.IsArray = v.IsArray; var vp = v as AST.Parameter; if (vp != null) { p.HasDefaultValue = vp.HasDefaultValue; p.DefaultValue = vp.DefaultValue; } return(p); }
private void DeclParameter(AST.IVariable arg, bool declareDefaultValue = false) { bool hasDefault = false; object defaultValue = null; var p = arg as AST.Parameter; if (p != null && declareDefaultValue) { hasDefault = p.HasDefaultValue; defaultValue = p.DefaultValue; } Code("{0} {1}", VariableType(arg), arg.Name); if (hasDefault) { Code(" = {0}", Literal(defaultValue, arg.Type)); } }
public void DeclParameter(AST.IVariable arg, bool declareDefaultValue = false) { bool hasDefault = false; object defaultValue = null; var p = arg as AST.Parameter; if (p != null && declareDefaultValue) { hasDefault = p.HasDefaultValue; defaultValue = p.DefaultValue; } ParameterType(arg); Code(" " + arg.Name); if (hasDefault) { Code(" = {0}", ToLiteral(defaultValue, arg.Type)); } }
public VariableTypeNode(AST.IVariable variable, bool?abi) { Var = variable; Abi = abi; }
public TypeRefNode(AST.IVariable variable, bool?abi = null) { Variable = variable; Type = Variable.Type; Abi = abi; }
public virtual string VariableType(AST.IVariable arg, bool?abi = null) { return(InlineNode(new VariableTypeNode(arg, abi))); }
public string MarshalParameter(AST.IVariable t, int paramIndex) { if (Strata != ApiStrata.ABI) { return(null); } if (!t.IsArray) { switch (t.Type.ConstructType) { case AST.Construct.Primitive: if (t.Type == BasicTypes.Boolean) { return("MarshalAs(UnmanagedType.I1)"); } else { return(null); } case AST.Construct.String: return("MarshalAs(UnmanagedType.LPStr)"); case AST.Construct.Struct: return(null); case AST.Construct.Object: default: return(null); } } else { switch (t.Type.ConstructType) { case AST.Construct.Primitive: { if (t.Type.IsBool) { return("MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1, SizeParamIndex = " + (paramIndex + 1).ToString() + ")"); } else { return("MarshalAs(UnmanagedType.LPArray, SizeParamIndex = " + (paramIndex + 1).ToString() + ")"); } } case AST.Construct.String: return("MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr, SizeParamIndex = " + (paramIndex + 1).ToString() + ")"); case AST.Construct.Struct: return("MarshalAs(UnmanagedType.LPArray, SizeParamIndex = " + (paramIndex + 1).ToString() + ")"); case AST.Construct.Object: return("MarshalAs(UnmanagedType.LPArray, SizeParamIndex = " + (paramIndex + 1).ToString() + ")"); case AST.Construct.Delegate: return("MarshalAs(UnmanagedType.LPArray, SizeParamIndex = " + (paramIndex + 1).ToString() + ")"); default: return(null); } } }
public void WriteWrappedCall(bool doConversion, bool isCallback, string callName, AST.IVariable retType, AST.Parameter contextArg, params AST.Parameter[] args) { var argConv = VarConversion.Get(this, isCallback, args); var retConv = VarConversion.Get(retType, this, isCallback); if (isCallback) { if (doConversion) { foreach (var arg in argConv) { arg.WritePrefix(this); } } if (retConv != null && retConv.Item != null) { Code("{0} ", retConv.Item); } Code("{0}(", callName); List(() => { if (contextArg != null) { ListItem(contextArg.Name); } foreach (var arg in argConv) { arg.WriteItem(this); } }); Line(");"); if (doConversion) { foreach (var arg in argConv) { arg.WriteSuffix(this); } } if (retConv != null) { retConv.WriteSuffix(this); } Line("return HResult.S_OK;"); } else { if (retConv != null) { argConv.Add(retConv); } if (doConversion) { foreach (var arg in argConv) { arg.WritePrefix(this); } } Code("Native.Throw({0}(", callName); List(() => { if (contextArg != null) { ListItem(contextArg.Name); } foreach (var arg in argConv) { arg.WriteItem(this); } }); Line("));"); if (doConversion) { foreach (var arg in argConv) { arg.WriteSuffix(this); } } } }
public void WriteWrappedCall(bool isCallback, string callName, AST.IVariable retType, AST.Parameter contextArg, params AST.Parameter[] args) { WriteWrappedCall(true, isCallback, callName, retType, contextArg, args); }
private string GetParameterType(AST.IVariable arg, bool?abi = null) { bool useabi = abi ?? Strata == ApiStrata.ABI; var usePimpl = PimplMode && !useabi && arg.Type != BasicTypes.IUnknown; var ctx = arg.Context; if (arg.Type.IsVoid) { return("void"); } bool refAdorn = ctx == AST.VariableContext.Ref; bool constAdorn = false; var output = TypeName(arg.Type, abi); Func <string, string> adornCom = s => useabi ? s + "*" : usePimpl ? s : "com_ptr<" + s + ">"; if (arg.IsArray) { var element = GetParameterType(arg.Type.ToVariable(), abi); refAdorn = false; constAdorn = false; if (useabi) { if (ctx == AST.VariableContext.Member) { output = "ABI::Array<" + element + ">"; } else { output = element + "*"; } } else { output = "Array<" + element + ">"; } switch (ctx) { case AST.VariableContext.In: // public: Array<T> // private: Array<T> break; case AST.VariableContext.Out: case AST.VariableContext.Ref: // public: Array<T>* // private: Array<T>& refAdorn = !useabi; break; case AST.VariableContext.Return: // public: Array<T> // private: Array<T> break; case AST.VariableContext.Member: // public: Array<T> // private: Array<T> break; default: Errors.InternalFailure(); throw new Exception(); } } else { if (arg.Type.IsString) { switch (ctx) { case AST.VariableContext.In: // public: char* // private: String break; case AST.VariableContext.Out: case AST.VariableContext.Ref: // public: char** // private: String& refAdorn = !useabi; break; case AST.VariableContext.Return: // public: char* // private: String break; case AST.VariableContext.Member: // public: char* // private: String break; default: Errors.InternalFailure(); throw new Exception(); } } else if (arg.Type.IsPrimitive || arg.Type.IsEnum) { switch (ctx) { case AST.VariableContext.In: break; case AST.VariableContext.Out: case AST.VariableContext.Ref: refAdorn = !useabi; break; case AST.VariableContext.Return: break; case AST.VariableContext.Member: break; default: Errors.InternalFailure(); throw new Exception(); } } else if (arg.Type.IsStruct) { switch (ctx) { case AST.VariableContext.In: // public: ABI::MyStruct // private: const MyStruct& refAdorn = !useabi; constAdorn = !useabi; break; case AST.VariableContext.Out: case AST.VariableContext.Ref: // public: ABI::MyStruct* // private: MyStruct& refAdorn = !useabi; break; case AST.VariableContext.Return: // public: ABI::MyStruct // private: MyStruct break; case AST.VariableContext.Member: // public: ABI::MyStruct // private: MyStruct break; default: Errors.InternalFailure(); throw new Exception(); } } else if (arg.Type.IsDelegate) { switch (ctx) { case AST.VariableContext.In: // public: ABI::DelegateBlob<Sig> // private: const Delegate<Sig>& refAdorn = !useabi; constAdorn = !useabi; break; case AST.VariableContext.Out: // public: ABI::DelegateBlob<Sig>* // private: Delegate<Sig>* refAdorn = !useabi; break; case AST.VariableContext.Ref: // public: ABI::DelegateBlob<Sig>* // private: Delegate<Sig>& refAdorn = !useabi; break; case AST.VariableContext.Return: // public: ABI::DelegateBlob<Sig> // private: Delegate<Sig> break; case AST.VariableContext.Member: if (useabi) { output = "ABI::DelegateBlob"; } // public: ABI::DelegateBlob<Sig> // private: Delegate<Sig> break; default: Errors.InternalFailure(); throw new Exception(); } } else if (arg.Type.IsObject) { switch (ctx) { case AST.VariableContext.In: // public: ABI::MyType* // private: MyType* if (!usePimpl) { output += "*"; } refAdorn = constAdorn = usePimpl; break; case AST.VariableContext.Out: case AST.VariableContext.Ref: // public: ABI::MyType** // private: com_ptr<MyType>& output = adornCom(output); refAdorn = !useabi; break; case AST.VariableContext.Return: // public: ABI::MyType* // private: com_ptr<MyType> output = adornCom(output); break; case AST.VariableContext.Member: // public: ABI::MyType* // private: com_ptr<MyType> output = adornCom(output); break; default: Errors.InternalFailure(); throw new Exception(); } } else { Errors.IncompatibleType(arg.Type); throw new Exception(); } } if (refAdorn) { output += "&"; } else if (ctx == AST.VariableContext.Out || ctx == AST.VariableContext.Ref) { output += "*"; } if (constAdorn) { output = "const " + output; } return(output); }
public override void ParameterType(AST.IVariable arg, bool?abi = null) { Code(GetParameterType(arg, abi)); }
public abstract string TypeName(AST.IVariable v, bool?abi = null);
public abstract void ParameterType(AST.IVariable arg, bool?abi = null);
public string TypeRef(AST.IVariable type, bool?abi = null) { return(InlineNode(new TypeRefNode(type, abi))); }
public static void Validate(AST.IVariable x) { }
public string VariableType(AST.IVariable arg, AST.VariableContext ctx, bool?abi = null) { return(VariableType(arg.InContext(ctx), abi)); }