Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Unified Diff: pkg/analysis_server/lib/src/services/refactoring/extract_local.dart

Issue 1431673003: Compute covering offsets/lengths. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
index 6cfd951cdab52349cfbd65a31fd2007428b92682..c865aec72eec276336d43c3be9b09ae729e72a28 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
@@ -40,6 +40,8 @@ class ExtractLocalRefactoringImpl extends RefactoringImpl
String name;
bool extractAll = true;
+ final List<int> coveringExpressionOffsets = <int>[];
+ final List<int> coveringExpressionLengths = <int>[];
final List<String> names = <String>[];
final List<int> offsets = <int>[];
final List<int> lengths = <int>[];
@@ -178,19 +180,58 @@ class ExtractLocalRefactoringImpl extends RefactoringImpl
/**
* Checks if [selectionRange] selects [Expression] which can be extracted, and
- * location of this [DartExpression] in AST allows extracting.
+ * location of this [Expression] in AST allows extracting.
*/
RefactoringStatus _checkSelection() {
- _ExtractExpressionAnalyzer _selectionAnalyzer =
- new _ExtractExpressionAnalyzer(selectionRange);
- unit.accept(_selectionAnalyzer);
- AstNode coveringNode = _selectionAnalyzer.coveringNode;
- // may be fatal error
+ String selectionStr;
+ // exclude whitespaces
{
- RefactoringStatus status = _selectionAnalyzer.status;
- if (status.hasFatalError) {
- return status;
+ selectionStr = utils.getRangeText(selectionRange);
+ int numLeading = countLeadingWhitespaces(selectionStr);
+ int numTrailing = countTrailingWhitespaces(selectionStr);
+ int offset = selectionRange.offset + numLeading;
+ int end = selectionRange.end - numTrailing;
+ selectionRange = new SourceRange(offset, end - offset);
+ }
+ // get covering node
+ AstNode coveringNode = new NodeLocator(
+ selectionRange.offset, selectionRange.end).searchWithin(unit);
+ // compute covering expressions
+ for (AstNode node = coveringNode; node is Expression; node = node.parent) {
+ AstNode parent = node.parent;
+ // cannot extract the name part of a property access
+ if (parent is PrefixedIdentifier && parent.identifier == node ||
+ parent is PropertyAccess && parent.propertyName == node) {
+ continue;
+ }
+ // fatal selection problems
+ if (coveringExpressionOffsets.isEmpty) {
+ if (node is SimpleIdentifier) {
+ Element element = node.bestElement;
+ if (element is FunctionElement || element is MethodElement) {
+ return new RefactoringStatus.fatal(
+ 'Cannot extract a single method name.',
+ newLocation_fromNode(node));
+ }
+ if (node.inDeclarationContext()) {
+ return new RefactoringStatus.fatal(
+ 'Cannot extract the name part of a declaration.',
+ newLocation_fromNode(node));
+ }
+ }
+ if (parent is AssignmentExpression && parent.leftHandSide == node) {
+ return new RefactoringStatus.fatal(
+ 'Cannot extract the left-hand side of an assignment.',
+ newLocation_fromNode(node));
+ }
}
+ // set selected expression
+ if (coveringExpressionOffsets.isEmpty) {
+ rootExpression = node;
+ }
+ // add the expression range
+ coveringExpressionOffsets.add(node.offset);
+ coveringExpressionLengths.add(node.length);
}
// we need enclosing block to add variable declaration statement
if (coveringNode == null ||
@@ -201,38 +242,18 @@ class ExtractLocalRefactoringImpl extends RefactoringImpl
}
// part of string literal
if (coveringNode is StringLiteral) {
- stringLiteralPart = utils.getRangeText(selectionRange);
- if (stringLiteralPart.startsWith("'") ||
- stringLiteralPart.startsWith('"') ||
- stringLiteralPart.endsWith("'") ||
- stringLiteralPart.endsWith('"')) {
- return new RefactoringStatus.fatal(
- 'Cannot extract only leading or trailing quote of string literal.');
- }
- return new RefactoringStatus();
- }
- // single node selected
- if (_selectionAnalyzer.selectedNodes.length == 1 &&
- !utils.selectionIncludesNonWhitespaceOutsideNode(
- selectionRange, _selectionAnalyzer.firstSelectedNode)) {
- AstNode selectedNode = _selectionAnalyzer.firstSelectedNode;
- if (selectedNode is Expression) {
- rootExpression = selectedNode;
- singleExpression = rootExpression;
- wholeStatementExpression =
- singleExpression.parent is ExpressionStatement;
+ if (selectionRange.offset > coveringNode.offset &&
+ selectionRange.end < coveringNode.end) {
+ stringLiteralPart = selectionStr;
return new RefactoringStatus();
}
}
- // fragment of binary expression selected
- if (coveringNode is BinaryExpression) {
- BinaryExpression binaryExpression = coveringNode;
- if (utils.validateBinaryExpressionRange(
- binaryExpression, selectionRange)) {
- rootExpression = binaryExpression;
- singleExpression = null;
- return new RefactoringStatus();
- }
+ // single node selected
+ if (rootExpression != null) {
+ singleExpression = rootExpression;
+ selectionRange = rangeNode(singleExpression);
+ wholeStatementExpression = singleExpression.parent is ExpressionStatement;
+ return new RefactoringStatus();
}
// invalid selection
return new RefactoringStatus.fatal(
@@ -259,7 +280,7 @@ class ExtractLocalRefactoringImpl extends RefactoringImpl
* Returns an [Element]-sensitive encoding of [tokens].
* Each [Token] with a [LocalVariableElement] has a suffix of the element id.
*
- * So, we can distingush different local variables with the same name, if
+ * So, we can distinguish different local variables with the same name, if
* there are multiple variables with the same name are declared in the
* function we are searching occurrences in.
*/
@@ -475,7 +496,7 @@ class _ExtractExpressionAnalyzer extends SelectionAnalyzer {
}
/**
- * Records fatal error with given message and [Locatiom].
+ * Records fatal error with given [message] and [location].
*/
void _invalidSelection(String message, Location location) {
status.addFatalError(message, location);
@@ -523,7 +544,7 @@ class _OccurrencesVisitor extends GeneralizingAstVisitor<Object> {
@override
Object visitStringLiteral(StringLiteral node) {
if (ref.stringLiteralPart != null) {
- int occuLength = ref.stringLiteralPart.length;
+ int length = ref.stringLiteralPart.length;
String value = ref.utils.getNodeText(node);
int lastIndex = 0;
while (true) {
@@ -531,10 +552,10 @@ class _OccurrencesVisitor extends GeneralizingAstVisitor<Object> {
if (index == -1) {
break;
}
- lastIndex = index + occuLength;
- int occuStart = node.offset + index;
- SourceRange occuRange = rangeStartLength(occuStart, occuLength);
- occurrences.add(occuRange);
+ lastIndex = index + length;
+ int start = node.offset + index;
+ SourceRange range = rangeStartLength(start, length);
+ occurrences.add(range);
}
return null;
}
@@ -560,8 +581,8 @@ class _OccurrencesVisitor extends GeneralizingAstVisitor<Object> {
List<Token> nodeTokens = TokenUtils.getTokens(nodeSource);
nodeSource = ref._encodeExpressionTokens(node, nodeTokens);
if (nodeSource == selectionSource) {
- SourceRange occuRange = rangeNode(node);
- _addOccurrence(occuRange);
+ SourceRange range = rangeNode(node);
+ _addOccurrence(range);
}
}
@@ -587,10 +608,10 @@ class _OccurrencesVisitor extends GeneralizingAstVisitor<Object> {
Token startToken = nodeTokens[startTokenIndex];
Token endToken = nodeTokens[endTokenIndex];
// add occurrence range
- int occuStart = nodeOffset + startToken.offset;
- int occuEnd = nodeOffset + endToken.end;
- SourceRange occuRange = rangeStartEnd(occuStart, occuEnd);
- _addOccurrence(occuRange);
+ int start = nodeOffset + startToken.offset;
+ int end = nodeOffset + endToken.end;
+ SourceRange range = rangeStartEnd(start, end);
+ _addOccurrence(range);
}
}
}

Powered by Google App Engine
This is Rietveld 408576698