| Index: pkg/analysis_server/lib/src/services/generated/util.dart
|
| diff --git a/pkg/analysis_server/lib/src/services/generated/util.dart b/pkg/analysis_server/lib/src/services/generated/util.dart
|
| index fdfb01bf22d2ef7318a3fdf39c7333b189ad952f..c969c961530833012218efc2575d335918a2781c 100644
|
| --- a/pkg/analysis_server/lib/src/services/generated/util.dart
|
| +++ b/pkg/analysis_server/lib/src/services/generated/util.dart
|
| @@ -16,9 +16,6 @@ import 'package:analyzer/src/generated/error.dart';
|
| import 'package:analyzer/src/generated/resolver.dart';
|
| import 'package:analyzer/src/generated/source.dart';
|
| import 'package:analyzer/src/generated/scanner.dart';
|
| -import 'change.dart';
|
| -import 'proposal.dart';
|
| -import 'status.dart';
|
| import 'stubs.dart';
|
|
|
| /**
|
| @@ -123,31 +120,6 @@ class CorrectionUtils {
|
| static List<String> _KNOWN_METHOD_NAME_PREFIXES = ["get", "is", "to"];
|
|
|
| /**
|
| - * Validates that the [Edit] replaces the expected part of the [Source] and adds this
|
| - * [Edit] to the [SourceChange].
|
| - */
|
| - static void addEdit(AnalysisContext context, SourceChange change, String description, String expected, Edit edit) {
|
| - if (_DEBUG_VALIDATE_EDITS) {
|
| - Source source = change.source;
|
| - String sourceContent = getSourceContent(context, source);
|
| - // prepare range
|
| - int beginIndex = edit.offset;
|
| - int endIndex = beginIndex + edit.length;
|
| - int sourceLength = sourceContent.length;
|
| - if (beginIndex >= sourceLength || endIndex >= sourceLength) {
|
| - throw new IllegalStateException("${source} has ${sourceLength} characters but ${beginIndex} to ${endIndex} requested.\n\nTry to use Tools | Reanalyze Sources.");
|
| - }
|
| - // check that range has expected content
|
| - String rangeContent = sourceContent.substring(beginIndex, endIndex);
|
| - if (rangeContent != expected) {
|
| - throw new IllegalStateException("${source} expected |${expected}| at ${beginIndex} to ${endIndex} but |${rangeContent}| found.\n\nTry to use Tools | Reanalyze Sources.");
|
| - }
|
| - }
|
| - // do add the Edit
|
| - change.addEdit(edit, description);
|
| - }
|
| -
|
| - /**
|
| * @return <code>true</code> if given [List]s are equals at given position.
|
| */
|
| static bool allListsEqual(List<List> lists, int position) {
|
| @@ -161,26 +133,6 @@ class CorrectionUtils {
|
| }
|
|
|
| /**
|
| - * @return the updated [String] with applied [Edit]s.
|
| - */
|
| - static String applyReplaceEdits(String s, List<Edit> edits) {
|
| - // sort edits
|
| - edits = [];
|
| - edits.sort((Edit o1, Edit o2) => o1.offset - o2.offset);
|
| - // apply edits
|
| - int delta = 0;
|
| - for (Edit edit in edits) {
|
| - int editOffset = edit.offset + delta;
|
| - String beforeEdit = s.substring(0, editOffset);
|
| - String afterEdit = s.substring(editOffset + edit.length);
|
| - s = "${beforeEdit}${edit.replacement}${afterEdit}";
|
| - delta += getDeltaOffset(edit);
|
| - }
|
| - // done
|
| - return s;
|
| - }
|
| -
|
| - /**
|
| * @return <code>true</code> if given [SourceRange] covers given [AstNode].
|
| */
|
| static bool covers(SourceRange r, AstNode node) {
|
| @@ -225,11 +177,6 @@ class CorrectionUtils {
|
| }
|
|
|
| /**
|
| - * @return the number of characters this [Edit] will move offsets after its range.
|
| - */
|
| - static int getDeltaOffset(Edit edit) => edit.replacement.length - edit.length;
|
| -
|
| - /**
|
| * @return the name of the [Element] kind.
|
| */
|
| static String getElementKindName(Element element) {
|
| @@ -939,17 +886,6 @@ class CorrectionUtils {
|
| return result;
|
| }
|
|
|
| - /**
|
| - * Adds enclosing parenthesis if the precedence of the [InvertedCondition] if less than the
|
| - * precedence of the expression we are going it to use in.
|
| - */
|
| - static String _parenthesizeIfRequired(CorrectionUtils_InvertedCondition expr, int newOperatorPrecedence) {
|
| - if (expr._precedence < newOperatorPrecedence) {
|
| - return "(${expr._source})";
|
| - }
|
| - return expr._source;
|
| - }
|
| -
|
| final CompilationUnit unit;
|
|
|
| LibraryElement _library;
|
| @@ -965,15 +901,6 @@ class CorrectionUtils {
|
| }
|
|
|
| /**
|
| - * @return the source of the given [SourceRange] with indentation changed from "oldIndent"
|
| - * to "newIndent", keeping indentation of the lines relative to each other.
|
| - */
|
| - Edit createIndentEdit(SourceRange range, String oldIndent, String newIndent) {
|
| - String newSource = getIndentSource(range, oldIndent, newIndent);
|
| - return new Edit(range.offset, range.length, newSource);
|
| - }
|
| -
|
| - /**
|
| * @return the [AstNode] that encloses the given offset.
|
| */
|
| AstNode findNode(int offset) => new NodeLocator.con1(offset).searchWithin(unit);
|
| @@ -1506,11 +1433,6 @@ class CorrectionUtils {
|
| }
|
|
|
| /**
|
| - * @return the source of the inverted condition for the given logical expression.
|
| - */
|
| - String invertCondition(Expression expression) => _invertCondition0(expression)._source;
|
| -
|
| - /**
|
| * @return <code>true</code> if selection range contains only whitespace.
|
| */
|
| bool isJustWhitespace(SourceRange range) => getText3(range).trim().length == 0;
|
| @@ -1571,89 +1493,6 @@ class CorrectionUtils {
|
| return null;
|
| }
|
|
|
| - /**
|
| - * @return the [InvertedCondition] for the given logical expression.
|
| - */
|
| - CorrectionUtils_InvertedCondition _invertCondition0(Expression expression) {
|
| - if (expression is BooleanLiteral) {
|
| - BooleanLiteral literal = expression;
|
| - if (literal.value) {
|
| - return CorrectionUtils_InvertedCondition._simple("false");
|
| - } else {
|
| - return CorrectionUtils_InvertedCondition._simple("true");
|
| - }
|
| - }
|
| - if (expression is BinaryExpression) {
|
| - BinaryExpression binary = expression;
|
| - TokenType operator = binary.operator.type;
|
| - Expression le = binary.leftOperand;
|
| - Expression re = binary.rightOperand;
|
| - CorrectionUtils_InvertedCondition ls = _invertCondition0(le);
|
| - CorrectionUtils_InvertedCondition rs = _invertCondition0(re);
|
| - if (operator == TokenType.LT) {
|
| - return CorrectionUtils_InvertedCondition._binary2(ls, " >= ", rs);
|
| - }
|
| - if (operator == TokenType.GT) {
|
| - return CorrectionUtils_InvertedCondition._binary2(ls, " <= ", rs);
|
| - }
|
| - if (operator == TokenType.LT_EQ) {
|
| - return CorrectionUtils_InvertedCondition._binary2(ls, " > ", rs);
|
| - }
|
| - if (operator == TokenType.GT_EQ) {
|
| - return CorrectionUtils_InvertedCondition._binary2(ls, " < ", rs);
|
| - }
|
| - if (operator == TokenType.EQ_EQ) {
|
| - return CorrectionUtils_InvertedCondition._binary2(ls, " != ", rs);
|
| - }
|
| - if (operator == TokenType.BANG_EQ) {
|
| - return CorrectionUtils_InvertedCondition._binary2(ls, " == ", rs);
|
| - }
|
| - if (operator == TokenType.AMPERSAND_AMPERSAND) {
|
| - int newPrecedence = TokenType.BAR_BAR.precedence;
|
| - return CorrectionUtils_InvertedCondition._binary(newPrecedence, ls, " || ", rs);
|
| - }
|
| - if (operator == TokenType.BAR_BAR) {
|
| - int newPrecedence = TokenType.AMPERSAND_AMPERSAND.precedence;
|
| - return CorrectionUtils_InvertedCondition._binary(newPrecedence, ls, " && ", rs);
|
| - }
|
| - }
|
| - if (expression is IsExpression) {
|
| - IsExpression isExpression = expression;
|
| - String expressionSource = getText(isExpression.expression);
|
| - String typeSource = getText(isExpression.type);
|
| - if (isExpression.notOperator == null) {
|
| - return CorrectionUtils_InvertedCondition._simple("${expressionSource} is! ${typeSource}");
|
| - } else {
|
| - return CorrectionUtils_InvertedCondition._simple("${expressionSource} is ${typeSource}");
|
| - }
|
| - }
|
| - if (expression is PrefixExpression) {
|
| - PrefixExpression prefixExpression = expression;
|
| - TokenType operator = prefixExpression.operator.type;
|
| - if (operator == TokenType.BANG) {
|
| - Expression operand = prefixExpression.operand;
|
| - while (operand is ParenthesizedExpression) {
|
| - ParenthesizedExpression pe = operand as ParenthesizedExpression;
|
| - operand = pe.expression;
|
| - }
|
| - return CorrectionUtils_InvertedCondition._simple(getText(operand));
|
| - }
|
| - }
|
| - if (expression is ParenthesizedExpression) {
|
| - ParenthesizedExpression pe = expression;
|
| - Expression innerExpresion = pe.expression;
|
| - while (innerExpresion is ParenthesizedExpression) {
|
| - innerExpresion = (innerExpresion as ParenthesizedExpression).expression;
|
| - }
|
| - return _invertCondition0(innerExpresion);
|
| - }
|
| - DartType type = expression.bestType;
|
| - if (type.displayName == "bool") {
|
| - return CorrectionUtils_InvertedCondition._simple("!${getText(expression)}");
|
| - }
|
| - return CorrectionUtils_InvertedCondition._simple(getText(expression));
|
| - }
|
| -
|
| bool _selectionIncludesNonWhitespaceOutsideOperands(SourceRange selection, List<Expression> operands) => _selectionIncludesNonWhitespaceOutsideRange(selection, SourceRangeFactory.rangeNodes(operands));
|
|
|
| /**
|
| @@ -1689,24 +1528,6 @@ class CorrectionUtils_InsertDesc {
|
| String suffix = "";
|
| }
|
|
|
| -/**
|
| - * This class is used to hold the source and also its precedence during inverting logical
|
| - * expressions.
|
| - */
|
| -class CorrectionUtils_InvertedCondition {
|
| - static CorrectionUtils_InvertedCondition _binary(int precedence, CorrectionUtils_InvertedCondition left, String operation, CorrectionUtils_InvertedCondition right) => new CorrectionUtils_InvertedCondition(precedence, "${CorrectionUtils._parenthesizeIfRequired(left, precedence)}${operation}${CorrectionUtils._parenthesizeIfRequired(right, precedence)}");
|
| -
|
| - static CorrectionUtils_InvertedCondition _binary2(CorrectionUtils_InvertedCondition left, String operation, CorrectionUtils_InvertedCondition right) => new CorrectionUtils_InvertedCondition(2147483647, "${left._source}${operation}${right._source}");
|
| -
|
| - static CorrectionUtils_InvertedCondition _simple(String source) => new CorrectionUtils_InvertedCondition(2147483647, source);
|
| -
|
| - final int _precedence;
|
| -
|
| - final String _source;
|
| -
|
| - CorrectionUtils_InvertedCondition(this._precedence, this._source);
|
| -}
|
| -
|
| class GeneralizingAstVisitor_CorrectionUtils_getOperandsInOrderFor extends GeneralizingAstVisitor<Object> {
|
| TokenType groupOperatorType;
|
|
|
| @@ -1881,452 +1702,6 @@ class NameOccurrencesFinder extends RecursiveAstVisitor<Object> {
|
| }
|
|
|
| /**
|
| - * Abstract visitor for visiting [AstNode]s covered by the selection [SourceRange].
|
| - */
|
| -class SelectionAnalyzer extends GeneralizingAstVisitor<Object> {
|
| - SourceRange selection;
|
| -
|
| - AstNode _coveringNode;
|
| -
|
| - List<AstNode> _selectedNodes;
|
| -
|
| - SelectionAnalyzer(SourceRange selection) {
|
| - assert(selection != null);
|
| - this.selection = selection;
|
| - }
|
| -
|
| - /**
|
| - * @return the [AstNode] with the shortest length which completely covers the specified
|
| - * selection.
|
| - */
|
| - AstNode get coveringNode => _coveringNode;
|
| -
|
| - /**
|
| - * @return the first selected [AstNode], may be <code>null</code>.
|
| - */
|
| - AstNode get firstSelectedNode {
|
| - if (_selectedNodes == null || _selectedNodes.isEmpty) {
|
| - return null;
|
| - }
|
| - return _selectedNodes[0];
|
| - }
|
| -
|
| - /**
|
| - * @return the last selected [AstNode], may be <code>null</code>.
|
| - */
|
| - AstNode get lastSelectedNode {
|
| - if (_selectedNodes == null || _selectedNodes.isEmpty) {
|
| - return null;
|
| - }
|
| - return _selectedNodes[_selectedNodes.length - 1];
|
| - }
|
| -
|
| - /**
|
| - * @return the [SourceRange] which covers selected [AstNode]s, may be
|
| - * <code>null</code> if no [AstNode]s under selection.
|
| - */
|
| - SourceRange get selectedNodeRange {
|
| - if (_selectedNodes == null || _selectedNodes.isEmpty) {
|
| - return null;
|
| - }
|
| - AstNode firstNode = _selectedNodes[0];
|
| - AstNode lastNode = _selectedNodes[_selectedNodes.length - 1];
|
| - return SourceRangeFactory.rangeStartEnd(firstNode, lastNode);
|
| - }
|
| -
|
| - /**
|
| - * @return the [AstNode]s fully covered by the selection [SourceRange].
|
| - */
|
| - List<AstNode> get selectedNodes {
|
| - if (_selectedNodes == null || _selectedNodes.isEmpty) {
|
| - return [];
|
| - }
|
| - return _selectedNodes;
|
| - }
|
| -
|
| - /**
|
| - * @return <code>true</code> if there are [AstNode] fully covered by the selection
|
| - * [SourceRange].
|
| - */
|
| - bool get hasSelectedNodes => _selectedNodes != null && !_selectedNodes.isEmpty;
|
| -
|
| - @override
|
| - Object visitNode(AstNode node) {
|
| - SourceRange nodeRange = SourceRangeFactory.rangeNode(node);
|
| - if (selection.covers(nodeRange)) {
|
| - if (isFirstNode) {
|
| - handleFirstSelectedNode(node);
|
| - } else {
|
| - handleNextSelectedNode(node);
|
| - }
|
| - return null;
|
| - } else if (selection.coveredBy(nodeRange)) {
|
| - _coveringNode = node;
|
| - node.visitChildren(this);
|
| - return null;
|
| - } else if (selection.startsIn(nodeRange)) {
|
| - handleSelectionStartsIn(node);
|
| - node.visitChildren(this);
|
| - return null;
|
| - } else if (selection.endsIn(nodeRange)) {
|
| - handleSelectionEndsIn(node);
|
| - node.visitChildren(this);
|
| - return null;
|
| - }
|
| - // no intersection
|
| - return null;
|
| - }
|
| -
|
| - /**
|
| - * Adds first selected [AstNode].
|
| - */
|
| - void handleFirstSelectedNode(AstNode node) {
|
| - _selectedNodes = [];
|
| - _selectedNodes.add(node);
|
| - }
|
| -
|
| - /**
|
| - * Adds second or more selected [AstNode].
|
| - */
|
| - void handleNextSelectedNode(AstNode node) {
|
| - if (identical(firstSelectedNode.parent, node.parent)) {
|
| - _selectedNodes.add(node);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Notifies that selection ends in given [AstNode].
|
| - */
|
| - void handleSelectionEndsIn(AstNode node) {
|
| - }
|
| -
|
| - /**
|
| - * Notifies that selection starts in given [AstNode].
|
| - */
|
| - void handleSelectionStartsIn(AstNode node) {
|
| - }
|
| -
|
| - /**
|
| - * Resets selected nodes.
|
| - */
|
| - void reset() {
|
| - _selectedNodes = null;
|
| - }
|
| -
|
| - /**
|
| - * @return <code>true</code> if there was no selected nodes yet.
|
| - */
|
| - bool get isFirstNode => _selectedNodes == null;
|
| -}
|
| -
|
| -/**
|
| - * Helper for building Dart source with tracked positions.
|
| - */
|
| -class SourceBuilder {
|
| - final int offset;
|
| -
|
| - JavaStringBuilder _buffer = new JavaStringBuilder();
|
| -
|
| - Map<String, List<SourceRange>> _linkedPositions = {};
|
| -
|
| - final Map<String, List<LinkedPositionProposal>> linkedProposals = {};
|
| -
|
| - String _currentPositionGroupId;
|
| -
|
| - int _currentPositionStart = 0;
|
| -
|
| - int _endPosition = -1;
|
| -
|
| - SourceBuilder.con1(this.offset);
|
| -
|
| - SourceBuilder.con2(SourceRange offsetRange) : this.con1(offsetRange.offset);
|
| -
|
| - /**
|
| - * Adds proposal for the current position, may be called after [startPosition].
|
| - */
|
| - void addProposal(CorrectionImage icon, String text) {
|
| - List<LinkedPositionProposal> proposals = linkedProposals[_currentPositionGroupId];
|
| - if (proposals == null) {
|
| - proposals = [];
|
| - linkedProposals[_currentPositionGroupId] = proposals;
|
| - }
|
| - proposals.add(new LinkedPositionProposal(icon, text));
|
| - }
|
| -
|
| - /**
|
| - * Appends source to the buffer.
|
| - */
|
| - SourceBuilder append(String s) {
|
| - _buffer.append(s);
|
| - return this;
|
| - }
|
| -
|
| - /**
|
| - * Ends position started using [startPosition].
|
| - */
|
| - void endPosition() {
|
| - assert(_currentPositionGroupId != null);
|
| - _addPosition();
|
| - _currentPositionGroupId = null;
|
| - }
|
| -
|
| - /**
|
| - * @return the "end position" for the [CorrectionProposal], may be <code>-1</code> if not
|
| - * set in this [SourceBuilder].
|
| - */
|
| - int get endPosition2 {
|
| - if (_endPosition == -1) {
|
| - return -1;
|
| - }
|
| - return offset + _endPosition;
|
| - }
|
| -
|
| - /**
|
| - * @return the [Map] or position IDs to their locations.
|
| - */
|
| - Map<String, List<SourceRange>> get linkedPositions => _linkedPositions;
|
| -
|
| - /**
|
| - * @return the length of the built source.
|
| - */
|
| - int length() => _buffer.length;
|
| -
|
| - /**
|
| - * Marks current position as "end position" of the [CorrectionProposal].
|
| - */
|
| - void setEndPosition() {
|
| - _endPosition = _buffer.length;
|
| - }
|
| -
|
| - /**
|
| - * Sets text-only proposals for the current position.
|
| - */
|
| - void set proposals(List<String> proposals) {
|
| - List<LinkedPositionProposal> proposalList = [];
|
| - for (String proposalText in proposals) {
|
| - proposalList.add(new LinkedPositionProposal(null, proposalText));
|
| - }
|
| - linkedProposals[_currentPositionGroupId] = proposalList;
|
| - }
|
| -
|
| - /**
|
| - * Starts linked position with given ID.
|
| - */
|
| - void startPosition(String groupId) {
|
| - assert(_currentPositionGroupId == null);
|
| - _currentPositionGroupId = groupId;
|
| - _currentPositionStart = _buffer.length;
|
| - }
|
| -
|
| - @override
|
| - String toString() => _buffer.toString();
|
| -
|
| - /**
|
| - * Adds position location [SourceRange] using current fields.
|
| - */
|
| - void _addPosition() {
|
| - List<SourceRange> locations = _linkedPositions[_currentPositionGroupId];
|
| - if (locations == null) {
|
| - locations = [];
|
| - _linkedPositions[_currentPositionGroupId] = locations;
|
| - }
|
| - int start = offset + _currentPositionStart;
|
| - int end = offset + _buffer.length;
|
| - locations.add(SourceRangeFactory.rangeStartEnd(start, end));
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * Analyzer to check if a selection covers a valid set of statements of AST.
|
| - */
|
| -class StatementAnalyzer extends SelectionAnalyzer {
|
| - /**
|
| - * @return <code>true</code> if "nodes" contains "node".
|
| - */
|
| - static bool _contains(List<AstNode> nodes, AstNode node) => nodes.contains(node);
|
| -
|
| - /**
|
| - * @return <code>true</code> if "nodes" contains one of the "otherNodes".
|
| - */
|
| - static bool _contains2(List<AstNode> nodes, List<AstNode> otherNodes) {
|
| - for (AstNode otherNode in otherNodes) {
|
| - if (nodes.contains(otherNode)) {
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - CorrectionUtils utils;
|
| -
|
| - RefactoringStatus _status = new RefactoringStatus();
|
| -
|
| - StatementAnalyzer.con1(CompilationUnit cunit, SourceRange selection) : this.con2(new CorrectionUtils(cunit), selection);
|
| -
|
| - StatementAnalyzer.con2(CorrectionUtils utils, SourceRange selection) : super(selection) {
|
| - this.utils = utils;
|
| - }
|
| -
|
| - /**
|
| - * @return the [RefactoringStatus] result of checking selection.
|
| - */
|
| - RefactoringStatus get status => _status;
|
| -
|
| - @override
|
| - Object visitCompilationUnit(CompilationUnit node) {
|
| - super.visitCompilationUnit(node);
|
| - if (!hasSelectedNodes) {
|
| - return null;
|
| - }
|
| - // check that selection does not begin/end in comment
|
| - {
|
| - int selectionStart = selection.offset;
|
| - int selectionEnd = selection.end;
|
| - List<SourceRange> commentRanges = utils.commentRanges;
|
| - for (SourceRange commentRange in commentRanges) {
|
| - if (commentRange.contains(selectionStart)) {
|
| - invalidSelection("Selection begins inside a comment.");
|
| - }
|
| - if (commentRange.containsExclusive(selectionEnd)) {
|
| - invalidSelection("Selection ends inside a comment.");
|
| - }
|
| - }
|
| - }
|
| - // more checks
|
| - if (!_status.hasFatalError) {
|
| - _checkSelectedNodes(node);
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - @override
|
| - Object visitDoStatement(DoStatement node) {
|
| - super.visitDoStatement(node);
|
| - List<AstNode> selectedNodes = this.selectedNodes;
|
| - if (_contains(selectedNodes, node.body)) {
|
| - invalidSelection("Operation not applicable to a 'do' statement's body and expression.");
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - @override
|
| - Object visitForStatement(ForStatement node) {
|
| - super.visitForStatement(node);
|
| - List<AstNode> selectedNodes = this.selectedNodes;
|
| - bool containsInit = _contains(selectedNodes, node.initialization) || _contains(selectedNodes, node.variables);
|
| - bool containsCondition = _contains(selectedNodes, node.condition);
|
| - bool containsUpdaters = _contains2(selectedNodes, node.updaters);
|
| - bool containsBody = _contains(selectedNodes, node.body);
|
| - if (containsInit && containsCondition) {
|
| - invalidSelection("Operation not applicable to a 'for' statement's initializer and condition.");
|
| - } else if (containsCondition && containsUpdaters) {
|
| - invalidSelection("Operation not applicable to a 'for' statement's condition and updaters.");
|
| - } else if (containsUpdaters && containsBody) {
|
| - invalidSelection("Operation not applicable to a 'for' statement's updaters and body.");
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - @override
|
| - Object visitSwitchStatement(SwitchStatement node) {
|
| - super.visitSwitchStatement(node);
|
| - List<AstNode> selectedNodes = this.selectedNodes;
|
| - List<SwitchMember> switchMembers = node.members;
|
| - for (AstNode selectedNode in selectedNodes) {
|
| - if (switchMembers.contains(selectedNode)) {
|
| - invalidSelection("Selection must either cover whole switch statement or parts of a single case block.");
|
| - break;
|
| - }
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - @override
|
| - Object visitTryStatement(TryStatement node) {
|
| - super.visitTryStatement(node);
|
| - AstNode firstSelectedNode = this.firstSelectedNode;
|
| - if (firstSelectedNode != null) {
|
| - if (identical(firstSelectedNode, node.body) || identical(firstSelectedNode, node.finallyBlock)) {
|
| - invalidSelection("Selection must either cover whole try statement or parts of try, catch, or finally block.");
|
| - } else {
|
| - List<CatchClause> catchClauses = node.catchClauses;
|
| - for (CatchClause catchClause in catchClauses) {
|
| - if (identical(firstSelectedNode, catchClause) || identical(firstSelectedNode, catchClause.body) || identical(firstSelectedNode, catchClause.exceptionParameter)) {
|
| - invalidSelection("Selection must either cover whole try statement or parts of try, catch, or finally block.");
|
| - }
|
| - }
|
| - }
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - @override
|
| - Object visitWhileStatement(WhileStatement node) {
|
| - super.visitWhileStatement(node);
|
| - List<AstNode> selectedNodes = this.selectedNodes;
|
| - if (_contains(selectedNodes, node.condition) && _contains(selectedNodes, node.body)) {
|
| - invalidSelection("Operation not applicable to a while statement's expression and body.");
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - /**
|
| - * Records fatal error with given message.
|
| - */
|
| - void invalidSelection(String message) {
|
| - invalidSelection2(message, null);
|
| - }
|
| -
|
| - /**
|
| - * Records fatal error with given message and [RefactoringStatusContext].
|
| - */
|
| - void invalidSelection2(String message, RefactoringStatusContext context) {
|
| - _status.addFatalError(message, context);
|
| - reset();
|
| - }
|
| -
|
| - /**
|
| - * Checks final selected [AstNode]s after processing [CompilationUnit].
|
| - */
|
| - void _checkSelectedNodes(CompilationUnit unit) {
|
| - List<AstNode> nodes = selectedNodes;
|
| - // some tokens before first selected node
|
| - {
|
| - AstNode firstNode = nodes[0];
|
| - SourceRange rangeBeforeFirstNode = SourceRangeFactory.rangeStartStart(selection, firstNode);
|
| - if (_hasTokens(rangeBeforeFirstNode)) {
|
| - invalidSelection2("The beginning of the selection contains characters that do not belong to a statement.", new RefactoringStatusContext.forUnit(unit, rangeBeforeFirstNode));
|
| - }
|
| - }
|
| - // some tokens after last selected node
|
| - {
|
| - AstNode lastNode = nodes.last;
|
| - SourceRange rangeAfterLastNode = SourceRangeFactory.rangeEndEnd(lastNode, selection);
|
| - if (_hasTokens(rangeAfterLastNode)) {
|
| - invalidSelection2("The end of the selection contains characters that do not belong to a statement.", new RefactoringStatusContext.forUnit(unit, rangeAfterLastNode));
|
| - }
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * @return the [Token]s in given [SourceRange].
|
| - */
|
| - List<Token> _getTokens(SourceRange range) {
|
| - try {
|
| - String text = utils.getText3(range);
|
| - return TokenUtils.getTokens(text);
|
| - } catch (e) {
|
| - return [];
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * @return <code>true</code> if there are [Token]s in the given [SourceRange].
|
| - */
|
| - bool _hasTokens(SourceRange range) => !_getTokens(range).isEmpty;
|
| -}
|
| -
|
| -/**
|
| * Utilities to work with [Token]s.
|
| */
|
| class TokenUtils {
|
| @@ -2384,54 +1759,3 @@ class TokenUtils {
|
| */
|
| static bool hasOnly(List<Token> tokens, TokenType type) => tokens.length == 1 && tokens[0].type == type;
|
| }
|
| -
|
| -class URIUtils {
|
| - /**
|
| - * Computes relative relative path to reference "target" from "base". Uses ".." if needed, in
|
| - * contrast to [URI#relativize].
|
| - */
|
| - static String computeRelativePath(String base, String target) {
|
| - // convert to URI separator
|
| - base = base.replaceAll("\\\\", "/");
|
| - target = target.replaceAll("\\\\", "/");
|
| - if (base.startsWith("/") && target.startsWith("/")) {
|
| - base = base.substring(1);
|
| - target = target.substring(1);
|
| - }
|
| - // equal paths - no relative
|
| - if (base == target) {
|
| - return null;
|
| - }
|
| - // split paths
|
| - List<String> baseParts = base.split("/");
|
| - List<String> targetParts = target.split("/");
|
| - // prepare maximum possible common root length
|
| - int length = baseParts.length < targetParts.length ? baseParts.length : targetParts.length;
|
| - // find common root
|
| - int lastCommonRoot = -1;
|
| - for (int i = 0; i < length; i++) {
|
| - if (baseParts[i] == targetParts[i]) {
|
| - lastCommonRoot = i;
|
| - } else {
|
| - break;
|
| - }
|
| - }
|
| - // append ..
|
| - JavaStringBuilder relativePath = new JavaStringBuilder();
|
| - for (int i = lastCommonRoot + 1; i < baseParts.length; i++) {
|
| - if (baseParts[i].length > 0) {
|
| - relativePath.append("../");
|
| - }
|
| - }
|
| - // append target folder names
|
| - for (int i = lastCommonRoot + 1; i < targetParts.length - 1; i++) {
|
| - String p = targetParts[i];
|
| - relativePath.append(p);
|
| - relativePath.append("/");
|
| - }
|
| - // append target file name
|
| - relativePath.append(targetParts[targetParts.length - 1]);
|
| - // done
|
| - return relativePath.toString();
|
| - }
|
| -}
|
|
|