コード例 #1
0
        public override bool IsValid(RefactoringOptions options)
        {
            IResolver resolver = options.GetResolver();
            INRefactoryASTProvider provider = options.GetASTProvider();

            if (resolver == null || provider == null)
            {
                return(false);
            }
            TextEditorData data = options.GetTextEditorData();

            if (data == null)
            {
                return(false);
            }
            if (data.IsSomethingSelected)
            {
                ExpressionResult expressionResult = new ExpressionResult(data.SelectedText.Trim());
                if (expressionResult.Expression.Contains(" ") || expressionResult.Expression.Contains("\t"))
                {
                    expressionResult.Expression = "(" + expressionResult.Expression + ")";
                }
                var endPoint = data.MainSelection.Anchor < data.MainSelection.Lead ? data.MainSelection.Lead : data.MainSelection.Anchor;
                options.ResolveResult = resolver.Resolve(expressionResult, new DomLocation(endPoint.Line, endPoint.Column));
                if (options.ResolveResult == null)
                {
                    return(false);
                }
                if (options.ResolveResult.CallingMember == null || !options.ResolveResult.CallingMember.BodyRegion.Contains(endPoint.Line, endPoint.Column))
                {
                    return(false);
                }
                return(true);
            }
            LineSegment    lineSegment = data.Document.GetLine(data.Caret.Line);
            string         line        = data.Document.GetTextAt(lineSegment);
            Expression     expression  = provider.ParseExpression(line);
            BlockStatement block       = provider.ParseText(line) as BlockStatement;

            if (expression == null || (block != null && block.Children [0] is LocalVariableDeclaration))
            {
                return(false);
            }

            options.ResolveResult = resolver.Resolve(new ExpressionResult(line), new DomLocation(options.Document.Editor.Caret.Line, options.Document.Editor.Caret.Column));
            return(options.ResolveResult.ResolvedType != null && !string.IsNullOrEmpty(options.ResolveResult.ResolvedType.FullName) && options.ResolveResult.ResolvedType.FullName != DomReturnType.Void.FullName);
        }
コード例 #2
0
        public override bool IsValid(RefactoringOptions options)
        {
            TextEditorData data = options.GetTextEditorData();
            LineSegment    line = data.Document.GetLine(data.Caret.Line);

            if (!data.IsSomethingSelected && line != null)
            {
                Stack <Span> stack = line.StartSpan != null ? new Stack <Span> (line.StartSpan) : new Stack <Span> ();
                Mono.TextEditor.Highlighting.SyntaxModeService.ScanSpans(data.Document, data.Document.SyntaxMode, data.Document.SyntaxMode, stack, line.Offset, data.Caret.Offset);
                foreach (Span span in stack)
                {
                    if (span.Color == "string.single" || span.Color == "string.double")
                    {
                        return(options.Document.CompilationUnit.GetMemberAt(data.Caret.Line, data.Caret.Column) != null);
                    }
                }
            }

            INRefactoryASTProvider provider = options.GetASTProvider();

            if (provider == null)
            {
                return(false);
            }
            string expressionText = null;

            if (options.ResolveResult != null && options.ResolveResult.ResolvedExpression != null)
            {
                expressionText = options.ResolveResult.ResolvedExpression.Expression;
            }

            if (string.IsNullOrEmpty(expressionText))
            {
                int start, end;
                expressionText = SearchNumber(data, out start, out end);
            }

            Expression expression = provider.ParseExpression(expressionText);

            return(expression is PrimitiveExpression);
        }
コード例 #3
0
        public override List <Change> PerformChanges(RefactoringOptions options, object properties)
        {
            TextEditorData data = options.GetTextEditorData();
            int            start, end;

            MonoDevelop.Refactoring.IntroduceConstant.IntroduceConstantRefactoring.SearchString(data, '"', out start, out end);
            LineSegment line = data.Document.GetLineByOffset(start);

            int closingTagLength = 1;                    // length of the closing "

            if (end > line.Offset + line.EditableLength) // assume missing closing tag
            {
                end = line.Offset + line.EditableLength;
                closingTagLength = 0;
            }

            INRefactoryASTProvider provider = options.GetASTProvider();

            List <Expression> args             = new List <Expression> ();
            IExpressionFinder expressionFinder = options.GetParser().CreateExpressionFinder(options.Dom);
            int expressionStart = start - 1;

            while (expressionStart > 0)
            {
                if (data.Document.GetCharAt(expressionStart) == '(')
                {
                    expressionStart--;
                    break;
                }
                expressionStart--;
            }
            // Add parameter to existing string.format call
            ExpressionResult     expressionResult = expressionFinder.FindFullExpression(options.Document.TextEditor.Text, expressionStart);
            InvocationExpression formatCall       = null;

            if (expressionResult != null)
            {
                InvocationExpression possibleFormatCall = provider.ParseExpression(expressionResult.Expression) as InvocationExpression;
                if (possibleFormatCall != null && possibleFormatCall.TargetObject is MemberReferenceExpression && ((MemberReferenceExpression)possibleFormatCall.TargetObject).MemberName == "Format")
                {
                    PrimitiveExpression expr = possibleFormatCall.Arguments[0] as PrimitiveExpression;
                    if (expr != null)
                    {
                        string str = data.Document.GetTextBetween(start + 1, data.SelectionRange.Offset) +
                                     "{" + (possibleFormatCall.Arguments.Count - 1) + "}" +
                                     data.Document.GetTextBetween(data.SelectionRange.EndOffset, end);
                        expr.Value       = str;
                        expr.StringValue = '"' + str + '"';
                        possibleFormatCall.Arguments.Add(new PrimitiveExpression(data.Document.GetTextAt(data.SelectionRange)));
                        formatCall = possibleFormatCall;
                        start      = data.Document.LocationToOffset(expressionResult.Region.Start.Line - 1, expressionResult.Region.Start.Column - 1);
                        end        = data.Document.LocationToOffset(expressionResult.Region.End.Line - 1, expressionResult.Region.End.Column - 1) - 1;
                    }
                }
            }

            // insert new format call
            if (formatCall == null)
            {
                string formattedString = UnescapeString(data.Document.GetTextBetween(start + 1, data.SelectionRange.Offset) + "{0}" + data.Document.GetTextBetween(data.SelectionRange.EndOffset, end));

                args.Add(new PrimitiveExpression(formattedString));
                args.Add(new PrimitiveExpression(data.Document.GetTextAt(data.SelectionRange)));

                TypeReference typeRef = new TypeReference("System.String");
                typeRef.IsKeyword = true;
                MemberReferenceExpression stringFormat = new MemberReferenceExpression(new TypeReferenceExpression(typeRef), "Format");
                formatCall = new InvocationExpression(stringFormat, args);
            }

            List <Change>     changes = new List <Change> ();
            TextReplaceChange change  = new TextReplaceChange();

            change.FileName           = options.Document.FileName;
            change.Offset             = start;
            change.RemovedChars       = end - start + closingTagLength;
            change.InsertedText       = provider.OutputNode(options.Dom, formatCall);
            change.MoveCaretToReplace = true;
            changes.Add(change);
            return(changes);
        }
コード例 #4
0
        public override List <Change> PerformChanges(RefactoringOptions options, object prop)
        {
            varCount       = 0;
            selectionStart = selectionEnd = -1;
            List <Change>          result   = new List <Change> ();
            IResolver              resolver = options.GetResolver();
            INRefactoryASTProvider provider = options.GetASTProvider();

            if (resolver == null || provider == null)
            {
                return(result);
            }
            TextEditorData data = options.GetTextEditorData();

            if (data == null)
            {
                return(result);
            }
            ResolveResult resolveResult;
            LineSegment   lineSegment;

            ICSharpCode.NRefactory.Ast.CompilationUnit unit = provider.ParseFile(data.Document.Text);
            MonoDevelop.Refactoring.ExtractMethod.VariableLookupVisitor visitor = new MonoDevelop.Refactoring.ExtractMethod.VariableLookupVisitor(resolver, new DomLocation(data.Caret.Line, data.Caret.Column));
            if (options.ResolveResult == null)
            {
                LoggingService.LogError("resolve result == null:" + options.ResolveResult);
                return(result);
            }
            IMember callingMember = options.ResolveResult.CallingMember;

            if (callingMember != null)
            {
                visitor.MemberLocation = new Location(callingMember.Location.Column, callingMember.Location.Line);
            }
            unit.AcceptVisitor(visitor, null);

            if (data.IsSomethingSelected)
            {
                ExpressionResult expressionResult = new ExpressionResult(data.SelectedText.Trim());
                if (expressionResult.Expression.Contains(" ") || expressionResult.Expression.Contains("\t"))
                {
                    expressionResult.Expression = "(" + expressionResult.Expression + ")";
                }
                resolveResult = resolver.Resolve(expressionResult, new DomLocation(data.Caret.Line, data.Caret.Column));
                if (resolveResult == null)
                {
                    return(result);
                }
                IReturnType resolvedType = resolveResult.ResolvedType;
                if (resolvedType == null || string.IsNullOrEmpty(resolvedType.Name))
                {
                    resolvedType = DomReturnType.Object;
                }
                varName = CreateVariableName(resolvedType, visitor);
                TypeReference returnType;
                if (resolveResult.ResolvedType == null || string.IsNullOrEmpty(resolveResult.ResolvedType.Name))
                {
                    returnType           = new TypeReference("var");
                    returnType.IsKeyword = true;
                }
                else
                {
                    returnType = options.ShortenTypeName(resolveResult.ResolvedType).ConvertToTypeReference();
                }
                options.ParseMember(resolveResult.CallingMember);

                TextReplaceChange insert = new TextReplaceChange();
                insert.FileName    = options.Document.FileName;
                insert.Description = GettextCatalog.GetString("Insert variable declaration");

                LocalVariableDeclaration varDecl = new LocalVariableDeclaration(returnType);
                varDecl.Variables.Add(new VariableDeclaration(varName, provider.ParseExpression(data.SelectedText)));

                GetContainingEmbeddedStatementVisitor blockVisitor = new GetContainingEmbeddedStatementVisitor();
                blockVisitor.LookupLocation = new Location(data.Caret.Column + 1, data.Caret.Line + 1);

                unit.AcceptVisitor(blockVisitor, null);

                StatementWithEmbeddedStatement containing = blockVisitor.ContainingStatement as StatementWithEmbeddedStatement;

                if (containing != null && !(containing.EmbeddedStatement is BlockStatement))
                {
                    insert.Offset       = data.Document.LocationToOffset(containing.StartLocation.Line - 1, containing.StartLocation.Column - 1);
                    lineSegment         = data.Document.GetLineByOffset(insert.Offset);
                    insert.RemovedChars = data.Document.LocationToOffset(containing.EndLocation.Line - 1, containing.EndLocation.Column - 1) - insert.Offset;
                    BlockStatement insertedBlock = new BlockStatement();
                    insertedBlock.AddChild(varDecl);
                    insertedBlock.AddChild(containing.EmbeddedStatement);

                    containing.EmbeddedStatement = insertedBlock;
                    insert.InsertedText          = provider.OutputNode(options.Dom, containing, options.GetWhitespaces(lineSegment.Offset)).TrimStart();
                    int offset, length;
                    if (SearchSubExpression(insert.InsertedText, data.SelectedText, 0, out offset, out length))
                    {
                        if (SearchSubExpression(insert.InsertedText, data.SelectedText, offset + 1, out offset, out length))
                        {
                            insert.InsertedText = insert.InsertedText.Substring(0, offset) + varName + insert.InsertedText.Substring(offset + length);
                            insertOffset        = insert.Offset + offset;
                        }
                    }
                }
                else if (blockVisitor.ContainingStatement is IfElseStatement)
                {
                    IfElseStatement ifElse = blockVisitor.ContainingStatement as IfElseStatement;

                    insert.Offset       = data.Document.LocationToOffset(blockVisitor.ContainingStatement.StartLocation.Line - 1, blockVisitor.ContainingStatement.StartLocation.Column - 1);
                    lineSegment         = data.Document.GetLineByOffset(insert.Offset);
                    insert.RemovedChars = data.Document.LocationToOffset(blockVisitor.ContainingStatement.EndLocation.Line - 1, blockVisitor.ContainingStatement.EndLocation.Column - 1) - insert.Offset;
                    BlockStatement insertedBlock = new BlockStatement();
                    insertedBlock.AddChild(varDecl);
                    if (blockVisitor.ContainsLocation(ifElse.TrueStatement[0]))
                    {
                        insertedBlock.AddChild(ifElse.TrueStatement[0]);
                        ifElse.TrueStatement[0] = insertedBlock;
                    }
                    else
                    {
                        insertedBlock.AddChild(ifElse.FalseStatement[0]);
                        ifElse.FalseStatement[0] = insertedBlock;
                    }

                    insert.InsertedText = provider.OutputNode(options.Dom, blockVisitor.ContainingStatement, options.GetWhitespaces(lineSegment.Offset));
                    int offset, length;

                    if (SearchSubExpression(insert.InsertedText, provider.OutputNode(options.Dom, insertedBlock), 0, out offset, out length))
                    {
                        if (SearchSubExpression(insert.InsertedText, data.SelectedText, offset + 1, out offset, out length))
                        {
                            if (SearchSubExpression(insert.InsertedText, data.SelectedText, offset + 1, out offset, out length))
                            {
                                insert.InsertedText = insert.InsertedText.Substring(0, offset) + varName + insert.InsertedText.Substring(offset + length);
                                insertOffset        = insert.Offset + offset;
                            }
                        }
                    }
                }
                else
                {
                    lineSegment         = data.Document.GetLine(data.Caret.Line);
                    insert.Offset       = lineSegment.Offset;
                    insert.InsertedText = options.GetWhitespaces(lineSegment.Offset) + provider.OutputNode(options.Dom, varDecl) + Environment.NewLine;
                    insertOffset        = insert.Offset + options.GetWhitespaces(lineSegment.Offset).Length + provider.OutputNode(options.Dom, varDecl.TypeReference).Length + " ".Length;

                    TextReplaceChange replace = new TextReplaceChange();
                    replace.FileName     = options.Document.FileName;
                    replace.Offset       = data.SelectionRange.Offset;
                    replace.RemovedChars = data.SelectionRange.Length;
                    replace.InsertedText = varName;
                    result.Add(replace);
                    replaceOffset = replace.Offset;
                    if (insert.Offset < replaceOffset)
                    {
                        replaceOffset += insert.InsertedText.Length - insert.RemovedChars;
                    }
                    varCount++;
                }
                result.Add(insert);
                varCount++;
                selectionStart = insert.Offset;
                return(result);
            }

            lineSegment = data.Document.GetLine(data.Caret.Line);
            string line = data.Document.GetTextAt(lineSegment);

            Expression expression = provider.ParseExpression(line);

            if (expression == null)
            {
                return(result);
            }

            resolveResult = resolver.Resolve(new ExpressionResult(line), new DomLocation(options.Document.TextEditor.CursorLine, options.Document.TextEditor.CursorColumn));

            if (resolveResult.ResolvedType != null && !string.IsNullOrEmpty(resolveResult.ResolvedType.FullName))
            {
                TextReplaceChange insert = new TextReplaceChange();
                insert.FileName    = options.Document.FileName;
                insert.Description = GettextCatalog.GetString("Insert variable declaration");
                insert.Offset      = lineSegment.Offset + options.GetWhitespaces(lineSegment.Offset).Length;
                varName            = CreateVariableName(resolveResult.ResolvedType, visitor);
                LocalVariableDeclaration varDecl = new LocalVariableDeclaration(options.ShortenTypeName(resolveResult.ResolvedType).ConvertToTypeReference());
                varDecl.Variables.Add(new VariableDeclaration(varName, expression));
                insert.RemovedChars = expression.EndLocation.Column - 1;
                insert.InsertedText = provider.OutputNode(options.Dom, varDecl);
                insertOffset        = insert.Offset + provider.OutputNode(options.Dom, varDecl.TypeReference).Length + " ".Length;

                result.Add(insert);
                varCount++;

                int idx = 0;
                while (idx < insert.InsertedText.Length - varName.Length)
                {
                    if (insert.InsertedText.Substring(idx, varName.Length) == varName && (idx == 0 || insert.InsertedText[idx - 1] == ' ') && (idx == insert.InsertedText.Length - varName.Length - 1 || insert.InsertedText[idx + varName.Length] == ' '))
                    {
                        selectionStart = insert.Offset + idx;
                        selectionEnd   = selectionStart + varName.Length;
                        break;
                    }
                    idx++;
                }
            }

            return(result);
        }
コード例 #5
0
        public override List <Change> PerformChanges(RefactoringOptions options, object properties)
        {
            List <Change> result = new List <Change> ();
            Parameters    param  = properties as Parameters;

            if (param == null)
            {
                return(result);
            }
            TextEditorData data          = options.GetTextEditorData();
            IResolver      resolver      = options.GetResolver();
            IMember        curMember     = options.Document.CompilationUnit.GetMemberAt(data.Caret.Line, data.Caret.Column);
            ResolveResult  resolveResult = options.ResolveResult;
            int            start         = 0;
            int            end           = 0;

            if (resolveResult == null)
            {
                LineSegment line = data.Document.GetLine(data.Caret.Line);
                if (line != null)
                {
                    Stack <Span> stack = line.StartSpan != null ? new Stack <Span> (line.StartSpan) : new Stack <Span> ();
                    Mono.TextEditor.Highlighting.SyntaxModeService.ScanSpans(data.Document, data.Document.SyntaxMode, data.Document.SyntaxMode, stack, line.Offset, data.Caret.Offset);
                    foreach (Span span in stack)
                    {
                        if (span.Color == "string.single" || span.Color == "string.double")
                        {
                            resolveResult = resolver.Resolve(new ExpressionResult(SearchString(data, span.Color == "string.single" ? '\'' : '"', out start, out end)), DomLocation.Empty);
                            end++;
                        }
                    }
                }
                if (end == 0)
                {
                    resolveResult = resolver.Resolve(new ExpressionResult(SearchNumber(data, out start, out end)), DomLocation.Empty);
                }
            }
            else
            {
                start = data.Document.LocationToOffset(resolveResult.ResolvedExpression.Region.Start.Line - 1, resolveResult.ResolvedExpression.Region.Start.Column - 1);
                end   = data.Document.LocationToOffset(resolveResult.ResolvedExpression.Region.End.Line - 1, resolveResult.ResolvedExpression.Region.End.Column - 1);
            }
            if (start == 0 && end == 0)
            {
                return(result);
            }
            INRefactoryASTProvider provider = options.GetASTProvider();

            FieldDeclaration    fieldDeclaration = new FieldDeclaration(null);
            VariableDeclaration varDecl          = new VariableDeclaration(param.Name);

            varDecl.Initializer = provider.ParseExpression(resolveResult.ResolvedExpression.Expression);
            fieldDeclaration.Fields.Add(varDecl);
            fieldDeclaration.Modifier                = param.Modifiers;
            fieldDeclaration.Modifier               |= ICSharpCode.NRefactory.Ast.Modifiers.Const;
            fieldDeclaration.TypeReference           = resolveResult.ResolvedType.ConvertToTypeReference();
            fieldDeclaration.TypeReference.IsKeyword = true;

            TextReplaceChange insertConstant = new TextReplaceChange();

            insertConstant.FileName     = options.Document.FileName;
            insertConstant.Description  = string.Format(GettextCatalog.GetString("Generate constant '{0}'"), param.Name);
            insertConstant.Offset       = data.Document.LocationToOffset(curMember.Location.Line - 1, 0);
            insertConstant.InsertedText = provider.OutputNode(options.Dom, fieldDeclaration, options.GetIndent(curMember)) + Environment.NewLine;
            result.Add(insertConstant);

            TextReplaceChange replaceConstant = new TextReplaceChange();

            replaceConstant.FileName     = options.Document.FileName;
            replaceConstant.Description  = string.Format(GettextCatalog.GetString("Replace expression with constant '{0}'"), param.Name);
            replaceConstant.Offset       = start;
            replaceConstant.RemovedChars = end - start;
            replaceConstant.InsertedText = param.Name;
            result.Add(replaceConstant);

            return(result);
        }
コード例 #6
0
        public override List <Change> PerformChanges(RefactoringOptions options, object prop)
        {
            varCount       = 0;
            selectionStart = selectionEnd = -1;

            List <Change>          result   = new List <Change> ();
            IResolver              resolver = options.GetResolver();
            INRefactoryASTProvider provider = options.GetASTProvider();
            TextEditorData         data     = options.GetTextEditorData();

            if (resolver == null || provider == null || data == null)
            {
                return(result);
            }

            DocumentLocation endPoint;

            if (data.IsSomethingSelected)
            {
                endPoint = data.MainSelection.Anchor < data.MainSelection.Lead ? data.MainSelection.Lead : data.MainSelection.Anchor;
            }
            else
            {
                endPoint = data.Caret.Location;
            }
            ResolveResult resolveResult;
            LineSegment   lineSegment;
            var           unit = provider.ParseFile(data.Document.Text);

            if (unit == null)
            {
                LoggingService.LogError("Declare local error: parese file == null");
                return(result);
            }
            var visitor = new VariableLookupVisitor(resolver, new DomLocation(endPoint.Line, endPoint.Column));

            if (options.ResolveResult == null)
            {
                LoggingService.LogError("Declare local error: resolve result == null");
                return(result);
            }
            IMember callingMember = options.ResolveResult.CallingMember;

            if (callingMember != null)
            {
                visitor.MemberLocation = new AstLocation(callingMember.Location.Column, callingMember.Location.Line);
            }
            unit.AcceptVisitor(visitor, null);

            ExpressionResult expressionResult = new ExpressionResult(data.SelectedText.Trim());

            if (expressionResult.Expression.Contains(" ") || expressionResult.Expression.Contains("\t"))
            {
                expressionResult.Expression = "(" + expressionResult.Expression + ")";
            }
            resolveResult = resolver.Resolve(expressionResult, new DomLocation(endPoint.Line, endPoint.Column));
            if (resolveResult == null)
            {
                return(result);
            }
            IReturnType resolvedType = GetResolvedType(options, resolveResult);

            AstType returnType;

            if (resolveResult.ResolvedType == null || string.IsNullOrEmpty(resolveResult.ResolvedType.Name))
            {
                returnType = new SimpleType("var");
            }
            else
            {
                returnType = options.ShortenTypeName(resolvedType).ConvertToTypeReference();
            }

            varName = CreateVariableName(resolvedType, visitor);
            options.ParseMember(resolveResult.CallingMember);

            // insert local variable declaration
            TextReplaceChange insert = new TextReplaceChange();

            insert.FileName    = options.Document.FileName;
            insert.Description = GettextCatalog.GetString("Insert variable declaration");

            var varDecl = new VariableDeclarationStatement(returnType, varName, provider.ParseExpression(data.SelectedText));

            var node = unit.GetNodeAt(endPoint.Line, endPoint.Column);

            var containing = node.Parent;

            while (!(containing.Parent is BlockStatement))
            {
                containing = containing.Parent;
            }

            if (containing is BlockStatement)
            {
                lineSegment = data.Document.GetLine(data.Caret.Line);
            }
            else
            {
                lineSegment = data.Document.GetLine(containing.StartLocation.Line);
            }
            insert.Offset       = lineSegment.Offset;
            insert.InsertedText = options.GetWhitespaces(lineSegment.Offset) + provider.OutputNode(options.Dom, varDecl);
            var insertOffset = insert.Offset + options.GetWhitespaces(lineSegment.Offset).Length + provider.OutputNode(options.Dom, varDecl.Type).Length + " ".Length;

            offsets.Add(insertOffset);
            result.Add(insert);
            varCount++;

            // replace main selection
            TextReplaceChange replace = new TextReplaceChange();

            replace.FileName     = options.Document.FileName;
            replace.Offset       = data.SelectionRange.Offset;
            replace.RemovedChars = data.SelectionRange.Length;
            replace.InsertedText = varName;
            result.Add(replace);
            int delta = insert.InsertedText.Length - insert.RemovedChars;

            offsets.Add(replace.Offset + delta);
            Console.WriteLine(replace.Offset);
            delta += varName.Length - replace.RemovedChars;
            varCount++;
            selectionStart = insert.Offset;

            if (replaceAll)
            {
                matches.Sort((x, y) => x.StartLocation.CompareTo(y.StartLocation));
                foreach (var match in matches)
                {
                    replace          = new TextReplaceChange();
                    replace.FileName = options.Document.FileName;
                    int start = data.LocationToOffset(match.StartLocation.Line, match.StartLocation.Column);
                    int end   = data.LocationToOffset(match.EndLocation.Line, match.EndLocation.Column);

                    replace.Offset       = start;
                    replace.RemovedChars = end - start;
                    replace.InsertedText = varName;
                    result.Add(replace);
                    offsets.Add(start + delta);
                    delta += varName.Length - replace.RemovedChars;
                }
            }
            return(result);
        }