コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
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);
        }