1using System.CodeDom.Compiler;
2using System.Collections.Generic;
7using Microsoft.CodeAnalysis;
11public class BadInteropObjectSourceGenerator
13 private readonly SourceProductionContext m_Context;
15 public BadInteropObjectSourceGenerator(SourceProductionContext context)
20 private string GenerateConstructor(
ObjectModel model)
22 StringBuilder sb =
new StringBuilder();
23 sb.Append($
"new {model.ClassName}Wrapper(new {model.ClassName}(");
25 bool hasCtx = method.
Parameters.Any(x => x.IsContext);
26 List<string> args =
new List<string>();
28 for (
int i = 0; i < method.Parameters.Length; i++)
38 int index = i - (hasCtx ? 1 : 0);
39 string suppressNullable = parameter.IsNullable ?
"" :
"!";
45 args.Add($
"new BadArray(args.ToList()).Unwrap<{parameter.CsharpType}>()");
49 args.Add($
"new BadArray(args.Skip({index}).ToList()).Unwrap<{parameter.CsharpType}>()");
54 args.Add($
"GetParameter<{parameter.CsharpType}>(args, {index}, {parameter.DefaultValue ?? $"default({parameter.
CsharpType})
"}){suppressNullable}"
59 args.Add($
"GetParameter<{parameter.CsharpType}>(args, {index}){suppressNullable}");
64 sb.Append(
string.Join(
", ", args));
69 private string GenerateInvocation(
MethodModel method,
string className)
71 StringBuilder sb =
new StringBuilder();
79 sb.Append(
"BadObject.Wrap(");
82 sb.Append($
"(({className})Value).{method.MethodName}(");
83 bool hasCtx = method.
Parameters.Any(x => x.IsContext);
84 List<string> args =
new List<string>();
86 for (
int i = 0; i < method.
Parameters.Length; i++)
96 int index = i - (hasCtx ? 1 : 0);
97 string suppressNullable = parameter.IsNullable ?
"" :
"!";
103 args.Add($
"new BadArray(args.ToList()).Unwrap<{parameter.CsharpType}>()");
107 args.Add($
"new BadArray(args.Skip({index}).ToList()).Unwrap<{parameter.CsharpType}>()");
112 args.Add($
"GetParameter<{parameter.CsharpType}>(args, {index}, {parameter.DefaultValue ?? $"default({parameter.
CsharpType})
"}){suppressNullable}"
117 args.Add($
"GetParameter<{parameter.CsharpType}>(args, {index}){suppressNullable}");
122 sb.Append(
string.Join(
", ", args));
127 sb.Append(
"; return BadObject.Null; }");
131 sb.Append($
", {method.AllowNativeReturn.ToString().ToLower()})");
134 return sb.ToString();
140 $
"new BadFunctionParameter(\"{model.Name}\", {model.HasDefaultValue.ToString().ToLower()}, {(!model.IsNullable).ToString().ToLower()}, {model.IsRestArgs.ToString().ToLower()}, null, BadNativeClassBuilder.GetNative(\"{model.Type}\"))";
143 private void GeneratePropertySource(IndentedTextWriter sb,
PropertyModel model,
string className)
147 sb.WriteLine($
"Properties[\"{model.ApiParameterName}\"] = BadObjectReference.Make(\"{model.ApiParameterName}\", p => Wrap((({className})Value).{model.ParameterName}));");
151 sb.WriteLine($
"Properties[\"{model.ApiParameterName}\"] = ");
153 sb.WriteLine($
"BadObjectReference.Make(\"{model.ApiParameterName}\",");
155 sb.WriteLine($
"p => Wrap((({className})Value).{model.ParameterName}),");
156 sb.WriteLine($
"(v, p, i) => (({className})Value).{model.ParameterName} = v.Unwrap<{model.ParameterType}>()");
162 private void GenerateMethodSource(IndentedTextWriter sb,
MethodModel method,
string className)
164 sb.WriteLine($
"Properties[\"{method.ApiMethodName}\"] = ");
166 sb.WriteLine($
"BadObjectReference.Make(\"{method.ApiMethodName}\",");
168 sb.WriteLine($
"p => new BadInteropFunction(");
170 sb.WriteLine($
"\"{method.ApiMethodName}\",");
171 sb.WriteLine($
"(ctx, args) => {GenerateInvocation(method, className)},");
172 sb.WriteLine(
"false,");
173 sb.Write($
"BadNativeClassBuilder.GetNative(\"{method.ReturnType}\")");
184 for (
int i = 0; i < method.
Parameters.Length; i++)
193 sb.WriteLine(GenerateParameterSource(parameter) + (i == method.
Parameters.Length - 1 ?
"" :
","));
197 sb.WriteLine(
").SetMetaData(");
199 sb.WriteLine(
"new BadMetaData(");
201 sb.WriteLine($
"\"{method.Description}\",");
202 sb.WriteLine($
"\"{method.ReturnDescription}\",");
203 sb.WriteLine($
"\"{method.ReturnType}\",");
204 sb.WriteLine(
"new Dictionary<string, BadParameterMetaData>");
217 sb.WriteLine($
"{{\"{parameter.Name}\", new BadParameterMetaData(\"{parameter.Type}\", \"{parameter.Description}\\nDefault Value: {parameter.DefaultValue!.Replace("\
"",
"\\\"")}\
")}},"
222 sb.WriteLine($
"{{\"{parameter.Name}\", new BadParameterMetaData(\"{parameter.Type}\", \"{parameter.Description}\")}},"
238 public string GenerateModelSource(SourceProductionContext context,
ObjectModel apiModel,
bool isError)
240 IndentedTextWriter tw =
new IndentedTextWriter(
new StringWriter());
241 tw.WriteLine(
"#nullable enable");
242 tw.WriteLine(
"using System.Collections.Generic;");
243 tw.WriteLine(
"using BadScript2.Parser;");
244 tw.WriteLine(
"using BadScript2.Runtime.Interop.Reflection;");
245 tw.WriteLine(
"using BadScript2.Runtime.Objects;");
246 tw.WriteLine(
"using BadScript2.Runtime.Interop.Functions;");
247 tw.WriteLine(
"using BadScript2.Runtime.Objects.Functions;");
248 tw.WriteLine(
"using BadScript2.Runtime.Objects.Types;");
249 tw.WriteLine(
"using BadScript2.Runtime.Interop;");
251 tw.WriteLine($
"namespace {apiModel.Namespace};");
252 tw.WriteLine($
"public partial class {apiModel.ClassName}Wrapper : {(string.IsNullOrEmpty(apiModel.BaseClassName) ? $"BadScript2.
Runtime.
Objects.
Native.
BadNative<{apiModel.ClassName}>
": apiModel.BaseClassName)}");
256 tw.WriteLine(
"private static BadClassPrototype? s_Prototype;");
257 tw.WriteLine(
"private static BadClassPrototype CreatePrototype()");
260 tw.WriteLine(
"T? GetParameter<T>(BadObject[] args, int i, T? defaultValue = default(T)) => args.Length>i?args[i].Unwrap<T>():defaultValue;");
261 tw.WriteLine($
"return new BadNativeClassPrototype<{apiModel.ClassName}Wrapper>(\"{apiModel.ObjectName}\", (ctx, args) => {GenerateConstructor(apiModel)}, {(string.IsNullOrEmpty(apiModel.BaseClassName) ? "null" : $"{apiModel.
BaseClassName}.Prototype
")});");
264 tw.WriteLine(
"public static BadClassPrototype Prototype => s_Prototype ??= CreatePrototype();");
268 tw.WriteLine(
"protected readonly Dictionary<string, BadObjectReference> Properties = new Dictionary<string, BadObjectReference>();");
271 tw.WriteLine($
"public {apiModel.ClassName}Wrapper({apiModel.ClassName} value) : base(value)");
276 tw.WriteLine(
"T? GetParameter<T>(BadObject[] args, int i, T? defaultValue = default(T)) => args.Length>i?args[i].Unwrap<T>():defaultValue;"
281 GeneratePropertySource(tw, method, apiModel.
ClassName);
285 GenerateMethodSource(tw, method, apiModel.
ClassName);
292 tw.WriteLine(
"public override bool HasProperty(string propName, BadScript2.Runtime.BadScope? caller = null)");
295 tw.WriteLine(
"return Properties.ContainsKey(propName) || base.HasProperty(propName, caller);");
299 tw.WriteLine(
"public override BadObjectReference GetProperty(string propName, BadScript2.Runtime.BadScope? caller = null)");
302 tw.WriteLine(
"if(Properties.TryGetValue(propName, out BadObjectReference? ret))");
305 tw.WriteLine(
"return ret;");
308 tw.WriteLine(
"return base.GetProperty(propName, caller);");
313 tw.WriteLine(
"public override BadClassPrototype GetPrototype() => Prototype;");
314 tw.WriteLine($
"public static implicit operator {apiModel.ClassName}Wrapper({apiModel.ClassName} obj) => new {apiModel.ClassName}Wrapper(obj);");
315 tw.WriteLine($
"public static implicit operator {apiModel.ClassName}({apiModel.ClassName}Wrapper obj) => ({apiModel.ClassName})obj.Value;");
322 string str = tw.InnerWriter.ToString();
Implements a Native Type.
Contains the Native Runtime Objects.
Contains the Runtime Objects.
Contains the Runtime Implementation.
The main namespace for the BadScript2 Language.
readonly bool IsVoidReturn
readonly ParameterModel[] Parameters
readonly MethodModel[] Methods
readonly PropertyModel[] Properties
readonly string ClassName
readonly? string BaseClassName
readonly MethodModel Constructor
readonly bool HasDefaultValue
readonly? string CsharpType