public static void BuildDictionary(string sourcePath) { BindingClass activeClass = null; foreach (var file in AllSourceFiles(sourcePath)) { string[] lines = System.IO.File.ReadAllLines(file); for (int i = 0; i < lines.Length; i++) { string line = lines[i].Trim(); if (line.StartsWith("class_")) { string name = (line.Split(new char[] { '"' }))[1]; if (name.StartsWith("__")) { continue; } var activeJavascriptClass = new JavascriptClass(name); int baseIndex = line.IndexOf("base<BND_"); if (baseIndex > 0) { int baseEnd = line.IndexOf(">", baseIndex); baseIndex += "base<BND_".Length; string baseClass = line.Substring(baseIndex, baseEnd - baseIndex); activeJavascriptClass.BaseClass = baseClass; } AllJavascriptClasses.Add(name.ToLowerInvariant(), activeJavascriptClass); activeClass = activeJavascriptClass; continue; } if (line.StartsWith("py::class_")) { string name = (line.Split(new char[] { '"' }))[1]; if (name.StartsWith("__")) { continue; } var activePythonClass = new PythonClass(name); int baseIndex = line.IndexOf(","); if (baseIndex > 0) { baseIndex = line.IndexOf("BND_", baseIndex); } if (baseIndex > 0) { int baseEnd = line.IndexOf(">", baseIndex); baseIndex += "BND_".Length; if (baseEnd > baseIndex) { string baseClass = line.Substring(baseIndex, baseEnd - baseIndex); activePythonClass.BaseClass = baseClass; } } AllPythonClasses.Add(name.ToLowerInvariant(), activePythonClass); activeClass = activePythonClass; continue; } if (line.StartsWith("enum_")) { string name = (line.Split(new char[] { '"' }))[1]; if (name.StartsWith("__")) { continue; } var jsenum = new JavascriptEnum(name); AllJavascriptEnums.Add(name.ToLowerInvariant(), jsenum); activeClass = jsenum; continue; } if (activeClass != null) { if (line.StartsWith(".constructor")) { int startIndex = line.IndexOf("<"); int endIndex = line.IndexOf(">", startIndex); string types = line.Substring(startIndex + 1, endIndex - startIndex - 1); activeClass.AddConstructor(types); continue; } if (line.IndexOf("py::init<") > 0) { int startIndex = line.IndexOf("py::init<") + "py::init<".Length; int endIndex = line.IndexOf(">", startIndex); string types = line.Substring(startIndex, endIndex - startIndex); activeClass.AddConstructor(types); continue; } if (line.StartsWith(".property") || line.StartsWith(".def_property")) { string propName = (line.Split(new char[] { '"' }))[1]; activeClass.AddProperty(propName); continue; } if (line.Contains("py::self")) { continue; } if (line.StartsWith(".function") || line.StartsWith(".def(")) { string funcName = (line.Split(new char[] { '"' }))[1]; activeClass.AddMethod(funcName, false, GetArgList(line)); } if (line.StartsWith(".class_function") || line.StartsWith(".def_static")) { string funcName = (line.Split(new char[] { '"' }))[1]; activeClass.AddMethod(funcName, true, GetArgList(line)); } if (line.StartsWith(";")) { activeClass = null; } if (activeClass is JavascriptEnum && line.StartsWith(".value")) { string enumValue = (line.Split(new char[] { '"' }))[1]; (activeClass as JavascriptEnum).Elements.Add(enumValue); } } } Console.WriteLine($"parse: {file}"); } }
public static void GenerateTypescriptDefinition(string directory) { if (!System.IO.Directory.Exists(directory)) { System.IO.Directory.CreateDirectory(directory); } var js = new StringBuilder(); js.AppendLine("declare module 'rhino3dm' {"); var keys = BindingClass.AllJavascriptEnums.Keys.ToList(); keys.Sort(); foreach (var key in keys) { js.AppendLine(); JavascriptEnum jsenum = BindingClass.AllJavascriptEnums[key]; js.AppendLine($"\tenum {jsenum.Name} {{"); for (int i = 0; i < jsenum.Elements.Count; i++) { if (i < (jsenum.Elements.Count - 1)) { js.AppendLine($"\t\t{jsenum.Elements[i]},"); } else { js.AppendLine($"\t\t{jsenum.Elements[i]}"); } } js.AppendLine("\t}"); } keys = BindingClass.AllJavascriptClasses.Keys.ToList(); keys.Sort(); foreach (var key in keys) { js.AppendLine(); var jsclass = GetJS(key); var rhcommon = RhinoCommonClass.Get(key); js.Append($"\tclass {jsclass.ClassName}"); if (!string.IsNullOrWhiteSpace(jsclass.BaseClass)) { js.Append($" extends {jsclass.BaseClass}"); } js.AppendLine(" {"); foreach (var prop in jsclass.Properties) { PropertyDeclarationSyntax propDecl = null; DocumentationCommentTriviaSyntax doccomment = null; for (int i = 0; i < rhcommon.Properties.Count; i++) { if (prop.Equals(rhcommon.Properties[i].Item1.Identifier.ToString(), StringComparison.InvariantCultureIgnoreCase)) { propDecl = rhcommon.Properties[i].Item1; doccomment = rhcommon.Properties[i].Item2; break; } } js.AppendLine("\t\t/**"); if (doccomment != null) { string[] comments = DocCommentToTypeScript(doccomment, propDecl); foreach (var comment in comments) { if (!string.IsNullOrWhiteSpace(comment)) { js.AppendLine($"\t\t * {comment}"); } } } string proptype = "any"; if (propDecl != null) { proptype = ToTypeScriptType(propDecl.Type.ToString()); } js.AppendLine("\t\t */"); js.AppendLine($"\t\t{prop}: {proptype};"); } foreach (var(isStatic, method, args) in jsclass.Methods) { MethodDeclarationSyntax methodDecl = null; DocumentationCommentTriviaSyntax doccomment = null; for (int i = 0; i < rhcommon.Methods.Count; i++) { if (method.Equals(rhcommon.Methods[i].Item1.Identifier.ToString(), StringComparison.InvariantCultureIgnoreCase)) { methodDecl = rhcommon.Methods[i].Item1; doccomment = rhcommon.Methods[i].Item2; break; } } List <string> paramNames = new List <string>(); List <string> paramTypes = new List <string>(); if (doccomment == null) { js.AppendLine("\t\t/** ... */"); } else { js.AppendLine("\t\t/**"); string s = DocCommentToTypeScript(doccomment, methodDecl, methodDecl.ParameterList, out paramNames, out paramTypes); string[] lines = s.Split(new char[] { '\n' }); for (int i = 0; i < lines.Length; i++) { string line = lines[i].Trim(); if (string.IsNullOrWhiteSpace(line)) { continue; } if (line.StartsWith("*")) { line = " " + line; } js.AppendLine($"\t\t{line}"); } js.AppendLine("\t\t */"); } string parameters = ""; for (int i = 0; i < paramNames.Count; i++) { parameters += $"{paramNames[i]}:{paramTypes[i]},"; } if (!string.IsNullOrEmpty(parameters)) { parameters = parameters.Substring(0, parameters.Length - 1); } string returnType = "void"; if (methodDecl != null) { returnType = ToTypeScriptType(methodDecl.ReturnType.ToString()); } if (isStatic) { js.AppendLine($"\t\tstatic {method}({parameters}): {returnType};"); } else { js.AppendLine($"\t\t{method}({parameters}): {returnType};"); } } js.AppendLine("\t}"); } js.AppendLine("}"); string path = System.IO.Path.Combine(directory, "rhino3dm.d.ts"); System.IO.File.WriteAllText(path, js.ToString()); }