private static void GenerateMethod(Context context, OutputBuffer output, MethodDeclarationSyntax method, bool asStatic) { if (method.HasDocumentation()) { output.AppendLine(method.GetDocumentation(output.GetIndent())); } output.Append($"public "); if (asStatic) { output.Append("static "); } output.Append($"{method.ReturnType} {method.Identifier}"); if (method.TypeParameterList != null) { output.Append(method.TypeParameterList.ToString()); } output.AppendLine(method.ParameterList.ToString()); if (method.ConstraintClauses.Any()) { output.AppendLine("\t" + method.ConstraintClauses.ToString()); } output.AppendLine("{"); if (method.ReturnType.ToString() != "void") { output.Append($"\tvar result = _js.Invoke(nameof({method.Identifier})"); foreach (var parameter in method.ParameterList.Parameters) { output.Append($", {parameter.Identifier}"); } output.AppendLine(");"); output.AppendLine(); output.AppendLine("\tif (result == null)"); output.AppendLine("\t\treturn null;"); output.AppendLine(); var returnType = method.ReturnType.ToString(); if (returnType.EndsWith("?")) { returnType = returnType.TrimEnd('?'); } output.AppendLine($"\treturn JSObjectWrapperFactory.Create<{returnType}>(result);"); } else { output.Append($"\t_js.Invoke(nameof({method.Identifier})"); foreach (var parameter in method.ParameterList.Parameters) { output.Append($", {parameter.Identifier}"); } output.AppendLine(");"); } output.AppendLine("}"); output.AppendLine(); }
private static void GenerateProperty(Context context, OutputBuffer output, PropertyDeclarationSyntax property, bool asStatic) { if (property.HasDocumentation()) { output.AppendLine(property.GetDocumentation(output.GetIndent())); } if (property.AccessorList == null) { throw new InvalidOperationException(CreateErrorMessage(property, $"AccessorList was expected.")); } string?wrappedType = null; foreach (var attribute in property.AttributeLists.Select(x => x.ToString().Trim('[', ']'))) { if (attribute.StartsWith("Wrap(") && attribute.EndsWith(")")) { wrappedType = attribute.Substring("Wrap(".Length, attribute.Length - "Wrap(".Length - ")".Length); } } bool canRead = property.AccessorList.Accessors.Any(x => x.Keyword.ToString() == "get"); bool canWrite = property.AccessorList.Accessors.Any(x => x.Keyword.ToString() == "set"); if (canRead && !canWrite) // readonly { output.Append($"private "); if (asStatic) { output.Append("static "); } output.AppendLine($"{property.Type}? _{property.Identifier};"); output.AppendLine(); } output.Append($"public "); if (asStatic) { output.Append("static "); } output.AppendLine($"{property.Type} {property.Identifier}"); output.AppendLine("{"); if (canRead && canWrite) { if (wrappedType == null) { output.AppendLine($"\tget => _js.GetObjectProperty<{property.Type}>(nameof({property.Identifier}));"); output.AppendLine($"\tset => _js.SetObjectProperty(nameof({property.Identifier}), value);"); } else { throw new NotImplementedException("Wrap not implemented for read / write properties."); } } else if (canRead && !canWrite) // readonly { output.Append($"\tget => _{property.Identifier} ?? (_{property.Identifier} = "); if (wrappedType == null) { output.Append($"_js.GetObjectProperty<{property.Type}>(nameof({property.Identifier}))"); } else { output.Append($"new {property.Type}(_js.GetObjectProperty<JSObject>(nameof({property.Identifier})))"); } output.AppendLine(");"); } output.AppendLine("}"); output.AppendLine(); }
private static void GenerateWrapper(Context context, OutputBuffer output, ClassDeclarationSyntax @class, List <string> implements) { context.Wrappers.Add(context.CurrentNamespace + "." + @class.Identifier.ToString()); output.Append($"public partial class {@class.Identifier}"); if (@class.BaseList != null || implements.Any()) { output.Append(" : "); if (@class.BaseList != null) { output.Append(string.Join(", ", @class.BaseList.Types.Select(x => x.ToString()))); } if (implements.Any()) { // If we already output the BaseList we need to add a , if (@class.BaseList != null) { output.Append(", "); } output.Append(string.Join(", ", implements)); } } output.AppendLine(); output.AppendLine("{"); output.Append("\tinternal static "); if (@class.BaseList != null) { output.Append("new "); } output.AppendLine($"void Initialize() {{ JSObjectWrapperFactory.RegisterFactory(typeof({@class.Identifier}), x => new {@class.Identifier}(x)); }}"); output.AppendLine(); if (@class.BaseList == null) { output.AppendLine("\tprotected readonly JSObject _js;"); output.AppendLine(); output.AppendLine($"\tinternal {@class.Identifier}(object obj)"); output.AppendLine("\t{"); output.AppendLine("\t\tif (!(obj is JSObject))"); output.AppendLine("\t\t\tthrow new WasmWranglerException($\"Expected {nameof(obj)} to be an instance of JSObject.\");"); output.AppendLine(); output.AppendLine("\t\t_js = (JSObject)obj;"); output.AppendLine("\t}"); } else { output.AppendLine($"\tinternal {@class.Identifier}(object obj) : base(obj) {{ }}"); } output.AppendLine(); output.IncreaseIndent(); foreach (var member in @class.Members) { GenerateInterfaceMember(context, output, member, false); } output.DecreaseIndent(); output.AppendLine("}"); output.AppendLine(); }