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

Unified Diff: pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart

Issue 2824233002: Complete for-statement (Closed)
Patch Set: Replace empty with synthetic Created 3 years, 8 months 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
« no previous file with comments | « no previous file | pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
diff --git a/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart b/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
index 13c35c1c2dc23374a7dd95d80cd49c2f6dad872e..0f4d004f956d6881132885da60f46ea7f86a95f6 100644
--- a/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
+++ b/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
@@ -37,6 +37,8 @@ class DartStatementCompletion {
'COMPLETE_DO_STMT', "Complete do-statement");
static const COMPLETE_IF_STMT = const StatementCompletionKind(
'COMPLETE_IF_STMT', "Complete if-statement");
+ static const COMPLETE_FOR_STMT = const StatementCompletionKind(
+ 'COMPLETE_FOR_STMT', "Complete for-statement");
static const COMPLETE_WHILE_STMT = const StatementCompletionKind(
'COMPLETE_WHILE_STMT', "Complete while-statement");
}
@@ -179,6 +181,10 @@ class StatementCompletionProcessor {
// TODO(messick) Consider changing (some of) this to a visitor.
if (_complete_ifStatement() ||
_complete_doStatement() ||
+ _complete_forStatement() ||
+ _complete_forEachStatement() ||
+ _complete_switchStatement() ||
+ _complete_tryStatement() ||
_complete_whileStatement() ||
_complete_simpleSemicolon() ||
_complete_simpleEnter()) {
@@ -187,11 +193,6 @@ class StatementCompletionProcessor {
return NO_COMPLETION;
}
- void _addIndentEdit(SourceRange range, String oldIndent, String newIndent) {
- SourceEdit edit = utils.createIndentEdit(range, oldIndent, newIndent);
- doSourceChange_addElementEdit(change, unitElement, edit);
- }
-
void _addInsertEdit(int offset, String text) {
SourceEdit edit = new SourceEdit(offset, 0, text);
doSourceChange_addElementEdit(change, unitElement, edit);
@@ -238,12 +239,6 @@ class StatementCompletionProcessor {
return false;
}
DoStatement statement = node;
- var stmt = new _DoIfWhileStructure(
- statement.whileKeyword,
- statement.leftParenthesis,
- statement.condition,
- statement.rightParenthesis,
- null);
SourceBuilder sb = _sourceBuilderAfterKeyword(statement.doKeyword);
bool hasWhileKeyword = statement.whileKeyword.lexeme == "while";
int exitDelta = 0;
@@ -266,8 +261,8 @@ class StatementCompletionProcessor {
sb = new SourceBuilder(file, sb.offset + delta);
sb.append(' ');
}
- _appendEmptyBraces(
- sb, !(hasWhileKeyword && _isEmptyExpression(statement.condition)));
+ _appendEmptyBraces(sb,
+ !(hasWhileKeyword && _isSyntheticExpression(statement.condition)));
if (delta != 0) {
exitDelta = sb.length - delta;
}
@@ -276,11 +271,17 @@ class StatementCompletionProcessor {
}
SourceBuilder sb2;
if (hasWhileKeyword) {
+ var stmt = new _KeywordConditionBlockStructure(
+ statement.whileKeyword,
+ statement.leftParenthesis,
+ statement.condition,
+ statement.rightParenthesis,
+ null);
sb2 = _complete_keywordCondition(stmt);
if (sb2.length == 0) {
// true if condition is '()'
if (exitPosition != null) {
- if (statement.semicolon.lexeme.isEmpty) {
+ if (statement.semicolon.isSynthetic) {
_insertBuilder(sb);
sb = new SourceBuilder(file, exitPosition.offset + 1);
sb.append(';');
@@ -309,8 +310,95 @@ class StatementCompletionProcessor {
return true;
}
+ bool _complete_forEachStatement() {
+ // TODO(messick) Implement _complete_forEachStatement
+ return false;
+ }
+
+ bool _complete_forStatement() {
+ if (errors.isEmpty || node is! ForStatement) {
+ return false;
+ }
+ ForStatement forNode = node;
+ SourceBuilder sb;
+ int delta = 0;
+ if (forNode.leftParenthesis.isSynthetic) {
+ if (!forNode.rightParenthesis.isSynthetic) {
+ return false;
+ }
+ // keywordOnly (unit test name suffix that exercises this branch)
+ sb = _sourceBuilderAfterKeyword(forNode.forKeyword);
+ sb.append('(');
+ sb.setExitOffset();
+ sb.append(')');
+ } else {
+ if (!forNode.rightSeparator.isSynthetic) {
+ // Fully-defined init, cond, updaters so nothing more needed here.
+ // emptyParts
+ sb = new SourceBuilder(file, forNode.rightParenthesis.offset + 1);
+ } else if (!forNode.leftSeparator.isSynthetic) {
+ if (_isSyntheticExpression(forNode.condition)) {
+ exitPosition = _newPosition(forNode.leftSeparator.offset + 1);
+ String text = utils
+ .getNodeText(forNode)
+ .substring(forNode.leftSeparator.offset - forNode.offset);
+ if (text.startsWith(new RegExp(r';\s*\)'))) {
+ // emptyCondition
+ int end = text.indexOf(')');
+ sb = new SourceBuilder(file, forNode.leftSeparator.offset);
+ // TODO(messick) Consider adding two semicolons here.
+ _addReplaceEdit(rangeStartLength(sb.offset, end), '; ');
+ delta = end - '; '.length;
+ } else {
+ // emptyInitializersEmptyCondition
+ exitPosition = _newPosition(forNode.rightParenthesis.offset);
+ sb = new SourceBuilder(file, forNode.rightParenthesis.offset);
+ }
+ } else {
+ // emptyUpdaters
+ exitPosition = _newPosition(forNode.rightSeparator.offset);
+ sb = new SourceBuilder(file, forNode.rightSeparator.offset);
+ _addReplaceEdit(rangeStartLength(sb.offset, 0), '; ');
+ delta = -'; '.length;
+ }
+ } else if (_isSyntheticExpression(forNode.initialization)) {
+ // emptyInitializers
+ exitPosition = _newPosition(forNode.rightParenthesis.offset);
+ sb = new SourceBuilder(file, forNode.rightParenthesis.offset);
+ } else {
+ int start = forNode.condition.offset + forNode.condition.length;
+ String text =
+ utils.getNodeText(forNode).substring(start - forNode.offset);
+ if (text.startsWith(new RegExp(r'\s*\)'))) {
+ // missingLeftSeparator
+ int end = text.indexOf(')');
+ sb = new SourceBuilder(file, start);
+ _addReplaceEdit(rangeStartLength(start, end), '; ');
+ delta = end - '; '.length;
+ exitPosition = new Position(file, start);
+ } else {
+ // Not possible; any comment following init is attached to init.
+ exitPosition = _newPosition(forNode.rightParenthesis.offset);
+ sb = new SourceBuilder(file, forNode.rightParenthesis.offset);
+ }
+ }
+ }
+ if (forNode.body is EmptyStatement) {
+ // keywordOnly
+ sb.append(' ');
+ _appendEmptyBraces(sb, exitPosition == null);
+ }
+ if (delta != 0 && exitPosition != null) {
+ // missingLeftSeparator
+ exitPosition = new Position(file, exitPosition.offset - delta);
+ }
+ _insertBuilder(sb);
+ _setCompletion(DartStatementCompletion.COMPLETE_FOR_STMT);
+ return true;
+ }
+
bool _complete_ifOrWhileStatement(
- _DoIfWhileStructure statement, StatementCompletionKind kind) {
+ _KeywordConditionBlockStructure statement, StatementCompletionKind kind) {
SourceBuilder sb = _complete_keywordCondition(statement);
if (statement.block is EmptyStatement) {
sb.append(' ');
@@ -330,7 +418,7 @@ class StatementCompletionProcessor {
if (ifNode.elseKeyword != null) {
return false;
}
- var stmt = new _DoIfWhileStructure(
+ var stmt = new _KeywordConditionBlockStructure(
ifNode.ifKeyword,
ifNode.leftParenthesis,
ifNode.condition,
@@ -342,11 +430,11 @@ class StatementCompletionProcessor {
return false;
}
- SourceBuilder _complete_keywordCondition(_DoIfWhileStructure statement) {
+ SourceBuilder _complete_keywordCondition(
+ _KeywordConditionBlockStructure statement) {
SourceBuilder sb;
- String text = _baseNodeText(node);
- if (statement.leftParenthesis.lexeme.isEmpty) {
- if (!statement.rightParenthesis.lexeme.isEmpty) {
+ if (statement.leftParenthesis.isSynthetic) {
+ if (!statement.rightParenthesis.isSynthetic) {
// Quite unlikely to see this so don't try to fix it.
return null;
}
@@ -355,7 +443,7 @@ class StatementCompletionProcessor {
sb.setExitOffset();
sb.append(')');
} else {
- if (_isEmptyExpression(statement.condition)) {
+ if (_isSyntheticExpression(statement.condition)) {
exitPosition = _newPosition(statement.leftParenthesis.offset + 1);
sb = new SourceBuilder(file, statement.rightParenthesis.offset + 1);
} else {
@@ -394,13 +482,23 @@ class StatementCompletionProcessor {
return false;
}
+ bool _complete_switchStatement() {
+ // TODO(messick) Implement _complete_switchStatement
+ return false;
+ }
+
+ bool _complete_tryStatement() {
+ // TODO(messick) Implement _complete_tryStatement
+ return false;
+ }
+
bool _complete_whileStatement() {
if (errors.isEmpty || node is! WhileStatement) {
return false;
}
WhileStatement whileNode = node;
if (whileNode != null) {
- var stmt = new _DoIfWhileStructure(
+ var stmt = new _KeywordConditionBlockStructure(
whileNode.whileKeyword,
whileNode.leftParenthesis,
whileNode.condition,
@@ -462,12 +560,8 @@ class StatementCompletionProcessor {
return stmt is Block && stmt.statements.isEmpty;
}
- bool _isEmptyExpression(Expression expr) {
- if (expr is! SimpleIdentifier) {
- return false;
- }
- SimpleIdentifier id = expr as SimpleIdentifier;
- return id.length == 0;
+ bool _isSyntheticExpression(Expression expr) {
+ return expr is SimpleIdentifier && expr.isSynthetic;
}
bool _isEmptyStatement(AstNode stmt) {
@@ -509,14 +603,14 @@ class StatementCompletionProcessor {
}
// Encapsulate common structure of if-statement and while-statement.
-class _DoIfWhileStructure {
+class _KeywordConditionBlockStructure {
final Token keyword;
final Token leftParenthesis, rightParenthesis;
final Expression condition;
final Statement block;
- _DoIfWhileStructure(this.keyword, this.leftParenthesis, this.condition,
- this.rightParenthesis, this.block);
+ _KeywordConditionBlockStructure(this.keyword, this.leftParenthesis,
+ this.condition, this.rightParenthesis, this.block);
int get offset => keyword.offset;
}
« no previous file with comments | « no previous file | pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698