Example #1
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);
        }
		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;
		}