| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library services.src.completion.statement; | 5 library services.src.completion.statement; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/plugin/protocol/protocol.dart'; | 9 import 'package:analysis_server/plugin/protocol/protocol.dart'; |
| 10 import 'package:analysis_server/src/protocol_server.dart' hide Element; | 10 import 'package:analysis_server/src/protocol_server.dart' hide Element; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 import 'package:analyzer/src/generated/engine.dart'; | 22 import 'package:analyzer/src/generated/engine.dart'; |
| 23 import 'package:analyzer/src/generated/java_core.dart'; | 23 import 'package:analyzer/src/generated/java_core.dart'; |
| 24 import 'package:analyzer/src/generated/source.dart'; | 24 import 'package:analyzer/src/generated/source.dart'; |
| 25 | 25 |
| 26 /** | 26 /** |
| 27 * An enumeration of possible statement completion kinds. | 27 * An enumeration of possible statement completion kinds. |
| 28 */ | 28 */ |
| 29 class DartStatementCompletion { | 29 class DartStatementCompletion { |
| 30 static const NO_COMPLETION = | 30 static const NO_COMPLETION = |
| 31 const StatementCompletionKind('No_COMPLETION', 'No completion available'); | 31 const StatementCompletionKind('No_COMPLETION', 'No completion available'); |
| 32 static const PLAIN_OLE_ENTER = const StatementCompletionKind( | 32 static const SIMPLE_ENTER = const StatementCompletionKind( |
| 33 'PLAIN_OLE_ENTER', "Insert a newline at the end of the current line"); | 33 'SIMPLE_ENTER', "Insert a newline at the end of the current line"); |
| 34 static const SIMPLE_SEMICOLON = const StatementCompletionKind( | 34 static const SIMPLE_SEMICOLON = const StatementCompletionKind( |
| 35 'SIMPLE_SEMICOLON', "Add a semicolon and newline"); | 35 'SIMPLE_SEMICOLON', "Add a semicolon and newline"); |
| 36 static const COMPLETE_IF_STMT = const StatementCompletionKind( | 36 static const COMPLETE_IF_STMT = const StatementCompletionKind( |
| 37 'COMPLETE_IF_STMT', "Complete if-statement"); | 37 'COMPLETE_IF_STMT', "Complete if-statement"); |
| 38 static const COMPLETE_WHILE_STMT = const StatementCompletionKind( | 38 static const COMPLETE_WHILE_STMT = const StatementCompletionKind( |
| 39 'COMPLETE_WHILE_STMT', "Complete while-statement"); | 39 'COMPLETE_WHILE_STMT', "Complete while-statement"); |
| 40 } | 40 } |
| 41 | 41 |
| 42 /** | 42 /** |
| 43 * A description of a statement completion. | 43 * A description of a statement completion. |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 node = node.getAncestor((n) => n is Statement); | 164 node = node.getAncestor((n) => n is Statement); |
| 165 for (engine.AnalysisError error in statementContext.errors) { | 165 for (engine.AnalysisError error in statementContext.errors) { |
| 166 if (error.offset >= node.offset && | 166 if (error.offset >= node.offset && |
| 167 error.offset <= node.offset + node.length) { | 167 error.offset <= node.offset + node.length) { |
| 168 if (error.errorCode is! HintCode) { | 168 if (error.errorCode is! HintCode) { |
| 169 errors.add(error); | 169 errors.add(error); |
| 170 } | 170 } |
| 171 } | 171 } |
| 172 } | 172 } |
| 173 | 173 |
| 174 // TODO(messick) Consider changing (some of) this to a visitor. |
| 174 if (_complete_ifStatement() || | 175 if (_complete_ifStatement() || |
| 175 _complete_whileStatement() || | 176 _complete_whileStatement() || |
| 176 _complete_simpleSemicolon() || | 177 _complete_simpleSemicolon() || |
| 177 _complete_plainOleEnter()) { | 178 _complete_simpleEnter()) { |
| 178 return completion; | 179 return completion; |
| 179 } | 180 } |
| 180 return NO_COMPLETION; | 181 return NO_COMPLETION; |
| 181 } | 182 } |
| 182 | 183 |
| 183 void _addIndentEdit(SourceRange range, String oldIndent, String newIndent) { | 184 void _addIndentEdit(SourceRange range, String oldIndent, String newIndent) { |
| 184 SourceEdit edit = utils.createIndentEdit(range, oldIndent, newIndent); | 185 SourceEdit edit = utils.createIndentEdit(range, oldIndent, newIndent); |
| 185 doSourceChange_addElementEdit(change, unitElement, edit); | 186 doSourceChange_addElementEdit(change, unitElement, edit); |
| 186 } | 187 } |
| 187 | 188 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 return false; | 270 return false; |
| 270 } | 271 } |
| 271 var stmt = new _IfWhileStructure(ifNode.ifKeyword, ifNode.leftParenthesis, | 272 var stmt = new _IfWhileStructure(ifNode.ifKeyword, ifNode.leftParenthesis, |
| 272 ifNode.condition, ifNode.rightParenthesis, ifNode.thenStatement); | 273 ifNode.condition, ifNode.rightParenthesis, ifNode.thenStatement); |
| 273 return _complete_ifOrWhileStatement( | 274 return _complete_ifOrWhileStatement( |
| 274 stmt, DartStatementCompletion.COMPLETE_IF_STMT); | 275 stmt, DartStatementCompletion.COMPLETE_IF_STMT); |
| 275 } | 276 } |
| 276 return false; | 277 return false; |
| 277 } | 278 } |
| 278 | 279 |
| 279 bool _complete_plainOleEnter() { | 280 bool _complete_simpleEnter() { |
| 280 int offset; | 281 int offset; |
| 281 if (!errors.isEmpty) { | 282 if (!errors.isEmpty) { |
| 282 offset = selectionOffset; | 283 offset = selectionOffset; |
| 283 } else { | 284 } else { |
| 284 String indent = utils.getLinePrefix(selectionOffset); | 285 String indent = utils.getLinePrefix(selectionOffset); |
| 285 int loc = utils.getLineNext(selectionOffset); | 286 int loc = utils.getLineNext(selectionOffset); |
| 286 _addInsertEdit(loc, indent + eol); | 287 _addInsertEdit(loc, indent + eol); |
| 287 offset = loc + indent.length + eol.length; | 288 offset = loc + indent.length + eol.length; |
| 288 } | 289 } |
| 289 _setCompletionAt(DartStatementCompletion.PLAIN_OLE_ENTER, offset); | 290 _setCompletionAt(DartStatementCompletion.SIMPLE_ENTER, offset); |
| 290 return true; | 291 return true; |
| 291 } | 292 } |
| 292 | 293 |
| 293 bool _complete_simpleSemicolon() { | 294 bool _complete_simpleSemicolon() { |
| 294 if (errors.length != 1) { | 295 if (errors.length != 1) { |
| 295 return false; | 296 return false; |
| 296 } | 297 } |
| 297 var error = _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'"); | 298 var error = _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'"); |
| 298 if (error != null) { | 299 if (error != null) { |
| 299 int insertOffset = error.offset + error.length; | 300 int insertOffset = error.offset + error.length; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 final Token keyword; | 402 final Token keyword; |
| 402 final Token leftParenthesis, rightParenthesis; | 403 final Token leftParenthesis, rightParenthesis; |
| 403 final Expression condition; | 404 final Expression condition; |
| 404 final Statement block; | 405 final Statement block; |
| 405 | 406 |
| 406 _IfWhileStructure(this.keyword, this.leftParenthesis, this.condition, | 407 _IfWhileStructure(this.keyword, this.leftParenthesis, this.condition, |
| 407 this.rightParenthesis, this.block); | 408 this.rightParenthesis, this.block); |
| 408 | 409 |
| 409 int get offset => keyword.offset; | 410 int get offset => keyword.offset; |
| 410 } | 411 } |
| OLD | NEW |