| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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.correction.util; | 5 library services.src.correction.util; |
| 6 | 6 |
| 7 import 'dart:math'; | 7 import 'dart:math'; |
| 8 | 8 |
| 9 import 'package:analysis_server/plugin/protocol/protocol.dart' | 9 import 'package:analysis_server/plugin/protocol/protocol.dart' |
| 10 show SourceChange, SourceEdit; | 10 show SourceChange, SourceEdit; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 import 'package:path/path.dart'; | 26 import 'package:path/path.dart'; |
| 27 | 27 |
| 28 /** | 28 /** |
| 29 * Adds edits to the given [change] that ensure that all the [libraries] are | 29 * Adds edits to the given [change] that ensure that all the [libraries] are |
| 30 * imported into the given [targetLibrary]. | 30 * imported into the given [targetLibrary]. |
| 31 */ | 31 */ |
| 32 void addLibraryImports(SourceChange change, LibraryElement targetLibrary, | 32 void addLibraryImports(SourceChange change, LibraryElement targetLibrary, |
| 33 Set<LibraryElement> libraries) { | 33 Set<LibraryElement> libraries) { |
| 34 CompilationUnitElement libUnitElement = targetLibrary.definingCompilationUnit; | 34 CompilationUnitElement libUnitElement = targetLibrary.definingCompilationUnit; |
| 35 CompilationUnit libUnit = getParsedUnit(libUnitElement); | 35 CompilationUnit libUnit = getParsedUnit(libUnitElement); |
| 36 // prepare new import location | 36 CorrectionUtils libUtils = new CorrectionUtils(libUnit); |
| 37 int offset = 0; | 37 String eol = libUtils.endOfLine; |
| 38 String prefix; | 38 // Prepare information about existing imports. |
| 39 String suffix; | 39 LibraryDirective libraryDirective; |
| 40 { | 40 List<_ImportDirectiveInfo> importDirectives = <_ImportDirectiveInfo>[]; |
| 41 // if no directives | 41 for (Directive directive in libUnit.directives) { |
| 42 prefix = ''; | 42 if (directive is LibraryDirective) { |
| 43 CorrectionUtils libraryUtils = new CorrectionUtils(libUnit); | 43 libraryDirective = directive; |
| 44 String eol = libraryUtils.endOfLine; | 44 } else if (directive is ImportDirective) { |
| 45 suffix = eol; | 45 importDirectives.add(new _ImportDirectiveInfo( |
| 46 // after last directive in library | 46 directive.uriContent, directive.offset, directive.end)); |
| 47 for (Directive directive in libUnit.directives) { | 47 } |
| 48 if (directive is LibraryDirective || directive is ImportDirective) { | 48 } |
| 49 offset = directive.end; | 49 |
| 50 prefix = eol; | 50 // Prepare all URIs to import. |
| 51 suffix = ''; | 51 List<String> uriList = libraries |
| 52 .map((library) => getLibrarySourceUri(targetLibrary, library.source)) |
| 53 .toList(); |
| 54 uriList.sort((a, b) => a.compareTo(b)); |
| 55 |
| 56 // Insert imports: between existing imports. |
| 57 if (importDirectives.isNotEmpty) { |
| 58 bool isFirstPackage = true; |
| 59 for (String importUri in uriList) { |
| 60 bool inserted = false; |
| 61 bool isPackage = importUri.startsWith('package:'); |
| 62 bool isAfterDart = false; |
| 63 for (_ImportDirectiveInfo existingImport in importDirectives) { |
| 64 if (existingImport.uri.startsWith('dart:')) { |
| 65 isAfterDart = true; |
| 66 } |
| 67 if (existingImport.uri.startsWith('package:')) { |
| 68 isFirstPackage = false; |
| 69 } |
| 70 if (importUri.compareTo(existingImport.uri) < 0) { |
| 71 String importCode = "import '$importUri';$eol"; |
| 72 doSourceChange_addElementEdit(change, targetLibrary, |
| 73 new SourceEdit(existingImport.offset, 0, importCode)); |
| 74 inserted = true; |
| 75 break; |
| 76 } |
| 77 } |
| 78 if (!inserted) { |
| 79 String importCode = "${eol}import '$importUri';"; |
| 80 if (isPackage && isFirstPackage && isAfterDart) { |
| 81 importCode = eol + importCode; |
| 82 } |
| 83 doSourceChange_addElementEdit(change, targetLibrary, |
| 84 new SourceEdit(importDirectives.last.end, 0, importCode)); |
| 85 } |
| 86 if (isPackage) { |
| 87 isFirstPackage = false; |
| 52 } | 88 } |
| 53 } | 89 } |
| 54 // if still at the beginning of the file, skip shebang and line comments | 90 return; |
| 55 if (offset == 0) { | 91 } |
| 56 CorrectionUtils_InsertDesc desc = libraryUtils.getInsertDescTop(); | 92 |
| 57 offset = desc.offset; | 93 // Insert imports: after the library directive. |
| 58 prefix = desc.prefix; | 94 if (libraryDirective != null) { |
| 59 suffix = desc.suffix + eol; | 95 String prefix = eol + eol; |
| 96 for (String importUri in uriList) { |
| 97 String importCode = "${prefix}import '$importUri';"; |
| 98 prefix = eol; |
| 99 doSourceChange_addElementEdit(change, targetLibrary, |
| 100 new SourceEdit(libraryDirective.end, 0, importCode)); |
| 60 } | 101 } |
| 102 return; |
| 61 } | 103 } |
| 62 // insert imports | 104 |
| 63 for (LibraryElement library in libraries) { | 105 // If still at the beginning of the file, skip shebang and line comments. |
| 64 String importUri = getLibrarySourceUri(targetLibrary, library.source); | 106 { |
| 65 String importCode = "${prefix}import '$importUri';$suffix"; | 107 CorrectionUtils_InsertDesc desc = libUtils.getInsertDescTop(); |
| 66 doSourceChange_addElementEdit( | 108 int offset = desc.offset; |
| 67 change, targetLibrary, new SourceEdit(offset, 0, importCode)); | 109 for (int i = 0; i < uriList.length; i++) { |
| 110 String importUri = uriList[i]; |
| 111 String importCode = "import '$importUri';$eol"; |
| 112 if (i == 0) { |
| 113 importCode = desc.prefix + importCode; |
| 114 } |
| 115 if (i == uriList.length - 1) { |
| 116 importCode = importCode + desc.suffix; |
| 117 } |
| 118 doSourceChange_addElementEdit( |
| 119 change, targetLibrary, new SourceEdit(offset, 0, importCode)); |
| 120 } |
| 68 } | 121 } |
| 69 } | 122 } |
| 70 | 123 |
| 71 /** | 124 /** |
| 72 * @return <code>true</code> if given [List]s are identical at given position. | 125 * @return <code>true</code> if given [List]s are identical at given position. |
| 73 */ | 126 */ |
| 74 bool allListsIdentical(List<List> lists, int position) { | 127 bool allListsIdentical(List<List> lists, int position) { |
| 75 Object element = lists[0][position]; | 128 Object element = lists[0][position]; |
| 76 for (List list in lists) { | 129 for (List list in lists) { |
| 77 if (list[position] != element) { | 130 if (list[position] != element) { |
| (...skipping 1381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1459 AstNode parent = node.parent; | 1512 AstNode parent = node.parent; |
| 1460 return parent is ConstructorName && parent.name == node || | 1513 return parent is ConstructorName && parent.name == node || |
| 1461 parent is MethodInvocation && | 1514 parent is MethodInvocation && |
| 1462 parent.methodName == node && | 1515 parent.methodName == node && |
| 1463 parent.realTarget != null || | 1516 parent.realTarget != null || |
| 1464 parent is PrefixedIdentifier && parent.identifier == node || | 1517 parent is PrefixedIdentifier && parent.identifier == node || |
| 1465 parent is PropertyAccess && parent.target == node; | 1518 parent is PropertyAccess && parent.target == node; |
| 1466 } | 1519 } |
| 1467 } | 1520 } |
| 1468 | 1521 |
| 1522 class _ImportDirectiveInfo { |
| 1523 final String uri; |
| 1524 final int offset; |
| 1525 final int end; |
| 1526 |
| 1527 _ImportDirectiveInfo(this.uri, this.offset, this.end); |
| 1528 } |
| 1529 |
| 1469 /** | 1530 /** |
| 1470 * A container with a source and its precedence. | 1531 * A container with a source and its precedence. |
| 1471 */ | 1532 */ |
| 1472 class _InvertedCondition { | 1533 class _InvertedCondition { |
| 1473 final int _precedence; | 1534 final int _precedence; |
| 1474 | 1535 |
| 1475 final String _source; | 1536 final String _source; |
| 1476 | 1537 |
| 1477 _InvertedCondition(this._precedence, this._source); | 1538 _InvertedCondition(this._precedence, this._source); |
| 1478 | 1539 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1499 _InvertedCondition expr, int newOperatorPrecedence) { | 1560 _InvertedCondition expr, int newOperatorPrecedence) { |
| 1500 if (expr._precedence < newOperatorPrecedence) { | 1561 if (expr._precedence < newOperatorPrecedence) { |
| 1501 return "(${expr._source})"; | 1562 return "(${expr._source})"; |
| 1502 } | 1563 } |
| 1503 return expr._source; | 1564 return expr._source; |
| 1504 } | 1565 } |
| 1505 | 1566 |
| 1506 static _InvertedCondition _simple(String source) => | 1567 static _InvertedCondition _simple(String source) => |
| 1507 new _InvertedCondition(2147483647, source); | 1568 new _InvertedCondition(2147483647, source); |
| 1508 } | 1569 } |
| OLD | NEW |