public override object VisitLocalVariableDeclaration(LocalVariableDeclaration localVariableDeclaration, object data) { if (searchedMember is LocalVariable) { LocalVariable searchedVariable = (LocalVariable)searchedMember; ICSharpCode.NRefactory.Ast.INode parent = localVariableDeclaration.Parent; while (parent != null && !(parent is MemberNode) && !(parent is ParametrizedNode)) { parent = parent.Parent; } if (parent != null && localVariableDeclaration.StartLocation.Line == searchedVariable.Location.Line && localVariableDeclaration.StartLocation.Column == searchedVariable.Location.Column && parent.StartLocation.Line == searchedVariable.DeclaringMember.Location.Line && parent.StartLocation.Column == searchedVariable.DeclaringMember.Location.Column) { foreach (VariableDeclaration decl in localVariableDeclaration.Variables) { if (decl.Name == searchedMemberName) { AddUniqueReference(decl.StartLocation.Y, decl.StartLocation.X, searchedMemberName); } } } } return(base.VisitLocalVariableDeclaration(localVariableDeclaration, data)); }
public override List <Change> PerformChanges(RefactoringOptions options, object prop) { IResolver resolver = options.GetResolver(); List <Change> result = new List <Change> (); INRefactoryASTProvider provider = options.GetASTProvider(); if (resolver == null || provider == null) { return(result); } TypeDeclaration newType = new TypeDeclaration(ICSharpCode.NRefactory.Ast.Modifiers.None, null); newType.Name = createExpression.CreateType.Type; newType.Type = GetNewTypeType(); ConstructorDeclaration constructor = new ConstructorDeclaration(newType.Name, ICSharpCode.NRefactory.Ast.Modifiers.Public, null, null); constructor.Body = new BlockStatement(); int i = 0; foreach (Expression expression in createExpression.Parameters) { i++; string output = provider.OutputNode(options.Dom, expression); string parameterName; if (Char.IsLetter(output[0]) || output[0] == '_') { parameterName = output; } else { parameterName = "par" + i; } ResolveResult resolveResult2 = resolver.Resolve(new ExpressionResult(output), options.ResolveResult.ResolvedExpression.Region.Start); TypeReference typeReference = new TypeReference(resolveResult2.ResolvedType.ToInvariantString()); typeReference.IsKeyword = true; ParameterDeclarationExpression pde = new ParameterDeclarationExpression(typeReference, parameterName); constructor.Parameters.Add(pde); } ICSharpCode.NRefactory.Ast.INode node = newType; IType curType = options.Document.CompilationUnit.GetTypeAt(options.Document.Editor.Caret.Line, options.Document.Editor.Caret.Column); if (curType != null && !string.IsNullOrEmpty(curType.Namespace)) { NamespaceDeclaration namespaceDeclaration = new NamespaceDeclaration(curType.Namespace); namespaceDeclaration.Children.Add(newType); node = namespaceDeclaration; } newType.Children.Add(constructor); string fileName = GetName(Path.Combine(Path.GetDirectoryName(options.Document.FileName), newType.Name + Path.GetExtension(options.Document.FileName))); string header = options.Dom.Project is DotNetProject?StandardHeaderService.GetHeader(options.Dom.Project, fileName, true) + Environment.NewLine : ""; CreateFileChange createFile = new CreateFileChange(fileName, header + provider.OutputNode(options.Dom, node)); result.Add(createFile); result.Add(new OpenFileChange(fileName)); return(result); }
internal static void EvaluateComplexityMetrics(ICSharpCode.NRefactory.Ast.INode method, MethodProperties props) { props.CyclometricComplexity = 1; props.LOCReal = 0; props.NumberOfVariables = 0; cls = props.ParentClass; ASTVisitor ctxAstVisitor = new ASTVisitor(); if (method is MethodDeclaration) { foreach (var statement in ((MethodDeclaration)method).Body.Children) { ctxAstVisitor.VisitStatement(statement, props); } } else if (method is ConstructorDeclaration) { foreach (var statement in ((ConstructorDeclaration)method).Body.Children) { ctxAstVisitor.VisitStatement(statement, props); } } cls.CyclometricComplexity += props.CyclometricComplexity; }
bool DoCaseCompletion(SharpDevelopTextAreaControl editor) { ICSharpCode.TextEditor.Caret caret = editor.ActiveTextAreaControl.Caret; NRefactoryResolver r = new NRefactoryResolver(LanguageProperties.CSharp); if (r.Initialize(ParserService.GetParseInformation(editor.FileName), caret.Line + 1, caret.Column + 1)) { AST.INode currentMember = r.ParseCurrentMember(editor.Text); if (currentMember != null) { CaseCompletionSwitchFinder ccsf = new CaseCompletionSwitchFinder(caret.Line + 1, caret.Column + 1); currentMember.AcceptVisitor(ccsf, null); if (ccsf.bestStatement != null) { r.RunLookupTableVisitor(currentMember); ResolveResult rr = r.ResolveInternal(ccsf.bestStatement.SwitchExpression, ExpressionContext.Default); if (rr != null && rr.ResolvedType != null) { return(ProvideContextCompletion(editor, rr.ResolvedType, ' ')); } } } } return(false); }
bool IsSearchedNode(ICSharpCode.NRefactory.Ast.INode node) { if (node == null || node.StartLocation.IsEmpty) { return(false); } foreach (var tuple in searchedMembers) { var searchedMember = tuple.Item1; var searchedMemberFile = tuple.Item3; var searchedMemberLocation = tuple.Item4; if (searchedMember is CompoundType) { foreach (IType part in ((CompoundType)searchedMember).Parts) { if (fileName == part.CompilationUnit.FileName && node.StartLocation.Line == part.Location.Line // && node.StartLocation.Column == part.Location.Column ) { return(true); } } } return((string.IsNullOrEmpty(searchedMemberFile) || fileName == searchedMemberFile) && node.StartLocation.Line == searchedMemberLocation.Line // && node.StartLocation.Column == this.searchedMemberLocation.Column ); } return(false); }
void CheckNode(ICSharpCode.NRefactory.Ast.INode node) { if (IsSearchedNode(node)) { int line, column; if (SearchText(searchedMemberName, node.StartLocation.Line, node.StartLocation.Column, out line, out column)) { AddUniqueReference(line, column, searchedMemberName); } } }
public override bool IsValid(RefactoringOptions options) { if (!(options.SelectedItem is LocalVariable)) { // Console.WriteLine ("!!! Item is not LocalVariable"); return(false); } ICSharpCode.NRefactory.Ast.INode result = GetMemberBodyNode(options); if (result == null) { return(false); } return(true); }
private void VisitStatement(ICSharpCode.NRefactory.Ast.INode statement, MethodProperties meth) { try{ if (statement is BlockStatement) { VisitStatement((BlockStatement)statement, meth); } else if (statement is IfElseStatement) { VisitStatement((IfElseStatement)statement, meth); } else if (statement is ElseIfSection) { VisitStatement((ElseIfSection)statement, meth); } else if (statement is ForeachStatement) { VisitStatement((ForeachStatement)statement, meth); } else if (statement is ForStatement) { VisitStatement((ForStatement)statement, meth); } else if (statement is ForNextStatement) { VisitStatement((ForNextStatement)statement, meth); } else if (statement is DoLoopStatement) { VisitStatement((DoLoopStatement)statement, meth); } else if (statement is SwitchStatement) { VisitStatement((SwitchStatement)statement, meth); } else if (statement is LocalVariableDeclaration) { VisitStatement((LocalVariableDeclaration)statement, meth); } else if (statement is ExpressionStatement) { VisitStatement((ExpressionStatement)statement, meth); } }catch (Exception ex) { Console.WriteLine(ex.ToString()); } //See other potential types to exploit }
public MethodProperties(IMethod m) { mthd = m; mthdAst = null; ParameterList = new List <string> (0); foreach (var param in m.Parameters) { ParameterList.Add(param.ReturnType.FullName); } AfferentCoupling = 0; EfferentCoupling = 0; FilePath = ""; this.FullName = mthd.FullName; this.StartLine = mthd.BodyRegion.Start.Line; this.EndLine = mthd.BodyRegion.End.Line; }
private static void ProcessNode(MetricsContext ctx, ICSharpCode.NRefactory.Ast.INode node) { if (node is UsingStatement) { //TODO do something (something to do with afferent and efferent coupling of namespaces) } else if (node is NamespaceDeclaration) { try { PrefixName.Push(((NamespaceDeclaration)node).Name); LOCEvaluate.EvaluateNamespaceLOC(ctx, (NamespaceDeclaration)node); PrefixName.Pop(); } catch (Exception e) { } } else if (node is TypeDeclaration) { LOCEvaluate.EvaluateTypeLOC(ctx, null, (TypeDeclaration)node, node.StartLocation.Line); } }
protected override void BeginVisit(ICSharpCode.NRefactory.Ast.INode node) { StatementWithEmbeddedStatement embedded = node as StatementWithEmbeddedStatement; if (embedded != null) { if (ContainsLocation(embedded.EmbeddedStatement)) { statementStack.Push(embedded); } } // if ... else ... is a special case if (node is IfElseStatement) { IfElseStatement ifElse = (IfElseStatement)node; if (ifElse.TrueStatement.Count > 0 && ContainsLocation(ifElse.TrueStatement[0]) || ifElse.FalseStatement.Count > 0 && ContainsLocation(ifElse.FalseStatement[0])) { statementStack.Push(ifElse); } } }
public override List <Change> PerformChanges(RefactoringOptions options, object properties) { ICSharpCode.NRefactory.Ast.INode memberNode = GetMemberBodyNode(options); List <Change> changes = new List <Change> (); if (memberNode == null) { return(null); } try { // Console.WriteLine ("AcceptVisitor"); // Console.WriteLine ("Start: " + memberNode.StartLocation.ToString () + " - End: " + memberNode.EndLocation.ToString ()); memberNode.AcceptVisitor(new IntegrateTemporaryVariableVisitor(), new IntegrateTemporaryVariableVisitorOptions(changes, options)); // Console.WriteLine ("AcceptVisitor done"); } catch (IntegrateTemporaryVariableException e) { // Console.WriteLine ("Exception catched"); MessageService.ShowError("Could not perform integration : ", e.Message); return(new List <Change>()); } // Console.WriteLine ("Changes calculated"); return(changes); }
public MethodProperties(ICSharpCode.NRefactory.Ast.INode m, ClassProperties prop) { mthd = null; ParameterList = new List <string> (0); if (m is MethodDeclaration) { mthdAst = (MethodDeclaration)m; VisitMethodMember((MethodDeclaration)m, prop); this.FullName = prop.FullName + "." + ((MethodDeclaration)m).Name.Substring(((MethodDeclaration)m).Name.LastIndexOf(".") + 1); } else if (m is ConstructorDeclaration) { mthdAst = (ConstructorDeclaration)m; VisitConstructorMember((ConstructorDeclaration)m, prop); this.FullName = prop.FullName + "." + ((ConstructorDeclaration)m).Name.Substring(((ConstructorDeclaration)m).Name.LastIndexOf(".") + 1); } AfferentCoupling = 0; EfferentCoupling = 0; FilePath = ""; this.ParentClass = prop; this.StartLine = mthdAst.StartLocation.Line; this.EndLine = mthdAst.EndLocation.Line; }
public MethodProperties (IMethod m) { mthd = m; mthdAst = null; ParameterList = new List<string> (0); foreach(var param in m.Parameters) { ParameterList.Add(param.ReturnType.FullName); } AfferentCoupling=0; EfferentCoupling=0; FilePath=""; this.FullName = mthd.FullName; this.StartLine = mthd.BodyRegion.Start.Line; this.EndLine = mthd.BodyRegion.End.Line; }
private static void ProcessMethod(MetricsContext ctx, ICSharpCode.NRefactory.Ast.INode method, IProperties parentClass) { if (method == null) { return; } StringBuilder methodName = new StringBuilder(""); string[] PrefixArray = PrefixName.ToArray(); for (int i = 0; i < PrefixArray.Length; i++) { methodName.Append(PrefixArray[PrefixArray.Length - i - 1] + "."); } List <string> methodParameterList = new List <string>(0); if (method is MethodDeclaration) { methodName.Append(((MethodDeclaration)method).Name); foreach (ParameterDeclarationExpression pde in ((MethodDeclaration)method).Parameters) { string type = pde.TypeReference.Type; if (type.Contains(".")) { type = type.Substring(type.LastIndexOf(".") + 1); } methodParameterList.Add(type); } } else if (method is ConstructorDeclaration) { methodName.Append(((ConstructorDeclaration)method).Name); foreach (ParameterDeclarationExpression pde in ((ConstructorDeclaration)method).Parameters) { string type = pde.TypeReference.Type; if (type.Contains(".")) { type = type.Substring(type.LastIndexOf(".") + 1); } methodParameterList.Add(type); } } StringBuilder MethodKey = new StringBuilder(); MethodKey.Append(methodName.ToString() + " "); foreach (string paramName in methodParameterList) { MethodKey.Append(paramName + " "); } try{ if (parentClass is ClassProperties) { if (!(parentClass as ClassProperties).Methods.ContainsKey(MethodKey.ToString())) { if (method is MethodDeclaration) { (parentClass as ClassProperties).Methods.Add(MethodKey.ToString(), new MethodProperties((MethodDeclaration)method, parentClass as ClassProperties)); } else if (method is ConstructorDeclaration) { (parentClass as ClassProperties).Methods.Add(MethodKey.ToString(), new MethodProperties((ConstructorDeclaration)method, parentClass as ClassProperties)); } } var currentMethodReference = (parentClass as ClassProperties).Methods[MethodKey.ToString()]; //Calculate all metrics here ASTVisitor.EvaluateComplexityMetrics(method, currentMethodReference); LOCEvaluate.EvaluateMethodLOC(currentMethodReference, FileText, FileDoc); currentMethodReference.FilePath = File.FilePath; } } catch (NullReferenceException ex) { LoggingService.LogError("Error in '" + methodName.ToString() + "'", ex); Console.WriteLine(MethodKey.ToString() + " hoo"); } }
// could work to extend selection to set of adjacent statements separated by blank lines Selection ExtendSelection(ITextEditor editor, CompilationUnit parsedCU, IList <ISpecial> commentsBlankLines, out INode selectedResultNode, Type[] interestingNodeTypes) { selectedResultNode = null; var selectionStart = editor.Document.OffsetToPosition(editor.SelectionStart); var selectionEnd = editor.Document.OffsetToPosition(editor.SelectionStart + editor.SelectionLength); Ast.INode currentNode = parsedCU.Children.Select( n => EditorContext.FindInnermostNodeContainingSelection(n, selectionStart, selectionEnd)).Where(n => n != null).FirstOrDefault(); if (currentNode == null) { return(null); } if (!IsNodeTypeInteresting(currentNode, interestingNodeTypes)) { // ignore uninteresting nodes in the AST currentNode = GetInterestingParent(currentNode, interestingNodeTypes); } if (currentNode == null) { return(null); } selectedResultNode = currentNode; // whole node already selected -> expand selection if (currentNode.StartLocation == selectionStart && currentNode.EndLocation == selectionEnd) { bool extendToComments = false; if (IsNodeTypeInteresting(currentNode, interestingNodeTypes)) { // if interesting node already selected, we can try to also add comments var selectionExtendedToComments = ExtendSelectionToComments(editor.Document, selectionStart, selectionEnd, commentsBlankLines); if (selectionExtendedToComments != null) { // Can be extended to comments -> extend selectionStart = selectionExtendedToComments.Start; selectionEnd = selectionExtendedToComments.End; extendToComments = true; } } if (!extendToComments) { var parent = GetInterestingParent(currentNode, interestingNodeTypes); // it can happen that parent region exactly matches child region - in this case we need to advance even to the next parent // bc otherwise the selection would never move while (parent != null && parent.StartLocation == selectionStart && parent.EndLocation == selectionEnd) { parent = GetInterestingParent(parent, interestingNodeTypes); } if (parent == null) { return(new Selection { Start = selectionStart, End = selectionEnd }); } // Select the parent var extendedSelectionStart = parent.StartLocation; var extendedLocationEnd = parent.EndLocation; selectedResultNode = parent; // if the extended selection would contain blank lines, extend the selection only to the blank lines/comments on both sides (use siblings) // if the selection contains blank lines or comments on both sides, dont do this var blankLines = commentsBlankLines.Where(s => s is BlankLine).Cast <BlankLine>().ToList(); //if (SelectionContainsBlankLines(extendedSelectionStart, extendedLocationEnd, blankLines)) { if (false) // blank line separators - implement later { } else { selectionStart = extendedSelectionStart; selectionEnd = extendedLocationEnd; } } } else { // select current node selectionStart = currentNode.StartLocation; selectionEnd = currentNode.EndLocation; selectedResultNode = currentNode; } return(new Selection { Start = selectionStart, End = selectionEnd }); }
public MethodProperties (ICSharpCode.NRefactory.Ast.INode m, ClassProperties prop) { mthd=null; ParameterList = new List<string> (0); if(m is MethodDeclaration) { mthdAst = (MethodDeclaration)m; VisitMethodMember((MethodDeclaration)m, prop); this.FullName = prop.FullName + "." + ((MethodDeclaration)m).Name.Substring(((MethodDeclaration)m).Name.LastIndexOf(".")+1); } else if(m is ConstructorDeclaration) { mthdAst = (ConstructorDeclaration)m; VisitConstructorMember((ConstructorDeclaration)m, prop); this.FullName = prop.FullName + "." + ((ConstructorDeclaration)m).Name.Substring(((ConstructorDeclaration)m).Name.LastIndexOf(".")+1); } AfferentCoupling=0; EfferentCoupling=0; FilePath=""; this.ParentClass = prop; this.StartLine = mthdAst.StartLocation.Line; this.EndLine = mthdAst.EndLocation.Line; }
ICSharpCode.NRefactory.Ast.INode Analyze(RefactoringOptions options, ExtractMethodParameters param, bool fillParameter) { IResolver resolver = options.GetResolver(); INRefactoryASTProvider provider = options.GetASTProvider(); if (resolver == null || provider == null) { return(null); } string text = options.Document.TextEditor.GetText(options.Document.TextEditor.SelectionStartPosition, options.Document.TextEditor.SelectionEndPosition); TextEditorData data = options.GetTextEditorData(); var cu = provider.ParseFile(data.Document.GetTextAt(0, data.SelectionRange.Offset) + "MethodCall ();" + data.Document.GetTextAt(data.SelectionRange.EndOffset, data.Document.Length - data.SelectionRange.EndOffset)); if (cu == null || provider.LastErrors.Count > 0) { cu = provider.ParseFile(data.Document.GetTextAt(0, data.SelectionRange.Offset) + "MethodCall ()" + data.Document.GetTextAt(data.SelectionRange.EndOffset, data.Document.Length - data.SelectionRange.EndOffset)); } if (cu == null || provider.LastErrors.Count > 0) { return(null); } param.Text = RemoveIndent(text, GetIndent(text)).TrimEnd('\n', '\r'); ICSharpCode.NRefactory.Ast.INode result = provider.ParseText(text); if (cu == null || provider.LastErrors.Count > 0) { return(null); } VariableLookupVisitor visitor = new VariableLookupVisitor(resolver, param.Location); visitor.MemberLocation = new Location(param.DeclaringMember.Location.Column, param.DeclaringMember.Location.Line); if (fillParameter) { if (result != null) { result.AcceptVisitor(visitor, null); } if (result is Expression) { ResolveResult resolveResult = resolver.Resolve(new ExpressionResult(text), param.Location); if (resolveResult != null) { param.ExpressionType = resolveResult.ResolvedType; } } var startLocation = data.Document.OffsetToLocation(data.SelectionRange.Offset); var endLocation = data.Document.OffsetToLocation(data.SelectionRange.EndOffset); // Console.WriteLine ("startLocation={0}, endLocation={1}", startLocation, endLocation); foreach (VariableDescriptor varDescr in visitor.VariableList.Where(v => !v.IsDefined && v.InitialValueUsed)) { if (startLocation <= varDescr.Location && varDescr.Location < endLocation) { continue; } // Console.WriteLine (varDescr.Location); // Console.WriteLine (startLocation <= varDescr.Location); // Console.WriteLine (varDescr.Location < endLocation); param.Parameters.Add(varDescr); } param.Variables = new List <VariableDescriptor> (visitor.Variables.Values); foreach (VariableDescriptor varDescr in visitor.VariableList.Where(v => !v.IsDefined && param.Variables.Contains(v))) { if (param.Parameters.Contains(varDescr)) { continue; } if (startLocation <= varDescr.Location && varDescr.Location < endLocation) { continue; } param.Parameters.Add(varDescr); } param.ReferencesMember = visitor.ReferencesMember; param.ChangedVariables = new HashSet <string> (visitor.Variables.Values.Where(v => v.GetsChanged).Select(v => v.Name)); // analyze the variables outside of the selected text IMember member = param.DeclaringMember; int startOffset = data.Document.LocationToOffset(member.BodyRegion.Start.Line, member.BodyRegion.Start.Column); int endOffset = data.Document.LocationToOffset(member.BodyRegion.End.Line, member.BodyRegion.End.Column); if (data.SelectionRange.Offset < startOffset || endOffset < data.SelectionRange.EndOffset) { return(null); } text = data.Document.GetTextBetween(startOffset, data.SelectionRange.Offset) + data.Document.GetTextBetween(data.SelectionRange.EndOffset, endOffset); ICSharpCode.NRefactory.Ast.INode parsedNode = provider.ParseText(text); visitor = new VariableLookupVisitor(resolver, param.Location); visitor.CutRegion = new DomRegion(data.MainSelection.MinLine, data.MainSelection.MaxLine); visitor.MemberLocation = new Location(param.DeclaringMember.Location.Column, param.DeclaringMember.Location.Line); if (parsedNode != null) { parsedNode.AcceptVisitor(visitor, null); } param.VariablesOutside = new Dictionary <string, VariableDescriptor> (); foreach (var pair in visitor.Variables) { if (startLocation < pair.Value.Location || endLocation >= pair.Value.Location) { param.VariablesOutside.Add(pair.Key, pair.Value); } } param.OutsideVariableList = new List <VariableDescriptor> (); foreach (var v in visitor.VariableList) { if (startLocation < v.Location || endLocation >= v.Location) { param.OutsideVariableList.Add(v); } } param.ChangedVariablesUsedOutside = new List <VariableDescriptor> (param.Variables.Where(v => v.GetsChanged && param.VariablesOutside.ContainsKey(v.Name))); param.OneChangedVariable = result is BlockStatement; if (param.OneChangedVariable) { param.OneChangedVariable = param.ChangedVariablesUsedOutside.Count == 1; } param.VariablesToGenerate = new List <VariableDescriptor> (param.ChangedVariablesUsedOutside.Where(v => v.IsDefined)); foreach (VariableDescriptor var in param.VariablesToGenerate) { param.Parameters.Add(var); } if (param.OneChangedVariable) { param.VariablesToDefine = new List <VariableDescriptor> (param.Parameters.Where(var => !var.InitialValueUsed)); param.VariablesToDefine.ForEach(var => param.Parameters.Remove(var)); } else { param.VariablesToDefine = new List <VariableDescriptor> (); } } return(result); }
public override List <Change> PerformChanges(RefactoringOptions options, object prop) { List <Change> result = new List <Change> (); ExtractMethodParameters param = (ExtractMethodParameters)prop; TextEditorData data = options.GetTextEditorData(); INRefactoryASTProvider provider = options.GetASTProvider(); IResolver resolver = options.GetResolver(); ICSharpCode.NRefactory.Ast.INode node = Analyze(options, param, false); if (param.VariablesToGenerate.Count > 0) { TextReplaceChange varGen = new TextReplaceChange(); varGen.Description = GettextCatalog.GetString("Generate some temporary variables"); varGen.FileName = options.Document.FileName; LineSegment line = data.Document.GetLine(Math.Max(0, data.Document.OffsetToLineNumber(data.SelectionRange.Offset) - 1)); varGen.Offset = line.Offset + line.EditableLength; varGen.InsertedText = Environment.NewLine + options.GetWhitespaces(line.Offset); foreach (VariableDescriptor var in param.VariablesToGenerate) { TypeReference tr = options.ShortenTypeName(var.ReturnType).ConvertToTypeReference(); varGen.InsertedText += provider.OutputNode(options.Dom, new LocalVariableDeclaration(new VariableDeclaration(var.Name, null, tr))).Trim(); } result.Add(varGen); } InvocationExpression invocation = new InvocationExpression(new IdentifierExpression(param.Name)); foreach (VariableDescriptor var in param.Parameters) { if (!param.OneChangedVariable && param.ChangedVariables.Contains(var.Name)) { FieldDirection fieldDirection = FieldDirection.Ref; VariableDescriptor outsideVar = null; if (param.VariablesOutside.TryGetValue(var.Name, out outsideVar) && (var.GetsAssigned || param.VariablesToGenerate.Where(v => v.Name == var.Name).Any())) { if (!outsideVar.GetsAssigned) { fieldDirection = FieldDirection.Out; } } invocation.Arguments.Add(new DirectionExpression(fieldDirection, new IdentifierExpression(var.Name))); } else { invocation.Arguments.Add(new IdentifierExpression(var.Name)); } } // string mimeType = DesktopService.GetMimeTypeForUri (options.Document.FileName); TypeReference returnType = new TypeReference("System.Void", true); ICSharpCode.NRefactory.Ast.INode outputNode; if (param.OneChangedVariable) { string name = param.ChangedVariables.First(); returnType = options.ShortenTypeName(param.Variables.Find(v => v.Name == name).ReturnType).ConvertToTypeReference(); if (param.OutsideVariableList.Any(v => v.Name == name && !v.IsDefined)) { LocalVariableDeclaration varDecl = new LocalVariableDeclaration(returnType); varDecl.Variables.Add(new VariableDeclaration(name, invocation)); outputNode = varDecl; } else { outputNode = new ExpressionStatement(new AssignmentExpression(new IdentifierExpression(name), ICSharpCode.NRefactory.Ast.AssignmentOperatorType.Assign, invocation)); } } else { outputNode = node is BlockStatement ? (ICSharpCode.NRefactory.Ast.INode) new ExpressionStatement(invocation) : invocation; } TextReplaceChange replacement = new TextReplaceChange(); replacement.Description = string.Format(GettextCatalog.GetString("Substitute selected statement(s) with call to {0}"), param.Name); replacement.FileName = options.Document.FileName; replacement.Offset = options.Document.TextEditor.SelectionStartPosition; replacement.RemovedChars = options.Document.TextEditor.SelectionEndPosition - options.Document.TextEditor.SelectionStartPosition; replacement.MoveCaretToReplace = true; LineSegment line1 = data.Document.GetLineByOffset(options.Document.TextEditor.SelectionEndPosition); if (options.Document.TextEditor.SelectionEndPosition == line1.Offset) { if (line1.Offset > 0) { LineSegment line2 = data.Document.GetLineByOffset(line1.Offset - 1); replacement.RemovedChars -= line2.DelimiterLength; } } replacement.InsertedText = options.GetWhitespaces(options.Document.TextEditor.SelectionStartPosition) + provider.OutputNode(options.Dom, outputNode).Trim(); result.Add(replacement); TextReplaceChange insertNewMethod = new TextReplaceChange(); insertNewMethod.FileName = options.Document.FileName; insertNewMethod.Description = string.Format(GettextCatalog.GetString("Create new method {0} from selected statement(s)"), param.Name); insertNewMethod.RemovedChars = param.InsertionPoint.LineBefore == NewLineInsertion.Eol ? 0 : param.InsertionPoint.Location.Column; insertNewMethod.Offset = data.Document.LocationToOffset(param.InsertionPoint.Location) - insertNewMethod.RemovedChars; ExtractMethodAstTransformer transformer = new ExtractMethodAstTransformer(param.VariablesToGenerate); node.AcceptVisitor(transformer, null); if (!param.OneChangedVariable && node is Expression) { ResolveResult resolveResult = resolver.Resolve(new ExpressionResult("(" + provider.OutputNode(options.Dom, node) + ")"), new DomLocation(options.Document.TextEditor.CursorLine, options.Document.TextEditor.CursorColumn)); if (resolveResult.ResolvedType != null) { returnType = options.ShortenTypeName(resolveResult.ResolvedType).ConvertToTypeReference(); } } MethodDeclaration methodDecl = new MethodDeclaration(); methodDecl.Name = param.Name; methodDecl.Modifier = param.Modifiers; methodDecl.TypeReference = returnType; if (!param.ReferencesMember) { methodDecl.Modifier |= ICSharpCode.NRefactory.Ast.Modifiers.Static; } if (node is BlockStatement) { methodDecl.Body = new BlockStatement(); methodDecl.Body.AddChild(new EmptyStatement()); if (param.OneChangedVariable) { methodDecl.Body.AddChild(new ReturnStatement(new IdentifierExpression(param.ChangedVariables.First()))); } } else if (node is Expression) { methodDecl.Body = new BlockStatement(); methodDecl.Body.AddChild(new ReturnStatement(node as Expression)); } foreach (VariableDescriptor var in param.VariablesToDefine) { BlockStatement block = methodDecl.Body; LocalVariableDeclaration varDecl = new LocalVariableDeclaration(options.ShortenTypeName(var.ReturnType).ConvertToTypeReference()); varDecl.Variables.Add(new VariableDeclaration(var.Name)); block.Children.Insert(0, varDecl); } foreach (VariableDescriptor var in param.Parameters) { TypeReference typeReference = options.ShortenTypeName(var.ReturnType).ConvertToTypeReference(); ParameterDeclarationExpression pde = new ParameterDeclarationExpression(typeReference, var.Name); if (!param.OneChangedVariable) { if (param.ChangedVariables.Contains(var.Name)) { pde.ParamModifier = ICSharpCode.NRefactory.Ast.ParameterModifiers.Ref; } if (param.VariablesToGenerate.Where(v => v.Name == var.Name).Any()) { pde.ParamModifier = ICSharpCode.NRefactory.Ast.ParameterModifiers.Out; } VariableDescriptor outsideVar = null; if (var.GetsAssigned && param.VariablesOutside.TryGetValue(var.Name, out outsideVar)) { if (!outsideVar.GetsAssigned) { pde.ParamModifier = ICSharpCode.NRefactory.Ast.ParameterModifiers.Out; } } } methodDecl.Parameters.Add(pde); } string indent = options.GetIndent(param.DeclaringMember); StringBuilder methodText = new StringBuilder(); switch (param.InsertionPoint.LineBefore) { case NewLineInsertion.Eol: methodText.AppendLine(); break; case NewLineInsertion.BlankLine: methodText.Append(indent); methodText.AppendLine(); break; } if (param.GenerateComment) { methodText.Append(indent); methodText.AppendLine("/// <summary>"); methodText.Append(indent); methodText.AppendLine("/// TODO: write a comment."); methodText.Append(indent); methodText.AppendLine("/// </summary>"); Ambience ambience = AmbienceService.GetAmbienceForFile(options.Document.FileName); foreach (ParameterDeclarationExpression pde in methodDecl.Parameters) { methodText.Append(indent); methodText.Append("/// <param name=\""); methodText.Append(pde.ParameterName); methodText.Append("\"> A "); methodText.Append(ambience.GetString(pde.TypeReference.ConvertToReturnType(), OutputFlags.IncludeGenerics | OutputFlags.UseFullName)); methodText.Append(" </param>"); methodText.AppendLine(); } if (methodDecl.TypeReference.Type != "System.Void") { methodText.Append(indent); methodText.AppendLine("/// <returns>"); methodText.Append(indent); methodText.Append("/// A "); methodText.AppendLine(ambience.GetString(methodDecl.TypeReference.ConvertToReturnType(), OutputFlags.IncludeGenerics | OutputFlags.UseFullName)); methodText.Append(indent); methodText.AppendLine("/// </returns>"); } } methodText.Append(indent); if (node is BlockStatement) { string text = provider.OutputNode(options.Dom, methodDecl, indent).Trim(); int emptyStatementMarker = text.LastIndexOf(';'); if (param.OneChangedVariable) { emptyStatementMarker = text.LastIndexOf(';', emptyStatementMarker - 1); } StringBuilder sb = new StringBuilder(); sb.Append(text.Substring(0, emptyStatementMarker)); sb.Append(AddIndent(param.Text, indent + "\t")); sb.Append(text.Substring(emptyStatementMarker + 1)); methodText.Append(sb.ToString()); } else { methodText.Append(provider.OutputNode(options.Dom, methodDecl, options.GetIndent(param.DeclaringMember)).Trim()); } switch (param.InsertionPoint.LineAfter) { case NewLineInsertion.Eol: methodText.AppendLine(); break; case NewLineInsertion.BlankLine: methodText.AppendLine(); methodText.AppendLine(); methodText.Append(indent); break; } insertNewMethod.InsertedText = methodText.ToString(); result.Add(insertNewMethod); return(result); }