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;
		}
Esempio n. 2
0
        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);
        }