private void InsertDeclaration(Declaration target) { var firstReference = target.References.OrderBy(r => r.Selection.StartLine).First(); var beginningOfInstructionSelection = GetBeginningOfInstructionSelection(target, firstReference.Selection); var oldLines = _editor.GetLines(beginningOfInstructionSelection); var newLines = oldLines.Insert(beginningOfInstructionSelection.StartColumn - 1, GetDeclarationString(target)); var newLinesWithoutStringLiterals = newLines.StripStringLiterals(); var lastIndexOfColon = newLinesWithoutStringLiterals.LastIndexOf(':'); while (lastIndexOfColon != -1) { var numberOfCharsToRemove = lastIndexOfColon == newLines.Length - 1 || newLines[lastIndexOfColon + 1] != ' ' ? 1 : 2; newLinesWithoutStringLiterals = newLinesWithoutStringLiterals .Remove(lastIndexOfColon, numberOfCharsToRemove) .Insert(lastIndexOfColon, Environment.NewLine); newLines = newLines .Remove(lastIndexOfColon, numberOfCharsToRemove) .Insert(lastIndexOfColon, Environment.NewLine); lastIndexOfColon = newLinesWithoutStringLiterals.LastIndexOf(':'); } _editor.DeleteLines(beginningOfInstructionSelection); _editor.InsertLines(beginningOfInstructionSelection.StartLine, newLines); }
private void RemoveVariable(Declaration target) { Selection selection; var declarationText = target.Context.GetText(); var multipleDeclarations = target.HasMultipleDeclarationsInStatement(); var variableStmtContext = target.GetVariableStmtContext(); if (!multipleDeclarations) { declarationText = variableStmtContext.GetText(); selection = target.GetVariableStmtContextSelection(); } else { selection = new Selection(target.Context.Start.Line, target.Context.Start.Column, target.Context.Stop.Line, target.Context.Stop.Column); } var oldLines = _editor.GetLines(selection); var newLines = oldLines.Replace(" _" + Environment.NewLine, string.Empty) .Remove(selection.StartColumn, declarationText.Length); if (multipleDeclarations) { selection = target.GetVariableStmtContextSelection(); newLines = RemoveExtraComma(_editor.GetLines(selection).Replace(oldLines, newLines), target.CountOfDeclarationsInStatement(), target.IndexOfVariableDeclarationInStatement()); } var newLinesWithoutExcessSpaces = newLines.Split(new[] { Environment.NewLine }, StringSplitOptions.None); for (var i = 0; i < newLinesWithoutExcessSpaces.Length; i++) { newLinesWithoutExcessSpaces[i] = newLinesWithoutExcessSpaces[i].RemoveExtraSpacesLeavingIndentation(); } for (var i = newLinesWithoutExcessSpaces.Length - 1; i >= 0; i--) { if (newLinesWithoutExcessSpaces[i].Trim() == string.Empty) { continue; } if (newLinesWithoutExcessSpaces[i].EndsWith(" _")) { newLinesWithoutExcessSpaces[i] = newLinesWithoutExcessSpaces[i].Remove(newLinesWithoutExcessSpaces[i].Length - 2); } break; } _editor.DeleteLines(selection); _editor.InsertLines(selection.StartLine, string.Join(Environment.NewLine, newLinesWithoutExcessSpaces)); }
public ExtractMethodModel(IActiveCodePaneEditor editor, IEnumerable<Declaration> declarations, QualifiedSelection selection) { var items = declarations.ToList(); _sourceMember = items.FindSelectedDeclaration(selection, DeclarationExtensions.ProcedureTypes, d => ((ParserRuleContext)d.Context.Parent).GetSelection()); if (_sourceMember == null) { throw new InvalidOperationException("Invalid selection."); } _extractedMethod = new ExtractedMethod(); _selection = selection; _selectedCode = editor.GetLines(selection.Selection); var inScopeDeclarations = items.Where(item => item.ParentScope == _sourceMember.Scope).ToList(); var inSelection = inScopeDeclarations.SelectMany(item => item.References) .Where(item => selection.Selection.Contains(item.Selection)) .ToList(); var usedInSelection = new HashSet<Declaration>(inScopeDeclarations.Where(item => selection.Selection.Contains(item.Selection) || item.References.Any(reference => inSelection.Contains(reference)))); var usedBeforeSelection = new HashSet<Declaration>(inScopeDeclarations.Where(item => item.Selection.StartLine < selection.Selection.StartLine || item.References.Any(reference => reference.Selection.StartLine < selection.Selection.StartLine))); var usedAfterSelection = new HashSet<Declaration>(inScopeDeclarations.Where(item => item.Selection.StartLine > selection.Selection.StartLine || item.References.Any(reference => reference.Selection.StartLine > selection.Selection.EndLine))); // identifiers used inside selection and before selection (or if it's a parameter) are candidates for parameters: var input = inScopeDeclarations.Where(item => usedInSelection.Contains(item) && (usedBeforeSelection.Contains(item) || item.DeclarationType == DeclarationType.Parameter)).ToList(); // identifiers used inside selection and after selection are candidates for return values: var output = inScopeDeclarations.Where(item => usedInSelection.Contains(item) && usedAfterSelection.Contains(item)) .ToList(); // identifiers used only inside and/or after selection are candidates for locals: _locals = inScopeDeclarations.Where(item => item.DeclarationType != DeclarationType.Parameter && ( item.References.All(reference => inSelection.Contains(reference)) || (usedAfterSelection.Contains(item) && (!usedBeforeSelection.Contains(item))))) .ToList(); // locals that are only used in selection are candidates for being moved into the new method: _declarationsToMove = _locals.Where(item => !usedAfterSelection.Contains(item)).ToList(); _output = output.Select(declaration => new ExtractedParameter(declaration.AsTypeName, ExtractedParameter.PassedBy.ByRef, declaration.IdentifierName)); _input = input.Where(declaration => !output.Contains(declaration)) .Select(declaration => new ExtractedParameter(declaration.AsTypeName, ExtractedParameter.PassedBy.ByVal, declaration.IdentifierName)); }
public ExtractMethodModel(IActiveCodePaneEditor editor, IEnumerable <Declaration> declarations, QualifiedSelection selection) { var items = declarations.ToList(); _sourceMember = items.FindSelectedDeclaration(selection, DeclarationExtensions.ProcedureTypes, d => ((ParserRuleContext)d.Context.Parent).GetSelection()); if (_sourceMember == null) { throw new InvalidOperationException("Invalid selection."); } _extractedMethod = new ExtractedMethod(); _selection = selection; _selectedCode = editor.GetLines(selection.Selection); var inScopeDeclarations = items.Where(item => item.ParentScope == _sourceMember.Scope).ToList(); var inSelection = inScopeDeclarations.SelectMany(item => item.References) .Where(item => selection.Selection.Contains(item.Selection)) .ToList(); var usedInSelection = new HashSet <Declaration>(inScopeDeclarations.Where(item => selection.Selection.Contains(item.Selection) || item.References.Any(reference => inSelection.Contains(reference)))); var usedBeforeSelection = new HashSet <Declaration>(inScopeDeclarations.Where(item => item.Selection.StartLine < selection.Selection.StartLine || item.References.Any(reference => reference.Selection.StartLine < selection.Selection.StartLine))); var usedAfterSelection = new HashSet <Declaration>(inScopeDeclarations.Where(item => item.Selection.StartLine > selection.Selection.StartLine || item.References.Any(reference => reference.Selection.StartLine > selection.Selection.EndLine))); // identifiers used inside selection and before selection (or if it's a parameter) are candidates for parameters: var input = inScopeDeclarations.Where(item => usedInSelection.Contains(item) && (usedBeforeSelection.Contains(item) || item.DeclarationType == DeclarationType.Parameter)).ToList(); // identifiers used inside selection and after selection are candidates for return values: var output = inScopeDeclarations.Where(item => usedInSelection.Contains(item) && usedAfterSelection.Contains(item)) .ToList(); // identifiers used only inside and/or after selection are candidates for locals: _locals = inScopeDeclarations.Where(item => item.DeclarationType != DeclarationType.Parameter && ( item.References.All(reference => inSelection.Contains(reference)) || (usedAfterSelection.Contains(item) && (!usedBeforeSelection.Contains(item))))) .ToList(); // locals that are only used in selection are candidates for being moved into the new method: _declarationsToMove = _locals.Where(item => !usedAfterSelection.Contains(item)).ToList(); _output = output.Select(declaration => new ExtractedParameter(declaration.AsTypeName, ExtractedParameter.PassedBy.ByRef, declaration.IdentifierName)); _input = input.Where(declaration => !output.Contains(declaration)) .Select(declaration => new ExtractedParameter(declaration.AsTypeName, ExtractedParameter.PassedBy.ByVal, declaration.IdentifierName)); }
private void RemoveField(Declaration target) { Selection selection; var declarationText = target.Context.GetText(); var multipleDeclarations = target.HasMultipleDeclarationsInStatement(); var variableStmtContext = target.GetVariableStmtContext(); if (!multipleDeclarations) { declarationText = variableStmtContext.GetText(); selection = target.GetVariableStmtContextSelection(); } else { selection = new Selection(target.Context.Start.Line, target.Context.Start.Column, target.Context.Stop.Line, target.Context.Stop.Column); } var oldLines = _editor.GetLines(selection); var newLines = oldLines.Replace(" _" + Environment.NewLine, string.Empty) .Remove(selection.StartColumn, declarationText.Length); if (multipleDeclarations) { selection = target.GetVariableStmtContextSelection(); newLines = RemoveExtraComma(_editor.GetLines(selection).Replace(oldLines, newLines), target.CountOfDeclarationsInStatement(), target.IndexOfVariableDeclarationInStatement()); } newLines = newLines.Replace(" _" + Environment.NewLine, string.Empty); _editor.DeleteLines(selection); if (newLines.Trim() != string.Empty) { _editor.InsertLines(selection.StartLine, newLines); } }