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 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:math'; | 6 import 'dart:math'; |
7 | 7 |
8 import 'package:analysis_server/src/protocol_server.dart' hide Element; | 8 import 'package:analysis_server/src/protocol_server.dart' hide Element; |
9 import 'package:analysis_server/src/services/correction/source_buffer.dart'; | 9 import 'package:analysis_server/src/services/correction/source_buffer.dart'; |
10 import 'package:analysis_server/src/services/correction/util.dart'; | 10 import 'package:analysis_server/src/services/correction/util.dart'; |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 } | 321 } |
322 loc = newlineLoc + expr.offset; | 322 loc = newlineLoc + expr.offset; |
323 } else { | 323 } else { |
324 // add first char of src | 324 // add first char of src |
325 delimiter = content.substring(0, 1); | 325 delimiter = content.substring(0, 1); |
326 loc = expr.offset + source.length; | 326 loc = expr.offset + source.length; |
327 } | 327 } |
328 _removeError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL); | 328 _removeError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL); |
329 _addInsertEdit(loc, delimiter); | 329 _addInsertEdit(loc, delimiter); |
330 } | 330 } |
331 expr = errorMatching(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "']'"); | 331 expr = errorMatching(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "']'") ?? |
| 332 errorMatching(ScannerErrorCode.EXPECTED_TOKEN, partialMatch: "']'"); |
332 if (expr != null) { | 333 if (expr != null) { |
333 expr = expr.getAncestor((n) => n is ListLiteral); | 334 expr = expr.getAncestor((n) => n is ListLiteral); |
334 if (expr != null) { | 335 if (expr != null) { |
335 ListLiteral lit = expr; | 336 ListLiteral lit = expr; |
336 if (lit.rightBracket.isSynthetic) { | 337 if (lit.rightBracket.isSynthetic) { |
337 String src = utils.getNodeText(expr).trim(); | 338 String src = utils.getNodeText(expr).trim(); |
338 int loc = expr.offset + src.length; | 339 int loc = expr.offset + src.length; |
339 if (src.contains(eol)) { | 340 if (src.contains(eol)) { |
340 String indent = utils.getNodePrefix(node); | 341 String indent = utils.getNodePrefix(node); |
341 _addInsertEdit(loc, ',' + eol + indent + ']'); | 342 _addInsertEdit(loc, ',' + eol + indent + ']'); |
342 } else { | 343 } else { |
343 _addInsertEdit(loc, ']'); | 344 _addInsertEdit(loc, ']'); |
344 } | 345 } |
345 _removeError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "']'"); | 346 _removeError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "']'"); |
| 347 _removeError(ScannerErrorCode.EXPECTED_TOKEN, partialMatch: "']'"); |
346 var ms = | 348 var ms = |
347 _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'"); | 349 _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'"); |
348 if (ms != null) { | 350 if (ms != null) { |
349 // Ensure the semicolon gets inserted in the correct location. | 351 // Ensure the semicolon gets inserted in the correct location. |
350 ms.offset = loc - 1; | 352 ms.offset = loc - 1; |
351 } | 353 } |
352 } | 354 } |
353 } | 355 } |
354 } | 356 } |
355 // The following code is similar to the code for ']' but does not work well. | 357 // The following code is similar to the code for ']' but does not work well. |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 outer is WhileStatement)) { | 420 outer is WhileStatement)) { |
419 return false; | 421 return false; |
420 } | 422 } |
421 int previousInsertions = _lengthOfInsertions(); | 423 int previousInsertions = _lengthOfInsertions(); |
422 int delta = 0; | 424 int delta = 0; |
423 if (errors.isNotEmpty) { | 425 if (errors.isNotEmpty) { |
424 var error = | 426 var error = |
425 _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'"); | 427 _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'"); |
426 if (error != null) { | 428 if (error != null) { |
427 int insertOffset; | 429 int insertOffset; |
428 if (expr == null || expr.isSynthetic) { | 430 // Fasta scanner reports unterminated string literal errors |
| 431 // and generates a synthetic string token with non-zero length. |
| 432 // Because of this, check for length == 0 rather than isSynthetic. |
| 433 if (expr == null || expr.length == 0) { |
429 if (node is ReturnStatement) { | 434 if (node is ReturnStatement) { |
430 insertOffset = (node as ReturnStatement).returnKeyword.end; | 435 insertOffset = (node as ReturnStatement).returnKeyword.end; |
431 } else if (node is ExpressionStatement) { | 436 } else if (node is ExpressionStatement) { |
432 insertOffset = | 437 insertOffset = |
433 ((node as ExpressionStatement).expression as ThrowExpression) | 438 ((node as ExpressionStatement).expression as ThrowExpression) |
434 .throwKeyword | 439 .throwKeyword |
435 .end; | 440 .end; |
436 } else { | 441 } else { |
437 insertOffset = node.end; // Not reached. | 442 insertOffset = node.end; // Not reached. |
438 } | 443 } |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 } else { | 826 } else { |
822 sb = new SourceBuilder(file, afterParen); | 827 sb = new SourceBuilder(file, afterParen); |
823 } | 828 } |
824 } | 829 } |
825 } | 830 } |
826 return sb; | 831 return sb; |
827 } | 832 } |
828 | 833 |
829 bool _complete_methodCall() { | 834 bool _complete_methodCall() { |
830 var parenError = | 835 var parenError = |
831 _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "')'"); | 836 _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "')'") ?? |
| 837 _findError(ScannerErrorCode.EXPECTED_TOKEN, partialMatch: "')'"); |
832 if (parenError == null) { | 838 if (parenError == null) { |
833 return false; | 839 return false; |
834 } | 840 } |
835 AstNode argList = _selectedNode(at: selectionOffset) | 841 AstNode argList = _selectedNode(at: selectionOffset) |
836 .getAncestor((n) => n is ArgumentList); | 842 .getAncestor((n) => n is ArgumentList); |
837 if (argList == null) { | 843 if (argList == null) { |
838 argList = _selectedNode(at: parenError.offset) | 844 argList = _selectedNode(at: parenError.offset) |
839 .getAncestor((n) => n is ArgumentList); | 845 .getAncestor((n) => n is ArgumentList); |
840 } | 846 } |
841 if (argList?.getAncestor((n) => n == node) == null) { | 847 if (argList?.getAncestor((n) => n == node) == null) { |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1233 final Token keyword; | 1239 final Token keyword; |
1234 final Token leftParenthesis, rightParenthesis; | 1240 final Token leftParenthesis, rightParenthesis; |
1235 final Expression condition; | 1241 final Expression condition; |
1236 final Statement block; | 1242 final Statement block; |
1237 | 1243 |
1238 _KeywordConditionBlockStructure(this.keyword, this.leftParenthesis, | 1244 _KeywordConditionBlockStructure(this.keyword, this.leftParenthesis, |
1239 this.condition, this.rightParenthesis, this.block); | 1245 this.condition, this.rightParenthesis, this.block); |
1240 | 1246 |
1241 int get offset => keyword.offset; | 1247 int get offset => keyword.offset; |
1242 } | 1248 } |
OLD | NEW |