string WriteMethod(ClassBuilder cb, MethodDeclarationSyntax method, DocumentationCommentTriviaSyntax comment, bool useRemotes) { int remoteCount = 0; StringBuilder sb = new StringBuilder(); if (comment != null) { string formattedComment = comment.ToFullString().Replace(T1, T2); sb.Append(T2 + formattedComment); } bool useAsReturnType; if (method.IsNonConst(out useAsReturnType) && useAsReturnType) { sb.Append($"{T2}public static {cb.ClassName} {method.Identifier}("); } else { sb.Append($"{T2}public static {method.ReturnType} {method.Identifier}("); } int paramCount = 0; if (!method.IsStatic()) { if (useRemotes && IsRemoteCandidate(cb.ClassName)) { sb.Append($"Remote<{cb.ClassName}> {cb.ClassName.ToLower()}"); remoteCount++; } else { sb.Append($"this {cb.ClassName} {cb.ClassName.ToLower()}"); } paramCount++; } if (method.IsNonConst(out useAsReturnType) && !useAsReturnType) { if (paramCount > 0) { sb.Append(", "); } sb.Append($"out {cb.ClassName} updatedInstance"); paramCount++; } for (int i = 0; i < method.ParameterList.Parameters.Count; i++) { if (paramCount > 0) { sb.Append(", "); } var parameter = method.ParameterList.Parameters[i]; if (useRemotes && IsRemoteCandidate(parameter.Type.ToString())) { sb.Append($"Remote<{parameter.Type}> {parameter.Identifier}"); remoteCount++; } else { sb.Append($"{parameter.ToFullString().Trim()}"); } paramCount++; } sb.AppendLine(")"); sb.AppendLine($"{T2}{{"); List <int> outParamIndices = new List <int>(); for (int i = 0; i < method.ParameterList.Parameters.Count; i++) { foreach (var modifier in method.ParameterList.Parameters[i].Modifiers) { if (modifier.Text == "out") { outParamIndices.Add(i); } } } if (outParamIndices.Count == 0) { if (method.IsNonConst(out useAsReturnType)) { if (useAsReturnType) { sb.Append($"{T3}return ComputeServer.Post<{cb.ClassName}>(ApiAddress(), "); } else { sb.Append($"{T3}return ComputeServer.Post<{method.ReturnType}, {cb.ClassName}>(ApiAddress(), out updatedInstance, "); } } else { sb.Append($"{T3}return ComputeServer.Post<{method.ReturnType}>(ApiAddress(), "); } } else { var parameter0 = method.ParameterList.Parameters[outParamIndices[0]]; if (outParamIndices.Count == 1) { sb.Append($"{T3}return ComputeServer.Post<{method.ReturnType}, {parameter0.Type}>(ApiAddress(), out {parameter0.Identifier}, "); } else { var parameter1 = method.ParameterList.Parameters[outParamIndices[1]]; sb.Append($"{T3}return ComputeServer.Post<{method.ReturnType}, {parameter0.Type}, {parameter1.Type}>(ApiAddress(), out {parameter0.Identifier}, out {parameter1.Identifier}, "); } } if (!method.IsStatic()) { sb.Append($"{cb.ClassName.ToLower()}"); if (method.ParameterList.Parameters.Count > 0) { sb.Append(", "); } } var orderedParams = new List <ParameterSyntax>(); foreach (var p in method.ParameterList.Parameters) { if (p.Modifiers.Count == 0) { orderedParams.Add(p); } } for (int i = 0; i < orderedParams.Count; i++) { if (i > 0) { sb.Append(", "); } var p = orderedParams[i]; sb.Append(p.Modifiers.Count > 0 ? $"{p.Modifiers} {p.Identifier}" : $"{p.Identifier}"); } sb.AppendLine(");"); sb.AppendLine($"{T2}}}"); if (remoteCount == 0 && useRemotes) { return(""); } return(sb.ToString()); }
protected abstract string ToComputeClient(ClassBuilder cb);
protected override string ToComputeClient(ClassBuilder cb) { StringBuilder sb = new StringBuilder(); sb.AppendLine(); int iMethod = 0; foreach (var(method, comment) in cb.Methods) { string methodName = GetMethodName(method, cb); if (string.IsNullOrWhiteSpace(methodName)) { continue; } sb.Append($"def {methodName}("); List <string> parameters = GetParameterNames(method, cb, out int outParamCount); for (int i = 0; i < parameters.Count; i++) { sb.Append(parameters[i] + ", "); } sb.AppendLine("multiple=False):"); StringBuilder summary; List <ParameterInfo> parameterList; ReturnInfo returnInfo; sb.Append(DocCommentToPythonDoc(comment, method, 1, out summary, out parameterList, out returnInfo)); sb.AppendLine($"{T1}url = \"{cb.EndPoint(method)}\""); sb.AppendLine($"{T1}if multiple: url += \"?multiple=true\""); var paramList = new StringBuilder(); for (int i = 0; i < parameters.Count; i++) { paramList.Append(parameters[i]); if (i < (parameters.Count - 1)) { paramList.Append(", "); } } sb.AppendLine($"{T1}args = [{paramList.ToString()}]"); if (parameters.Count == 1) { sb.AppendLine($"{T1}if multiple: args = [[item] for item in {parameters[0]}]"); } else { sb.AppendLine($"{T1}if multiple: args = zip({paramList.ToString()})"); } string endpoint = method.Identifier.ToString(); sb.AppendLine($"{T1}response = Util.ComputeFetch(url, args)"); if (outParamCount == 0) { bool returnIsArray = returnInfo.Type.EndsWith("[]"); string returnClassName = returnIsArray ? returnInfo.Type.Substring(0, returnInfo.Type.Length - 2) : returnInfo.Type; var returnCB = ClassBuilder.Get(returnClassName); if (returnCB != null) { var baseClass = returnCB; while (true) { var b = ClassBuilder.Get(baseClass.BaseClassName); if (b != null) { baseClass = b; continue; } break; } if (baseClass.ClassName == "CommonObject" || baseClass.ClassName == "GeometryBase") { sb.AppendLine($"{T1}response = Util.DecodeToCommonObject(response)"); } if (baseClass.ClassName == "Point3d" || baseClass.ClassName == "Vector3d" || baseClass.ClassName == "Line") { sb.AppendLine($"{T1}response = Util.DecodeTo{baseClass.ClassName}(response)"); } } } sb.AppendLine($"{T1}return response"); sb.AppendLine(); iMethod++; if (iMethod < cb.Methods.Count) { sb.AppendLine(); } } return(sb.ToString()); }
public static List <string> GetParameterNames(MethodDeclarationSyntax method, ClassBuilder cb, out int outParamCount) { outParamCount = 0; List <string> parameters = new List <string>(); if (!method.IsStatic()) { parameters.Add("this" + cb.ClassName); } for (int i = 0; i < method.ParameterList.Parameters.Count; i++) { bool isOutParameter = false; foreach (var modifier in method.ParameterList.Parameters[i].Modifiers) { if (modifier.Text == "out") { outParamCount++; isOutParameter = true; } } if (!isOutParameter) { parameters.Add(method.ParameterList.Parameters[i].Identifier.ToString()); } } return(parameters); }
protected override string ToComputeClient(ClassBuilder cb) { var sb = new StringBuilder(); sb.AppendLine(); sb.AppendLine($"{T1}public static class {cb.ClassName}Compute"); sb.AppendLine($"{T1}{{"); sb.AppendLine($"{T2}static string ApiAddress([CallerMemberName] string caller = null)"); sb.AppendLine($"{T2}{{"); sb.AppendLine($"{T3}return ComputeServer.ApiAddress(typeof({cb.ClassName}), caller);"); sb.AppendLine($"{T2}}}"); foreach (var(method, comment) in cb.Methods) { if (comment != null) { string formattedComment = comment.ToFullString().Replace(T1, T2); sb.Append(T2 + formattedComment); } bool useAsReturnType; if (method.IsNonConst(out useAsReturnType) && useAsReturnType) { sb.Append($"{T2}public static {cb.ClassName} {method.Identifier}("); } else { sb.Append($"{T2}public static {method.ReturnType} {method.Identifier}("); } int paramCount = 0; if (!method.IsStatic()) { sb.Append($"this {cb.ClassName} {cb.ClassName.ToLower()}"); paramCount++; } if (method.IsNonConst(out useAsReturnType) && !useAsReturnType) { if (paramCount > 0) { sb.Append(", "); } sb.Append($"out {cb.ClassName} updatedInstance"); paramCount++; } for (int i = 0; i < method.ParameterList.Parameters.Count; i++) { if (paramCount > 0) { sb.Append(", "); } sb.Append($"{method.ParameterList.Parameters[i].ToFullString().Trim()}"); paramCount++; } sb.AppendLine(")"); sb.AppendLine($"{T2}{{"); List <int> outParamIndices = new List <int>(); for (int i = 0; i < method.ParameterList.Parameters.Count; i++) { foreach (var modifier in method.ParameterList.Parameters[i].Modifiers) { if (modifier.Text == "out") { outParamIndices.Add(i); } } } if (outParamIndices.Count == 0) { if (method.IsNonConst(out useAsReturnType)) { if (useAsReturnType) { sb.Append($"{T3}return ComputeServer.Post<{cb.ClassName}>(ApiAddress(), "); } else { sb.Append($"{T3}return ComputeServer.Post<{method.ReturnType}, {cb.ClassName}>(ApiAddress(), out updatedInstance, "); } } else { sb.Append($"{T3}return ComputeServer.Post<{method.ReturnType}>(ApiAddress(), "); } } else { var parameter0 = method.ParameterList.Parameters[outParamIndices[0]]; if (outParamIndices.Count == 1) { sb.Append($"{T3}return ComputeServer.Post<{method.ReturnType}, {parameter0.Type}>(ApiAddress(), out {parameter0.Identifier}, "); } else { var parameter1 = method.ParameterList.Parameters[outParamIndices[1]]; sb.Append($"{T3}return ComputeServer.Post<{method.ReturnType}, {parameter0.Type}, {parameter1.Type}>(ApiAddress(), out {parameter0.Identifier}, out {parameter1.Identifier}, "); } } if (!method.IsStatic()) { sb.Append($"{cb.ClassName.ToLower()}"); if (method.ParameterList.Parameters.Count > 0) { sb.Append(", "); } } var orderedParams = new List <ParameterSyntax>(); foreach (var p in method.ParameterList.Parameters) { if (p.Modifiers.Count == 0) { orderedParams.Add(p); } } for (int i = 0; i < orderedParams.Count; i++) { if (i > 0) { sb.Append(", "); } var p = orderedParams[i]; sb.Append(p.Modifiers.Count > 0 ? $"{p.Modifiers} {p.Identifier}" : $"{p.Identifier}"); } sb.AppendLine(");"); sb.AppendLine($"{T2}}}"); } sb.AppendLine($"{T1}}}"); return(sb.ToString()); }
static void Main(string[] args) { const string rhinocommonPath = @"C:\dev\github\mcneel\rhino\src4\DotNetSDK\rhinocommon\dotnet"; Console.WriteLine("[BEGIN PARSE]"); Console.ForegroundColor = ConsoleColor.DarkGreen; ClassBuilder.BuildClassDictionary(rhinocommonPath); Console.ResetColor(); Console.WriteLine("[END PARSE]"); string[] filter = new string[] { ".AreaMassProperties", ".BezierCurve", ".Brep", ".BrepFace", ".Curve", ".Extrusion", ".GeometryBase", ".Intersection", ".Mesh", ".NurbsCurve", ".NurbsSurface", ".SubD", ".Surface", ".VolumeMassProperties" }; var di = SharedRepoDirectory(); Console.ForegroundColor = ConsoleColor.Blue; var classes = ClassBuilder.FilteredList(ClassBuilder.AllClasses, filter); // Javascript Console.WriteLine("Writing javascript client"); var js = new JavascriptClient(); string javascriptPath = "compute.rhino3d.js"; if (di != null) { string dir = Path.Combine(di.FullName, "computeclient_js"); if (Directory.Exists(dir)) { javascriptPath = Path.Combine(dir, javascriptPath); } } js.Write(ClassBuilder.AllClasses, javascriptPath, filter); DirectoryInfo jsdocDirectory = new DirectoryInfo("docs\\javascript"); if (di != null) { string dir = Path.Combine(di.FullName, "computeclient_js", "docs"); if (Directory.Exists(dir)) { jsdocDirectory = new DirectoryInfo(dir); } } Console.WriteLine("Writing javascript docs"); RstClient.WriteJavascriptDocs(classes, jsdocDirectory); // Python Console.WriteLine("Writing python client"); string basePythonDirectory = ""; if (di != null) { string dir = Path.Combine(di.FullName, "computeclient_py"); if (Directory.Exists(dir)) { basePythonDirectory = dir; } } var py = new PythonClient(); py.Write(ClassBuilder.AllClasses, basePythonDirectory, filter); Console.WriteLine("Writing python docs"); RstClient.WritePythonDocs(basePythonDirectory, classes); // C# Console.WriteLine("Writing C# client"); var cs = new DotNetClient(); cs.Write(ClassBuilder.AllClasses, "RhinoCompute.cs", filter); Console.ResetColor(); }
protected override string ToComputeClient(ClassBuilder cb) { StringBuilder sb = new StringBuilder(); sb.AppendLine(); int iMethod = 0; int overloadIndex = 0; string prevMethodName = ""; foreach (var(method, comment) in cb.Methods) { string methodName = method.Identifier.ToString(); if (methodName.Equals(prevMethodName)) { overloadIndex++; methodName = $"{methodName}{overloadIndex}"; } else { overloadIndex = 0; prevMethodName = methodName; } sb.Append($"def {methodName}("); List <string> parameters = new List <string>(); if (!method.IsStatic()) { parameters.Add("this" + cb.ClassName); } for (int i = 0; i < method.ParameterList.Parameters.Count; i++) { parameters.Add(method.ParameterList.Parameters[i].Identifier.ToString()); } for (int i = 0; i < parameters.Count; i++) { sb.Append(parameters[i]); if (i < (parameters.Count - 1)) { sb.Append(", "); } } sb.AppendLine("):"); sb.Append($"{T1}args = ["); for (int i = 0; i < parameters.Count; i++) { sb.Append(parameters[i]); if (i < (parameters.Count - 1)) { sb.Append(", "); } } sb.AppendLine("]"); string endpoint = method.Identifier.ToString(); sb.AppendLine($"{T1}response = Util.ComputeFetch(\"{cb.EndPoint(method)}\", args)"); sb.AppendLine($"{T1}return response"); sb.AppendLine(); iMethod++; if (iMethod < cb.Methods.Count) { sb.AppendLine(); } } return(sb.ToString()); }