public void WriteValidationMethodBody(CSharpFile file, DocumentScript script) { foreach (var expr in file.IndexOfWebMthdDecl) { // if parameters are present, go to next iteration without doing anything. if (expr.Parameters.Count != 0) { continue; } if (expr.Name != "Valid" + (expr.NextSibling.GetChildByRole(Roles.Identifier).GetText())) { continue; } // logic to insert parameters to validation Method. var copy = (MethodDeclaration)expr.Clone(); string str = string.Join(", ", from parameter in expr.NextSibling.Descendants.OfType <ParameterDeclaration>() select parameter.GetText()); var chldOfTypPar = expr.GetChildByRole(Roles.RPar); int offset = script.GetCurrentOffset(chldOfTypPar.StartLocation); script.InsertText(offset, str); // Insert Static keyword to validation method. script.InsertText(script.GetCurrentOffset(expr.ReturnType.StartLocation), "static "); // logic to insert if else statements inside validation Method body int offset1 = script.GetCurrentOffset(expr.LastChild.FirstChild.EndLocation); var locationToInsert = expr.LastChild.LastChild.PrevSibling; script.InsertBefore(locationToInsert, allPatterns.ValidationFieldDecl()); foreach (var inv in expr.NextSibling.Children.OfType <ParameterDeclaration>()) { string dataType = inv.FirstChild.GetText(); string varName = inv.LastChild.GetText(); if (dataType.Contains("int")) { script.InsertBefore(locationToInsert, allPatterns.IfElStmtInt(varName)); } else if (dataType.Contains("string") || dataType.Contains("String")) { script.InsertBefore(locationToInsert, allPatterns.IfElStmtStr(varName)); } else if (dataType.Contains("float") || dataType.Contains("decimal") || dataType.Contains("Decimal")) { script.InsertBefore(locationToInsert, allPatterns.IfElseFloatDecimal(varName)); } else { script.InsertText(script.GetCurrentOffset(locationToInsert.StartLocation), "DummyText_DatatypeIsDifferent "); } } } }
private void DummyTextForTryCallValidation(CSharpFile file, DocumentScript script) { foreach (var expr in file.IndexOfIfElStmtValidation) { script.InsertText(script.GetCurrentOffset(expr.StartLocation), "DummyText "); } }
// Checking Whether Try Catch is Present in WebMethod public void CheckTryCatchInWebMethodBody(CSharpFile file, DocumentScript script) { foreach (MethodDeclaration expr in file.IndexOfWebMthdDecl) { var copy = (MethodDeclaration)expr.NextSibling.Clone(); if (expr.NextSibling.FirstChild.GetText().Contains("WebMethod") && !expr.NextSibling.Descendants.OfType <TryCatchStatement>().Any()) { script.InsertText(script.GetCurrentOffset(expr.NextSibling.StartLocation), "DummyText_TryCatchNotPresent"); } } }
public void InsertParametersIfElseInWebmethodTry(CSharpFile file, DocumentScript script) { foreach (var expr in file.IndexOfIfElStmt) { //check if parameters are passed before, go to next iteration if (!(expr.Descendants.OfType <InvocationExpression>().First().GetText().Split("()".ToCharArray())[1] == "")) { continue; } // logic to add parameters in if block (in try catch of webmethod) to Validation Method. var copy = (IfElseStatement)expr.Clone(); var ParentExpr = expr.GetParent <MethodDeclaration>(); string str = string.Join(", ", from parameter in ParentExpr.Descendants.OfType <ParameterDeclaration>() select parameter.Name); int parameterOffset = script.GetCurrentOffset(expr.GetChildByRole(Roles.RPar).StartLocation) - 1; script.InsertText(parameterOffset, str); // putting Return Vriable Name in If Else Block. if (expr.GetParent <MethodDeclaration>().ReturnType.GetText() != "void") { var returnVar = expr.GetParent <MethodDeclaration>().Body.LastChild.PrevSibling.FirstChild; int retValueOffset = script.GetCurrentOffset(expr.LastChild.LastChild.StartLocation); if (returnVar.GetText() == "return") { string retString = returnVar.NextSibling.GetText(); script.InsertText(retValueOffset, " " + retString); } else { script.InsertText(retValueOffset, " DummyText"); } } } }
void CreateField(CodeMemberField newField) { // insert new field below InitializeComponents() var bodyRegion = initializeComponents.BodyRegion; DocumentScript script = GetScript(bodyRegion.FileName); string newline = DocumentUtilities.GetLineTerminator(script.OriginalDocument, bodyRegion.BeginLine); string indentation = DocumentUtilities.GetIndentation(script.OriginalDocument, bodyRegion.BeginLine); var insertionLocation = new TextLocation(bodyRegion.EndLine + 1, 1); int insertionOffset = script.GetCurrentOffset(insertionLocation); string code = indentation + GenerateField(newField) + newline; script.InsertText(insertionOffset, code); }
void CreateField(CodeMemberField newField) { // insert new field below the last field or InitializeComponents() IField field = null; if (formClass != null) { field = formClass.Fields.LastOrDefault(f => string.Equals(f.Region.FileName, initializeComponents.Region.FileName, StringComparison.OrdinalIgnoreCase)); } var bodyRegion = field != null ? field.BodyRegion : initializeComponents.BodyRegion; DocumentScript script = GetScript(bodyRegion.FileName); string newline = DocumentUtilities.GetLineTerminator(script.OriginalDocument, bodyRegion.BeginLine); string indentation = DocumentUtilities.GetIndentation(script.OriginalDocument, bodyRegion.BeginLine); var insertionLocation = new TextLocation(bodyRegion.EndLine + 1, 1); int insertionOffset = script.GetCurrentOffset(insertionLocation); string code = indentation + GenerateField(newField) + newline; script.InsertText(insertionOffset, code); }
public static void Main(string[] args) { /* * if (args.Length == 0) { * Console.WriteLine("Please specify the path to a .sln file on the command line"); * * Console.Write("Press any key to continue . . . "); * Console.ReadKey(true); * return; * } * */ List <string> list = new List <string>(); Solution solution = new Solution("C:\\Martin\\GitHub\\HotFixForUnity\\AddMethodTool\\AddMethod.sln"); //Solution solution = new Solution(args[0]); // foreach (var file in solution.AllFiles) { // var astResolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.UnresolvedTypeSystemForFile); // foreach (var invocation in file.SyntaxTree.Descendants.OfType<InvocationExpression>()) { // // Retrieve semantics for the invocation // var rr = astResolver.Resolve(invocation) as InvocationResolveResult; // if (rr == null) { // // Not an invocation resolve result - e.g. could be a UnknownMemberResolveResult instead // continue; // } // if (rr.Member.FullName != "System.String.IndexOf") { // // Invocation isn't a string.IndexOf call // continue; // } // if (rr.Member.Parameters.First().Type.FullName != "System.String") { // // Ignore the overload that accepts a char, as that doesn't take a StringComparison. // // (looking for a char always performs the expected ordinal comparison) // continue; // } // if (rr.Member.Parameters.Last().Type.FullName == "System.StringComparison") { // // Already using the overload that specifies a StringComparison // continue; // } // Console.WriteLine(invocation.GetRegion() + ": " + invocation.GetText()); // file.IndexOfInvocations.Add(invocation); // } // } // Console.WriteLine("Found {0} places to refactor in {1} files.", // solution.AllFiles.Sum(f => f.IndexOfInvocations.Count), // solution.AllFiles.Count(f => f.IndexOfInvocations.Count > 0)); Console.Write("Apply refactorings? "); //string answer = Console.ReadLine(); //if ("yes".Equals(answer, StringComparison.OrdinalIgnoreCase) || "y".Equals(answer, StringComparison.OrdinalIgnoreCase)) { foreach (var file in solution.AllFiles) { // if (file.IndexOfInvocations.Count == 0) // continue; // DocumentScript expects the the AST to stay unmodified (so that it fits // to the document state at the time of the DocumentScript constructor call), // so we call Freeze() to prevent accidental modifications (e.g. forgetting a Clone() call). file.SyntaxTree.Freeze(); // AST resolver used to find context for System.StringComparison generation var compilation = file.Project.Compilation; var astResolver = new CSharpAstResolver(compilation, file.SyntaxTree, file.UnresolvedTypeSystemForFile); // Create a document containing the file content: var document = new StringBuilderDocument(file.OriginalText); var formattingOptions = FormattingOptionsFactory.CreateAllman(); var options = new TextEditorOptions(); // using (var script = new DocumentScript(document, formattingOptions, options)) { // foreach (InvocationExpression expr in file.IndexOfInvocations) { // // Generate a reference to System.StringComparison in this context: // var astBuilder = new TypeSystemAstBuilder(astResolver.GetResolverStateBefore(expr)); // IType stringComparison = compilation.FindType(typeof(StringComparison)); // AstType stringComparisonAst = astBuilder.ConvertType(stringComparison); // // // Alternative 1: clone a portion of the AST and modify it // var copy = (InvocationExpression)expr.Clone(); // copy.Arguments.Add(stringComparisonAst.Member("Ordinal")); // script.Replace(expr, copy); // // // // Alternative 2: perform direct text insertion // // int offset = script.GetCurrentOffset(expr.RParToken.StartLocation); // // script.InsertText(offset, ", " + stringComparisonAst.GetText() + ".Ordinal"); // } // } using (var script = new DocumentScript(document, formattingOptions, options)) { CSharpParser parser = new CSharpParser(); //SyntaxTree syntaxTree = parser.Parse(code, srcFilePath); SyntaxTree syntaxTree = file.SyntaxTree; foreach (var classDec in syntaxTree.Descendants.OfType <TypeDeclaration>()) { if (classDec.ClassType == ClassType.Class || classDec.ClassType == ClassType.Struct) { var className = classDec.Name; foreach (var method in classDec.Children.OfType <MethodDeclaration>()) { var returnType = method.ReturnType.ToString(); if (returnType.Contains("IEnumerator") || returnType.Contains("IEnumerable")) // 暂不支持yield! { continue; } Console.WriteLine("className:" + className + " method:" + method.Name); AstNodeCollection <ParameterDeclaration> paramlist = method.Parameters; string strParaType = string.Format("{0},{1}", className, method.Name); string numberType = ",{0}"; string numberPara = ", typeof(object)";//兼容性思路,无论是静态还是非静态都传入object string strPara = ", null"; if ((method.Modifiers & Modifiers.Static) != Modifiers.Static) { strPara = ", this"; } int number = 1; foreach (ParameterDeclaration param in paramlist) { Console.WriteLine("param " + param.Name); strPara += string.Format(", {0}", param.Name); numberType += string.Format(",{0}{1}{2}", "{", number, "}"); numberPara += string.Format(", typeof({0})", param.Type); number++; } int offset = script.GetCurrentOffset(method.Body.LBraceToken.StartLocation); script.InsertText(offset + 1, "\n" + "\n" + string.Format("if (FixUtil.Instance.NeedFix(\"{0}.{1}\"))\n", className, method.Name) + "{\n" + string.Format(" string strParameter = string.Format(\"{0}{1}\"{2});\n", strParaType, numberType, numberPara) + string.Format(" FixUtil.Instance.Fix(strParameter{0});\n", strPara) + " return;\n" + "}\n"); // script.InsertText(offset + 1, "\n" + // "\n" + // string.Format("if (FixUtil.Instance.NeedFix("+className+"."+method.Name+"))\n" + // "{\n" + // string.Format(" FixUtil.Instance.Fix(\"{0}.{1}\"{2});\n", className, method.Name, str) + // " return;\n" + // "}\n"); } } } } File.WriteAllText(Path.ChangeExtension(file.FileName, ".output.cs"), document.Text); } string text = Console.ReadLine(); } }
/// <summary> /// 代码注入! GOGOGO /// </summary> /// <param name="srcFilePath"></param> /// <param name="outputFilePath"></param> public void Inject(string srcFilePath, string outputFilePath) { UTF8Encoding utf8 = new UTF8Encoding(false); var predefineSymbolsSb = new StringBuilder(); if (_defineSymbols != null) { foreach (var symbol in _defineSymbols) { predefineSymbolsSb.AppendFormat("#define {0}\n", symbol); } } var code = File.ReadAllText(srcFilePath, Encoding.UTF8); code = predefineSymbolsSb.ToString() + code; // 加入宏 var document = new StringBuilderDocument(code); var formattingOptions = FormattingOptionsFactory.CreateAllman(); var options = new TextEditorOptions(); using (var script = new DocumentScript(document, formattingOptions, options)) { CSharpParser parser = new CSharpParser(); SyntaxTree syntaxTree = parser.Parse(code, srcFilePath); foreach (var classDec in syntaxTree.Descendants.OfType <TypeDeclaration>()) { if (classDec.ClassType == ClassType.Class || classDec.ClassType == ClassType.Struct) { var className = classDec.Name; foreach (var method in classDec.Children.OfType <MethodDeclaration>()) { var returnType = method.ReturnType.ToString(); if (returnType.Contains("IEnumerator") || returnType.Contains("IEnumerable")) // 暂不支持yield! { continue; } var methodSegment = script.GetSegment(method); var methodOffset = methodSegment.Offset; // 方法偏移 var paramsTypes = method.Parameters; //method.Children.OfType<ParameterDeclaration>();// typeName var paramsTypesStrs = new List <string>(); // 参数 if (!method.HasModifier(Modifiers.Static)) { paramsTypesStrs.Add("this"); // 非静态方法,加this } var paramsOutStrs = new List <string>(); // out 的参数 foreach (var paramsType in paramsTypes) { paramsTypesStrs.Add(paramsType.Name); if (paramsType.ParameterModifier == ParameterModifier.Out) { // out 的参数 paramsOutStrs.Add(string.Format("{0} = default({1});", paramsType.Name, paramsType.Type)); } } if (_beforeInsert != null) { var insertBeforeText = _beforeInsert(className, method.Name, returnType, paramsTypesStrs.ToArray(), paramsOutStrs.ToArray()); if (!string.IsNullOrEmpty(insertBeforeText)) { script.InsertText(methodOffset, insertBeforeText); } } foreach (var blockStatement in method.Descendants.OfType <BlockStatement>()) { int insertOffset; if (blockStatement.Statements.Count == 0) // 空函数 { var segment = script.GetSegment(blockStatement); insertOffset = segment.Offset + 1; // 越过"/" } else { var firstChildStatement = blockStatement.Statements.First(); var segment = script.GetSegment(firstChildStatement); insertOffset = segment.Offset; } script.InsertText(insertOffset, _afterInsert(className, method.Name, returnType, paramsTypesStrs.ToArray(), paramsOutStrs.ToArray())); break; // 仅对第一个方法包体(BlockStatement), 其它不是方法进行处理 } } } } } var resultText = document.Text; resultText = resultText.Substring(predefineSymbolsSb.Length); // 移除宏定义 File.WriteAllText(outputFilePath, resultText, utf8); }