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.Editor.GetTextAt (options.Document.Editor.SelectionRange); 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; }
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); }