| OLD | NEW |
| 1 // This code was auto-generated, is not intended to be edited, and is subject to | 1 // This code was auto-generated, is not intended to be edited, and is subject to |
| 2 // significant change. Please see the README file for more information. | 2 // significant change. Please see the README file for more information. |
| 3 library engine.resolver; | 3 library engine.resolver; |
| 4 import 'dart:collection'; | 4 import 'dart:collection'; |
| 5 import 'java_core.dart'; | 5 import 'java_core.dart'; |
| 6 import 'java_engine.dart'; | 6 import 'java_engine.dart'; |
| 7 import 'instrumentation.dart'; | 7 import 'instrumentation.dart'; |
| 8 import 'source.dart'; | 8 import 'source.dart'; |
| 9 import 'error.dart'; | 9 import 'error.dart'; |
| 10 import 'scanner.dart' as sc; | 10 import 'scanner.dart' as sc; |
| (...skipping 1230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1241 * @param errorCode the error code of the error to be reported | 1241 * @param errorCode the error code of the error to be reported |
| 1242 * @param offset the offset of the first character to be highlighted | 1242 * @param offset the offset of the first character to be highlighted |
| 1243 * @param length the number of characters to be highlighted | 1243 * @param length the number of characters to be highlighted |
| 1244 * @param arguments the arguments used to compose the error message | 1244 * @param arguments the arguments used to compose the error message |
| 1245 */ | 1245 */ |
| 1246 void reportError(ErrorCode errorCode, int offset, int length, List<Object> arg
uments) { | 1246 void reportError(ErrorCode errorCode, int offset, int length, List<Object> arg
uments) { |
| 1247 _errorListener.onError(new AnalysisError.con2(_htmlElement.source, offset, l
ength, errorCode, arguments)); | 1247 _errorListener.onError(new AnalysisError.con2(_htmlElement.source, offset, l
ength, errorCode, arguments)); |
| 1248 } | 1248 } |
| 1249 } | 1249 } |
| 1250 /** | 1250 /** |
| 1251 * Instances of the class `DeadCodeVerifier` traverse an AST structure looking f
or cases of |
| 1252 * [HintCode#DEAD_CODE]. |
| 1253 * |
| 1254 * @coverage dart.engine.resolver |
| 1255 */ |
| 1256 class DeadCodeVerifier extends RecursiveASTVisitor<Object> { |
| 1257 |
| 1258 /** |
| 1259 * The error reporter by which errors will be reported. |
| 1260 */ |
| 1261 ErrorReporter _errorReporter; |
| 1262 |
| 1263 /** |
| 1264 * Create a new instance of the [DeadCodeVerifier]. |
| 1265 * |
| 1266 * @param errorReporter the error reporter |
| 1267 */ |
| 1268 DeadCodeVerifier(ErrorReporter errorReporter) { |
| 1269 this._errorReporter = errorReporter; |
| 1270 } |
| 1271 Object visitBinaryExpression(BinaryExpression node) { |
| 1272 sc.Token operator = node.operator; |
| 1273 bool isAmpAmp = identical(operator.type, sc.TokenType.AMPERSAND_AMPERSAND); |
| 1274 bool isBarBar = identical(operator.type, sc.TokenType.BAR_BAR); |
| 1275 if (isAmpAmp || isBarBar) { |
| 1276 Expression lhsCondition = node.leftOperand; |
| 1277 ValidResult lhsResult = getConstantBooleanValue(lhsCondition); |
| 1278 if (lhsResult != null) { |
| 1279 if (identical(lhsResult, ValidResult.RESULT_TRUE) && isBarBar) { |
| 1280 _errorReporter.reportError2(HintCode.DEAD_CODE, node.rightOperand, [])
; |
| 1281 safelyVisit(lhsCondition); |
| 1282 return null; |
| 1283 } else if (identical(lhsResult, ValidResult.RESULT_FALSE) && isAmpAmp) { |
| 1284 _errorReporter.reportError2(HintCode.DEAD_CODE, node.rightOperand, [])
; |
| 1285 safelyVisit(lhsCondition); |
| 1286 return null; |
| 1287 } |
| 1288 } |
| 1289 } |
| 1290 return super.visitBinaryExpression(node); |
| 1291 } |
| 1292 |
| 1293 /** |
| 1294 * For each [Block], this method reports and error on all statements between t
he end of the |
| 1295 * block and the first return statement (assuming there it is not at the end o
f the block.) |
| 1296 * |
| 1297 * @param node the block to evaluate |
| 1298 */ |
| 1299 Object visitBlock(Block node) { |
| 1300 NodeList<Statement> statements = node.statements; |
| 1301 int size = statements.length; |
| 1302 for (int i = 0; i < size; i++) { |
| 1303 Statement currentStatement = statements[i]; |
| 1304 safelyVisit(currentStatement); |
| 1305 if (currentStatement is ReturnStatement && i != size - 1) { |
| 1306 Statement nextStatement = statements[i + 1]; |
| 1307 Statement lastStatement = statements[size - 1]; |
| 1308 int offset = nextStatement.offset; |
| 1309 int length = lastStatement.end - offset; |
| 1310 _errorReporter.reportError3(HintCode.DEAD_CODE, offset, length, []); |
| 1311 return null; |
| 1312 } |
| 1313 } |
| 1314 return null; |
| 1315 } |
| 1316 Object visitConditionalExpression(ConditionalExpression node) { |
| 1317 Expression conditionExpression = node.condition; |
| 1318 ValidResult result = getConstantBooleanValue(conditionExpression); |
| 1319 if (result != null) { |
| 1320 if (identical(result, ValidResult.RESULT_TRUE)) { |
| 1321 _errorReporter.reportError2(HintCode.DEAD_CODE, node.elseExpression, [])
; |
| 1322 safelyVisit(node.thenExpression); |
| 1323 return null; |
| 1324 } else { |
| 1325 _errorReporter.reportError2(HintCode.DEAD_CODE, node.thenExpression, [])
; |
| 1326 safelyVisit(node.elseExpression); |
| 1327 return null; |
| 1328 } |
| 1329 } |
| 1330 return super.visitConditionalExpression(node); |
| 1331 } |
| 1332 Object visitIfStatement(IfStatement node) { |
| 1333 Expression conditionExpression = node.condition; |
| 1334 ValidResult result = getConstantBooleanValue(conditionExpression); |
| 1335 if (result != null) { |
| 1336 if (identical(result, ValidResult.RESULT_TRUE)) { |
| 1337 Statement elseStatement = node.elseStatement; |
| 1338 if (elseStatement != null) { |
| 1339 _errorReporter.reportError2(HintCode.DEAD_CODE, elseStatement, []); |
| 1340 safelyVisit(node.thenStatement); |
| 1341 return null; |
| 1342 } |
| 1343 } else { |
| 1344 _errorReporter.reportError2(HintCode.DEAD_CODE, node.thenStatement, []); |
| 1345 safelyVisit(node.elseStatement); |
| 1346 return null; |
| 1347 } |
| 1348 } |
| 1349 return super.visitIfStatement(node); |
| 1350 } |
| 1351 Object visitTryStatement(TryStatement node) { |
| 1352 safelyVisit(node.body); |
| 1353 safelyVisit(node.finallyClause); |
| 1354 NodeList<CatchClause> catchClauses = node.catchClauses; |
| 1355 int numOfCatchClauses = catchClauses.length; |
| 1356 List<Type2> visitedTypes = new List<Type2>(); |
| 1357 for (int i = 0; i < numOfCatchClauses; i++) { |
| 1358 CatchClause catchClause = catchClauses[i]; |
| 1359 if (catchClause.onKeyword != null) { |
| 1360 TypeName typeName = catchClause.exceptionType; |
| 1361 if (typeName != null && typeName.type != null) { |
| 1362 Type2 currentType = typeName.type; |
| 1363 if (currentType.isObject) { |
| 1364 safelyVisit(catchClause); |
| 1365 if (i + 1 != numOfCatchClauses) { |
| 1366 CatchClause nextCatchClause = catchClauses[i + 1]; |
| 1367 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; |
| 1368 int offset = nextCatchClause.offset; |
| 1369 int length = lastCatchClause.end - offset; |
| 1370 _errorReporter.reportError3(HintCode.DEAD_CODE_CATCH_FOLLOWING_CAT
CH, offset, length, []); |
| 1371 return null; |
| 1372 } |
| 1373 } |
| 1374 for (Type2 type in visitedTypes) { |
| 1375 if (currentType.isSubtypeOf(type)) { |
| 1376 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; |
| 1377 int offset = catchClause.offset; |
| 1378 int length = lastCatchClause.end - offset; |
| 1379 _errorReporter.reportError3(HintCode.DEAD_CODE_ON_CATCH_SUBTYPE, o
ffset, length, [currentType.displayName, type.displayName]); |
| 1380 return null; |
| 1381 } |
| 1382 } |
| 1383 visitedTypes.add(currentType); |
| 1384 } |
| 1385 safelyVisit(catchClause); |
| 1386 } else { |
| 1387 safelyVisit(catchClause); |
| 1388 if (i + 1 != numOfCatchClauses) { |
| 1389 CatchClause nextCatchClause = catchClauses[i + 1]; |
| 1390 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; |
| 1391 int offset = nextCatchClause.offset; |
| 1392 int length = lastCatchClause.end - offset; |
| 1393 _errorReporter.reportError3(HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH,
offset, length, []); |
| 1394 return null; |
| 1395 } |
| 1396 } |
| 1397 } |
| 1398 return null; |
| 1399 } |
| 1400 Object visitWhileStatement(WhileStatement node) { |
| 1401 Expression conditionExpression = node.condition; |
| 1402 safelyVisit(conditionExpression); |
| 1403 ValidResult result = getConstantBooleanValue(conditionExpression); |
| 1404 if (result != null) { |
| 1405 if (identical(result, ValidResult.RESULT_FALSE)) { |
| 1406 _errorReporter.reportError2(HintCode.DEAD_CODE, node.body, []); |
| 1407 return null; |
| 1408 } |
| 1409 } |
| 1410 safelyVisit(node.body); |
| 1411 return null; |
| 1412 } |
| 1413 |
| 1414 /** |
| 1415 * Given some [Expression], this method returns [ValidResult#RESULT_TRUE] if i
t is |
| 1416 * `true`, [ValidResult#RESULT_FALSE] if it is `false`, or `null` if the |
| 1417 * expression is not a constant boolean value. |
| 1418 * |
| 1419 * @param expression the expression to evaluate |
| 1420 * @return [ValidResult#RESULT_TRUE] if it is `true`, [ValidResult#RESULT_FALS
E] |
| 1421 * if it is `false`, or `null` if the expression is not a constant boo
lean |
| 1422 * value |
| 1423 */ |
| 1424 ValidResult getConstantBooleanValue(Expression expression) { |
| 1425 if (expression is BooleanLiteral) { |
| 1426 if (((expression as BooleanLiteral)).value) { |
| 1427 return ValidResult.RESULT_TRUE; |
| 1428 } else { |
| 1429 return ValidResult.RESULT_FALSE; |
| 1430 } |
| 1431 } else { |
| 1432 EvaluationResultImpl result = expression.accept(new ConstantVisitor()); |
| 1433 if (identical(result, ValidResult.RESULT_TRUE)) { |
| 1434 return ValidResult.RESULT_TRUE; |
| 1435 } else if (identical(result, ValidResult.RESULT_FALSE)) { |
| 1436 return ValidResult.RESULT_FALSE; |
| 1437 } |
| 1438 return null; |
| 1439 } |
| 1440 } |
| 1441 |
| 1442 /** |
| 1443 * If the given node is not `null`, visit this instance of the dead code verif
ier. |
| 1444 * |
| 1445 * @param node the node to be visited |
| 1446 */ |
| 1447 void safelyVisit(ASTNode node) { |
| 1448 if (node != null) { |
| 1449 node.accept(this); |
| 1450 } |
| 1451 } |
| 1452 } |
| 1453 /** |
| 1454 * Instances of the class `HintGenerator` traverse a library's worth of dart cod
e at a time to |
| 1455 * generate hints over the set of sources. |
| 1456 * |
| 1457 * @see HintCode |
| 1458 * @coverage dart.engine.resolver |
| 1459 */ |
| 1460 class HintGenerator { |
| 1461 List<CompilationUnit> _compilationUnits; |
| 1462 AnalysisContext _context; |
| 1463 AnalysisErrorListener _errorListener; |
| 1464 ImportsVerifier _importsVerifier; |
| 1465 DeadCodeVerifier _deadCodeVerifier; |
| 1466 HintGenerator(List<CompilationUnit> compilationUnits, AnalysisContext context,
AnalysisErrorListener errorListener) { |
| 1467 this._compilationUnits = compilationUnits; |
| 1468 this._context = context; |
| 1469 this._errorListener = errorListener; |
| 1470 LibraryElement library = compilationUnits[0].element.library; |
| 1471 _importsVerifier = new ImportsVerifier(library); |
| 1472 } |
| 1473 void generateForLibrary() { |
| 1474 for (int i = 0; i < _compilationUnits.length; i++) { |
| 1475 CompilationUnitElement element = _compilationUnits[i].element; |
| 1476 if (element != null) { |
| 1477 if (i == 0) { |
| 1478 _importsVerifier.inDefiningCompilationUnit = true; |
| 1479 generateForCompilationUnit(_compilationUnits[i], element.source); |
| 1480 _importsVerifier.inDefiningCompilationUnit = false; |
| 1481 } else { |
| 1482 generateForCompilationUnit(_compilationUnits[i], element.source); |
| 1483 } |
| 1484 } |
| 1485 } |
| 1486 _importsVerifier.generateUnusedImportHints(new ErrorReporter(_errorListener,
_compilationUnits[0].element.source)); |
| 1487 } |
| 1488 void generateForCompilationUnit(CompilationUnit unit, Source source) { |
| 1489 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source); |
| 1490 _importsVerifier.visitCompilationUnit(unit); |
| 1491 _deadCodeVerifier = new DeadCodeVerifier(errorReporter); |
| 1492 _deadCodeVerifier.visitCompilationUnit(unit); |
| 1493 } |
| 1494 } |
| 1495 /** |
| 1496 * Instances of the class `ImportsVerifier` visit all of the referenced librarie
s in the |
| 1497 * source code verifying that all of the imports are used, otherwise a |
| 1498 * [HintCode#UNUSED_IMPORT] is generated with |
| 1499 * [generateUnusedImportHints]. |
| 1500 * |
| 1501 * While this class does not yet have support for an "Organize Imports" action,
this logic built up |
| 1502 * in this class could be used for such an action in the future. |
| 1503 * |
| 1504 * @coverage dart.engine.resolver |
| 1505 */ |
| 1506 class ImportsVerifier extends RecursiveASTVisitor<Object> { |
| 1507 |
| 1508 /** |
| 1509 * This is set to `true` if the current compilation unit which is being visite
d is the |
| 1510 * defining compilation unit for the library, its value can be set with |
| 1511 * [setInDefiningCompilationUnit]. |
| 1512 */ |
| 1513 bool _inDefiningCompilationUnit = false; |
| 1514 |
| 1515 /** |
| 1516 * The current library. |
| 1517 */ |
| 1518 LibraryElement _currentLibrary; |
| 1519 |
| 1520 /** |
| 1521 * A list of [ImportDirective]s that the current library imports, as identifie
rs are visited |
| 1522 * by this visitor and an import has been identified as being used by the libr
ary, the |
| 1523 * [ImportDirective] is removed from this list. After all the sources in the l
ibrary have |
| 1524 * been evaluated, this list represents the set of unused imports. |
| 1525 * |
| 1526 * @see ImportsVerifier#generateUnusedImportErrors(ErrorReporter) |
| 1527 */ |
| 1528 List<ImportDirective> _unusedImports; |
| 1529 |
| 1530 /** |
| 1531 * This is a map between the set of [LibraryElement]s that the current library
imports, and |
| 1532 * a list of [ImportDirective]s that imports the library. In cases where the c
urrent library |
| 1533 * imports a library with a single directive (such as `import lib1.dart;`), th
e library |
| 1534 * element will map to a list of one [ImportDirective], which will then be rem
oved from the |
| 1535 * [unusedImports] list. In cases where the current library imports a library
with multiple |
| 1536 * directives (such as `import lib1.dart; import lib1.dart show C;`), the |
| 1537 * [LibraryElement] will be mapped to a list of the import directives, and the
namespace |
| 1538 * will need to be used to compute the correct [ImportDirective] being used, s
ee |
| 1539 * [namespaceMap]. |
| 1540 */ |
| 1541 Map<LibraryElement, List<ImportDirective>> _libraryMap; |
| 1542 |
| 1543 /** |
| 1544 * In cases where there is more than one import directive per library element,
this mapping is |
| 1545 * used to determine which of the multiple import directives are used by gener
ating a |
| 1546 * [Namespace] for each of the imports to do lookups in the same way that they
are done from |
| 1547 * the [ElementResolver]. |
| 1548 */ |
| 1549 Map<ImportDirective, Namespace> _namespaceMap; |
| 1550 |
| 1551 /** |
| 1552 * This is a map between prefix elements and the import directive from which t
hey are derived. In |
| 1553 * cases where a type is referenced via a prefix element, the import directive
can be marked as |
| 1554 * used (removed from the unusedImports) by looking at the resolved `lib` in `
lib.X`, |
| 1555 * instead of looking at which library the `lib.X` resolves. |
| 1556 */ |
| 1557 Map<PrefixElement, ImportDirective> _prefixElementMap; |
| 1558 |
| 1559 /** |
| 1560 * Create a new instance of the [ImportsVerifier]. |
| 1561 * |
| 1562 * @param errorReporter the error reporter |
| 1563 */ |
| 1564 ImportsVerifier(LibraryElement library) { |
| 1565 this._currentLibrary = library; |
| 1566 this._unusedImports = new List<ImportDirective>(); |
| 1567 this._libraryMap = new Map<LibraryElement, List<ImportDirective>>(); |
| 1568 this._namespaceMap = new Map<ImportDirective, Namespace>(); |
| 1569 this._prefixElementMap = new Map<PrefixElement, ImportDirective>(); |
| 1570 } |
| 1571 |
| 1572 /** |
| 1573 * After all of the compilation units have been visited by this visitor, this
method can be called |
| 1574 * to report an [HintCode#UNUSED_IMPORT] hint for each of the import directive
s in the |
| 1575 * [unusedImports] list. |
| 1576 * |
| 1577 * @param errorReporter the error reporter to report the set of [HintCode#UNUS
ED_IMPORT] |
| 1578 * hints to |
| 1579 */ |
| 1580 void generateUnusedImportHints(ErrorReporter errorReporter) { |
| 1581 for (ImportDirective unusedImport in _unusedImports) { |
| 1582 errorReporter.reportError2(HintCode.UNUSED_IMPORT, unusedImport.uri, []); |
| 1583 } |
| 1584 } |
| 1585 Object visitCompilationUnit(CompilationUnit node) { |
| 1586 if (_inDefiningCompilationUnit) { |
| 1587 NodeList<Directive> directives = node.directives; |
| 1588 for (Directive directive in directives) { |
| 1589 if (directive is ImportDirective) { |
| 1590 ImportDirective importDirective = directive as ImportDirective; |
| 1591 LibraryElement libraryElement = importDirective.uriElement; |
| 1592 if (libraryElement != null) { |
| 1593 _unusedImports.add(importDirective); |
| 1594 if (importDirective.asToken != null) { |
| 1595 SimpleIdentifier prefixIdentifier = importDirective.prefix; |
| 1596 if (prefixIdentifier != null) { |
| 1597 Element element = prefixIdentifier.element; |
| 1598 if (element is PrefixElement) { |
| 1599 PrefixElement prefixElementKey = element as PrefixElement; |
| 1600 _prefixElementMap[prefixElementKey] = importDirective; |
| 1601 } |
| 1602 } |
| 1603 } |
| 1604 putIntoLibraryMap(libraryElement, importDirective); |
| 1605 addAdditionalLibrariesForExports(_libraryMap, libraryElement, import
Directive, new List<LibraryElement>()); |
| 1606 } |
| 1607 } |
| 1608 } |
| 1609 } |
| 1610 if (_unusedImports.isEmpty) { |
| 1611 return null; |
| 1612 } |
| 1613 return super.visitCompilationUnit(node); |
| 1614 } |
| 1615 Object visitExportDirective(ExportDirective node) => null; |
| 1616 Object visitImportDirective(ImportDirective node) => null; |
| 1617 Object visitLibraryDirective(LibraryDirective node) => null; |
| 1618 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 1619 SimpleIdentifier prefixIdentifier = node.prefix; |
| 1620 Element element = prefixIdentifier.element; |
| 1621 if (element is PrefixElement) { |
| 1622 _unusedImports.remove(_prefixElementMap[element]); |
| 1623 return null; |
| 1624 } |
| 1625 return visitIdentifier(element, prefixIdentifier.name); |
| 1626 } |
| 1627 Object visitSimpleIdentifier(SimpleIdentifier node) => visitIdentifier(node.el
ement, node.name); |
| 1628 void set inDefiningCompilationUnit(bool inDefiningCompilationUnit2) { |
| 1629 this._inDefiningCompilationUnit = inDefiningCompilationUnit2; |
| 1630 } |
| 1631 |
| 1632 /** |
| 1633 * Recursively add any exported library elements into the [libraryMap]. |
| 1634 */ |
| 1635 void addAdditionalLibrariesForExports(Map<LibraryElement, List<ImportDirective
>> map, LibraryElement library, ImportDirective importDirective, List<LibraryEle
ment> exportPath) { |
| 1636 if (exportPath.contains(library)) { |
| 1637 return; |
| 1638 } |
| 1639 for (LibraryElement exportedLibraryElt in library.exportedLibraries) { |
| 1640 putIntoLibraryMap(exportedLibraryElt, importDirective); |
| 1641 exportPath.add(exportedLibraryElt); |
| 1642 addAdditionalLibrariesForExports(map, exportedLibraryElt, importDirective,
exportPath); |
| 1643 } |
| 1644 } |
| 1645 |
| 1646 /** |
| 1647 * Lookup and return the [Namespace] from the [namespaceMap], if the map does
not |
| 1648 * have the computed namespace, compute it and cache it in the map. If the imp
ort directive is not |
| 1649 * resolved or is not resolvable, `null` is returned. |
| 1650 * |
| 1651 * @param importDirective the import directive used to compute the returned na
mespace |
| 1652 * @return the computed or looked up [Namespace] |
| 1653 */ |
| 1654 Namespace computeNamespace(ImportDirective importDirective) { |
| 1655 Namespace namespace = _namespaceMap[importDirective]; |
| 1656 if (namespace == null) { |
| 1657 ImportElement importElement = importDirective.element as ImportElement; |
| 1658 if (importElement != null) { |
| 1659 NamespaceBuilder builder = new NamespaceBuilder(); |
| 1660 namespace = builder.createImportNamespace(importElement); |
| 1661 _namespaceMap[importDirective] = namespace; |
| 1662 } |
| 1663 } |
| 1664 return namespace; |
| 1665 } |
| 1666 |
| 1667 /** |
| 1668 * The [libraryMap] is a mapping between a library elements and a list of impo
rt |
| 1669 * directives, but when adding these mappings into the [libraryMap], this meth
od can be |
| 1670 * used to simply add the mapping between the library element an an import dir
ective without |
| 1671 * needing to check to see if a list needs to be created. |
| 1672 */ |
| 1673 void putIntoLibraryMap(LibraryElement libraryElement, ImportDirective importDi
rective) { |
| 1674 List<ImportDirective> importList = _libraryMap[libraryElement]; |
| 1675 if (importList == null) { |
| 1676 importList = new List<ImportDirective>(); |
| 1677 _libraryMap[libraryElement] = importList; |
| 1678 } |
| 1679 importList.add(importDirective); |
| 1680 } |
| 1681 Object visitIdentifier(Element element, String name) { |
| 1682 if (element == null) { |
| 1683 return null; |
| 1684 } |
| 1685 if (element is MultiplyDefinedElement) { |
| 1686 MultiplyDefinedElement multiplyDefinedElement = element as MultiplyDefined
Element; |
| 1687 for (Element elt in multiplyDefinedElement.conflictingElements) { |
| 1688 visitIdentifier(elt, name); |
| 1689 } |
| 1690 return null; |
| 1691 } |
| 1692 LibraryElement containingLibrary = element.library; |
| 1693 if (containingLibrary == null) { |
| 1694 return null; |
| 1695 } |
| 1696 if (_currentLibrary == containingLibrary) { |
| 1697 return null; |
| 1698 } |
| 1699 List<ImportDirective> importsFromSameLibrary = _libraryMap[containingLibrary
]; |
| 1700 if (importsFromSameLibrary == null) { |
| 1701 return null; |
| 1702 } |
| 1703 if (importsFromSameLibrary.length == 1) { |
| 1704 ImportDirective usedImportDirective = importsFromSameLibrary[0]; |
| 1705 _unusedImports.remove(usedImportDirective); |
| 1706 } else { |
| 1707 for (ImportDirective importDirective in importsFromSameLibrary) { |
| 1708 Namespace namespace = computeNamespace(importDirective); |
| 1709 if (namespace != null && namespace.get(name) != null) { |
| 1710 _unusedImports.remove(importDirective); |
| 1711 } |
| 1712 } |
| 1713 } |
| 1714 return null; |
| 1715 } |
| 1716 } |
| 1717 /** |
| 1718 * Instances of the class `PubVerifier` traverse an AST structure looking for de
viations from |
| 1719 * pub best practices. |
| 1720 */ |
| 1721 class PubVerifier extends RecursiveASTVisitor<Object> { |
| 1722 static String _PUBSPEC_YAML = "pubspec.yaml"; |
| 1723 |
| 1724 /** |
| 1725 * The analysis context containing the sources to be analyzed |
| 1726 */ |
| 1727 AnalysisContext _context; |
| 1728 |
| 1729 /** |
| 1730 * The error reporter by which errors will be reported. |
| 1731 */ |
| 1732 ErrorReporter _errorReporter; |
| 1733 PubVerifier(AnalysisContext context, ErrorReporter errorReporter) { |
| 1734 this._context = context; |
| 1735 this._errorReporter = errorReporter; |
| 1736 } |
| 1737 Object visitImportDirective(ImportDirective directive) { |
| 1738 return null; |
| 1739 } |
| 1740 |
| 1741 /** |
| 1742 * This verifies that the passed file import directive is not contained in a s
ource inside a |
| 1743 * package "lib" directory hierarchy referencing a source outside that package
"lib" directory |
| 1744 * hierarchy. |
| 1745 * |
| 1746 * @param uriLiteral the import URL (not `null`) |
| 1747 * @param path the file path being verified (not `null`) |
| 1748 * @return `true` if and only if an error code is generated on the passed node |
| 1749 * @see PubSuggestionCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE |
| 1750 */ |
| 1751 bool checkForFileImportInsideLibReferencesFileOutside(StringLiteral uriLiteral
, String path) { |
| 1752 Source source = getSource(uriLiteral); |
| 1753 String fullName = getSourceFullName(source); |
| 1754 if (fullName != null) { |
| 1755 int pathIndex = 0; |
| 1756 int fullNameIndex = fullName.length; |
| 1757 while (pathIndex < path.length && JavaString.startsWithBefore(path, "../",
pathIndex)) { |
| 1758 fullNameIndex = JavaString.lastIndexOf(fullName, '/', fullNameIndex); |
| 1759 if (fullNameIndex < 4) { |
| 1760 return false; |
| 1761 } |
| 1762 if (JavaString.startsWithBefore(fullName, "/lib", fullNameIndex - 4)) { |
| 1763 String relativePubspecPath = path.substring(0, pathIndex + 3) + _PUBSP
EC_YAML; |
| 1764 Source pubspecSource = _context.sourceFactory.resolveUri(source, relat
ivePubspecPath); |
| 1765 if (pubspecSource.exists()) { |
| 1766 _errorReporter.reportError2(PubSuggestionCode.FILE_IMPORT_INSIDE_LIB
_REFERENCES_FILE_OUTSIDE, uriLiteral, []); |
| 1767 } |
| 1768 return true; |
| 1769 } |
| 1770 pathIndex += 3; |
| 1771 } |
| 1772 } |
| 1773 return false; |
| 1774 } |
| 1775 |
| 1776 /** |
| 1777 * This verifies that the passed file import directive is not contained in a s
ource outside a |
| 1778 * package "lib" directory hierarchy referencing a source inside that package
"lib" directory |
| 1779 * hierarchy. |
| 1780 * |
| 1781 * @param uriLiteral the import URL (not `null`) |
| 1782 * @param path the file path being verified (not `null`) |
| 1783 * @return `true` if and only if an error code is generated on the passed node |
| 1784 * @see PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE |
| 1785 */ |
| 1786 bool checkForFileImportOutsideLibReferencesFileInside(StringLiteral uriLiteral
, String path) { |
| 1787 if (path.startsWith("lib/")) { |
| 1788 if (checkForFileImportOutsideLibReferencesFileInside2(uriLiteral, path, 0)
) { |
| 1789 return true; |
| 1790 } |
| 1791 } |
| 1792 int pathIndex = path.indexOf("/lib/"); |
| 1793 while (pathIndex != -1) { |
| 1794 if (checkForFileImportOutsideLibReferencesFileInside2(uriLiteral, path, pa
thIndex + 1)) { |
| 1795 return true; |
| 1796 } |
| 1797 pathIndex = JavaString.indexOf(path, "/lib/", pathIndex + 4); |
| 1798 } |
| 1799 return false; |
| 1800 } |
| 1801 bool checkForFileImportOutsideLibReferencesFileInside2(StringLiteral uriLitera
l, String path, int pathIndex) { |
| 1802 Source source = getSource(uriLiteral); |
| 1803 String relativePubspecPath = path.substring(0, pathIndex) + _PUBSPEC_YAML; |
| 1804 Source pubspecSource = _context.sourceFactory.resolveUri(source, relativePub
specPath); |
| 1805 if (!pubspecSource.exists()) { |
| 1806 return false; |
| 1807 } |
| 1808 String fullName = getSourceFullName(source); |
| 1809 if (fullName != null) { |
| 1810 if (!fullName.contains("/lib/")) { |
| 1811 _errorReporter.reportError2(PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_RE
FERENCES_FILE_INSIDE, uriLiteral, []); |
| 1812 return true; |
| 1813 } |
| 1814 } |
| 1815 return false; |
| 1816 } |
| 1817 |
| 1818 /** |
| 1819 * This verifies that the passed package import directive does not contain "..
" |
| 1820 * |
| 1821 * @param uriLiteral the import URL (not `null`) |
| 1822 * @param path the path to be validated (not `null`) |
| 1823 * @return `true` if and only if an error code is generated on the passed node |
| 1824 * @see PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT |
| 1825 */ |
| 1826 bool checkForPackageImportContainsDotDot(StringLiteral uriLiteral, String path
) { |
| 1827 if (path.startsWith("../") || path.contains("/../")) { |
| 1828 _errorReporter.reportError2(PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_
DOT, uriLiteral, []); |
| 1829 return true; |
| 1830 } |
| 1831 return false; |
| 1832 } |
| 1833 |
| 1834 /** |
| 1835 * Answer the source associated with the compilation unit containing the given
AST node. |
| 1836 * |
| 1837 * @param node the node (not `null`) |
| 1838 * @return the source or `null` if it could not be determined |
| 1839 */ |
| 1840 Source getSource(ASTNode node) { |
| 1841 Source source = null; |
| 1842 CompilationUnit unit = node.getAncestor(CompilationUnit); |
| 1843 if (unit != null) { |
| 1844 CompilationUnitElement element = unit.element; |
| 1845 if (element != null) { |
| 1846 source = element.source; |
| 1847 } |
| 1848 } |
| 1849 return source; |
| 1850 } |
| 1851 |
| 1852 /** |
| 1853 * Answer the full name of the given source. The returned value will have all |
| 1854 * [File#separatorChar] replace by '/'. |
| 1855 * |
| 1856 * @param source the source |
| 1857 * @return the full name or `null` if it could not be determined |
| 1858 */ |
| 1859 String getSourceFullName(Source source) { |
| 1860 if (source != null) { |
| 1861 String fullName = source.fullName; |
| 1862 if (fullName != null) { |
| 1863 return fullName.replaceAll(r'\', '/'); |
| 1864 } |
| 1865 } |
| 1866 return null; |
| 1867 } |
| 1868 } |
| 1869 /** |
| 1251 * Instances of the class `DeclarationResolver` are used to resolve declarations
in an AST | 1870 * Instances of the class `DeclarationResolver` are used to resolve declarations
in an AST |
| 1252 * structure to already built elements. | 1871 * structure to already built elements. |
| 1253 */ | 1872 */ |
| 1254 class DeclarationResolver extends RecursiveASTVisitor<Object> { | 1873 class DeclarationResolver extends RecursiveASTVisitor<Object> { |
| 1255 | 1874 |
| 1256 /** | 1875 /** |
| 1257 * The compilation unit containing the AST nodes being visited. | 1876 * The compilation unit containing the AST nodes being visited. |
| 1258 */ | 1877 */ |
| 1259 CompilationUnitElement _enclosingUnit; | 1878 CompilationUnitElement _enclosingUnit; |
| 1260 | 1879 |
| (...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1882 /** | 2501 /** |
| 1883 * The name of the method that can be implemented by a class to allow its inst
ances to be invoked | 2502 * The name of the method that can be implemented by a class to allow its inst
ances to be invoked |
| 1884 * as if they were a function. | 2503 * as if they were a function. |
| 1885 */ | 2504 */ |
| 1886 static String CALL_METHOD_NAME = "call"; | 2505 static String CALL_METHOD_NAME = "call"; |
| 1887 | 2506 |
| 1888 /** | 2507 /** |
| 1889 * The name of the method that will be invoked if an attempt is made to invoke
an undefined method | 2508 * The name of the method that will be invoked if an attempt is made to invoke
an undefined method |
| 1890 * on an object. | 2509 * on an object. |
| 1891 */ | 2510 */ |
| 1892 static String _NO_SUCH_METHOD_METHOD_NAME = "noSuchMethod"; | 2511 static String NO_SUCH_METHOD_METHOD_NAME = "noSuchMethod"; |
| 1893 | 2512 |
| 1894 /** | 2513 /** |
| 1895 * Initialize a newly created visitor to resolve the nodes in a compilation un
it. | 2514 * Initialize a newly created visitor to resolve the nodes in a compilation un
it. |
| 1896 * | 2515 * |
| 1897 * @param resolver the resolver driving this participant | 2516 * @param resolver the resolver driving this participant |
| 1898 */ | 2517 */ |
| 1899 ElementResolver(ResolverVisitor resolver) { | 2518 ElementResolver(ResolverVisitor resolver) { |
| 1900 this._resolver = resolver; | 2519 this._resolver = resolver; |
| 1901 _strictMode = resolver.definingLibrary.context.analysisOptions.strictMode; | 2520 _strictMode = resolver.definingLibrary.context.analysisOptions.strictMode; |
| 1902 } | 2521 } |
| 1903 Object visitAssignmentExpression(AssignmentExpression node) { | 2522 Object visitAssignmentExpression(AssignmentExpression node) { |
| 1904 sc.Token operator = node.operator; | 2523 sc.Token operator = node.operator; |
| 1905 sc.TokenType operatorType = operator.type; | 2524 sc.TokenType operatorType = operator.type; |
| 1906 if (operatorType != sc.TokenType.EQ) { | 2525 if (operatorType != sc.TokenType.EQ) { |
| 1907 operatorType = operatorFromCompoundAssignment(operatorType); | 2526 operatorType = operatorFromCompoundAssignment(operatorType); |
| 1908 Expression leftHandSide = node.leftHandSide; | 2527 Expression leftHandSide = node.leftHandSide; |
| 1909 if (leftHandSide != null) { | 2528 if (leftHandSide != null) { |
| 1910 String methodName = operatorType.lexeme; | 2529 String methodName = operatorType.lexeme; |
| 1911 Type2 staticType = getStaticType(leftHandSide); | 2530 Type2 staticType = getStaticType(leftHandSide); |
| 1912 MethodElement staticMethod = lookUpMethod(leftHandSide, staticType, meth
odName); | 2531 MethodElement staticMethod = lookUpMethod(leftHandSide, staticType, meth
odName); |
| 1913 node.staticElement = staticMethod; | 2532 node.staticElement = staticMethod; |
| 1914 Type2 propagatedType = getPropagatedType(leftHandSide); | 2533 Type2 propagatedType = getPropagatedType(leftHandSide); |
| 1915 MethodElement propagatedMethod = lookUpMethod(leftHandSide, propagatedTy
pe, methodName); | 2534 MethodElement propagatedMethod = lookUpMethod(leftHandSide, propagatedTy
pe, methodName); |
| 1916 node.element = select2(staticMethod, propagatedMethod); | 2535 node.propagatedElement = propagatedMethod; |
| 1917 if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode
|| propagatedType == null || shouldReportMissingMember(propagatedType, propagate
dMethod))) { | 2536 if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode
|| propagatedType == null || shouldReportMissingMember(propagatedType, propagate
dMethod))) { |
| 1918 _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_METHOD, operato
r, [methodName, staticType.displayName]); | 2537 _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_METHOD, operato
r, [methodName, staticType.displayName]); |
| 1919 } | 2538 } |
| 1920 } | 2539 } |
| 1921 } | 2540 } |
| 1922 return null; | 2541 return null; |
| 1923 } | 2542 } |
| 1924 Object visitBinaryExpression(BinaryExpression node) { | 2543 Object visitBinaryExpression(BinaryExpression node) { |
| 1925 sc.Token operator = node.operator; | 2544 sc.Token operator = node.operator; |
| 1926 if (operator.isUserDefinableOperator) { | 2545 if (operator.isUserDefinableOperator) { |
| 1927 Expression leftOperand = node.leftOperand; | 2546 Expression leftOperand = node.leftOperand; |
| 1928 if (leftOperand != null) { | 2547 if (leftOperand != null) { |
| 1929 String methodName = operator.lexeme; | 2548 String methodName = operator.lexeme; |
| 1930 Type2 staticType = getStaticType(leftOperand); | 2549 Type2 staticType = getStaticType(leftOperand); |
| 1931 MethodElement staticMethod = lookUpMethod(leftOperand, staticType, metho
dName); | 2550 MethodElement staticMethod = lookUpMethod(leftOperand, staticType, metho
dName); |
| 1932 node.staticElement = staticMethod; | 2551 node.staticElement = staticMethod; |
| 1933 Type2 propagatedType = getPropagatedType(leftOperand); | 2552 Type2 propagatedType = getPropagatedType(leftOperand); |
| 1934 MethodElement propagatedMethod = lookUpMethod(leftOperand, propagatedTyp
e, methodName); | 2553 MethodElement propagatedMethod = lookUpMethod(leftOperand, propagatedTyp
e, methodName); |
| 1935 node.element = select2(staticMethod, propagatedMethod); | 2554 node.propagatedElement = propagatedMethod; |
| 1936 if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode
|| propagatedType == null || shouldReportMissingMember(propagatedType, propagate
dMethod))) { | 2555 if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode
|| propagatedType == null || shouldReportMissingMember(propagatedType, propagate
dMethod))) { |
| 1937 _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_OPERATOR, opera
tor, [methodName, staticType.displayName]); | 2556 _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_OPERATOR, opera
tor, [methodName, staticType.displayName]); |
| 1938 } | 2557 } |
| 1939 } | 2558 } |
| 1940 } | 2559 } |
| 1941 return null; | 2560 return null; |
| 1942 } | 2561 } |
| 1943 Object visitBreakStatement(BreakStatement node) { | 2562 Object visitBreakStatement(BreakStatement node) { |
| 1944 SimpleIdentifier labelNode = node.label; | 2563 SimpleIdentifier labelNode = node.label; |
| 1945 LabelElementImpl labelElement = lookupLabel(node, labelNode); | 2564 LabelElementImpl labelElement = lookupLabel(node, labelNode); |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2228 } else { | 2847 } else { |
| 2229 Type2 targetType = getStaticType(target); | 2848 Type2 targetType = getStaticType(target); |
| 2230 staticElement = resolveInvokedElement(target, targetType, methodName); | 2849 staticElement = resolveInvokedElement(target, targetType, methodName); |
| 2231 propagatedElement = resolveInvokedElement(target, getPropagatedType(target
), methodName); | 2850 propagatedElement = resolveInvokedElement(target, getPropagatedType(target
), methodName); |
| 2232 } | 2851 } |
| 2233 staticElement = convertSetterToGetter(staticElement); | 2852 staticElement = convertSetterToGetter(staticElement); |
| 2234 propagatedElement = convertSetterToGetter(propagatedElement); | 2853 propagatedElement = convertSetterToGetter(propagatedElement); |
| 2235 recordResolution2(methodName, staticElement, propagatedElement); | 2854 recordResolution2(methodName, staticElement, propagatedElement); |
| 2236 ArgumentList argumentList = node.argumentList; | 2855 ArgumentList argumentList = node.argumentList; |
| 2237 if (staticElement != null) { | 2856 if (staticElement != null) { |
| 2238 List<ParameterElement> parameters = computePropagatedParameters(argumentLi
st, staticElement); | 2857 List<ParameterElement> parameters = computeCorrespondingParameters(argumen
tList, staticElement); |
| 2239 if (parameters != null) { | 2858 if (parameters != null) { |
| 2240 argumentList.correspondingStaticParameters = parameters; | 2859 argumentList.correspondingStaticParameters = parameters; |
| 2241 } | 2860 } |
| 2242 } | 2861 } |
| 2243 if (propagatedElement != null) { | 2862 if (propagatedElement != null) { |
| 2244 List<ParameterElement> parameters = computePropagatedParameters(argumentLi
st, propagatedElement); | 2863 List<ParameterElement> parameters = computeCorrespondingParameters(argumen
tList, propagatedElement); |
| 2245 if (parameters != null) { | 2864 if (parameters != null) { |
| 2246 argumentList.correspondingParameters = parameters; | 2865 argumentList.correspondingPropagatedParameters = parameters; |
| 2247 } | 2866 } |
| 2248 } | 2867 } |
| 2249 ErrorCode errorCode = checkForInvocationError(target, staticElement); | 2868 ErrorCode errorCode = checkForInvocationError(target, staticElement); |
| 2250 if (identical(errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION))
{ | 2869 if (identical(errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION))
{ |
| 2251 _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, me
thodName, [methodName.name]); | 2870 _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, me
thodName, [methodName.name]); |
| 2252 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) { | 2871 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) { |
| 2253 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_FUNCTION, methodName
, [methodName.name]); | 2872 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_FUNCTION, methodName
, [methodName.name]); |
| 2254 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { | 2873 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { |
| 2255 String targetTypeName; | 2874 String targetTypeName; |
| 2256 if (target == null) { | 2875 if (target == null) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2283 return null; | 2902 return null; |
| 2284 } | 2903 } |
| 2285 Object visitPostfixExpression(PostfixExpression node) { | 2904 Object visitPostfixExpression(PostfixExpression node) { |
| 2286 Expression operand = node.operand; | 2905 Expression operand = node.operand; |
| 2287 String methodName = getPostfixOperator(node); | 2906 String methodName = getPostfixOperator(node); |
| 2288 Type2 staticType = getStaticType(operand); | 2907 Type2 staticType = getStaticType(operand); |
| 2289 MethodElement staticMethod = lookUpMethod(operand, staticType, methodName); | 2908 MethodElement staticMethod = lookUpMethod(operand, staticType, methodName); |
| 2290 node.staticElement = staticMethod; | 2909 node.staticElement = staticMethod; |
| 2291 Type2 propagatedType = getPropagatedType(operand); | 2910 Type2 propagatedType = getPropagatedType(operand); |
| 2292 MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, metho
dName); | 2911 MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, metho
dName); |
| 2293 node.element = select2(staticMethod, propagatedMethod); | 2912 node.propagatedElement = propagatedMethod; |
| 2294 if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || p
ropagatedType == null || shouldReportMissingMember(propagatedType, propagatedMet
hod))) { | 2913 if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || p
ropagatedType == null || shouldReportMissingMember(propagatedType, propagatedMet
hod))) { |
| 2295 _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_OPERATOR, node.oper
ator, [methodName, staticType.displayName]); | 2914 _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_OPERATOR, node.oper
ator, [methodName, staticType.displayName]); |
| 2296 } | 2915 } |
| 2297 return null; | 2916 return null; |
| 2298 } | 2917 } |
| 2299 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 2918 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 2300 SimpleIdentifier prefix = node.prefix; | 2919 SimpleIdentifier prefix = node.prefix; |
| 2301 SimpleIdentifier identifier = node.identifier; | 2920 SimpleIdentifier identifier = node.identifier; |
| 2302 Element prefixElement = prefix.element; | 2921 Element prefixElement = prefix.element; |
| 2303 if (prefixElement is PrefixElement) { | 2922 if (prefixElement is PrefixElement) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2334 sc.Token operator = node.operator; | 2953 sc.Token operator = node.operator; |
| 2335 sc.TokenType operatorType = operator.type; | 2954 sc.TokenType operatorType = operator.type; |
| 2336 if (operatorType.isUserDefinableOperator || identical(operatorType, sc.Token
Type.PLUS_PLUS) || identical(operatorType, sc.TokenType.MINUS_MINUS)) { | 2955 if (operatorType.isUserDefinableOperator || identical(operatorType, sc.Token
Type.PLUS_PLUS) || identical(operatorType, sc.TokenType.MINUS_MINUS)) { |
| 2337 Expression operand = node.operand; | 2956 Expression operand = node.operand; |
| 2338 String methodName = getPrefixOperator(node); | 2957 String methodName = getPrefixOperator(node); |
| 2339 Type2 staticType = getStaticType(operand); | 2958 Type2 staticType = getStaticType(operand); |
| 2340 MethodElement staticMethod = lookUpMethod(operand, staticType, methodName)
; | 2959 MethodElement staticMethod = lookUpMethod(operand, staticType, methodName)
; |
| 2341 node.staticElement = staticMethod; | 2960 node.staticElement = staticMethod; |
| 2342 Type2 propagatedType = getPropagatedType(operand); | 2961 Type2 propagatedType = getPropagatedType(operand); |
| 2343 MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, met
hodName); | 2962 MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, met
hodName); |
| 2344 node.element = select2(staticMethod, propagatedMethod); | 2963 node.propagatedElement = propagatedMethod; |
| 2345 if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode ||
propagatedType == null || shouldReportMissingMember(propagatedType, propagatedM
ethod))) { | 2964 if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode ||
propagatedType == null || shouldReportMissingMember(propagatedType, propagatedM
ethod))) { |
| 2346 _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_OPERATOR, operato
r, [methodName, staticType.displayName]); | 2965 _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_OPERATOR, operato
r, [methodName, staticType.displayName]); |
| 2347 } | 2966 } |
| 2348 } | 2967 } |
| 2349 return null; | 2968 return null; |
| 2350 } | 2969 } |
| 2351 Object visitPropertyAccess(PropertyAccess node) { | 2970 Object visitPropertyAccess(PropertyAccess node) { |
| 2352 Expression target = node.realTarget; | 2971 Expression target = node.realTarget; |
| 2353 if (target is SuperExpression && !isSuperInValidContext((target as SuperExpr
ession))) { | 2972 if (target is SuperExpression && !isSuperInValidContext((target as SuperExpr
ession))) { |
| 2354 return null; | 2973 return null; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2378 node.staticElement = element; | 2997 node.staticElement = element; |
| 2379 node.element = element; | 2998 node.element = element; |
| 2380 ArgumentList argumentList = node.argumentList; | 2999 ArgumentList argumentList = node.argumentList; |
| 2381 List<ParameterElement> parameters = resolveArgumentsToParameters(false, argu
mentList, element); | 3000 List<ParameterElement> parameters = resolveArgumentsToParameters(false, argu
mentList, element); |
| 2382 if (parameters != null) { | 3001 if (parameters != null) { |
| 2383 argumentList.correspondingStaticParameters = parameters; | 3002 argumentList.correspondingStaticParameters = parameters; |
| 2384 } | 3003 } |
| 2385 return null; | 3004 return null; |
| 2386 } | 3005 } |
| 2387 Object visitSimpleIdentifier(SimpleIdentifier node) { | 3006 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 2388 if (node.element != null) { | 3007 if (node.staticElement != null || node.element != null) { |
| 2389 return null; | 3008 return null; |
| 2390 } | 3009 } |
| 2391 Element element = resolveSimpleIdentifier(node); | 3010 Element element = resolveSimpleIdentifier(node); |
| 2392 if (isFactoryConstructorReturnType(node) && element != _resolver.enclosingCl
ass) { | 3011 if (isFactoryConstructorReturnType(node) && element != _resolver.enclosingCl
ass) { |
| 2393 _resolver.reportError(CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLAS
S, node, []); | 3012 _resolver.reportError(CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLAS
S, node, []); |
| 2394 } else if (element == null) { | 3013 } else if (element == null || (element is PrefixElement && !isValidAsPrefix(
node))) { |
| 2395 if (isConstructorReturnType(node)) { | 3014 if (isConstructorReturnType(node)) { |
| 2396 _resolver.reportError(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, nod
e, []); | 3015 _resolver.reportError(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, nod
e, []); |
| 2397 } else if (!classDeclaresNoSuchMethod(_resolver.enclosingClass)) { | 3016 } else { |
| 2398 _resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, node, [nod
e.name]); | 3017 _resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, node, [nod
e.name]); |
| 2399 } | 3018 } |
| 2400 } | 3019 } |
| 2401 recordResolution(node, element); | 3020 recordResolution(node, element); |
| 2402 if (node.parent is Annotation) { | 3021 if (node.parent is Annotation) { |
| 2403 Annotation annotation = node.parent as Annotation; | 3022 Annotation annotation = node.parent as Annotation; |
| 2404 resolveAnnotationElement(annotation, element, null); | 3023 resolveAnnotationElement(annotation, element, null); |
| 2405 } | 3024 } |
| 2406 return null; | 3025 return null; |
| 2407 } | 3026 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2484 } | 3103 } |
| 2485 | 3104 |
| 2486 /** | 3105 /** |
| 2487 * Given that we have found code to invoke the given element, return the error
code that should be | 3106 * Given that we have found code to invoke the given element, return the error
code that should be |
| 2488 * reported, or `null` if no error should be reported. | 3107 * reported, or `null` if no error should be reported. |
| 2489 * | 3108 * |
| 2490 * @param target the target of the invocation, or `null` if there was no targe
t | 3109 * @param target the target of the invocation, or `null` if there was no targe
t |
| 2491 * @param element the element to be invoked | 3110 * @param element the element to be invoked |
| 2492 * @return the error code that should be reported | 3111 * @return the error code that should be reported |
| 2493 */ | 3112 */ |
| 2494 ErrorCode checkForInvocationError(Expression target, Element element2) { | 3113 ErrorCode checkForInvocationError(Expression target, Element element) { |
| 2495 if (element2 is PropertyAccessorElement) { | 3114 if (element is PropertyAccessorElement) { |
| 2496 FunctionType getterType = ((element2 as PropertyAccessorElement)).type; | 3115 FunctionType getterType = ((element as PropertyAccessorElement)).type; |
| 2497 if (getterType != null) { | 3116 if (getterType != null) { |
| 2498 Type2 returnType = getterType.returnType; | 3117 Type2 returnType = getterType.returnType; |
| 2499 if (!isExecutableType(returnType)) { | 3118 if (!isExecutableType(returnType)) { |
| 2500 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; | 3119 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; |
| 2501 } | 3120 } |
| 2502 } | 3121 } |
| 2503 } else if (element2 is ExecutableElement) { | 3122 } else if (element is ExecutableElement) { |
| 2504 return null; | 3123 return null; |
| 2505 } else if (element2 == null && target is SuperExpression) { | 3124 } else if (element == null && target is SuperExpression) { |
| 2506 return StaticTypeWarningCode.UNDEFINED_SUPER_METHOD; | 3125 return StaticTypeWarningCode.UNDEFINED_SUPER_METHOD; |
| 2507 } else { | 3126 } else { |
| 2508 if (element2 is PropertyInducingElement) { | 3127 if (element is PropertyInducingElement) { |
| 2509 PropertyAccessorElement getter = ((element2 as PropertyInducingElement))
.getter; | 3128 PropertyAccessorElement getter = ((element as PropertyInducingElement)).
getter; |
| 2510 FunctionType getterType = getter.type; | 3129 FunctionType getterType = getter.type; |
| 2511 if (getterType != null) { | 3130 if (getterType != null) { |
| 2512 Type2 returnType = getterType.returnType; | 3131 Type2 returnType = getterType.returnType; |
| 2513 if (!isExecutableType(returnType)) { | 3132 if (!isExecutableType(returnType)) { |
| 2514 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; | 3133 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; |
| 2515 } | 3134 } |
| 2516 } | 3135 } |
| 2517 } else if (element2 is VariableElement) { | 3136 } else if (element is VariableElement) { |
| 2518 Type2 variableType = ((element2 as VariableElement)).type; | 3137 Type2 variableType = ((element as VariableElement)).type; |
| 2519 if (!isExecutableType(variableType)) { | 3138 if (!isExecutableType(variableType)) { |
| 2520 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; | 3139 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; |
| 2521 } | 3140 } |
| 2522 } else { | 3141 } else { |
| 2523 if (target == null) { | 3142 if (target == null) { |
| 2524 ClassElement enclosingClass = _resolver.enclosingClass; | 3143 ClassElement enclosingClass = _resolver.enclosingClass; |
| 2525 if (enclosingClass == null) { | 3144 if (enclosingClass == null) { |
| 2526 return StaticTypeWarningCode.UNDEFINED_FUNCTION; | 3145 return StaticTypeWarningCode.UNDEFINED_FUNCTION; |
| 2527 } else if (element2 == null) { | 3146 } else if (element == null) { |
| 2528 if (!classDeclaresNoSuchMethod(enclosingClass)) { | 3147 return StaticTypeWarningCode.UNDEFINED_METHOD; |
| 2529 return StaticTypeWarningCode.UNDEFINED_METHOD; | |
| 2530 } | |
| 2531 } else { | 3148 } else { |
| 2532 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; | 3149 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; |
| 2533 } | 3150 } |
| 2534 } else { | 3151 } else { |
| 2535 Type2 targetType = getStaticType(target); | 3152 Type2 targetType = getStaticType(target); |
| 2536 if (targetType == null) { | 3153 if (targetType == null) { |
| 2537 return StaticTypeWarningCode.UNDEFINED_FUNCTION; | 3154 return StaticTypeWarningCode.UNDEFINED_FUNCTION; |
| 2538 } else if (!targetType.isDynamic && !classDeclaresNoSuchMethod2(target
Type.element)) { | 3155 } else if (!targetType.isDynamic) { |
| 2539 return StaticTypeWarningCode.UNDEFINED_METHOD; | 3156 return StaticTypeWarningCode.UNDEFINED_METHOD; |
| 2540 } | 3157 } |
| 2541 } | 3158 } |
| 2542 } | 3159 } |
| 2543 } | 3160 } |
| 2544 return null; | 3161 return null; |
| 2545 } | 3162 } |
| 2546 | 3163 |
| 2547 /** | 3164 /** |
| 2548 * Return `true` if the given class declares a method named "noSuchMethod" and
is not the | |
| 2549 * class 'Object'. | |
| 2550 * | |
| 2551 * @param element the class being tested | |
| 2552 * @return `true` if the given class declares a method named "noSuchMethod" | |
| 2553 */ | |
| 2554 bool classDeclaresNoSuchMethod(ClassElement classElement) { | |
| 2555 if (classElement == null) { | |
| 2556 return false; | |
| 2557 } | |
| 2558 MethodElement methodElement = classElement.lookUpMethod(_NO_SUCH_METHOD_METH
OD_NAME, _resolver.definingLibrary); | |
| 2559 return methodElement != null && methodElement.enclosingElement.supertype !=
null; | |
| 2560 } | |
| 2561 | |
| 2562 /** | |
| 2563 * Return `true` if the given element represents a class that declares a metho
d named | |
| 2564 * "noSuchMethod" and is not the class 'Object'. | |
| 2565 * | |
| 2566 * @param element the element being tested | |
| 2567 * @return `true` if the given element represents a class that declares a meth
od named | |
| 2568 * "noSuchMethod" | |
| 2569 */ | |
| 2570 bool classDeclaresNoSuchMethod2(Element element) { | |
| 2571 if (element is ClassElement) { | |
| 2572 return classDeclaresNoSuchMethod((element as ClassElement)); | |
| 2573 } | |
| 2574 return false; | |
| 2575 } | |
| 2576 | |
| 2577 /** | |
| 2578 * Given a list of arguments and the element that will be invoked using those
argument, compute | 3165 * Given a list of arguments and the element that will be invoked using those
argument, compute |
| 2579 * the list of parameters that correspond to the list of arguments. Return the
parameters that | 3166 * the list of parameters that correspond to the list of arguments. Return the
parameters that |
| 2580 * correspond to the arguments, or `null` if no correspondence could be comput
ed. | 3167 * correspond to the arguments, or `null` if no correspondence could be comput
ed. |
| 2581 * | 3168 * |
| 2582 * @param argumentList the list of arguments being passed to the element | 3169 * @param argumentList the list of arguments being passed to the element |
| 2583 * @param executableElement the element that will be invoked with the argument
s | 3170 * @param executableElement the element that will be invoked with the argument
s |
| 2584 * @return the parameters that correspond to the arguments | 3171 * @return the parameters that correspond to the arguments |
| 2585 */ | 3172 */ |
| 2586 List<ParameterElement> computePropagatedParameters(ArgumentList argumentList,
Element element2) { | 3173 List<ParameterElement> computeCorrespondingParameters(ArgumentList argumentLis
t, Element element2) { |
| 2587 if (element2 is PropertyAccessorElement) { | 3174 if (element2 is PropertyAccessorElement) { |
| 2588 FunctionType getterType = ((element2 as PropertyAccessorElement)).type; | 3175 FunctionType getterType = ((element2 as PropertyAccessorElement)).type; |
| 2589 if (getterType != null) { | 3176 if (getterType != null) { |
| 2590 Type2 getterReturnType = getterType.returnType; | 3177 Type2 getterReturnType = getterType.returnType; |
| 2591 if (getterReturnType is InterfaceType) { | 3178 if (getterReturnType is InterfaceType) { |
| 2592 MethodElement callMethod = ((getterReturnType as InterfaceType)).lookU
pMethod(CALL_METHOD_NAME, _resolver.definingLibrary); | 3179 MethodElement callMethod = ((getterReturnType as InterfaceType)).lookU
pMethod(CALL_METHOD_NAME, _resolver.definingLibrary); |
| 2593 if (callMethod != null) { | 3180 if (callMethod != null) { |
| 2594 return resolveArgumentsToParameters(false, argumentList, callMethod)
; | 3181 return resolveArgumentsToParameters(false, argumentList, callMethod)
; |
| 2595 } | 3182 } |
| 2596 } else if (getterReturnType is FunctionType) { | 3183 } else if (getterReturnType is FunctionType) { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2773 bool isStatic(Element element) { | 3360 bool isStatic(Element element) { |
| 2774 if (element is ExecutableElement) { | 3361 if (element is ExecutableElement) { |
| 2775 return ((element as ExecutableElement)).isStatic; | 3362 return ((element as ExecutableElement)).isStatic; |
| 2776 } else if (element is PropertyInducingElement) { | 3363 } else if (element is PropertyInducingElement) { |
| 2777 return ((element as PropertyInducingElement)).isStatic; | 3364 return ((element as PropertyInducingElement)).isStatic; |
| 2778 } | 3365 } |
| 2779 return false; | 3366 return false; |
| 2780 } | 3367 } |
| 2781 | 3368 |
| 2782 /** | 3369 /** |
| 3370 * Return `true` if the given node can validly be resolved to a prefix: |
| 3371 * |
| 3372 * * it is the prefix in an import directive, or |
| 3373 * * it is the prefix in a prefixed identifier. |
| 3374 * |
| 3375 * |
| 3376 * @param node the node being tested |
| 3377 * @return `true` if the given node is the prefix in an import directive |
| 3378 */ |
| 3379 bool isValidAsPrefix(SimpleIdentifier node) { |
| 3380 ASTNode parent = node.parent; |
| 3381 if (parent is ImportDirective) { |
| 3382 return identical(((parent as ImportDirective)).prefix, node); |
| 3383 } else if (parent is PrefixedIdentifier) { |
| 3384 return true; |
| 3385 } else if (parent is MethodInvocation) { |
| 3386 return identical(((parent as MethodInvocation)).target, node); |
| 3387 } |
| 3388 return false; |
| 3389 } |
| 3390 |
| 3391 /** |
| 2783 * Looks up the method element with the given name for index expression, repor
ts | 3392 * Looks up the method element with the given name for index expression, repor
ts |
| 2784 * [StaticWarningCode#UNDEFINED_OPERATOR] if not found. | 3393 * [StaticWarningCode#UNDEFINED_OPERATOR] if not found. |
| 2785 * | 3394 * |
| 2786 * @param node the index expression to resolve | 3395 * @param node the index expression to resolve |
| 2787 * @param target the target of the expression | 3396 * @param target the target of the expression |
| 2788 * @param methodName the name of the operator associated with the context of u
sing of the given | 3397 * @param methodName the name of the operator associated with the context of u
sing of the given |
| 2789 * index expression | 3398 * index expression |
| 2790 * @return `true` if and only if an error code is generated on the passed node | 3399 * @return `true` if and only if an error code is generated on the passed node |
| 2791 */ | 3400 */ |
| 2792 bool lookUpCheckIndexOperator(IndexExpression node, Expression target, String
methodName, Type2 staticType, Type2 propagatedType) { | 3401 bool lookUpCheckIndexOperator(IndexExpression node, Expression target, String
methodName, Type2 staticType, Type2 propagatedType) { |
| 2793 MethodElement staticMethod = lookUpMethod(target, staticType, methodName); | 3402 MethodElement staticMethod = lookUpMethod(target, staticType, methodName); |
| 2794 MethodElement propagatedMethod = lookUpMethod(target, propagatedType, method
Name); | 3403 MethodElement propagatedMethod = lookUpMethod(target, propagatedType, method
Name); |
| 2795 node.staticElement = staticMethod; | 3404 node.staticElement = staticMethod; |
| 2796 node.element = select2(staticMethod, propagatedMethod); | 3405 node.propagatedElement = propagatedMethod; |
| 2797 if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || p
ropagatedType == null || shouldReportMissingMember(propagatedType, propagatedMet
hod))) { | 3406 if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || p
ropagatedType == null || shouldReportMissingMember(propagatedType, propagatedMet
hod))) { |
| 2798 sc.Token leftBracket = node.leftBracket; | 3407 sc.Token leftBracket = node.leftBracket; |
| 2799 sc.Token rightBracket = node.rightBracket; | 3408 sc.Token rightBracket = node.rightBracket; |
| 2800 if (leftBracket == null || rightBracket == null) { | 3409 if (leftBracket == null || rightBracket == null) { |
| 2801 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_OPERATOR, node, [m
ethodName, staticType.displayName]); | 3410 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_OPERATOR, node, [m
ethodName, staticType.displayName]); |
| 2802 return true; | 3411 return true; |
| 2803 } else { | 3412 } else { |
| 2804 int offset = leftBracket.offset; | 3413 int offset = leftBracket.offset; |
| 2805 int length = rightBracket.offset - offset + 1; | 3414 int length = rightBracket.offset - offset + 1; |
| 2806 _resolver.reportError5(StaticTypeWarningCode.UNDEFINED_OPERATOR, offset,
length, [methodName, staticType.displayName]); | 3415 _resolver.reportError5(StaticTypeWarningCode.UNDEFINED_OPERATOR, offset,
length, [methodName, staticType.displayName]); |
| (...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3308 List<ParameterElement> resolvedParameters = new List<ParameterElement>(argum
entCount); | 3917 List<ParameterElement> resolvedParameters = new List<ParameterElement>(argum
entCount); |
| 3309 int positionalArgumentCount = 0; | 3918 int positionalArgumentCount = 0; |
| 3310 Set<String> usedNames = new Set<String>(); | 3919 Set<String> usedNames = new Set<String>(); |
| 3311 for (int i = 0; i < argumentCount; i++) { | 3920 for (int i = 0; i < argumentCount; i++) { |
| 3312 Expression argument = arguments[i]; | 3921 Expression argument = arguments[i]; |
| 3313 if (argument is NamedExpression) { | 3922 if (argument is NamedExpression) { |
| 3314 SimpleIdentifier nameNode = ((argument as NamedExpression)).name.label; | 3923 SimpleIdentifier nameNode = ((argument as NamedExpression)).name.label; |
| 3315 String name = nameNode.name; | 3924 String name = nameNode.name; |
| 3316 ParameterElement element = namedParameters[name]; | 3925 ParameterElement element = namedParameters[name]; |
| 3317 if (element == null) { | 3926 if (element == null) { |
| 3318 ErrorCode errorCode = reportError2 ? CompileTimeErrorCode.UNDEFINED_NA
MED_PARAMETER : StaticWarningCode.UNDEFINED_NAMED_PARAMETER; | 3927 ErrorCode errorCode = (reportError2 ? CompileTimeErrorCode.UNDEFINED_N
AMED_PARAMETER : StaticWarningCode.UNDEFINED_NAMED_PARAMETER) as ErrorCode; |
| 3319 _resolver.reportError(errorCode, nameNode, [name]); | 3928 _resolver.reportError(errorCode, nameNode, [name]); |
| 3320 } else { | 3929 } else { |
| 3321 resolvedParameters[i] = element; | 3930 resolvedParameters[i] = element; |
| 3322 recordResolution(nameNode, element); | 3931 recordResolution(nameNode, element); |
| 3323 } | 3932 } |
| 3324 if (!javaSetAdd(usedNames, name)) { | 3933 if (!javaSetAdd(usedNames, name)) { |
| 3325 _resolver.reportError(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, n
ameNode, [name]); | 3934 _resolver.reportError(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, n
ameNode, [name]); |
| 3326 } | 3935 } |
| 3327 } else { | 3936 } else { |
| 3328 positionalArgumentCount++; | 3937 positionalArgumentCount++; |
| 3329 if (unnamedIndex < unnamedParameterCount) { | 3938 if (unnamedIndex < unnamedParameterCount) { |
| 3330 resolvedParameters[i] = unnamedParameters[unnamedIndex++]; | 3939 resolvedParameters[i] = unnamedParameters[unnamedIndex++]; |
| 3331 } | 3940 } |
| 3332 } | 3941 } |
| 3333 } | 3942 } |
| 3334 if (positionalArgumentCount < requiredParameters.length) { | 3943 if (positionalArgumentCount < requiredParameters.length) { |
| 3335 ErrorCode errorCode = reportError2 ? CompileTimeErrorCode.NOT_ENOUGH_REQUI
RED_ARGUMENTS : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS; | 3944 ErrorCode errorCode = (reportError2 ? CompileTimeErrorCode.NOT_ENOUGH_REQU
IRED_ARGUMENTS : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS) as ErrorCode; |
| 3336 _resolver.reportError(errorCode, argumentList, [requiredParameters.length,
positionalArgumentCount]); | 3945 _resolver.reportError(errorCode, argumentList, [requiredParameters.length,
positionalArgumentCount]); |
| 3337 } else if (positionalArgumentCount > unnamedParameterCount) { | 3946 } else if (positionalArgumentCount > unnamedParameterCount) { |
| 3338 ErrorCode errorCode = reportError2 ? CompileTimeErrorCode.EXTRA_POSITIONAL
_ARGUMENTS : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS; | 3947 ErrorCode errorCode = (reportError2 ? CompileTimeErrorCode.EXTRA_POSITIONA
L_ARGUMENTS : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS) as ErrorCode; |
| 3339 _resolver.reportError(errorCode, argumentList, [unnamedParameterCount, pos
itionalArgumentCount]); | 3948 _resolver.reportError(errorCode, argumentList, [unnamedParameterCount, pos
itionalArgumentCount]); |
| 3340 } | 3949 } |
| 3341 return resolvedParameters; | 3950 return resolvedParameters; |
| 3342 } | 3951 } |
| 3343 | 3952 |
| 3344 /** | 3953 /** |
| 3345 * Resolve the names in the given combinators in the scope of the given librar
y. | 3954 * Resolve the names in the given combinators in the scope of the given librar
y. |
| 3346 * | 3955 * |
| 3347 * @param library the library that defines the names | 3956 * @param library the library that defines the names |
| 3348 * @param combinators the combinators containing the names to be resolved | 3957 * @param combinators the combinators containing the names to be resolved |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3455 recordResolution(propertyName, staticElement); | 4064 recordResolution(propertyName, staticElement); |
| 3456 } | 4065 } |
| 3457 return; | 4066 return; |
| 3458 } | 4067 } |
| 3459 propertyName.staticElement = staticElement; | 4068 propertyName.staticElement = staticElement; |
| 3460 Type2 propagatedType = getPropagatedType(target); | 4069 Type2 propagatedType = getPropagatedType(target); |
| 3461 ExecutableElement propagatedElement = resolveProperty(target, propagatedType
, propertyName); | 4070 ExecutableElement propagatedElement = resolveProperty(target, propagatedType
, propertyName); |
| 3462 Element selectedElement = select(staticElement, propagatedElement); | 4071 Element selectedElement = select(staticElement, propagatedElement); |
| 3463 propertyName.element = selectedElement; | 4072 propertyName.element = selectedElement; |
| 3464 if (shouldReportMissingMember(staticType, staticElement) && (_strictMode ||
propagatedType == null || shouldReportMissingMember(propagatedType, propagatedEl
ement))) { | 4073 if (shouldReportMissingMember(staticType, staticElement) && (_strictMode ||
propagatedType == null || shouldReportMissingMember(propagatedType, propagatedEl
ement))) { |
| 3465 bool staticNoSuchMethod = staticType != null && classDeclaresNoSuchMethod2
(staticType.element); | 4074 bool isStaticProperty = isStatic(selectedElement); |
| 3466 bool propagatedNoSuchMethod = propagatedType != null && classDeclaresNoSuc
hMethod2(propagatedType.element); | 4075 if (propertyName.inSetterContext()) { |
| 3467 if (!staticNoSuchMethod && (_strictMode || !propagatedNoSuchMethod)) { | 4076 if (isStaticProperty) { |
| 3468 bool isStaticProperty = isStatic(selectedElement); | 4077 _resolver.reportError(StaticWarningCode.UNDEFINED_SETTER, propertyName
, [propertyName.name, staticType.displayName]); |
| 3469 if (propertyName.inSetterContext()) { | |
| 3470 if (isStaticProperty) { | |
| 3471 _resolver.reportError(StaticWarningCode.UNDEFINED_SETTER, propertyNa
me, [propertyName.name, staticType.displayName]); | |
| 3472 } else { | |
| 3473 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_SETTER, proper
tyName, [propertyName.name, staticType.displayName]); | |
| 3474 } | |
| 3475 } else if (propertyName.inGetterContext()) { | |
| 3476 if (isStaticProperty) { | |
| 3477 _resolver.reportError(StaticWarningCode.UNDEFINED_GETTER, propertyNa
me, [propertyName.name, staticType.displayName]); | |
| 3478 } else { | |
| 3479 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_GETTER, proper
tyName, [propertyName.name, staticType.displayName]); | |
| 3480 } | |
| 3481 } else { | 4078 } else { |
| 3482 _resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, property
Name, [propertyName.name]); | 4079 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_SETTER, property
Name, [propertyName.name, staticType.displayName]); |
| 3483 } | 4080 } |
| 4081 } else if (propertyName.inGetterContext()) { |
| 4082 if (isStaticProperty) { |
| 4083 _resolver.reportError(StaticWarningCode.UNDEFINED_GETTER, propertyName
, [propertyName.name, staticType.displayName]); |
| 4084 } else { |
| 4085 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_GETTER, property
Name, [propertyName.name, staticType.displayName]); |
| 4086 } |
| 4087 } else { |
| 4088 _resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, propertyNa
me, [propertyName.name]); |
| 3484 } | 4089 } |
| 3485 } | 4090 } |
| 3486 } | 4091 } |
| 3487 | 4092 |
| 3488 /** | 4093 /** |
| 3489 * Resolve the given simple identifier if possible. Return the element to whic
h it could be | 4094 * Resolve the given simple identifier if possible. Return the element to whic
h it could be |
| 3490 * resolved, or `null` if it could not be resolved. This does not record the r
esults of the | 4095 * resolved, or `null` if it could not be resolved. This does not record the r
esults of the |
| 3491 * resolution. | 4096 * resolution. |
| 3492 * | 4097 * |
| 3493 * @param node the identifier to be resolved | 4098 * @param node the identifier to be resolved |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3600 * given type and not finding any member. | 4205 * given type and not finding any member. |
| 3601 * | 4206 * |
| 3602 * @param type the type in which we attempted to perform the look-up | 4207 * @param type the type in which we attempted to perform the look-up |
| 3603 * @param member the result of the look-up | 4208 * @param member the result of the look-up |
| 3604 * @return `true` if we should report an error | 4209 * @return `true` if we should report an error |
| 3605 */ | 4210 */ |
| 3606 bool shouldReportMissingMember(Type2 type, ExecutableElement member) { | 4211 bool shouldReportMissingMember(Type2 type, ExecutableElement member) { |
| 3607 if (member != null || type == null || type.isDynamic) { | 4212 if (member != null || type == null || type.isDynamic) { |
| 3608 return false; | 4213 return false; |
| 3609 } | 4214 } |
| 3610 if (type is InterfaceType) { | |
| 3611 return !classDeclaresNoSuchMethod(((type as InterfaceType)).element); | |
| 3612 } | |
| 3613 return true; | 4215 return true; |
| 3614 } | 4216 } |
| 3615 } | 4217 } |
| 3616 /** | 4218 /** |
| 3617 * Instances of the class `SyntheticIdentifier` implement an identifier that can
be used to | 4219 * Instances of the class `SyntheticIdentifier` implement an identifier that can
be used to |
| 3618 * look up names in the lexical scope when there is no identifier in the AST str
ucture. There is | 4220 * look up names in the lexical scope when there is no identifier in the AST str
ucture. There is |
| 3619 * no identifier in the AST when the parser could not distinguish between a meth
od invocation and | 4221 * no identifier in the AST when the parser could not distinguish between a meth
od invocation and |
| 3620 * an invocation of a top-level function imported with a prefix. | 4222 * an invocation of a top-level function imported with a prefix. |
| 3621 */ | 4223 */ |
| 3622 class ElementResolver_SyntheticIdentifier extends Identifier { | 4224 class ElementResolver_SyntheticIdentifier extends Identifier { |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3919 */ | 4521 */ |
| 3920 Map<String, ExecutableElement> computeInterfaceLookupMap(ClassElement classElt
, Set<ClassElement> visitedInterfaces) { | 4522 Map<String, ExecutableElement> computeInterfaceLookupMap(ClassElement classElt
, Set<ClassElement> visitedInterfaces) { |
| 3921 Map<String, ExecutableElement> resultMap = _interfaceLookup[classElt]; | 4523 Map<String, ExecutableElement> resultMap = _interfaceLookup[classElt]; |
| 3922 if (resultMap != null) { | 4524 if (resultMap != null) { |
| 3923 return resultMap; | 4525 return resultMap; |
| 3924 } else { | 4526 } else { |
| 3925 resultMap = new Map<String, ExecutableElement>(); | 4527 resultMap = new Map<String, ExecutableElement>(); |
| 3926 } | 4528 } |
| 3927 InterfaceType supertype = classElt.supertype; | 4529 InterfaceType supertype = classElt.supertype; |
| 3928 ClassElement superclassElement = supertype != null ? supertype.element : nul
l; | 4530 ClassElement superclassElement = supertype != null ? supertype.element : nul
l; |
| 4531 List<InterfaceType> mixins = classElt.mixins; |
| 3929 List<InterfaceType> interfaces = classElt.interfaces; | 4532 List<InterfaceType> interfaces = classElt.interfaces; |
| 3930 if ((superclassElement == null || supertype.isObject) && interfaces.length =
= 0) { | 4533 if ((superclassElement == null || supertype.isObject) && mixins.length == 0
&& interfaces.length == 0) { |
| 3931 _interfaceLookup[classElt] = resultMap; | 4534 _interfaceLookup[classElt] = resultMap; |
| 3932 return resultMap; | 4535 return resultMap; |
| 3933 } | 4536 } |
| 3934 List<Map<String, ExecutableElement>> lookupMaps = new List<Map<String, Execu
tableElement>>(); | 4537 List<Map<String, ExecutableElement>> lookupMaps = new List<Map<String, Execu
tableElement>>(); |
| 3935 if (superclassElement != null) { | 4538 if (superclassElement != null) { |
| 3936 if (!visitedInterfaces.contains(superclassElement)) { | 4539 if (!visitedInterfaces.contains(superclassElement)) { |
| 3937 try { | 4540 try { |
| 3938 javaSetAdd(visitedInterfaces, superclassElement); | 4541 javaSetAdd(visitedInterfaces, superclassElement); |
| 3939 lookupMaps.add(computeInterfaceLookupMap(superclassElement, visitedInt
erfaces)); | 4542 lookupMaps.add(computeInterfaceLookupMap(superclassElement, visitedInt
erfaces)); |
| 3940 } finally { | 4543 } finally { |
| 3941 visitedInterfaces.remove(superclassElement); | 4544 visitedInterfaces.remove(superclassElement); |
| 3942 } | 4545 } |
| 3943 } else { | 4546 } else { |
| 3944 Map<String, ExecutableElement> map = _interfaceLookup[classElt]; | 4547 Map<String, ExecutableElement> map = _interfaceLookup[classElt]; |
| 3945 if (map != null) { | 4548 if (map != null) { |
| 3946 lookupMaps.add(map); | 4549 lookupMaps.add(map); |
| 3947 } else { | 4550 } else { |
| 3948 _interfaceLookup[superclassElement] = resultMap; | 4551 _interfaceLookup[superclassElement] = resultMap; |
| 3949 return resultMap; | 4552 return resultMap; |
| 3950 } | 4553 } |
| 3951 } | 4554 } |
| 3952 } | 4555 } |
| 4556 for (InterfaceType mixinType in mixins) { |
| 4557 ClassElement mixinElement = mixinType.element; |
| 4558 if (mixinElement == null) { |
| 4559 continue; |
| 4560 } |
| 4561 Map<String, ExecutableElement> mapWithMixinMembers = new Map<String, Execu
tableElement>(); |
| 4562 recordMapWithClassMembers(mapWithMixinMembers, mixinElement); |
| 4563 lookupMaps.add(mapWithMixinMembers); |
| 4564 } |
| 3953 for (InterfaceType interfaceType in interfaces) { | 4565 for (InterfaceType interfaceType in interfaces) { |
| 3954 ClassElement interfaceElement = interfaceType.element; | 4566 ClassElement interfaceElement = interfaceType.element; |
| 3955 if (interfaceElement != null) { | 4567 if (interfaceElement != null) { |
| 3956 if (!visitedInterfaces.contains(interfaceElement)) { | 4568 if (!visitedInterfaces.contains(interfaceElement)) { |
| 3957 try { | 4569 try { |
| 3958 javaSetAdd(visitedInterfaces, interfaceElement); | 4570 javaSetAdd(visitedInterfaces, interfaceElement); |
| 3959 lookupMaps.add(computeInterfaceLookupMap(interfaceElement, visitedIn
terfaces)); | 4571 lookupMaps.add(computeInterfaceLookupMap(interfaceElement, visitedIn
terfaces)); |
| 3960 } finally { | 4572 } finally { |
| 3961 visitedInterfaces.remove(interfaceElement); | 4573 visitedInterfaces.remove(interfaceElement); |
| 3962 } | 4574 } |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4134 return accessor; | 4746 return accessor; |
| 4135 } | 4747 } |
| 4136 } | 4748 } |
| 4137 return null; | 4749 return null; |
| 4138 } | 4750 } |
| 4139 | 4751 |
| 4140 /** | 4752 /** |
| 4141 * Record the passed map with the set of all members (methods, getters and set
ters) in the class | 4753 * Record the passed map with the set of all members (methods, getters and set
ters) in the class |
| 4142 * into the passed map. | 4754 * into the passed map. |
| 4143 * | 4755 * |
| 4144 * @param map some non-`null` | 4756 * @param map some non-`null` map to put the methods and accessors from the pa
ssed |
| 4757 * [ClassElement] into |
| 4145 * @param classElt the class element that will be recorded into the passed map | 4758 * @param classElt the class element that will be recorded into the passed map |
| 4146 */ | 4759 */ |
| 4147 void recordMapWithClassMembers(Map<String, ExecutableElement> map, ClassElemen
t classElt) { | 4760 void recordMapWithClassMembers(Map<String, ExecutableElement> map, ClassElemen
t classElt) { |
| 4148 List<MethodElement> methods = classElt.methods; | 4761 List<MethodElement> methods = classElt.methods; |
| 4149 for (MethodElement method in methods) { | 4762 for (MethodElement method in methods) { |
| 4150 if (method.isAccessibleIn(_library) && !method.isStatic) { | 4763 if (method.isAccessibleIn(_library) && !method.isStatic) { |
| 4151 map[method.name] = method; | 4764 map[method.name] = method; |
| 4152 } | 4765 } |
| 4153 } | 4766 } |
| 4154 List<PropertyAccessorElement> accessors = classElt.accessors; | 4767 List<PropertyAccessorElement> accessors = classElt.accessors; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4273 CompilationUnit getAST(Source source) { | 4886 CompilationUnit getAST(Source source) { |
| 4274 CompilationUnit unit = _astMap[source]; | 4887 CompilationUnit unit = _astMap[source]; |
| 4275 if (unit == null) { | 4888 if (unit == null) { |
| 4276 unit = _analysisContext.computeResolvableCompilationUnit(source); | 4889 unit = _analysisContext.computeResolvableCompilationUnit(source); |
| 4277 _astMap[source] = unit; | 4890 _astMap[source] = unit; |
| 4278 } | 4891 } |
| 4279 return unit; | 4892 return unit; |
| 4280 } | 4893 } |
| 4281 | 4894 |
| 4282 /** | 4895 /** |
| 4896 * Return an array of the [CompilationUnit]s that make up the library. The fir
st unit is |
| 4897 * always the defining unit. |
| 4898 * |
| 4899 * @return an array of the [CompilationUnit]s that make up the library. The fi
rst unit is |
| 4900 * always the defining unit |
| 4901 */ |
| 4902 List<CompilationUnit> get compilationUnits { |
| 4903 List<CompilationUnit> unitArrayList = new List<CompilationUnit>(); |
| 4904 unitArrayList.add(definingCompilationUnit); |
| 4905 for (Source source in _astMap.keys.toSet()) { |
| 4906 if (_librarySource != source) { |
| 4907 unitArrayList.add(getAST(source)); |
| 4908 } |
| 4909 } |
| 4910 return new List.from(unitArrayList); |
| 4911 } |
| 4912 |
| 4913 /** |
| 4283 * Return a collection containing the sources for the compilation units in thi
s library, including | 4914 * Return a collection containing the sources for the compilation units in thi
s library, including |
| 4284 * the defining compilation unit. | 4915 * the defining compilation unit. |
| 4285 * | 4916 * |
| 4286 * @return the sources for the compilation units in this library | 4917 * @return the sources for the compilation units in this library |
| 4287 */ | 4918 */ |
| 4288 Set<Source> get compilationUnitSources => _astMap.keys.toSet(); | 4919 Set<Source> get compilationUnitSources => _astMap.keys.toSet(); |
| 4289 | 4920 |
| 4290 /** | 4921 /** |
| 4291 * Return the AST structure associated with the defining compilation unit for
this library. | 4922 * Return the AST structure associated with the defining compilation unit for
this library. |
| 4292 * | 4923 * |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4389 * @return the result of resolving the URI against the URI of the library | 5020 * @return the result of resolving the URI against the URI of the library |
| 4390 */ | 5021 */ |
| 4391 Source getSource(UriBasedDirective directive) { | 5022 Source getSource(UriBasedDirective directive) { |
| 4392 StringLiteral uriLiteral = directive.uri; | 5023 StringLiteral uriLiteral = directive.uri; |
| 4393 if (uriLiteral is StringInterpolation) { | 5024 if (uriLiteral is StringInterpolation) { |
| 4394 _errorListener.onError(new AnalysisError.con2(_librarySource, uriLiteral.o
ffset, uriLiteral.length, CompileTimeErrorCode.URI_WITH_INTERPOLATION, [])); | 5025 _errorListener.onError(new AnalysisError.con2(_librarySource, uriLiteral.o
ffset, uriLiteral.length, CompileTimeErrorCode.URI_WITH_INTERPOLATION, [])); |
| 4395 return null; | 5026 return null; |
| 4396 } | 5027 } |
| 4397 String uriContent = uriLiteral.stringValue.trim(); | 5028 String uriContent = uriLiteral.stringValue.trim(); |
| 4398 _directiveUris[directive] = uriContent; | 5029 _directiveUris[directive] = uriContent; |
| 5030 uriContent = Uri.encodeFull(uriContent); |
| 4399 try { | 5031 try { |
| 4400 parseUriWithException(uriContent); | 5032 parseUriWithException(uriContent); |
| 4401 Source source = getSource2(uriContent); | 5033 Source source = getSource2(uriContent); |
| 4402 if (source == null || !source.exists()) { | 5034 if (source == null || !source.exists()) { |
| 4403 _errorListener.onError(new AnalysisError.con2(_librarySource, uriLiteral
.offset, uriLiteral.length, CompileTimeErrorCode.URI_DOES_NOT_EXIST, [uriContent
])); | 5035 _errorListener.onError(new AnalysisError.con2(_librarySource, uriLiteral
.offset, uriLiteral.length, CompileTimeErrorCode.URI_DOES_NOT_EXIST, [uriContent
])); |
| 4404 } | 5036 } |
| 4405 return source; | 5037 return source; |
| 4406 } on URISyntaxException catch (exception) { | 5038 } on URISyntaxException catch (exception) { |
| 4407 _errorListener.onError(new AnalysisError.con2(_librarySource, uriLiteral.o
ffset, uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriContent])); | 5039 _errorListener.onError(new AnalysisError.con2(_librarySource, uriLiteral.o
ffset, uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriContent])); |
| 4408 } | 5040 } |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4962 } | 5594 } |
| 4963 SimpleIdentifier prefixNode = ((directive as ImportDirective)).pre
fix; | 5595 SimpleIdentifier prefixNode = ((directive as ImportDirective)).pre
fix; |
| 4964 if (prefixNode != null) { | 5596 if (prefixNode != null) { |
| 4965 String prefixName = prefixNode.name; | 5597 String prefixName = prefixNode.name; |
| 4966 PrefixElementImpl prefix = nameToPrefixMap[prefixName]; | 5598 PrefixElementImpl prefix = nameToPrefixMap[prefixName]; |
| 4967 if (prefix == null) { | 5599 if (prefix == null) { |
| 4968 prefix = new PrefixElementImpl(prefixNode); | 5600 prefix = new PrefixElementImpl(prefixNode); |
| 4969 nameToPrefixMap[prefixName] = prefix; | 5601 nameToPrefixMap[prefixName] = prefix; |
| 4970 } | 5602 } |
| 4971 importElement.prefix = prefix; | 5603 importElement.prefix = prefix; |
| 5604 prefixNode.staticElement = prefix; |
| 4972 } | 5605 } |
| 4973 directive.element = importElement; | 5606 directive.element = importElement; |
| 4974 imports.add(importElement); | 5607 imports.add(importElement); |
| 4975 if (doesCompilationUnitHavePartOfDirective(importedLibrary.getAST(
importedSource))) { | 5608 if (doesCompilationUnitHavePartOfDirective(importedLibrary.getAST(
importedSource))) { |
| 4976 StringLiteral uriLiteral = importDirective.uri; | 5609 StringLiteral uriLiteral = importDirective.uri; |
| 4977 _errorListener.onError(new AnalysisError.con2(library.librarySou
rce, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.IMPORT_OF_NON_LI
BRARY, [uriLiteral.toSource()])); | 5610 _errorListener.onError(new AnalysisError.con2(library.librarySou
rce, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.IMPORT_OF_NON_LI
BRARY, [uriLiteral.toSource()])); |
| 4978 } | 5611 } |
| 4979 } | 5612 } |
| 4980 } | 5613 } |
| 4981 } else if (directive is ExportDirective) { | 5614 } else if (directive is ExportDirective) { |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5306 */ | 5939 */ |
| 5307 Source resolveSource(Source librarySource, UriBasedDirective directive) { | 5940 Source resolveSource(Source librarySource, UriBasedDirective directive) { |
| 5308 StringLiteral uriLiteral = directive.uri; | 5941 StringLiteral uriLiteral = directive.uri; |
| 5309 if (uriLiteral is StringInterpolation) { | 5942 if (uriLiteral is StringInterpolation) { |
| 5310 return null; | 5943 return null; |
| 5311 } | 5944 } |
| 5312 String uriContent = uriLiteral.stringValue.trim(); | 5945 String uriContent = uriLiteral.stringValue.trim(); |
| 5313 if (uriContent == null) { | 5946 if (uriContent == null) { |
| 5314 return null; | 5947 return null; |
| 5315 } | 5948 } |
| 5949 uriContent = Uri.encodeFull(uriContent); |
| 5316 try { | 5950 try { |
| 5317 parseUriWithException(uriContent); | 5951 parseUriWithException(uriContent); |
| 5318 return _analysisContext.sourceFactory.resolveUri(librarySource, uriContent
); | 5952 return _analysisContext.sourceFactory.resolveUri(librarySource, uriContent
); |
| 5319 } on URISyntaxException catch (exception) { | 5953 } on URISyntaxException catch (exception) { |
| 5320 return null; | 5954 return null; |
| 5321 } | 5955 } |
| 5322 } | 5956 } |
| 5323 | 5957 |
| 5324 /** | 5958 /** |
| 5325 * Run additional analyses, such as the [ConstantVerifier] and [ErrorVerifier] | 5959 * Run additional analyses, such as the [ConstantVerifier] and [ErrorVerifier] |
| (...skipping 17 matching lines...) Expand all Loading... |
| 5343 * the library cannot be analyzed | 5977 * the library cannot be analyzed |
| 5344 */ | 5978 */ |
| 5345 void runAdditionalAnalyses2(Library library) { | 5979 void runAdditionalAnalyses2(Library library) { |
| 5346 for (Source source in library.compilationUnitSources) { | 5980 for (Source source in library.compilationUnitSources) { |
| 5347 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source); | 5981 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source); |
| 5348 CompilationUnit unit = library.getAST(source); | 5982 CompilationUnit unit = library.getAST(source); |
| 5349 ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, _t
ypeProvider); | 5983 ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, _t
ypeProvider); |
| 5350 unit.accept(constantVerifier); | 5984 unit.accept(constantVerifier); |
| 5351 ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, library.lib
raryElement, _typeProvider, library.inheritanceManager); | 5985 ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, library.lib
raryElement, _typeProvider, library.inheritanceManager); |
| 5352 unit.accept(errorVerifier); | 5986 unit.accept(errorVerifier); |
| 5353 if (_enableHints) { | 5987 } |
| 5354 new HintVerifier(_analysisContext, errorReporter).visitCompilationUnit(u
nit); | 5988 if (_enableHints) { |
| 5355 } | 5989 HintGenerator hintGenerator = new HintGenerator(library.compilationUnits,
_analysisContext, _errorListener); |
| 5990 hintGenerator.generateForLibrary(); |
| 5356 } | 5991 } |
| 5357 } | 5992 } |
| 5358 } | 5993 } |
| 5359 /** | 5994 /** |
| 5360 * Instances of the class `ResolverVisitor` are used to resolve the nodes within
a single | 5995 * Instances of the class `ResolverVisitor` are used to resolve the nodes within
a single |
| 5361 * compilation unit. | 5996 * compilation unit. |
| 5362 * | 5997 * |
| 5363 * @coverage dart.engine.resolver | 5998 * @coverage dart.engine.resolver |
| 5364 */ | 5999 */ |
| 5365 class ResolverVisitor extends ScopedVisitor { | 6000 class ResolverVisitor extends ScopedVisitor { |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5667 Object visitHideCombinator(HideCombinator node) => null; | 6302 Object visitHideCombinator(HideCombinator node) => null; |
| 5668 Object visitIfStatement(IfStatement node) { | 6303 Object visitIfStatement(IfStatement node) { |
| 5669 Expression condition = node.condition; | 6304 Expression condition = node.condition; |
| 5670 safelyVisit(condition); | 6305 safelyVisit(condition); |
| 5671 Map<Element, Type2> thenOverrides = null; | 6306 Map<Element, Type2> thenOverrides = null; |
| 5672 Statement thenStatement = node.thenStatement; | 6307 Statement thenStatement = node.thenStatement; |
| 5673 if (thenStatement != null) { | 6308 if (thenStatement != null) { |
| 5674 try { | 6309 try { |
| 5675 _overrideManager.enterScope(); | 6310 _overrideManager.enterScope(); |
| 5676 propagateTrueState(condition); | 6311 propagateTrueState(condition); |
| 5677 thenStatement.accept(this); | 6312 visitStatementInScope(thenStatement); |
| 5678 } finally { | 6313 } finally { |
| 5679 thenOverrides = _overrideManager.captureLocalOverrides(); | 6314 thenOverrides = _overrideManager.captureLocalOverrides(); |
| 5680 _overrideManager.exitScope(); | 6315 _overrideManager.exitScope(); |
| 5681 } | 6316 } |
| 5682 } | 6317 } |
| 5683 Map<Element, Type2> elseOverrides = null; | 6318 Map<Element, Type2> elseOverrides = null; |
| 5684 Statement elseStatement = node.elseStatement; | 6319 Statement elseStatement = node.elseStatement; |
| 5685 if (elseStatement != null) { | 6320 if (elseStatement != null) { |
| 5686 try { | 6321 try { |
| 5687 _overrideManager.enterScope(); | 6322 _overrideManager.enterScope(); |
| 5688 propagateFalseState(condition); | 6323 propagateFalseState(condition); |
| 5689 elseStatement.accept(this); | 6324 visitStatementInScope(elseStatement); |
| 5690 } finally { | 6325 } finally { |
| 5691 elseOverrides = _overrideManager.captureLocalOverrides(); | 6326 elseOverrides = _overrideManager.captureLocalOverrides(); |
| 5692 _overrideManager.exitScope(); | 6327 _overrideManager.exitScope(); |
| 5693 } | 6328 } |
| 5694 } | 6329 } |
| 5695 node.accept(_elementResolver); | 6330 node.accept(_elementResolver); |
| 5696 node.accept(_typeAnalyzer); | 6331 node.accept(_typeAnalyzer); |
| 5697 bool thenIsAbrupt = isAbruptTermination2(thenStatement); | 6332 bool thenIsAbrupt = isAbruptTermination2(thenStatement); |
| 5698 bool elseIsAbrupt = isAbruptTermination2(elseStatement); | 6333 bool elseIsAbrupt = isAbruptTermination2(elseStatement); |
| 5699 if (elseIsAbrupt && !thenIsAbrupt) { | 6334 if (elseIsAbrupt && !thenIsAbrupt) { |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5791 } | 6426 } |
| 5792 Object visitTypeName(TypeName node) => null; | 6427 Object visitTypeName(TypeName node) => null; |
| 5793 Object visitWhileStatement(WhileStatement node) { | 6428 Object visitWhileStatement(WhileStatement node) { |
| 5794 Expression condition = node.condition; | 6429 Expression condition = node.condition; |
| 5795 safelyVisit(condition); | 6430 safelyVisit(condition); |
| 5796 Statement body = node.body; | 6431 Statement body = node.body; |
| 5797 if (body != null) { | 6432 if (body != null) { |
| 5798 try { | 6433 try { |
| 5799 _overrideManager.enterScope(); | 6434 _overrideManager.enterScope(); |
| 5800 propagateTrueState(condition); | 6435 propagateTrueState(condition); |
| 5801 body.accept(this); | 6436 visitStatementInScope(body); |
| 5802 } finally { | 6437 } finally { |
| 5803 _overrideManager.exitScope(); | 6438 _overrideManager.exitScope(); |
| 5804 } | 6439 } |
| 5805 } | 6440 } |
| 5806 node.accept(_elementResolver); | 6441 node.accept(_elementResolver); |
| 5807 node.accept(_typeAnalyzer); | 6442 node.accept(_typeAnalyzer); |
| 5808 return null; | 6443 return null; |
| 5809 } | 6444 } |
| 5810 | 6445 |
| 5811 /** | 6446 /** |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5879 try { | 6514 try { |
| 5880 _overrideManager.enterScope(); | 6515 _overrideManager.enterScope(); |
| 5881 if (loopVariable != null && iterator != null) { | 6516 if (loopVariable != null && iterator != null) { |
| 5882 LocalVariableElement loopElement = loopVariable.element; | 6517 LocalVariableElement loopElement = loopVariable.element; |
| 5883 if (loopElement != null) { | 6518 if (loopElement != null) { |
| 5884 Type2 iteratorElementType = getIteratorElementType(iterator); | 6519 Type2 iteratorElementType = getIteratorElementType(iterator); |
| 5885 override(loopElement, iteratorElementType); | 6520 override(loopElement, iteratorElementType); |
| 5886 recordPropagatedType(loopVariable.identifier, iteratorElementType); | 6521 recordPropagatedType(loopVariable.identifier, iteratorElementType); |
| 5887 } | 6522 } |
| 5888 } | 6523 } |
| 5889 body.accept(this); | 6524 visitStatementInScope(body); |
| 5890 } finally { | 6525 } finally { |
| 5891 _overrideManager.exitScope(); | 6526 _overrideManager.exitScope(); |
| 5892 } | 6527 } |
| 5893 } | 6528 } |
| 5894 node.accept(_elementResolver); | 6529 node.accept(_elementResolver); |
| 5895 node.accept(_typeAnalyzer); | 6530 node.accept(_typeAnalyzer); |
| 5896 } | 6531 } |
| 5897 void visitForStatementInScope(ForStatement node) { | 6532 void visitForStatementInScope(ForStatement node) { |
| 5898 safelyVisit(node.variables); | 6533 safelyVisit(node.variables); |
| 5899 safelyVisit(node.initialization); | 6534 safelyVisit(node.initialization); |
| 5900 safelyVisit(node.condition); | 6535 safelyVisit(node.condition); |
| 5901 _overrideManager.enterScope(); | 6536 _overrideManager.enterScope(); |
| 5902 try { | 6537 try { |
| 5903 propagateTrueState(node.condition); | 6538 propagateTrueState(node.condition); |
| 5904 safelyVisit(node.body); | 6539 visitStatementInScope(node.body); |
| 5905 node.updaters.accept(this); | 6540 node.updaters.accept(this); |
| 5906 } finally { | 6541 } finally { |
| 5907 _overrideManager.exitScope(); | 6542 _overrideManager.exitScope(); |
| 5908 } | 6543 } |
| 5909 } | 6544 } |
| 5910 | 6545 |
| 5911 /** | 6546 /** |
| 5912 * Return the best type information available for the given element. If the ty
pe of the element | 6547 * Return the best type information available for the given element. If the ty
pe of the element |
| 5913 * has been overridden, then return the overriding type. Otherwise, return the
static type. | 6548 * has been overridden, then return the overriding type. Otherwise, return the
static type. |
| 5914 * | 6549 * |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5981 _overrideManager.setType(element, expectedType); | 6616 _overrideManager.setType(element, expectedType); |
| 5982 } | 6617 } |
| 5983 } | 6618 } |
| 5984 } | 6619 } |
| 5985 | 6620 |
| 5986 /** | 6621 /** |
| 5987 * Try to infer types of parameters of the [FunctionExpression] arguments. | 6622 * Try to infer types of parameters of the [FunctionExpression] arguments. |
| 5988 */ | 6623 */ |
| 5989 void inferFunctionExpressionsParametersTypes(ArgumentList argumentList) { | 6624 void inferFunctionExpressionsParametersTypes(ArgumentList argumentList) { |
| 5990 for (Expression argument in argumentList.arguments) { | 6625 for (Expression argument in argumentList.arguments) { |
| 5991 ParameterElement parameter = argument.parameterElement; | 6626 ParameterElement parameter = argument.propagatedParameterElement; |
| 5992 if (parameter == null) { | 6627 if (parameter == null) { |
| 5993 parameter = argument.staticParameterElement; | 6628 parameter = argument.staticParameterElement; |
| 5994 } | 6629 } |
| 5995 if (parameter != null) { | 6630 if (parameter != null) { |
| 5996 inferFunctionExpressionParametersTypes(argument, parameter.type); | 6631 inferFunctionExpressionParametersTypes(argument, parameter.type); |
| 5997 } | 6632 } |
| 5998 } | 6633 } |
| 5999 } | 6634 } |
| 6000 | 6635 |
| 6001 /** | 6636 /** |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6209 LibraryElement get definingLibrary => _definingLibrary; | 6844 LibraryElement get definingLibrary => _definingLibrary; |
| 6210 | 6845 |
| 6211 /** | 6846 /** |
| 6212 * Return the object used to access the types from the core library. | 6847 * Return the object used to access the types from the core library. |
| 6213 * | 6848 * |
| 6214 * @return the object used to access the types from the core library | 6849 * @return the object used to access the types from the core library |
| 6215 */ | 6850 */ |
| 6216 TypeProvider get typeProvider => _typeProvider; | 6851 TypeProvider get typeProvider => _typeProvider; |
| 6217 Object visitBlock(Block node) { | 6852 Object visitBlock(Block node) { |
| 6218 Scope outerScope = _nameScope; | 6853 Scope outerScope = _nameScope; |
| 6219 _nameScope = new EnclosedScope(_nameScope); | |
| 6220 try { | 6854 try { |
| 6855 _nameScope = new EnclosedScope(_nameScope); |
| 6221 super.visitBlock(node); | 6856 super.visitBlock(node); |
| 6222 } finally { | 6857 } finally { |
| 6223 _nameScope = outerScope; | 6858 _nameScope = outerScope; |
| 6224 } | 6859 } |
| 6225 return null; | 6860 return null; |
| 6226 } | 6861 } |
| 6227 Object visitCatchClause(CatchClause node) { | 6862 Object visitCatchClause(CatchClause node) { |
| 6228 SimpleIdentifier exception = node.exceptionParameter; | 6863 SimpleIdentifier exception = node.exceptionParameter; |
| 6229 if (exception != null) { | 6864 if (exception != null) { |
| 6230 Scope outerScope = _nameScope; | 6865 Scope outerScope = _nameScope; |
| 6231 _nameScope = new EnclosedScope(_nameScope); | |
| 6232 try { | 6866 try { |
| 6867 _nameScope = new EnclosedScope(_nameScope); |
| 6233 _nameScope.define(exception.element); | 6868 _nameScope.define(exception.element); |
| 6234 SimpleIdentifier stackTrace = node.stackTraceParameter; | 6869 SimpleIdentifier stackTrace = node.stackTraceParameter; |
| 6235 if (stackTrace != null) { | 6870 if (stackTrace != null) { |
| 6236 _nameScope.define(stackTrace.element); | 6871 _nameScope.define(stackTrace.element); |
| 6237 } | 6872 } |
| 6238 super.visitCatchClause(node); | 6873 super.visitCatchClause(node); |
| 6239 } finally { | 6874 } finally { |
| 6240 _nameScope = outerScope; | 6875 _nameScope = outerScope; |
| 6241 } | 6876 } |
| 6242 } | 6877 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6274 } | 6909 } |
| 6275 Object visitDeclaredIdentifier(DeclaredIdentifier node) { | 6910 Object visitDeclaredIdentifier(DeclaredIdentifier node) { |
| 6276 VariableElement element = node.element; | 6911 VariableElement element = node.element; |
| 6277 if (element != null) { | 6912 if (element != null) { |
| 6278 _nameScope.define(element); | 6913 _nameScope.define(element); |
| 6279 } | 6914 } |
| 6280 super.visitDeclaredIdentifier(node); | 6915 super.visitDeclaredIdentifier(node); |
| 6281 return null; | 6916 return null; |
| 6282 } | 6917 } |
| 6283 Object visitDoStatement(DoStatement node) { | 6918 Object visitDoStatement(DoStatement node) { |
| 6284 LabelScope outerScope = _labelScope; | 6919 LabelScope outerLabelScope = _labelScope; |
| 6285 _labelScope = new LabelScope.con1(outerScope, false, false); | |
| 6286 try { | 6920 try { |
| 6287 super.visitDoStatement(node); | 6921 _labelScope = new LabelScope.con1(_labelScope, false, false); |
| 6922 visitStatementInScope(node.body); |
| 6923 safelyVisit(node.condition); |
| 6288 } finally { | 6924 } finally { |
| 6289 _labelScope = outerScope; | 6925 _labelScope = outerLabelScope; |
| 6290 } | 6926 } |
| 6291 return null; | 6927 return null; |
| 6292 } | 6928 } |
| 6293 Object visitForEachStatement(ForEachStatement node) { | 6929 Object visitForEachStatement(ForEachStatement node) { |
| 6930 Scope outerNameScope = _nameScope; |
| 6294 LabelScope outerLabelScope = _labelScope; | 6931 LabelScope outerLabelScope = _labelScope; |
| 6295 _labelScope = new LabelScope.con1(outerLabelScope, false, false); | |
| 6296 Scope outerNameScope = _nameScope; | |
| 6297 _nameScope = new EnclosedScope(_nameScope); | |
| 6298 try { | 6932 try { |
| 6933 _nameScope = new EnclosedScope(_nameScope); |
| 6934 _labelScope = new LabelScope.con1(outerLabelScope, false, false); |
| 6299 visitForEachStatementInScope(node); | 6935 visitForEachStatementInScope(node); |
| 6300 } finally { | 6936 } finally { |
| 6937 _labelScope = outerLabelScope; |
| 6301 _nameScope = outerNameScope; | 6938 _nameScope = outerNameScope; |
| 6302 _labelScope = outerLabelScope; | |
| 6303 } | 6939 } |
| 6304 return null; | 6940 return null; |
| 6305 } | 6941 } |
| 6306 Object visitForStatement(ForStatement node) { | 6942 Object visitForStatement(ForStatement node) { |
| 6943 Scope outerNameScope = _nameScope; |
| 6307 LabelScope outerLabelScope = _labelScope; | 6944 LabelScope outerLabelScope = _labelScope; |
| 6308 _labelScope = new LabelScope.con1(outerLabelScope, false, false); | |
| 6309 Scope outerNameScope = _nameScope; | |
| 6310 _nameScope = new EnclosedScope(_nameScope); | |
| 6311 try { | 6945 try { |
| 6946 _nameScope = new EnclosedScope(_nameScope); |
| 6947 _labelScope = new LabelScope.con1(outerLabelScope, false, false); |
| 6312 visitForStatementInScope(node); | 6948 visitForStatementInScope(node); |
| 6313 } finally { | 6949 } finally { |
| 6950 _labelScope = outerLabelScope; |
| 6314 _nameScope = outerNameScope; | 6951 _nameScope = outerNameScope; |
| 6315 _labelScope = outerLabelScope; | |
| 6316 } | 6952 } |
| 6317 return null; | 6953 return null; |
| 6318 } | 6954 } |
| 6319 Object visitFunctionDeclaration(FunctionDeclaration node) { | 6955 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 6320 ExecutableElement function = node.element; | 6956 ExecutableElement function = node.element; |
| 6321 Scope outerScope = _nameScope; | 6957 Scope outerScope = _nameScope; |
| 6322 try { | 6958 try { |
| 6323 _nameScope = new FunctionScope(_nameScope, function); | 6959 _nameScope = new FunctionScope(_nameScope, function); |
| 6324 super.visitFunctionDeclaration(node); | 6960 super.visitFunctionDeclaration(node); |
| 6325 } finally { | 6961 } finally { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 6351 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 6987 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 6352 Scope outerScope = _nameScope; | 6988 Scope outerScope = _nameScope; |
| 6353 try { | 6989 try { |
| 6354 _nameScope = new FunctionTypeScope(_nameScope, node.element); | 6990 _nameScope = new FunctionTypeScope(_nameScope, node.element); |
| 6355 super.visitFunctionTypeAlias(node); | 6991 super.visitFunctionTypeAlias(node); |
| 6356 } finally { | 6992 } finally { |
| 6357 _nameScope = outerScope; | 6993 _nameScope = outerScope; |
| 6358 } | 6994 } |
| 6359 return null; | 6995 return null; |
| 6360 } | 6996 } |
| 6997 Object visitIfStatement(IfStatement node) { |
| 6998 safelyVisit(node.condition); |
| 6999 visitStatementInScope(node.thenStatement); |
| 7000 visitStatementInScope(node.elseStatement); |
| 7001 return null; |
| 7002 } |
| 6361 Object visitLabeledStatement(LabeledStatement node) { | 7003 Object visitLabeledStatement(LabeledStatement node) { |
| 6362 LabelScope outerScope = addScopesFor(node.labels); | 7004 LabelScope outerScope = addScopesFor(node.labels); |
| 6363 try { | 7005 try { |
| 6364 super.visitLabeledStatement(node); | 7006 super.visitLabeledStatement(node); |
| 6365 } finally { | 7007 } finally { |
| 6366 _labelScope = outerScope; | 7008 _labelScope = outerScope; |
| 6367 } | 7009 } |
| 6368 return null; | 7010 return null; |
| 6369 } | 7011 } |
| 6370 Object visitMethodDeclaration(MethodDeclaration node) { | 7012 Object visitMethodDeclaration(MethodDeclaration node) { |
| 6371 Scope outerScope = _nameScope; | 7013 Scope outerScope = _nameScope; |
| 6372 try { | 7014 try { |
| 6373 _nameScope = new FunctionScope(_nameScope, node.element); | 7015 _nameScope = new FunctionScope(_nameScope, node.element); |
| 6374 super.visitMethodDeclaration(node); | 7016 super.visitMethodDeclaration(node); |
| 6375 } finally { | 7017 } finally { |
| 6376 _nameScope = outerScope; | 7018 _nameScope = outerScope; |
| 6377 } | 7019 } |
| 6378 return null; | 7020 return null; |
| 6379 } | 7021 } |
| 6380 Object visitSwitchCase(SwitchCase node) { | 7022 Object visitSwitchCase(SwitchCase node) { |
| 6381 node.expression.accept(this); | 7023 node.expression.accept(this); |
| 6382 Scope outerNameScope = _nameScope; | 7024 Scope outerNameScope = _nameScope; |
| 6383 _nameScope = new EnclosedScope(_nameScope); | |
| 6384 try { | 7025 try { |
| 7026 _nameScope = new EnclosedScope(_nameScope); |
| 6385 node.statements.accept(this); | 7027 node.statements.accept(this); |
| 6386 } finally { | 7028 } finally { |
| 6387 _nameScope = outerNameScope; | 7029 _nameScope = outerNameScope; |
| 6388 } | 7030 } |
| 6389 return null; | 7031 return null; |
| 6390 } | 7032 } |
| 6391 Object visitSwitchDefault(SwitchDefault node) { | 7033 Object visitSwitchDefault(SwitchDefault node) { |
| 6392 Scope outerNameScope = _nameScope; | 7034 Scope outerNameScope = _nameScope; |
| 6393 _nameScope = new EnclosedScope(_nameScope); | |
| 6394 try { | 7035 try { |
| 7036 _nameScope = new EnclosedScope(_nameScope); |
| 6395 node.statements.accept(this); | 7037 node.statements.accept(this); |
| 6396 } finally { | 7038 } finally { |
| 6397 _nameScope = outerNameScope; | 7039 _nameScope = outerNameScope; |
| 6398 } | 7040 } |
| 6399 return null; | 7041 return null; |
| 6400 } | 7042 } |
| 6401 Object visitSwitchStatement(SwitchStatement node) { | 7043 Object visitSwitchStatement(SwitchStatement node) { |
| 6402 LabelScope outerScope = _labelScope; | 7044 LabelScope outerScope = _labelScope; |
| 6403 _labelScope = new LabelScope.con1(outerScope, true, false); | 7045 try { |
| 6404 for (SwitchMember member in node.members) { | 7046 _labelScope = new LabelScope.con1(outerScope, true, false); |
| 6405 for (Label label in member.labels) { | 7047 for (SwitchMember member in node.members) { |
| 6406 SimpleIdentifier labelName = label.label; | 7048 for (Label label in member.labels) { |
| 6407 LabelElement labelElement = labelName.element as LabelElement; | 7049 SimpleIdentifier labelName = label.label; |
| 6408 _labelScope = new LabelScope.con2(_labelScope, labelName.name, labelElem
ent); | 7050 LabelElement labelElement = labelName.element as LabelElement; |
| 7051 _labelScope = new LabelScope.con2(_labelScope, labelName.name, labelEl
ement); |
| 7052 } |
| 6409 } | 7053 } |
| 6410 } | |
| 6411 try { | |
| 6412 super.visitSwitchStatement(node); | 7054 super.visitSwitchStatement(node); |
| 6413 } finally { | 7055 } finally { |
| 6414 _labelScope = outerScope; | 7056 _labelScope = outerScope; |
| 6415 } | 7057 } |
| 6416 return null; | 7058 return null; |
| 6417 } | 7059 } |
| 6418 Object visitVariableDeclaration(VariableDeclaration node) { | 7060 Object visitVariableDeclaration(VariableDeclaration node) { |
| 6419 if (node.parent.parent is! TopLevelVariableDeclaration && node.parent.parent
is! FieldDeclaration) { | 7061 if (node.parent.parent is! TopLevelVariableDeclaration && node.parent.parent
is! FieldDeclaration) { |
| 6420 VariableElement element = node.element; | 7062 VariableElement element = node.element; |
| 6421 if (element != null) { | 7063 if (element != null) { |
| 6422 _nameScope.define(element); | 7064 _nameScope.define(element); |
| 6423 } | 7065 } |
| 6424 } | 7066 } |
| 6425 super.visitVariableDeclaration(node); | 7067 super.visitVariableDeclaration(node); |
| 6426 return null; | 7068 return null; |
| 6427 } | 7069 } |
| 6428 Object visitWhileStatement(WhileStatement node) { | 7070 Object visitWhileStatement(WhileStatement node) { |
| 6429 LabelScope outerScope = _labelScope; | 7071 LabelScope outerScope = _labelScope; |
| 6430 _labelScope = new LabelScope.con1(outerScope, false, false); | |
| 6431 try { | 7072 try { |
| 6432 super.visitWhileStatement(node); | 7073 _labelScope = new LabelScope.con1(outerScope, false, false); |
| 7074 safelyVisit(node.condition); |
| 7075 visitStatementInScope(node.body); |
| 6433 } finally { | 7076 } finally { |
| 6434 _labelScope = outerScope; | 7077 _labelScope = outerScope; |
| 6435 } | 7078 } |
| 6436 return null; | 7079 return null; |
| 6437 } | 7080 } |
| 6438 | 7081 |
| 6439 /** | 7082 /** |
| 6440 * Return the label scope in which the current node is being resolved. | 7083 * Return the label scope in which the current node is being resolved. |
| 6441 * | 7084 * |
| 6442 * @return the label scope in which the current node is being resolved | 7085 * @return the label scope in which the current node is being resolved |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6498 /** | 7141 /** |
| 6499 * Visit the given statement after it's scope has been created. This replaces
the normal call to | 7142 * Visit the given statement after it's scope has been created. This replaces
the normal call to |
| 6500 * the inherited visit method so that ResolverVisitor can intervene when type
propagation is | 7143 * the inherited visit method so that ResolverVisitor can intervene when type
propagation is |
| 6501 * enabled. | 7144 * enabled. |
| 6502 * | 7145 * |
| 6503 * @param node the statement to be visited | 7146 * @param node the statement to be visited |
| 6504 */ | 7147 */ |
| 6505 void visitForEachStatementInScope(ForEachStatement node) { | 7148 void visitForEachStatementInScope(ForEachStatement node) { |
| 6506 safelyVisit(node.iterator); | 7149 safelyVisit(node.iterator); |
| 6507 safelyVisit(node.loopVariable); | 7150 safelyVisit(node.loopVariable); |
| 6508 safelyVisit(node.body); | 7151 visitStatementInScope(node.body); |
| 6509 } | 7152 } |
| 6510 | 7153 |
| 6511 /** | 7154 /** |
| 6512 * Visit the given statement after it's scope has been created. This replaces
the normal call to | 7155 * Visit the given statement after it's scope has been created. This replaces
the normal call to |
| 6513 * the inherited visit method so that ResolverVisitor can intervene when type
propagation is | 7156 * the inherited visit method so that ResolverVisitor can intervene when type
propagation is |
| 6514 * enabled. | 7157 * enabled. |
| 6515 * | 7158 * |
| 6516 * @param node the statement to be visited | 7159 * @param node the statement to be visited |
| 6517 */ | 7160 */ |
| 6518 void visitForStatementInScope(ForStatement node) { | 7161 void visitForStatementInScope(ForStatement node) { |
| 6519 super.visitForStatement(node); | 7162 safelyVisit(node.variables); |
| 7163 safelyVisit(node.initialization); |
| 7164 safelyVisit(node.condition); |
| 7165 node.updaters.accept(this); |
| 7166 visitStatementInScope(node.body); |
| 6520 } | 7167 } |
| 6521 | 7168 |
| 6522 /** | 7169 /** |
| 7170 * Visit the given statement after it's scope has been created. This is used b
y ResolverVisitor to |
| 7171 * correctly visit the 'then' and 'else' statements of an 'if' statement. |
| 7172 * |
| 7173 * @param node the statement to be visited |
| 7174 */ |
| 7175 void visitStatementInScope(Statement node) { |
| 7176 if (node is Block) { |
| 7177 visitBlock((node as Block)); |
| 7178 } else if (node != null) { |
| 7179 Scope outerNameScope = _nameScope; |
| 7180 try { |
| 7181 _nameScope = new EnclosedScope(_nameScope); |
| 7182 node.accept(this); |
| 7183 } finally { |
| 7184 _nameScope = outerNameScope; |
| 7185 } |
| 7186 } |
| 7187 } |
| 7188 |
| 7189 /** |
| 6523 * Add scopes for each of the given labels. | 7190 * Add scopes for each of the given labels. |
| 6524 * | 7191 * |
| 6525 * @param labels the labels for which new scopes are to be added | 7192 * @param labels the labels for which new scopes are to be added |
| 6526 * @return the scope that was in effect before the new scopes were added | 7193 * @return the scope that was in effect before the new scopes were added |
| 6527 */ | 7194 */ |
| 6528 LabelScope addScopesFor(NodeList<Label> labels) { | 7195 LabelScope addScopesFor(NodeList<Label> labels) { |
| 6529 LabelScope outerScope = _labelScope; | 7196 LabelScope outerScope = _labelScope; |
| 6530 for (Label label in labels) { | 7197 for (Label label in labels) { |
| 6531 SimpleIdentifier labelNameNode = label.label; | 7198 SimpleIdentifier labelNameNode = label.label; |
| 6532 String labelName = labelNameNode.name; | 7199 String labelName = labelNameNode.name; |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6746 * e<sub>2</sub>)</i> where <i>a</i> and <i>i</i> are a variables that are not
used in | 7413 * e<sub>2</sub>)</i> where <i>a</i> and <i>i</i> are a variables that are not
used in |
| 6747 * <i>e<sub>3</sub></i>.</blockquote> | 7414 * <i>e<sub>3</sub></i>.</blockquote> |
| 6748 */ | 7415 */ |
| 6749 Object visitAssignmentExpression(AssignmentExpression node) { | 7416 Object visitAssignmentExpression(AssignmentExpression node) { |
| 6750 sc.TokenType operator = node.operator.type; | 7417 sc.TokenType operator = node.operator.type; |
| 6751 if (identical(operator, sc.TokenType.EQ)) { | 7418 if (identical(operator, sc.TokenType.EQ)) { |
| 6752 Expression rightHandSide = node.rightHandSide; | 7419 Expression rightHandSide = node.rightHandSide; |
| 6753 Type2 staticType = getStaticType(rightHandSide); | 7420 Type2 staticType = getStaticType(rightHandSide); |
| 6754 recordStaticType(node, staticType); | 7421 recordStaticType(node, staticType); |
| 6755 Type2 overrideType = staticType; | 7422 Type2 overrideType = staticType; |
| 6756 Type2 propagatedType = getPropagatedType(rightHandSide); | 7423 Type2 propagatedType = rightHandSide.propagatedType; |
| 6757 if (propagatedType != null) { | 7424 if (propagatedType != null) { |
| 6758 if (propagatedType.isMoreSpecificThan(staticType)) { | 7425 if (propagatedType.isMoreSpecificThan(staticType)) { |
| 6759 recordPropagatedType2(node, propagatedType); | 7426 recordPropagatedType2(node, propagatedType); |
| 6760 } | 7427 } |
| 6761 overrideType = propagatedType; | 7428 overrideType = propagatedType; |
| 6762 } | 7429 } |
| 6763 VariableElement element = _resolver.getOverridableElement(node.leftHandSid
e); | 7430 VariableElement element = _resolver.getOverridableElement(node.leftHandSid
e); |
| 6764 if (element != null) { | 7431 if (element != null) { |
| 6765 _resolver.override(element, overrideType); | 7432 _resolver.override(element, overrideType); |
| 6766 } | 7433 } |
| 6767 } else { | 7434 } else { |
| 6768 ExecutableElement staticMethodElement = node.staticElement; | 7435 ExecutableElement staticMethodElement = node.staticElement; |
| 6769 Type2 staticType = computeStaticReturnType(staticMethodElement); | 7436 Type2 staticType = computeStaticReturnType(staticMethodElement); |
| 6770 recordStaticType(node, staticType); | 7437 recordStaticType(node, staticType); |
| 6771 MethodElement propagatedMethodElement = node.element; | 7438 MethodElement propagatedMethodElement = node.propagatedElement; |
| 6772 if (propagatedMethodElement != staticMethodElement) { | 7439 if (propagatedMethodElement != staticMethodElement) { |
| 6773 Type2 propagatedType = computeStaticReturnType(propagatedMethodElement); | 7440 Type2 propagatedType = computeStaticReturnType(propagatedMethodElement); |
| 6774 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy
pe)) { | 7441 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy
pe)) { |
| 6775 recordPropagatedType2(node, propagatedType); | 7442 recordPropagatedType2(node, propagatedType); |
| 6776 } | 7443 } |
| 6777 } | 7444 } |
| 6778 } | 7445 } |
| 6779 return null; | 7446 return null; |
| 6780 } | 7447 } |
| 6781 | 7448 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6814 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio
n | 7481 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio
n |
| 6815 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A multiplicative expression of the
form <i>super op | 7482 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A multiplicative expression of the
form <i>super op |
| 6816 * e<sub>2</sub></i> is equivalent to the method invocation | 7483 * e<sub>2</sub></i> is equivalent to the method invocation |
| 6817 * <i>super.op(e<sub>2</sub>)</i>.</blockquote> | 7484 * <i>super.op(e<sub>2</sub>)</i>.</blockquote> |
| 6818 */ | 7485 */ |
| 6819 Object visitBinaryExpression(BinaryExpression node) { | 7486 Object visitBinaryExpression(BinaryExpression node) { |
| 6820 ExecutableElement staticMethodElement = node.staticElement; | 7487 ExecutableElement staticMethodElement = node.staticElement; |
| 6821 Type2 staticType = computeStaticReturnType(staticMethodElement); | 7488 Type2 staticType = computeStaticReturnType(staticMethodElement); |
| 6822 staticType = refineBinaryExpressionType(node, staticType); | 7489 staticType = refineBinaryExpressionType(node, staticType); |
| 6823 recordStaticType(node, staticType); | 7490 recordStaticType(node, staticType); |
| 6824 MethodElement propagatedMethodElement = node.element; | 7491 MethodElement propagatedMethodElement = node.propagatedElement; |
| 6825 if (propagatedMethodElement != staticMethodElement) { | 7492 if (propagatedMethodElement != staticMethodElement) { |
| 6826 Type2 propagatedType = computeStaticReturnType(propagatedMethodElement); | 7493 Type2 propagatedType = computeStaticReturnType(propagatedMethodElement); |
| 6827 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType
)) { | 7494 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType
)) { |
| 6828 recordPropagatedType2(node, propagatedType); | 7495 recordPropagatedType2(node, propagatedType); |
| 6829 } | 7496 } |
| 6830 } | 7497 } |
| 6831 return null; | 7498 return null; |
| 6832 } | 7499 } |
| 6833 | 7500 |
| 6834 /** | 7501 /** |
| 6835 * The Dart Language Specification, 12.4: <blockquote>The static type of a boo
lean literal is | 7502 * The Dart Language Specification, 12.4: <blockquote>The static type of a boo
lean literal is |
| 6836 * bool.</blockquote> | 7503 * bool.</blockquote> |
| 6837 */ | 7504 */ |
| 6838 Object visitBooleanLiteral(BooleanLiteral node) { | 7505 Object visitBooleanLiteral(BooleanLiteral node) { |
| 6839 recordStaticType(node, _typeProvider.boolType); | 7506 recordStaticType(node, _typeProvider.boolType); |
| 6840 return null; | 7507 return null; |
| 6841 } | 7508 } |
| 6842 | 7509 |
| 6843 /** | 7510 /** |
| 6844 * The Dart Language Specification, 12.15.2: <blockquote>A cascaded method inv
ocation expression | 7511 * The Dart Language Specification, 12.15.2: <blockquote>A cascaded method inv
ocation expression |
| 6845 * of the form <i>e..suffix</i> is equivalent to the expression <i>(t) {t.suff
ix; return | 7512 * of the form <i>e..suffix</i> is equivalent to the expression <i>(t) {t.suff
ix; return |
| 6846 * t;}(e)</i>.</blockquote> | 7513 * t;}(e)</i>.</blockquote> |
| 6847 */ | 7514 */ |
| 6848 Object visitCascadeExpression(CascadeExpression node) { | 7515 Object visitCascadeExpression(CascadeExpression node) { |
| 6849 recordStaticType(node, getStaticType(node.target)); | 7516 recordStaticType(node, getStaticType(node.target)); |
| 6850 recordPropagatedType2(node, getPropagatedType(node.target)); | 7517 recordPropagatedType2(node, node.target.propagatedType); |
| 6851 return null; | 7518 return null; |
| 6852 } | 7519 } |
| 6853 | 7520 |
| 6854 /** | 7521 /** |
| 6855 * The Dart Language Specification, 12.19: <blockquote> ... a conditional expr
ession <i>c</i> of | 7522 * The Dart Language Specification, 12.19: <blockquote> ... a conditional expr
ession <i>c</i> of |
| 6856 * the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> ... | 7523 * the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> ... |
| 6857 * | 7524 * |
| 6858 * It is a static type warning if the type of e<sub>1</sub> may not be assigne
d to `bool`. | 7525 * It is a static type warning if the type of e<sub>1</sub> may not be assigne
d to `bool`. |
| 6859 * | 7526 * |
| 6860 * The static type of <i>c</i> is the least upper bound of the static type of
<i>e<sub>2</sub></i> | 7527 * The static type of <i>c</i> is the least upper bound of the static type of
<i>e<sub>2</sub></i> |
| 6861 * and the static type of <i>e<sub>3</sub></i>.</blockquote> | 7528 * and the static type of <i>e<sub>3</sub></i>.</blockquote> |
| 6862 */ | 7529 */ |
| 6863 Object visitConditionalExpression(ConditionalExpression node) { | 7530 Object visitConditionalExpression(ConditionalExpression node) { |
| 6864 Type2 staticThenType = getStaticType(node.thenExpression); | 7531 Type2 staticThenType = getStaticType(node.thenExpression); |
| 6865 Type2 staticElseType = getStaticType(node.elseExpression); | 7532 Type2 staticElseType = getStaticType(node.elseExpression); |
| 6866 if (staticThenType == null) { | 7533 if (staticThenType == null) { |
| 6867 staticThenType = _dynamicType; | 7534 staticThenType = _dynamicType; |
| 6868 } | 7535 } |
| 6869 if (staticElseType == null) { | 7536 if (staticElseType == null) { |
| 6870 staticElseType = _dynamicType; | 7537 staticElseType = _dynamicType; |
| 6871 } | 7538 } |
| 6872 Type2 staticType = staticThenType.getLeastUpperBound(staticElseType); | 7539 Type2 staticType = staticThenType.getLeastUpperBound(staticElseType); |
| 6873 if (staticType == null) { | 7540 if (staticType == null) { |
| 6874 staticType = _dynamicType; | 7541 staticType = _dynamicType; |
| 6875 } | 7542 } |
| 6876 recordStaticType(node, staticType); | 7543 recordStaticType(node, staticType); |
| 6877 Type2 propagatedThenType = getPropagatedType(node.thenExpression); | 7544 Type2 propagatedThenType = node.thenExpression.propagatedType; |
| 6878 Type2 propagatedElseType = getPropagatedType(node.elseExpression); | 7545 Type2 propagatedElseType = node.elseExpression.propagatedType; |
| 6879 if (propagatedThenType != null || propagatedElseType != null) { | 7546 if (propagatedThenType != null || propagatedElseType != null) { |
| 6880 if (propagatedThenType == null) { | 7547 if (propagatedThenType == null) { |
| 6881 propagatedThenType = staticThenType; | 7548 propagatedThenType = staticThenType; |
| 6882 } | 7549 } |
| 6883 if (propagatedElseType == null) { | 7550 if (propagatedElseType == null) { |
| 6884 propagatedElseType = staticElseType; | 7551 propagatedElseType = staticElseType; |
| 6885 } | 7552 } |
| 6886 Type2 propagatedType = propagatedThenType.getLeastUpperBound(propagatedEls
eType); | 7553 Type2 propagatedType = propagatedThenType.getLeastUpperBound(propagatedEls
eType); |
| 6887 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType
)) { | 7554 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType
)) { |
| 6888 recordPropagatedType2(node, propagatedType); | 7555 recordPropagatedType2(node, propagatedType); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6962 * static type of <i>i</i> is the declared return type of <i>F</i>.</blockquot
e> | 7629 * static type of <i>i</i> is the declared return type of <i>F</i>.</blockquot
e> |
| 6963 */ | 7630 */ |
| 6964 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 7631 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
| 6965 ExecutableElement staticMethodElement = node.staticElement; | 7632 ExecutableElement staticMethodElement = node.staticElement; |
| 6966 Type2 staticStaticType = computeStaticReturnType(staticMethodElement); | 7633 Type2 staticStaticType = computeStaticReturnType(staticMethodElement); |
| 6967 recordStaticType(node, staticStaticType); | 7634 recordStaticType(node, staticStaticType); |
| 6968 Type2 staticPropagatedType = computePropagatedReturnType(staticMethodElement
); | 7635 Type2 staticPropagatedType = computePropagatedReturnType(staticMethodElement
); |
| 6969 if (staticPropagatedType != null && (staticStaticType == null || staticPropa
gatedType.isMoreSpecificThan(staticStaticType))) { | 7636 if (staticPropagatedType != null && (staticStaticType == null || staticPropa
gatedType.isMoreSpecificThan(staticStaticType))) { |
| 6970 recordPropagatedType2(node, staticPropagatedType); | 7637 recordPropagatedType2(node, staticPropagatedType); |
| 6971 } | 7638 } |
| 6972 ExecutableElement propagatedMethodElement = node.element; | 7639 ExecutableElement propagatedMethodElement = node.propagatedElement; |
| 6973 if (propagatedMethodElement != staticMethodElement) { | 7640 if (propagatedMethodElement != staticMethodElement) { |
| 6974 Type2 propagatedStaticType = computeStaticReturnType(propagatedMethodEleme
nt); | 7641 Type2 propagatedStaticType = computeStaticReturnType(propagatedMethodEleme
nt); |
| 6975 if (propagatedStaticType != null && (staticStaticType == null || propagate
dStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == nu
ll || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) { | 7642 if (propagatedStaticType != null && (staticStaticType == null || propagate
dStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == nu
ll || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) { |
| 6976 recordPropagatedType2(node, propagatedStaticType); | 7643 recordPropagatedType2(node, propagatedStaticType); |
| 6977 } | 7644 } |
| 6978 Type2 propagatedPropagatedType = computePropagatedReturnType(propagatedMet
hodElement); | 7645 Type2 propagatedPropagatedType = computePropagatedReturnType(propagatedMet
hodElement); |
| 6979 if (propagatedPropagatedType != null && (staticStaticType == null || propa
gatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedTy
pe == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType))
&& (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificThan
(propagatedStaticType))) { | 7646 if (propagatedPropagatedType != null && (staticStaticType == null || propa
gatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedTy
pe == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType))
&& (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificThan
(propagatedStaticType))) { |
| 6980 recordPropagatedType2(node, propagatedPropagatedType); | 7647 recordPropagatedType2(node, propagatedPropagatedType); |
| 6981 } | 7648 } |
| 6982 } | 7649 } |
| 6983 return null; | 7650 return null; |
| 6984 } | 7651 } |
| 6985 | 7652 |
| 6986 /** | 7653 /** |
| 6987 * The Dart Language Specification, 12.29: <blockquote>An assignable expressio
n of the form | 7654 * The Dart Language Specification, 12.29: <blockquote>An assignable expressio
n of the form |
| 6988 * <i>e<sub>1</sub>[e<sub>2</sub>]</i> is evaluated as a method invocation of
the operator method | 7655 * <i>e<sub>1</sub>[e<sub>2</sub>]</i> is evaluated as a method invocation of
the operator method |
| 6989 * <i>[]</i> on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.</bloc
kquote> | 7656 * <i>[]</i> on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.</bloc
kquote> |
| 6990 */ | 7657 */ |
| 6991 Object visitIndexExpression(IndexExpression node) { | 7658 Object visitIndexExpression(IndexExpression node) { |
| 6992 if (node.inSetterContext()) { | 7659 if (node.inSetterContext()) { |
| 6993 ExecutableElement staticMethodElement = node.staticElement; | 7660 ExecutableElement staticMethodElement = node.staticElement; |
| 6994 Type2 staticType = computeArgumentType(staticMethodElement); | 7661 Type2 staticType = computeArgumentType(staticMethodElement); |
| 6995 recordStaticType(node, staticType); | 7662 recordStaticType(node, staticType); |
| 6996 MethodElement propagatedMethodElement = node.element; | 7663 MethodElement propagatedMethodElement = node.propagatedElement; |
| 6997 if (propagatedMethodElement != staticMethodElement) { | 7664 if (propagatedMethodElement != staticMethodElement) { |
| 6998 Type2 propagatedType = computeArgumentType(propagatedMethodElement); | 7665 Type2 propagatedType = computeArgumentType(propagatedMethodElement); |
| 6999 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy
pe)) { | 7666 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy
pe)) { |
| 7000 recordPropagatedType2(node, propagatedType); | 7667 recordPropagatedType2(node, propagatedType); |
| 7001 } | 7668 } |
| 7002 } | 7669 } |
| 7003 } else { | 7670 } else { |
| 7004 ExecutableElement staticMethodElement = node.staticElement; | 7671 ExecutableElement staticMethodElement = node.staticElement; |
| 7005 Type2 staticType = computeStaticReturnType(staticMethodElement); | 7672 Type2 staticType = computeStaticReturnType(staticMethodElement); |
| 7006 recordStaticType(node, staticType); | 7673 recordStaticType(node, staticType); |
| 7007 MethodElement propagatedMethodElement = node.element; | 7674 MethodElement propagatedMethodElement = node.propagatedElement; |
| 7008 if (propagatedMethodElement != staticMethodElement) { | 7675 if (propagatedMethodElement != staticMethodElement) { |
| 7009 Type2 propagatedType = computeStaticReturnType(propagatedMethodElement); | 7676 Type2 propagatedType = computeStaticReturnType(propagatedMethodElement); |
| 7010 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy
pe)) { | 7677 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy
pe)) { |
| 7011 recordPropagatedType2(node, propagatedType); | 7678 recordPropagatedType2(node, propagatedType); |
| 7012 } | 7679 } |
| 7013 } | 7680 } |
| 7014 } | 7681 } |
| 7015 return null; | 7682 return null; |
| 7016 } | 7683 } |
| 7017 | 7684 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7088 Type2 argumentType = getType2(argumentTypeName); | 7755 Type2 argumentType = getType2(argumentTypeName); |
| 7089 if (argumentType != null) { | 7756 if (argumentType != null) { |
| 7090 staticType = argumentType; | 7757 staticType = argumentType; |
| 7091 } | 7758 } |
| 7092 } | 7759 } |
| 7093 } | 7760 } |
| 7094 recordStaticType(node, _typeProvider.listType.substitute4(<Type2> [staticTyp
e])); | 7761 recordStaticType(node, _typeProvider.listType.substitute4(<Type2> [staticTyp
e])); |
| 7095 NodeList<Expression> elements = node.elements; | 7762 NodeList<Expression> elements = node.elements; |
| 7096 int count = elements.length; | 7763 int count = elements.length; |
| 7097 if (count > 0) { | 7764 if (count > 0) { |
| 7098 Type2 propagatedType = getBestType(elements[0]); | 7765 Type2 propagatedType = elements[0].bestType; |
| 7099 for (int i = 1; i < count; i++) { | 7766 for (int i = 1; i < count; i++) { |
| 7100 Type2 elementType = getBestType(elements[i]); | 7767 Type2 elementType = elements[i].bestType; |
| 7101 if (propagatedType != elementType) { | 7768 if (propagatedType != elementType) { |
| 7102 propagatedType = _dynamicType; | 7769 propagatedType = _dynamicType; |
| 7103 } else { | 7770 } else { |
| 7104 propagatedType = propagatedType.getLeastUpperBound(elementType); | 7771 propagatedType = propagatedType.getLeastUpperBound(elementType); |
| 7105 if (propagatedType == null) { | 7772 if (propagatedType == null) { |
| 7106 propagatedType = _dynamicType; | 7773 propagatedType = _dynamicType; |
| 7107 } | 7774 } |
| 7108 } | 7775 } |
| 7109 } | 7776 } |
| 7110 if (propagatedType.isMoreSpecificThan(staticType)) { | 7777 if (propagatedType.isMoreSpecificThan(staticType)) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7143 if (entryValueType != null) { | 7810 if (entryValueType != null) { |
| 7144 staticValueType = entryValueType; | 7811 staticValueType = entryValueType; |
| 7145 } | 7812 } |
| 7146 } | 7813 } |
| 7147 } | 7814 } |
| 7148 recordStaticType(node, _typeProvider.mapType.substitute4(<Type2> [staticKeyT
ype, staticValueType])); | 7815 recordStaticType(node, _typeProvider.mapType.substitute4(<Type2> [staticKeyT
ype, staticValueType])); |
| 7149 NodeList<MapLiteralEntry> entries = node.entries; | 7816 NodeList<MapLiteralEntry> entries = node.entries; |
| 7150 int count = entries.length; | 7817 int count = entries.length; |
| 7151 if (count > 0) { | 7818 if (count > 0) { |
| 7152 MapLiteralEntry entry = entries[0]; | 7819 MapLiteralEntry entry = entries[0]; |
| 7153 Type2 propagatedKeyType = getBestType(entry.key); | 7820 Type2 propagatedKeyType = entry.key.bestType; |
| 7154 Type2 propagatedValueType = getBestType(entry.value); | 7821 Type2 propagatedValueType = entry.value.bestType; |
| 7155 for (int i = 1; i < count; i++) { | 7822 for (int i = 1; i < count; i++) { |
| 7156 entry = entries[i]; | 7823 entry = entries[i]; |
| 7157 Type2 elementKeyType = getBestType(entry.key); | 7824 Type2 elementKeyType = entry.key.bestType; |
| 7158 if (propagatedKeyType != elementKeyType) { | 7825 if (propagatedKeyType != elementKeyType) { |
| 7159 propagatedKeyType = _dynamicType; | 7826 propagatedKeyType = _dynamicType; |
| 7160 } else { | 7827 } else { |
| 7161 propagatedKeyType = propagatedKeyType.getLeastUpperBound(elementKeyTyp
e); | 7828 propagatedKeyType = propagatedKeyType.getLeastUpperBound(elementKeyTyp
e); |
| 7162 if (propagatedKeyType == null) { | 7829 if (propagatedKeyType == null) { |
| 7163 propagatedKeyType = _dynamicType; | 7830 propagatedKeyType = _dynamicType; |
| 7164 } | 7831 } |
| 7165 } | 7832 } |
| 7166 Type2 elementValueType = getBestType(entry.value); | 7833 Type2 elementValueType = entry.value.bestType; |
| 7167 if (propagatedValueType != elementValueType) { | 7834 if (propagatedValueType != elementValueType) { |
| 7168 propagatedValueType = _dynamicType; | 7835 propagatedValueType = _dynamicType; |
| 7169 } else { | 7836 } else { |
| 7170 propagatedValueType = propagatedValueType.getLeastUpperBound(elementVa
lueType); | 7837 propagatedValueType = propagatedValueType.getLeastUpperBound(elementVa
lueType); |
| 7171 if (propagatedValueType == null) { | 7838 if (propagatedValueType == null) { |
| 7172 propagatedValueType = _dynamicType; | 7839 propagatedValueType = _dynamicType; |
| 7173 } | 7840 } |
| 7174 } | 7841 } |
| 7175 } | 7842 } |
| 7176 bool betterKey = propagatedKeyType != null && propagatedKeyType.isMoreSpec
ificThan(staticKeyType); | 7843 bool betterKey = propagatedKeyType != null && propagatedKeyType.isMoreSpec
ificThan(staticKeyType); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7232 } | 7899 } |
| 7233 Type2 staticStaticType = computeStaticReturnType(staticMethodElement); | 7900 Type2 staticStaticType = computeStaticReturnType(staticMethodElement); |
| 7234 recordStaticType(node, staticStaticType); | 7901 recordStaticType(node, staticStaticType); |
| 7235 Type2 staticPropagatedType = computePropagatedReturnType(staticMethodElement
); | 7902 Type2 staticPropagatedType = computePropagatedReturnType(staticMethodElement
); |
| 7236 if (staticPropagatedType != null && (staticStaticType == null || staticPropa
gatedType.isMoreSpecificThan(staticStaticType))) { | 7903 if (staticPropagatedType != null && (staticStaticType == null || staticPropa
gatedType.isMoreSpecificThan(staticStaticType))) { |
| 7237 recordPropagatedType2(node, staticPropagatedType); | 7904 recordPropagatedType2(node, staticPropagatedType); |
| 7238 } | 7905 } |
| 7239 String methodName = methodNameNode.name; | 7906 String methodName = methodNameNode.name; |
| 7240 if (methodName == "then") { | 7907 if (methodName == "then") { |
| 7241 Expression target = node.realTarget; | 7908 Expression target = node.realTarget; |
| 7242 Type2 targetType = target == null ? null : getBestType(target); | 7909 Type2 targetType = target == null ? null : target.bestType; |
| 7243 if (isAsyncFutureType(targetType)) { | 7910 if (isAsyncFutureType(targetType)) { |
| 7244 NodeList<Expression> arguments = node.argumentList.arguments; | 7911 NodeList<Expression> arguments = node.argumentList.arguments; |
| 7245 if (arguments.length == 1) { | 7912 if (arguments.length == 1) { |
| 7246 Expression closureArg = arguments[0]; | 7913 Expression closureArg = arguments[0]; |
| 7247 if (closureArg is FunctionExpression) { | 7914 if (closureArg is FunctionExpression) { |
| 7248 FunctionExpression closureExpr = closureArg as FunctionExpression; | 7915 FunctionExpression closureExpr = closureArg as FunctionExpression; |
| 7249 Type2 returnType = computePropagatedReturnType(closureExpr.element); | 7916 Type2 returnType = computePropagatedReturnType(closureExpr.element); |
| 7250 if (returnType != null) { | 7917 if (returnType != null) { |
| 7251 InterfaceTypeImpl newFutureType; | 7918 InterfaceTypeImpl newFutureType; |
| 7252 if (isAsyncFutureType(returnType)) { | 7919 if (isAsyncFutureType(returnType)) { |
| 7253 newFutureType = returnType as InterfaceTypeImpl; | 7920 newFutureType = returnType as InterfaceTypeImpl; |
| 7254 } else { | 7921 } else { |
| 7255 InterfaceType futureType = targetType as InterfaceType; | 7922 InterfaceType futureType = targetType as InterfaceType; |
| 7256 newFutureType = new InterfaceTypeImpl.con1(futureType.element); | 7923 newFutureType = new InterfaceTypeImpl.con1(futureType.element); |
| 7257 newFutureType.typeArguments = <Type2> [returnType]; | 7924 newFutureType.typeArguments = <Type2> [returnType]; |
| 7258 } | 7925 } |
| 7259 recordPropagatedType2(node, newFutureType); | 7926 recordPropagatedType2(node, newFutureType); |
| 7260 return null; | 7927 return null; |
| 7261 } | 7928 } |
| 7262 } | 7929 } |
| 7263 } | 7930 } |
| 7264 } | 7931 } |
| 7265 } | 7932 } |
| 7266 if (methodName == "\$dom_createEvent") { | 7933 if (methodName == "\$dom_createEvent") { |
| 7267 Expression target = node.realTarget; | 7934 Expression target = node.realTarget; |
| 7268 if (target != null) { | 7935 if (target != null) { |
| 7269 Type2 targetType = getBestType(target); | 7936 Type2 targetType = target.bestType; |
| 7270 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" ||
targetType.name == "Document")) { | 7937 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" ||
targetType.name == "Document")) { |
| 7271 LibraryElement library = targetType.element.library; | 7938 LibraryElement library = targetType.element.library; |
| 7272 if (isHtmlLibrary(library)) { | 7939 if (isHtmlLibrary(library)) { |
| 7273 Type2 returnType = getFirstArgumentAsType(library, node.argumentList
); | 7940 Type2 returnType = getFirstArgumentAsType(library, node.argumentList
); |
| 7274 if (returnType != null) { | 7941 if (returnType != null) { |
| 7275 recordPropagatedType2(node, returnType); | 7942 recordPropagatedType2(node, returnType); |
| 7276 } | 7943 } |
| 7277 } | 7944 } |
| 7278 } | 7945 } |
| 7279 } | 7946 } |
| 7280 } else if (methodName == "query") { | 7947 } else if (methodName == "query") { |
| 7281 Expression target = node.realTarget; | 7948 Expression target = node.realTarget; |
| 7282 if (target == null) { | 7949 if (target == null) { |
| 7283 Element methodElement = methodNameNode.element; | 7950 Element methodElement = methodNameNode.element; |
| 7284 if (methodElement != null) { | 7951 if (methodElement != null) { |
| 7285 LibraryElement library = methodElement.library; | 7952 LibraryElement library = methodElement.library; |
| 7286 if (isHtmlLibrary(library)) { | 7953 if (isHtmlLibrary(library)) { |
| 7287 Type2 returnType = getFirstArgumentAsQuery(library, node.argumentLis
t); | 7954 Type2 returnType = getFirstArgumentAsQuery(library, node.argumentLis
t); |
| 7288 if (returnType != null) { | 7955 if (returnType != null) { |
| 7289 recordPropagatedType2(node, returnType); | 7956 recordPropagatedType2(node, returnType); |
| 7290 } | 7957 } |
| 7291 } | 7958 } |
| 7292 } | 7959 } |
| 7293 } else { | 7960 } else { |
| 7294 Type2 targetType = getBestType(target); | 7961 Type2 targetType = target.bestType; |
| 7295 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" ||
targetType.name == "Document")) { | 7962 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" ||
targetType.name == "Document")) { |
| 7296 LibraryElement library = targetType.element.library; | 7963 LibraryElement library = targetType.element.library; |
| 7297 if (isHtmlLibrary(library)) { | 7964 if (isHtmlLibrary(library)) { |
| 7298 Type2 returnType = getFirstArgumentAsQuery(library, node.argumentLis
t); | 7965 Type2 returnType = getFirstArgumentAsQuery(library, node.argumentLis
t); |
| 7299 if (returnType != null) { | 7966 if (returnType != null) { |
| 7300 recordPropagatedType2(node, returnType); | 7967 recordPropagatedType2(node, returnType); |
| 7301 } | 7968 } |
| 7302 } | 7969 } |
| 7303 } | 7970 } |
| 7304 } | 7971 } |
| 7305 } else if (methodName == "\$dom_createElement") { | 7972 } else if (methodName == "\$dom_createElement") { |
| 7306 Expression target = node.realTarget; | 7973 Expression target = node.realTarget; |
| 7307 Type2 targetType = getBestType(target); | 7974 Type2 targetType = target.bestType; |
| 7308 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || t
argetType.name == "Document")) { | 7975 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || t
argetType.name == "Document")) { |
| 7309 LibraryElement library = targetType.element.library; | 7976 LibraryElement library = targetType.element.library; |
| 7310 if (isHtmlLibrary(library)) { | 7977 if (isHtmlLibrary(library)) { |
| 7311 Type2 returnType = getFirstArgumentAsQuery(library, node.argumentList)
; | 7978 Type2 returnType = getFirstArgumentAsQuery(library, node.argumentList)
; |
| 7312 if (returnType != null) { | 7979 if (returnType != null) { |
| 7313 recordPropagatedType2(node, returnType); | 7980 recordPropagatedType2(node, returnType); |
| 7314 } | 7981 } |
| 7315 } | 7982 } |
| 7316 } | 7983 } |
| 7317 } else if (methodName == "JS") { | 7984 } else if (methodName == "JS") { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 7330 if (propagatedPropagatedType != null && (staticStaticType == null || pro
pagatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagated
Type == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType
)) && (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificTh
an(propagatedStaticType))) { | 7997 if (propagatedPropagatedType != null && (staticStaticType == null || pro
pagatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagated
Type == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType
)) && (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificTh
an(propagatedStaticType))) { |
| 7331 recordPropagatedType2(node, propagatedPropagatedType); | 7998 recordPropagatedType2(node, propagatedPropagatedType); |
| 7332 } | 7999 } |
| 7333 } | 8000 } |
| 7334 } | 8001 } |
| 7335 return null; | 8002 return null; |
| 7336 } | 8003 } |
| 7337 Object visitNamedExpression(NamedExpression node) { | 8004 Object visitNamedExpression(NamedExpression node) { |
| 7338 Expression expression = node.expression; | 8005 Expression expression = node.expression; |
| 7339 recordStaticType(node, getStaticType(expression)); | 8006 recordStaticType(node, getStaticType(expression)); |
| 7340 recordPropagatedType2(node, getPropagatedType(expression)); | 8007 recordPropagatedType2(node, expression.propagatedType); |
| 7341 return null; | 8008 return null; |
| 7342 } | 8009 } |
| 7343 | 8010 |
| 7344 /** | 8011 /** |
| 7345 * The Dart Language Specification, 12.2: <blockquote>The static type of `null
` is bottom. | 8012 * The Dart Language Specification, 12.2: <blockquote>The static type of `null
` is bottom. |
| 7346 * </blockquote> | 8013 * </blockquote> |
| 7347 */ | 8014 */ |
| 7348 Object visitNullLiteral(NullLiteral node) { | 8015 Object visitNullLiteral(NullLiteral node) { |
| 7349 recordStaticType(node, _typeProvider.bottomType); | 8016 recordStaticType(node, _typeProvider.bottomType); |
| 7350 return null; | 8017 return null; |
| 7351 } | 8018 } |
| 7352 Object visitParenthesizedExpression(ParenthesizedExpression node) { | 8019 Object visitParenthesizedExpression(ParenthesizedExpression node) { |
| 7353 Expression expression = node.expression; | 8020 Expression expression = node.expression; |
| 7354 recordStaticType(node, getStaticType(expression)); | 8021 recordStaticType(node, getStaticType(expression)); |
| 7355 recordPropagatedType2(node, getPropagatedType(expression)); | 8022 recordPropagatedType2(node, expression.propagatedType); |
| 7356 return null; | 8023 return null; |
| 7357 } | 8024 } |
| 7358 | 8025 |
| 7359 /** | 8026 /** |
| 7360 * The Dart Language Specification, 12.28: <blockquote>A postfix expression of
the form | 8027 * The Dart Language Specification, 12.28: <blockquote>A postfix expression of
the form |
| 7361 * <i>v++</i>, where <i>v</i> is an identifier, is equivalent to <i>(){var r =
v; v = r + 1; | 8028 * <i>v++</i>, where <i>v</i> is an identifier, is equivalent to <i>(){var r =
v; v = r + 1; |
| 7362 * return r}()</i>. | 8029 * return r}()</i>. |
| 7363 * | 8030 * |
| 7364 * A postfix expression of the form <i>C.v++</i> is equivalent to <i>(){var r
= C.v; C.v = r + 1; | 8031 * A postfix expression of the form <i>C.v++</i> is equivalent to <i>(){var r
= C.v; C.v = r + 1; |
| 7365 * return r}()</i>. | 8032 * return r}()</i>. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 7386 Expression operand = node.operand; | 8053 Expression operand = node.operand; |
| 7387 Type2 staticType = getStaticType(operand); | 8054 Type2 staticType = getStaticType(operand); |
| 7388 sc.TokenType operator = node.operator.type; | 8055 sc.TokenType operator = node.operator.type; |
| 7389 if (identical(operator, sc.TokenType.MINUS_MINUS) || identical(operator, sc.
TokenType.PLUS_PLUS)) { | 8056 if (identical(operator, sc.TokenType.MINUS_MINUS) || identical(operator, sc.
TokenType.PLUS_PLUS)) { |
| 7390 Type2 intType = _typeProvider.intType; | 8057 Type2 intType = _typeProvider.intType; |
| 7391 if (identical(getStaticType(node.operand), intType)) { | 8058 if (identical(getStaticType(node.operand), intType)) { |
| 7392 staticType = intType; | 8059 staticType = intType; |
| 7393 } | 8060 } |
| 7394 } | 8061 } |
| 7395 recordStaticType(node, staticType); | 8062 recordStaticType(node, staticType); |
| 7396 recordPropagatedType2(node, getPropagatedType(operand)); | 8063 recordPropagatedType2(node, operand.propagatedType); |
| 7397 return null; | 8064 return null; |
| 7398 } | 8065 } |
| 7399 | 8066 |
| 7400 /** | 8067 /** |
| 7401 * See [visitSimpleIdentifier]. | 8068 * See [visitSimpleIdentifier]. |
| 7402 */ | 8069 */ |
| 7403 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 8070 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 7404 SimpleIdentifier prefixedIdentifier = node.identifier; | 8071 SimpleIdentifier prefixedIdentifier = node.identifier; |
| 7405 Element element = prefixedIdentifier.element; | 8072 Element element = prefixedIdentifier.element; |
| 7406 Type2 staticType = _dynamicType; | 8073 Type2 staticType = _dynamicType; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7445 } else { | 8112 } else { |
| 7446 ExecutableElement staticMethodElement = node.staticElement; | 8113 ExecutableElement staticMethodElement = node.staticElement; |
| 7447 Type2 staticType = computeStaticReturnType(staticMethodElement); | 8114 Type2 staticType = computeStaticReturnType(staticMethodElement); |
| 7448 if (identical(operator, sc.TokenType.MINUS_MINUS) || identical(operator, s
c.TokenType.PLUS_PLUS)) { | 8115 if (identical(operator, sc.TokenType.MINUS_MINUS) || identical(operator, s
c.TokenType.PLUS_PLUS)) { |
| 7449 Type2 intType = _typeProvider.intType; | 8116 Type2 intType = _typeProvider.intType; |
| 7450 if (identical(getStaticType(node.operand), intType)) { | 8117 if (identical(getStaticType(node.operand), intType)) { |
| 7451 staticType = intType; | 8118 staticType = intType; |
| 7452 } | 8119 } |
| 7453 } | 8120 } |
| 7454 recordStaticType(node, staticType); | 8121 recordStaticType(node, staticType); |
| 7455 MethodElement propagatedMethodElement = node.element; | 8122 MethodElement propagatedMethodElement = node.propagatedElement; |
| 7456 if (propagatedMethodElement != staticMethodElement) { | 8123 if (propagatedMethodElement != staticMethodElement) { |
| 7457 Type2 propagatedType = computeStaticReturnType(propagatedMethodElement); | 8124 Type2 propagatedType = computeStaticReturnType(propagatedMethodElement); |
| 7458 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy
pe)) { | 8125 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy
pe)) { |
| 7459 recordPropagatedType2(node, propagatedType); | 8126 recordPropagatedType2(node, propagatedType); |
| 7460 } | 8127 } |
| 7461 } | 8128 } |
| 7462 } | 8129 } |
| 7463 return null; | 8130 return null; |
| 7464 } | 8131 } |
| 7465 | 8132 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7628 return null; | 8295 return null; |
| 7629 } | 8296 } |
| 7630 Object visitSuperExpression(SuperExpression node) { | 8297 Object visitSuperExpression(SuperExpression node) { |
| 7631 if (_thisType == null) { | 8298 if (_thisType == null) { |
| 7632 recordStaticType(node, _dynamicType); | 8299 recordStaticType(node, _dynamicType); |
| 7633 } else { | 8300 } else { |
| 7634 recordStaticType(node, _thisType); | 8301 recordStaticType(node, _thisType); |
| 7635 } | 8302 } |
| 7636 return null; | 8303 return null; |
| 7637 } | 8304 } |
| 8305 Object visitSymbolLiteral(SymbolLiteral node) { |
| 8306 recordStaticType(node, _typeProvider.symbolType); |
| 8307 return null; |
| 8308 } |
| 7638 | 8309 |
| 7639 /** | 8310 /** |
| 7640 * The Dart Language Specification, 12.10: <blockquote>The static type of `thi
s` is the | 8311 * The Dart Language Specification, 12.10: <blockquote>The static type of `thi
s` is the |
| 7641 * interface of the immediately enclosing class.</blockquote> | 8312 * interface of the immediately enclosing class.</blockquote> |
| 7642 */ | 8313 */ |
| 7643 Object visitThisExpression(ThisExpression node) { | 8314 Object visitThisExpression(ThisExpression node) { |
| 7644 if (_thisType == null) { | 8315 if (_thisType == null) { |
| 7645 recordStaticType(node, _dynamicType); | 8316 recordStaticType(node, _dynamicType); |
| 7646 } else { | 8317 } else { |
| 7647 recordStaticType(node, _thisType); | 8318 recordStaticType(node, _thisType); |
| 7648 } | 8319 } |
| 7649 return null; | 8320 return null; |
| 7650 } | 8321 } |
| 7651 | 8322 |
| 7652 /** | 8323 /** |
| 7653 * The Dart Language Specification, 12.8: <blockquote>The static type of a thr
ow expression is | 8324 * The Dart Language Specification, 12.8: <blockquote>The static type of a thr
ow expression is |
| 7654 * bottom.</blockquote> | 8325 * bottom.</blockquote> |
| 7655 */ | 8326 */ |
| 7656 Object visitThrowExpression(ThrowExpression node) { | 8327 Object visitThrowExpression(ThrowExpression node) { |
| 7657 recordStaticType(node, _typeProvider.bottomType); | 8328 recordStaticType(node, _typeProvider.bottomType); |
| 7658 return null; | 8329 return null; |
| 7659 } | 8330 } |
| 7660 Object visitVariableDeclaration(VariableDeclaration node) { | 8331 Object visitVariableDeclaration(VariableDeclaration node) { |
| 7661 Expression initializer = node.initializer; | 8332 Expression initializer = node.initializer; |
| 7662 if (initializer != null) { | 8333 if (initializer != null) { |
| 7663 Type2 rightType = getBestType(initializer); | 8334 Type2 rightType = initializer.bestType; |
| 7664 SimpleIdentifier name = node.name; | 8335 SimpleIdentifier name = node.name; |
| 7665 recordPropagatedType2(name, rightType); | 8336 recordPropagatedType2(name, rightType); |
| 7666 VariableElement element = name.element as VariableElement; | 8337 VariableElement element = name.element as VariableElement; |
| 7667 if (element != null) { | 8338 if (element != null) { |
| 7668 _resolver.override(element, rightType); | 8339 _resolver.override(element, rightType); |
| 7669 } | 8340 } |
| 7670 } | 8341 } |
| 7671 return null; | 8342 return null; |
| 7672 } | 8343 } |
| 7673 | 8344 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 7704 * Given a function body, compute the propagated return type of the function.
The propagated | 8375 * Given a function body, compute the propagated return type of the function.
The propagated |
| 7705 * return type of functions with a block body is the least upper bound of all | 8376 * return type of functions with a block body is the least upper bound of all |
| 7706 * [ReturnStatement] expressions, with an expression body it is the type of th
e expression. | 8377 * [ReturnStatement] expressions, with an expression body it is the type of th
e expression. |
| 7707 * | 8378 * |
| 7708 * @param body the boy of the function whose propagated return type is to be c
omputed | 8379 * @param body the boy of the function whose propagated return type is to be c
omputed |
| 7709 * @return the propagated return type that was computed | 8380 * @return the propagated return type that was computed |
| 7710 */ | 8381 */ |
| 7711 Type2 computePropagatedReturnType2(FunctionBody body) { | 8382 Type2 computePropagatedReturnType2(FunctionBody body) { |
| 7712 if (body is ExpressionFunctionBody) { | 8383 if (body is ExpressionFunctionBody) { |
| 7713 ExpressionFunctionBody expressionBody = body as ExpressionFunctionBody; | 8384 ExpressionFunctionBody expressionBody = body as ExpressionFunctionBody; |
| 7714 return getBestType(expressionBody.expression); | 8385 return expressionBody.expression.bestType; |
| 7715 } | 8386 } |
| 7716 if (body is BlockFunctionBody) { | 8387 if (body is BlockFunctionBody) { |
| 7717 List<Type2> result = [null]; | 8388 List<Type2> result = [null]; |
| 7718 body.accept(new GeneralizingASTVisitor_8(this, result)); | 8389 body.accept(new GeneralizingASTVisitor_8(result)); |
| 7719 return result[0]; | 8390 return result[0]; |
| 7720 } | 8391 } |
| 7721 return null; | 8392 return null; |
| 7722 } | 8393 } |
| 7723 | 8394 |
| 7724 /** | 8395 /** |
| 7725 * Compute the static return type of the method or function represented by the
given element. | 8396 * Compute the static return type of the method or function represented by the
given element. |
| 7726 * | 8397 * |
| 7727 * @param element the element representing the method or function invoked by t
he given node | 8398 * @param element the element representing the method or function invoked by t
he given node |
| 7728 * @return the static return type that was computed | 8399 * @return the static return type that was computed |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7792 */ | 8463 */ |
| 7793 Type2 computeStaticReturnType3(FunctionExpression node) { | 8464 Type2 computeStaticReturnType3(FunctionExpression node) { |
| 7794 FunctionBody body = node.body; | 8465 FunctionBody body = node.body; |
| 7795 if (body is ExpressionFunctionBody) { | 8466 if (body is ExpressionFunctionBody) { |
| 7796 return getStaticType(((body as ExpressionFunctionBody)).expression); | 8467 return getStaticType(((body as ExpressionFunctionBody)).expression); |
| 7797 } | 8468 } |
| 7798 return _dynamicType; | 8469 return _dynamicType; |
| 7799 } | 8470 } |
| 7800 | 8471 |
| 7801 /** | 8472 /** |
| 7802 * Return the propagated type of the given expression if it is available, or t
he static type if | |
| 7803 * there is no propagated type. | |
| 7804 * | |
| 7805 * @param expression the expression whose type is to be returned | |
| 7806 * @return the propagated or static type of the given expression | |
| 7807 */ | |
| 7808 Type2 getBestType(Expression expression) { | |
| 7809 Type2 type = expression.propagatedType; | |
| 7810 if (type == null) { | |
| 7811 type = expression.staticType; | |
| 7812 if (type == null) { | |
| 7813 return _dynamicType; | |
| 7814 } | |
| 7815 } | |
| 7816 return type; | |
| 7817 } | |
| 7818 | |
| 7819 /** | |
| 7820 * If the given element name can be mapped to the name of a class defined with
in the given | 8473 * If the given element name can be mapped to the name of a class defined with
in the given |
| 7821 * library, return the type specified by the argument. | 8474 * library, return the type specified by the argument. |
| 7822 * | 8475 * |
| 7823 * @param library the library in which the specified type would be defined | 8476 * @param library the library in which the specified type would be defined |
| 7824 * @param elementName the name of the element for which a type is being sought | 8477 * @param elementName the name of the element for which a type is being sought |
| 7825 * @param nameMap an optional map used to map the element name to a type name | 8478 * @param nameMap an optional map used to map the element name to a type name |
| 7826 * @return the type specified by the first argument in the argument list | 8479 * @return the type specified by the first argument in the argument list |
| 7827 */ | 8480 */ |
| 7828 Type2 getElementNameAsType(LibraryElement library, String elementName, Map<Str
ing, String> nameMap) { | 8481 Type2 getElementNameAsType(LibraryElement library, String elementName, Map<Str
ing, String> nameMap) { |
| 7829 if (elementName != null) { | 8482 if (elementName != null) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7902 * given library, return the type specified by the argument. | 8555 * given library, return the type specified by the argument. |
| 7903 * | 8556 * |
| 7904 * @param library the library in which the specified type would be defined | 8557 * @param library the library in which the specified type would be defined |
| 7905 * @param argumentList the list of arguments from which a type is to be extrac
ted | 8558 * @param argumentList the list of arguments from which a type is to be extrac
ted |
| 7906 * @param nameMap an optional map used to map the element name to a type name | 8559 * @param nameMap an optional map used to map the element name to a type name |
| 7907 * @return the type specified by the first argument in the argument list | 8560 * @return the type specified by the first argument in the argument list |
| 7908 */ | 8561 */ |
| 7909 Type2 getFirstArgumentAsType2(LibraryElement library, ArgumentList argumentLis
t, Map<String, String> nameMap) => getElementNameAsType(library, getFirstArgumen
tAsString(argumentList), nameMap); | 8562 Type2 getFirstArgumentAsType2(LibraryElement library, ArgumentList argumentLis
t, Map<String, String> nameMap) => getElementNameAsType(library, getFirstArgumen
tAsString(argumentList), nameMap); |
| 7910 | 8563 |
| 7911 /** | 8564 /** |
| 7912 * Return the propagated type of the given expression. | |
| 7913 * | |
| 7914 * @param expression the expression whose type is to be returned | |
| 7915 * @return the propagated type of the given expression | |
| 7916 */ | |
| 7917 Type2 getPropagatedType(Expression expression) { | |
| 7918 Type2 type = expression.propagatedType; | |
| 7919 return type; | |
| 7920 } | |
| 7921 | |
| 7922 /** | |
| 7923 * Return the static type of the given expression. | 8565 * Return the static type of the given expression. |
| 7924 * | 8566 * |
| 7925 * @param expression the expression whose type is to be returned | 8567 * @param expression the expression whose type is to be returned |
| 7926 * @return the static type of the given expression | 8568 * @return the static type of the given expression |
| 7927 */ | 8569 */ |
| 7928 Type2 getStaticType(Expression expression) { | 8570 Type2 getStaticType(Expression expression) { |
| 7929 Type2 type = expression.staticType; | 8571 Type2 type = expression.staticType; |
| 7930 if (type == null) { | 8572 if (type == null) { |
| 7931 return _dynamicType; | 8573 return _dynamicType; |
| 7932 } | 8574 } |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8098 if (identical(getStaticType(node.leftOperand), intType) && identical(getSt
aticType(node.rightOperand), intType)) { | 8740 if (identical(getStaticType(node.leftOperand), intType) && identical(getSt
aticType(node.rightOperand), intType)) { |
| 8099 staticType = intType; | 8741 staticType = intType; |
| 8100 } | 8742 } |
| 8101 } | 8743 } |
| 8102 return staticType; | 8744 return staticType; |
| 8103 } | 8745 } |
| 8104 get thisType_J2DAccessor => _thisType; | 8746 get thisType_J2DAccessor => _thisType; |
| 8105 set thisType_J2DAccessor(__v) => _thisType = __v; | 8747 set thisType_J2DAccessor(__v) => _thisType = __v; |
| 8106 } | 8748 } |
| 8107 class GeneralizingASTVisitor_8 extends GeneralizingASTVisitor<Object> { | 8749 class GeneralizingASTVisitor_8 extends GeneralizingASTVisitor<Object> { |
| 8108 final StaticTypeAnalyzer StaticTypeAnalyzer_this; | |
| 8109 List<Type2> result; | 8750 List<Type2> result; |
| 8110 GeneralizingASTVisitor_8(this.StaticTypeAnalyzer_this, this.result) : super(); | 8751 GeneralizingASTVisitor_8(this.result) : super(); |
| 8111 Object visitExpression(Expression node) => null; | 8752 Object visitExpression(Expression node) => null; |
| 8112 Object visitReturnStatement(ReturnStatement node) { | 8753 Object visitReturnStatement(ReturnStatement node) { |
| 8113 Type2 type; | 8754 Type2 type; |
| 8114 Expression expression = node.expression; | 8755 Expression expression = node.expression; |
| 8115 if (expression != null) { | 8756 if (expression != null) { |
| 8116 type = StaticTypeAnalyzer_this.getBestType(expression); | 8757 type = expression.bestType; |
| 8117 } else { | 8758 } else { |
| 8118 type = BottomTypeImpl.instance; | 8759 type = BottomTypeImpl.instance; |
| 8119 } | 8760 } |
| 8120 if (result[0] == null) { | 8761 if (result[0] == null) { |
| 8121 result[0] = type; | 8762 result[0] = type; |
| 8122 } else { | 8763 } else { |
| 8123 result[0] = result[0].getLeastUpperBound(type); | 8764 result[0] = result[0].getLeastUpperBound(type); |
| 8124 } | 8765 } |
| 8125 return null; | 8766 return null; |
| 8126 } | 8767 } |
| (...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8631 } | 9272 } |
| 8632 return null; | 9273 return null; |
| 8633 } | 9274 } |
| 8634 Object visitClassDeclaration(ClassDeclaration node) { | 9275 Object visitClassDeclaration(ClassDeclaration node) { |
| 8635 _hasReferenceToSuper = false; | 9276 _hasReferenceToSuper = false; |
| 8636 super.visitClassDeclaration(node); | 9277 super.visitClassDeclaration(node); |
| 8637 ClassElementImpl classElement = getClassElement(node.name); | 9278 ClassElementImpl classElement = getClassElement(node.name); |
| 8638 InterfaceType superclassType = null; | 9279 InterfaceType superclassType = null; |
| 8639 ExtendsClause extendsClause = node.extendsClause; | 9280 ExtendsClause extendsClause = node.extendsClause; |
| 8640 if (extendsClause != null) { | 9281 if (extendsClause != null) { |
| 8641 ErrorCode errorCode = node.withClause == null ? CompileTimeErrorCode.EXTEN
DS_NON_CLASS : CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS; | 9282 ErrorCode errorCode = (node.withClause == null ? CompileTimeErrorCode.EXTE
NDS_NON_CLASS : CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS) as ErrorCo
de; |
| 8642 superclassType = resolveType(extendsClause.superclass, errorCode, errorCod
e); | 9283 superclassType = resolveType(extendsClause.superclass, errorCode, errorCod
e); |
| 8643 if (superclassType != typeProvider.objectType) { | 9284 if (superclassType != typeProvider.objectType) { |
| 8644 classElement.validMixin = false; | 9285 classElement.validMixin = false; |
| 8645 } | 9286 } |
| 8646 } | 9287 } |
| 8647 if (classElement != null) { | 9288 if (classElement != null) { |
| 8648 if (superclassType == null) { | 9289 if (superclassType == null) { |
| 8649 InterfaceType objectType = typeProvider.objectType; | 9290 InterfaceType objectType = typeProvider.objectType; |
| 8650 if (classElement.type != objectType) { | 9291 if (classElement.type != objectType) { |
| 8651 superclassType = objectType; | 9292 superclassType = objectType; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8819 if (name.name == null) { | 9460 if (name.name == null) { |
| 8820 PrefixedIdentifier prefixedIdentifier = typeName as PrefixedIdentifier
; | 9461 PrefixedIdentifier prefixedIdentifier = typeName as PrefixedIdentifier
; |
| 8821 SimpleIdentifier prefix = prefixedIdentifier.prefix; | 9462 SimpleIdentifier prefix = prefixedIdentifier.prefix; |
| 8822 element = nameScope.lookup(prefix, definingLibrary); | 9463 element = nameScope.lookup(prefix, definingLibrary); |
| 8823 if (element is PrefixElement) { | 9464 if (element is PrefixElement) { |
| 8824 if (parent.parent is InstanceCreationExpression && ((parent.parent a
s InstanceCreationExpression)).isConst) { | 9465 if (parent.parent is InstanceCreationExpression && ((parent.parent a
s InstanceCreationExpression)).isConst) { |
| 8825 reportError(CompileTimeErrorCode.CONST_WITH_NON_TYPE, prefixedIden
tifier.identifier, [prefixedIdentifier.identifier.name]); | 9466 reportError(CompileTimeErrorCode.CONST_WITH_NON_TYPE, prefixedIden
tifier.identifier, [prefixedIdentifier.identifier.name]); |
| 8826 } else { | 9467 } else { |
| 8827 reportError(StaticWarningCode.NEW_WITH_NON_TYPE, prefixedIdentifie
r.identifier, [prefixedIdentifier.identifier.name]); | 9468 reportError(StaticWarningCode.NEW_WITH_NON_TYPE, prefixedIdentifie
r.identifier, [prefixedIdentifier.identifier.name]); |
| 8828 } | 9469 } |
| 9470 setElement(prefix, element); |
| 8829 return null; | 9471 return null; |
| 8830 } else if (element != null) { | 9472 } else if (element != null) { |
| 8831 name.name = prefixedIdentifier.identifier; | 9473 name.name = prefixedIdentifier.identifier; |
| 8832 name.period = prefixedIdentifier.period; | 9474 name.period = prefixedIdentifier.period; |
| 8833 node.name = prefix; | 9475 node.name = prefix; |
| 8834 typeName = prefix; | 9476 typeName = prefix; |
| 8835 } | 9477 } |
| 8836 } | 9478 } |
| 8837 } | 9479 } |
| 8838 } | 9480 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 8867 } else if (isTypeNameTargetInRedirectedConstructor(node)) { | 9509 } else if (isTypeNameTargetInRedirectedConstructor(node)) { |
| 8868 reportError(StaticWarningCode.REDIRECT_TO_NON_CLASS, typeName, [typeName
.name]); | 9510 reportError(StaticWarningCode.REDIRECT_TO_NON_CLASS, typeName, [typeName
.name]); |
| 8869 } else if (isTypeNameInTypeArgumentList(node)) { | 9511 } else if (isTypeNameInTypeArgumentList(node)) { |
| 8870 reportError(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, typeName, [
typeName.name]); | 9512 reportError(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, typeName, [
typeName.name]); |
| 8871 } else { | 9513 } else { |
| 8872 reportError(StaticWarningCode.UNDEFINED_CLASS, typeName, [typeName.name]
); | 9514 reportError(StaticWarningCode.UNDEFINED_CLASS, typeName, [typeName.name]
); |
| 8873 } | 9515 } |
| 8874 elementValid = false; | 9516 elementValid = false; |
| 8875 } | 9517 } |
| 8876 if (!elementValid) { | 9518 if (!elementValid) { |
| 8877 setElement(typeName, _dynamicType.element); | 9519 if (element is MultiplyDefinedElement) { |
| 9520 setElement(typeName, element); |
| 9521 } else { |
| 9522 setElement(typeName, _dynamicType.element); |
| 9523 } |
| 8878 typeName.staticType = _dynamicType; | 9524 typeName.staticType = _dynamicType; |
| 8879 node.type = _dynamicType; | 9525 node.type = _dynamicType; |
| 8880 return null; | 9526 return null; |
| 8881 } | 9527 } |
| 8882 Type2 type = null; | 9528 Type2 type = null; |
| 8883 if (element is ClassElement) { | 9529 if (element is ClassElement) { |
| 8884 setElement(typeName, element); | 9530 setElement(typeName, element); |
| 8885 type = ((element as ClassElement)).type; | 9531 type = ((element as ClassElement)).type; |
| 8886 } else if (element is FunctionTypeAliasElement) { | 9532 } else if (element is FunctionTypeAliasElement) { |
| 8887 setElement(typeName, element); | 9533 setElement(typeName, element); |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9362 * list and associate the created type with the element. | 10008 * list and associate the created type with the element. |
| 9363 * | 10009 * |
| 9364 * @param element the parameter element whose type is to be set | 10010 * @param element the parameter element whose type is to be set |
| 9365 * @param returnType the (possibly `null`) return type of the function | 10011 * @param returnType the (possibly `null`) return type of the function |
| 9366 * @param parameterList the list of parameters to the function | 10012 * @param parameterList the list of parameters to the function |
| 9367 */ | 10013 */ |
| 9368 void setFunctionTypedParameterType(ParameterElementImpl element, TypeName retu
rnType2, FormalParameterList parameterList) { | 10014 void setFunctionTypedParameterType(ParameterElementImpl element, TypeName retu
rnType2, FormalParameterList parameterList) { |
| 9369 List<ParameterElement> parameters = getElements(parameterList); | 10015 List<ParameterElement> parameters = getElements(parameterList); |
| 9370 FunctionTypeAliasElementImpl aliasElement = new FunctionTypeAliasElementImpl
(null); | 10016 FunctionTypeAliasElementImpl aliasElement = new FunctionTypeAliasElementImpl
(null); |
| 9371 aliasElement.synthetic = true; | 10017 aliasElement.synthetic = true; |
| 9372 aliasElement.parameters = parameters; | 10018 aliasElement.shareParameters(parameters); |
| 9373 aliasElement.returnType = computeReturnType(returnType2); | 10019 aliasElement.returnType = computeReturnType(returnType2); |
| 9374 FunctionTypeImpl type = new FunctionTypeImpl.con2(aliasElement); | 10020 FunctionTypeImpl type = new FunctionTypeImpl.con2(aliasElement); |
| 9375 ClassElement definingClass = element.getAncestor(ClassElement); | 10021 ClassElement definingClass = element.getAncestor(ClassElement); |
| 9376 if (definingClass != null) { | 10022 if (definingClass != null) { |
| 9377 aliasElement.typeVariables = definingClass.typeVariables; | 10023 aliasElement.shareTypeVariables(definingClass.typeVariables); |
| 9378 type.typeArguments = definingClass.type.typeArguments; | 10024 type.typeArguments = definingClass.type.typeArguments; |
| 9379 } else { | 10025 } else { |
| 9380 FunctionTypeAliasElement alias = element.getAncestor(FunctionTypeAliasElem
ent); | 10026 FunctionTypeAliasElement alias = element.getAncestor(FunctionTypeAliasElem
ent); |
| 9381 while (alias != null && alias.isSynthetic) { | 10027 while (alias != null && alias.isSynthetic) { |
| 9382 alias = alias.getAncestor(FunctionTypeAliasElement); | 10028 alias = alias.getAncestor(FunctionTypeAliasElement); |
| 9383 } | 10029 } |
| 9384 if (alias != null) { | 10030 if (alias != null) { |
| 9385 aliasElement.typeVariables = alias.typeVariables; | 10031 aliasElement.typeVariables = alias.typeVariables; |
| 9386 type.typeArguments = alias.type.typeArguments; | 10032 type.typeArguments = alias.type.typeArguments; |
| 9387 } else { | 10033 } else { |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9647 } | 10293 } |
| 9648 /** | 10294 /** |
| 9649 * Instances of the class `LibraryImportScope` represent the scope containing al
l of the names | 10295 * Instances of the class `LibraryImportScope` represent the scope containing al
l of the names |
| 9650 * available from imported libraries. | 10296 * available from imported libraries. |
| 9651 * | 10297 * |
| 9652 * @coverage dart.engine.resolver | 10298 * @coverage dart.engine.resolver |
| 9653 */ | 10299 */ |
| 9654 class LibraryImportScope extends Scope { | 10300 class LibraryImportScope extends Scope { |
| 9655 | 10301 |
| 9656 /** | 10302 /** |
| 9657 * @return `true` if the given [Identifier] is the part of type annotation. | |
| 9658 */ | |
| 9659 static bool isTypeAnnotation(Identifier identifier) { | |
| 9660 ASTNode parent = identifier.parent; | |
| 9661 if (parent is TypeName) { | |
| 9662 ASTNode parent2 = parent.parent; | |
| 9663 if (parent2 is FunctionDeclaration) { | |
| 9664 FunctionDeclaration decl = parent2 as FunctionDeclaration; | |
| 9665 return identical(decl.returnType, parent); | |
| 9666 } | |
| 9667 if (parent2 is FunctionTypeAlias) { | |
| 9668 FunctionTypeAlias decl = parent2 as FunctionTypeAlias; | |
| 9669 return identical(decl.returnType, parent); | |
| 9670 } | |
| 9671 if (parent2 is MethodDeclaration) { | |
| 9672 MethodDeclaration decl = parent2 as MethodDeclaration; | |
| 9673 return identical(decl.returnType, parent); | |
| 9674 } | |
| 9675 if (parent2 is VariableDeclarationList) { | |
| 9676 VariableDeclarationList decl = parent2 as VariableDeclarationList; | |
| 9677 return identical(decl.type, parent); | |
| 9678 } | |
| 9679 if (parent2 is SimpleFormalParameter) { | |
| 9680 SimpleFormalParameter decl = parent2 as SimpleFormalParameter; | |
| 9681 return identical(decl.type, parent); | |
| 9682 } | |
| 9683 if (parent2 is TypeParameter) { | |
| 9684 TypeParameter decl = parent2 as TypeParameter; | |
| 9685 return identical(decl.bound, parent); | |
| 9686 } | |
| 9687 if (parent2 is TypeArgumentList) { | |
| 9688 ASTNode parent3 = parent2.parent; | |
| 9689 if (parent3 is TypeName) { | |
| 9690 TypeName typeName = parent3 as TypeName; | |
| 9691 if (identical((typeName).typeArguments, parent2)) { | |
| 9692 return isTypeAnnotation(typeName.name); | |
| 9693 } | |
| 9694 } | |
| 9695 } | |
| 9696 return false; | |
| 9697 } | |
| 9698 return false; | |
| 9699 } | |
| 9700 | |
| 9701 /** | |
| 9702 * The element representing the library in which this scope is enclosed. | 10303 * The element representing the library in which this scope is enclosed. |
| 9703 */ | 10304 */ |
| 9704 LibraryElement _definingLibrary; | 10305 LibraryElement _definingLibrary; |
| 9705 | 10306 |
| 9706 /** | 10307 /** |
| 9707 * The listener that is to be informed when an error is encountered. | 10308 * The listener that is to be informed when an error is encountered. |
| 9708 */ | 10309 */ |
| 9709 AnalysisErrorListener _errorListener; | 10310 AnalysisErrorListener _errorListener; |
| 9710 | 10311 |
| 9711 /** | 10312 /** |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9753 String libName1 = "", libName2 = ""; | 10354 String libName1 = "", libName2 = ""; |
| 9754 List<Element> conflictingMembers = ((foundElement as MultiplyDefinedElemen
tImpl)).conflictingElements; | 10355 List<Element> conflictingMembers = ((foundElement as MultiplyDefinedElemen
tImpl)).conflictingElements; |
| 9755 LibraryElement enclosingLibrary = conflictingMembers[0].getAncestor(Librar
yElement); | 10356 LibraryElement enclosingLibrary = conflictingMembers[0].getAncestor(Librar
yElement); |
| 9756 if (enclosingLibrary != null) { | 10357 if (enclosingLibrary != null) { |
| 9757 libName1 = enclosingLibrary.definingCompilationUnit.displayName; | 10358 libName1 = enclosingLibrary.definingCompilationUnit.displayName; |
| 9758 } | 10359 } |
| 9759 enclosingLibrary = conflictingMembers[1].getAncestor(LibraryElement); | 10360 enclosingLibrary = conflictingMembers[1].getAncestor(LibraryElement); |
| 9760 if (enclosingLibrary != null) { | 10361 if (enclosingLibrary != null) { |
| 9761 libName2 = enclosingLibrary.definingCompilationUnit.displayName; | 10362 libName2 = enclosingLibrary.definingCompilationUnit.displayName; |
| 9762 } | 10363 } |
| 9763 ErrorCode errorCode = isTypeAnnotation(identifier) ? StaticWarningCode.AMB
IGUOUS_IMPORT : CompileTimeErrorCode.AMBIGUOUS_IMPORT; | 10364 _errorListener.onError(new AnalysisError.con2(source, identifier.offset, i
dentifier.length, StaticWarningCode.AMBIGUOUS_IMPORT, [foundEltName, libName1, l
ibName2])); |
| 9764 _errorListener.onError(new AnalysisError.con2(source, identifier.offset, i
dentifier.length, errorCode, [foundEltName, libName1, libName2])); | |
| 9765 return foundElement; | 10365 return foundElement; |
| 9766 } | 10366 } |
| 9767 if (foundElement != null) { | 10367 if (foundElement != null) { |
| 9768 defineWithoutChecking2(name, foundElement); | 10368 defineWithoutChecking2(name, foundElement); |
| 9769 } | 10369 } |
| 9770 return foundElement; | 10370 return foundElement; |
| 9771 } | 10371 } |
| 9772 | 10372 |
| 9773 /** | 10373 /** |
| 9774 * Create all of the namespaces associated with the libraries imported into th
is library. The | 10374 * Create all of the namespaces associated with the libraries imported into th
is library. The |
| (...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10295 * Instances of the class `ConstantVerifier` traverse an AST structure looking f
or additional | 10895 * Instances of the class `ConstantVerifier` traverse an AST structure looking f
or additional |
| 10296 * errors and warnings not covered by the parser and resolver. In particular, it
looks for errors | 10896 * errors and warnings not covered by the parser and resolver. In particular, it
looks for errors |
| 10297 * and warnings related to constant expressions. | 10897 * and warnings related to constant expressions. |
| 10298 * | 10898 * |
| 10299 * @coverage dart.engine.resolver | 10899 * @coverage dart.engine.resolver |
| 10300 */ | 10900 */ |
| 10301 class ConstantVerifier extends RecursiveASTVisitor<Object> { | 10901 class ConstantVerifier extends RecursiveASTVisitor<Object> { |
| 10302 | 10902 |
| 10303 /** | 10903 /** |
| 10304 * The error reporter by which errors will be reported. | 10904 * The error reporter by which errors will be reported. |
| 10305 */ | |
| 10306 ErrorReporter _errorReporter; | |
| 10307 | |
| 10308 /** | |
| 10309 * The type representing the type 'bool'. | |
| 10310 */ | |
| 10311 InterfaceType _boolType; | |
| 10312 | |
| 10313 /** | |
| 10314 * The type representing the type 'int'. | |
| 10315 */ | |
| 10316 InterfaceType _intType; | |
| 10317 | |
| 10318 /** | |
| 10319 * The type representing the type 'num'. | |
| 10320 */ | |
| 10321 InterfaceType _numType; | |
| 10322 | |
| 10323 /** | |
| 10324 * The type representing the type 'string'. | |
| 10325 */ | |
| 10326 InterfaceType _stringType; | |
| 10327 | |
| 10328 /** | |
| 10329 * Initialize a newly created constant verifier. | |
| 10330 * | |
| 10331 * @param errorReporter the error reporter by which errors will be reported | |
| 10332 */ | |
| 10333 ConstantVerifier(ErrorReporter errorReporter, TypeProvider typeProvider) { | |
| 10334 this._errorReporter = errorReporter; | |
| 10335 this._boolType = typeProvider.boolType; | |
| 10336 this._intType = typeProvider.intType; | |
| 10337 this._numType = typeProvider.numType; | |
| 10338 this._stringType = typeProvider.stringType; | |
| 10339 } | |
| 10340 Object visitAnnotation(Annotation node) { | |
| 10341 super.visitAnnotation(node); | |
| 10342 Element element = node.element; | |
| 10343 if (element is ConstructorElement) { | |
| 10344 ConstructorElement constructorElement = element as ConstructorElement; | |
| 10345 if (!constructorElement.isConst) { | |
| 10346 _errorReporter.reportError2(CompileTimeErrorCode.NON_CONSTANT_ANNOTATION
_CONSTRUCTOR, node, []); | |
| 10347 return null; | |
| 10348 } | |
| 10349 ArgumentList argumentList = node.arguments; | |
| 10350 if (argumentList == null) { | |
| 10351 _errorReporter.reportError2(CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCT
OR_ARGUMENTS, node, []); | |
| 10352 return null; | |
| 10353 } | |
| 10354 validateConstantArguments(argumentList); | |
| 10355 } | |
| 10356 return null; | |
| 10357 } | |
| 10358 Object visitConstructorDeclaration(ConstructorDeclaration node) { | |
| 10359 if (node.constKeyword != null) { | |
| 10360 validateInitializers(node); | |
| 10361 } | |
| 10362 validateDefaultValues(node.parameters); | |
| 10363 return super.visitConstructorDeclaration(node); | |
| 10364 } | |
| 10365 Object visitFunctionExpression(FunctionExpression node) { | |
| 10366 super.visitFunctionExpression(node); | |
| 10367 validateDefaultValues(node.parameters); | |
| 10368 return null; | |
| 10369 } | |
| 10370 Object visitInstanceCreationExpression(InstanceCreationExpression node) { | |
| 10371 validateConstantArguments2(node); | |
| 10372 return super.visitInstanceCreationExpression(node); | |
| 10373 } | |
| 10374 Object visitListLiteral(ListLiteral node) { | |
| 10375 super.visitListLiteral(node); | |
| 10376 if (node.modifier != null) { | |
| 10377 for (Expression element in node.elements) { | |
| 10378 validate(element, CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT); | |
| 10379 } | |
| 10380 } | |
| 10381 return null; | |
| 10382 } | |
| 10383 Object visitMapLiteral(MapLiteral node) { | |
| 10384 super.visitMapLiteral(node); | |
| 10385 bool isConst = node.modifier != null; | |
| 10386 bool reportEqualKeys = true; | |
| 10387 Set<Object> keys = new Set<Object>(); | |
| 10388 List<Expression> invalidKeys = new List<Expression>(); | |
| 10389 for (MapLiteralEntry entry in node.entries) { | |
| 10390 Expression key = entry.key; | |
| 10391 if (isConst) { | |
| 10392 EvaluationResultImpl result = validate(key, CompileTimeErrorCode.NON_CON
STANT_MAP_KEY); | |
| 10393 validate(entry.value, CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE); | |
| 10394 if (result is ValidResult) { | |
| 10395 Object value = ((result as ValidResult)).value; | |
| 10396 if (keys.contains(value)) { | |
| 10397 invalidKeys.add(key); | |
| 10398 } else { | |
| 10399 javaSetAdd(keys, value); | |
| 10400 } | |
| 10401 } | |
| 10402 } else { | |
| 10403 EvaluationResultImpl result = key.accept(new ConstantVisitor()); | |
| 10404 if (result is ValidResult) { | |
| 10405 Object value = ((result as ValidResult)).value; | |
| 10406 if (keys.contains(value)) { | |
| 10407 invalidKeys.add(key); | |
| 10408 } else { | |
| 10409 javaSetAdd(keys, value); | |
| 10410 } | |
| 10411 } else { | |
| 10412 reportEqualKeys = false; | |
| 10413 } | |
| 10414 } | |
| 10415 } | |
| 10416 if (reportEqualKeys) { | |
| 10417 for (Expression key in invalidKeys) { | |
| 10418 _errorReporter.reportError2(StaticWarningCode.EQUAL_KEYS_IN_MAP, key, []
); | |
| 10419 } | |
| 10420 } | |
| 10421 return null; | |
| 10422 } | |
| 10423 Object visitMethodDeclaration(MethodDeclaration node) { | |
| 10424 super.visitMethodDeclaration(node); | |
| 10425 validateDefaultValues(node.parameters); | |
| 10426 return null; | |
| 10427 } | |
| 10428 Object visitSwitchCase(SwitchCase node) { | |
| 10429 super.visitSwitchCase(node); | |
| 10430 validate(node.expression, CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION)
; | |
| 10431 return null; | |
| 10432 } | |
| 10433 Object visitVariableDeclaration(VariableDeclaration node) { | |
| 10434 super.visitVariableDeclaration(node); | |
| 10435 Expression initializer = node.initializer; | |
| 10436 if (initializer != null && node.isConst) { | |
| 10437 VariableElementImpl element = node.element as VariableElementImpl; | |
| 10438 EvaluationResultImpl result = element.evaluationResult; | |
| 10439 if (result == null) { | |
| 10440 result = validate(initializer, CompileTimeErrorCode.CONST_INITIALIZED_WI
TH_NON_CONSTANT_VALUE); | |
| 10441 element.evaluationResult = result; | |
| 10442 } else if (result is ErrorResult) { | |
| 10443 reportErrors(result, CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CON
STANT_VALUE); | |
| 10444 } | |
| 10445 } | |
| 10446 return null; | |
| 10447 } | |
| 10448 | |
| 10449 /** | |
| 10450 * Return `true` if the given value is the result of evaluating an expression
whose value is | |
| 10451 * a valid key in a const map literal. Keys in const map literals must be eith
er a string, number, | |
| 10452 * boolean, list, map, or null. | |
| 10453 * | |
| 10454 * @param value | |
| 10455 * @return `true` if the given value is a valid key in a const map literal | |
| 10456 */ | |
| 10457 bool isValidConstMapKey(Object value) => true; | |
| 10458 | |
| 10459 /** | |
| 10460 * If the given result represents one or more errors, report those errors. Exc
ept for special | |
| 10461 * cases, use the given error code rather than the one reported in the error. | |
| 10462 * | |
| 10463 * @param result the result containing any errors that need to be reported | |
| 10464 * @param errorCode the error code to be used if the result represents an erro
r | |
| 10465 */ | |
| 10466 void reportErrors(EvaluationResultImpl result, ErrorCode errorCode2) { | |
| 10467 if (result is ErrorResult) { | |
| 10468 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) { | |
| 10469 ErrorCode dataErrorCode = data.errorCode; | |
| 10470 if (identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCE
PTION) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE)
|| identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRIN
G) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL) || ide
ntical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_INT) || identical(dat
aErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM)) { | |
| 10471 _errorReporter.reportError2(dataErrorCode, data.node, []); | |
| 10472 } else { | |
| 10473 _errorReporter.reportError2(errorCode2, data.node, []); | |
| 10474 } | |
| 10475 } | |
| 10476 } | |
| 10477 } | |
| 10478 | |
| 10479 /** | |
| 10480 * Validate that the given expression is a compile time constant. Return the v
alue of the compile | |
| 10481 * time constant, or `null` if the expression is not a compile time constant. | |
| 10482 * | |
| 10483 * @param expression the expression to be validated | |
| 10484 * @param errorCode the error code to be used if the expression is not a compi
le time constant | |
| 10485 * @return the value of the compile time constant | |
| 10486 */ | |
| 10487 EvaluationResultImpl validate(Expression expression, ErrorCode errorCode) { | |
| 10488 EvaluationResultImpl result = expression.accept(new ConstantVisitor()); | |
| 10489 reportErrors(result, errorCode); | |
| 10490 return result; | |
| 10491 } | |
| 10492 | |
| 10493 /** | |
| 10494 * Validate that if the passed arguments are constant expressions. | |
| 10495 * | |
| 10496 * @param argumentList the argument list to evaluate | |
| 10497 */ | |
| 10498 void validateConstantArguments(ArgumentList argumentList) { | |
| 10499 for (Expression argument in argumentList.arguments) { | |
| 10500 if (argument is NamedExpression) { | |
| 10501 argument = ((argument as NamedExpression)).expression; | |
| 10502 } | |
| 10503 validate(argument, CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT); | |
| 10504 } | |
| 10505 } | |
| 10506 | |
| 10507 /** | |
| 10508 * Validate that if the passed instance creation is 'const' then all its argum
ents are constant | |
| 10509 * expressions. | |
| 10510 * | |
| 10511 * @param node the instance creation evaluate | |
| 10512 */ | |
| 10513 void validateConstantArguments2(InstanceCreationExpression node) { | |
| 10514 if (!node.isConst) { | |
| 10515 return; | |
| 10516 } | |
| 10517 ArgumentList argumentList = node.argumentList; | |
| 10518 if (argumentList == null) { | |
| 10519 return; | |
| 10520 } | |
| 10521 validateConstantArguments(argumentList); | |
| 10522 } | |
| 10523 | |
| 10524 /** | |
| 10525 * Validate that the default value associated with each of the parameters in t
he given list is a | |
| 10526 * compile time constant. | |
| 10527 * | |
| 10528 * @param parameters the list of parameters to be validated | |
| 10529 */ | |
| 10530 void validateDefaultValues(FormalParameterList parameters2) { | |
| 10531 if (parameters2 == null) { | |
| 10532 return; | |
| 10533 } | |
| 10534 for (FormalParameter parameter in parameters2.parameters) { | |
| 10535 if (parameter is DefaultFormalParameter) { | |
| 10536 DefaultFormalParameter defaultParameter = parameter as DefaultFormalPara
meter; | |
| 10537 Expression defaultValue = defaultParameter.defaultValue; | |
| 10538 if (defaultValue != null) { | |
| 10539 EvaluationResultImpl result = validate(defaultValue, CompileTimeErrorC
ode.NON_CONSTANT_DEFAULT_VALUE); | |
| 10540 VariableElementImpl element = parameter.element as VariableElementImpl
; | |
| 10541 element.evaluationResult = result; | |
| 10542 } | |
| 10543 } | |
| 10544 } | |
| 10545 } | |
| 10546 | |
| 10547 /** | |
| 10548 * Validates that the given expression is a compile time constant. | |
| 10549 * | |
| 10550 * @param parameterElements the elements of parameters of constant constructor
, they are | |
| 10551 * considered as a valid potentially constant expressions | |
| 10552 * @param expression the expression to validate | |
| 10553 */ | |
| 10554 void validateInitializerExpression(List<ParameterElement> parameterElements, E
xpression expression) { | |
| 10555 EvaluationResultImpl result = expression.accept(new ConstantVisitor_10(this,
parameterElements)); | |
| 10556 reportErrors(result, CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER)
; | |
| 10557 } | |
| 10558 | |
| 10559 /** | |
| 10560 * Validates that all of the arguments of a constructor initializer are compil
e time constants. | |
| 10561 * | |
| 10562 * @param parameterElements the elements of parameters of constant constructor
, they are | |
| 10563 * considered as a valid potentially constant expressions | |
| 10564 * @param argumentList the argument list to validate | |
| 10565 */ | |
| 10566 void validateInitializerInvocationArguments(List<ParameterElement> parameterEl
ements, ArgumentList argumentList) { | |
| 10567 if (argumentList == null) { | |
| 10568 return; | |
| 10569 } | |
| 10570 for (Expression argument in argumentList.arguments) { | |
| 10571 validateInitializerExpression(parameterElements, argument); | |
| 10572 } | |
| 10573 } | |
| 10574 | |
| 10575 /** | |
| 10576 * Validates that the expressions of the given initializers (of a constant con
structor) are all | |
| 10577 * compile time constants. | |
| 10578 * | |
| 10579 * @param constructor the constant constructor declaration to validate | |
| 10580 */ | |
| 10581 void validateInitializers(ConstructorDeclaration constructor) { | |
| 10582 List<ParameterElement> parameterElements = constructor.parameters.elements; | |
| 10583 NodeList<ConstructorInitializer> initializers = constructor.initializers; | |
| 10584 for (ConstructorInitializer initializer in initializers) { | |
| 10585 if (initializer is ConstructorFieldInitializer) { | |
| 10586 ConstructorFieldInitializer fieldInitializer = initializer as Constructo
rFieldInitializer; | |
| 10587 validateInitializerExpression(parameterElements, fieldInitializer.expres
sion); | |
| 10588 } | |
| 10589 if (initializer is RedirectingConstructorInvocation) { | |
| 10590 RedirectingConstructorInvocation invocation = initializer as Redirecting
ConstructorInvocation; | |
| 10591 validateInitializerInvocationArguments(parameterElements, invocation.arg
umentList); | |
| 10592 } | |
| 10593 if (initializer is SuperConstructorInvocation) { | |
| 10594 SuperConstructorInvocation invocation = initializer as SuperConstructorI
nvocation; | |
| 10595 validateInitializerInvocationArguments(parameterElements, invocation.arg
umentList); | |
| 10596 } | |
| 10597 } | |
| 10598 } | |
| 10599 } | |
| 10600 class ConstantVisitor_10 extends ConstantVisitor { | |
| 10601 final ConstantVerifier ConstantVerifier_this; | |
| 10602 List<ParameterElement> parameterElements; | |
| 10603 ConstantVisitor_10(this.ConstantVerifier_this, this.parameterElements) : super
(); | |
| 10604 EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) { | |
| 10605 Element element = node.element; | |
| 10606 for (ParameterElement parameterElement in parameterElements) { | |
| 10607 if (identical(parameterElement, element) && parameterElement != null) { | |
| 10608 Type2 type = parameterElement.type; | |
| 10609 if (type != null) { | |
| 10610 if (type.isDynamic) { | |
| 10611 return ValidResult.RESULT_DYNAMIC; | |
| 10612 } | |
| 10613 if (type.isSubtypeOf(ConstantVerifier_this._boolType)) { | |
| 10614 return ValidResult.RESULT_BOOL; | |
| 10615 } | |
| 10616 if (type.isSubtypeOf(ConstantVerifier_this._intType)) { | |
| 10617 return ValidResult.RESULT_INT; | |
| 10618 } | |
| 10619 if (type.isSubtypeOf(ConstantVerifier_this._numType)) { | |
| 10620 return ValidResult.RESULT_NUM; | |
| 10621 } | |
| 10622 if (type.isSubtypeOf(ConstantVerifier_this._stringType)) { | |
| 10623 return ValidResult.RESULT_STRING; | |
| 10624 } | |
| 10625 } | |
| 10626 return ValidResult.RESULT_OBJECT; | |
| 10627 } | |
| 10628 } | |
| 10629 return super.visitSimpleIdentifier(node); | |
| 10630 } | |
| 10631 } | |
| 10632 /** | |
| 10633 * Instances of the class `DeadCodeVerifier` traverse an AST structure looking f
or cases of | |
| 10634 * [HintCode#DEAD_CODE]. | |
| 10635 * | |
| 10636 * @coverage dart.engine.resolver | |
| 10637 */ | |
| 10638 class DeadCodeVerifier extends RecursiveASTVisitor<Object> { | |
| 10639 | |
| 10640 /** | |
| 10641 * The error reporter by which errors will be reported. | |
| 10642 */ | 10905 */ |
| 10643 ErrorReporter _errorReporter; | 10906 ErrorReporter _errorReporter; |
| 10644 | 10907 |
| 10645 /** | 10908 /** |
| 10646 * Create a new instance of the [DeadCodeVerifier]. | 10909 * The type representing the type 'bool'. |
| 10647 * | 10910 */ |
| 10648 * @param errorReporter the error reporter | 10911 InterfaceType _boolType; |
| 10649 */ | 10912 |
| 10650 DeadCodeVerifier(ErrorReporter errorReporter) { | 10913 /** |
| 10914 * The type representing the type 'int'. |
| 10915 */ |
| 10916 InterfaceType _intType; |
| 10917 |
| 10918 /** |
| 10919 * The type representing the type 'num'. |
| 10920 */ |
| 10921 InterfaceType _numType; |
| 10922 |
| 10923 /** |
| 10924 * The type representing the type 'string'. |
| 10925 */ |
| 10926 InterfaceType _stringType; |
| 10927 |
| 10928 /** |
| 10929 * Initialize a newly created constant verifier. |
| 10930 * |
| 10931 * @param errorReporter the error reporter by which errors will be reported |
| 10932 */ |
| 10933 ConstantVerifier(ErrorReporter errorReporter, TypeProvider typeProvider) { |
| 10651 this._errorReporter = errorReporter; | 10934 this._errorReporter = errorReporter; |
| 10652 } | 10935 this._boolType = typeProvider.boolType; |
| 10653 Object visitBinaryExpression(BinaryExpression node) { | 10936 this._intType = typeProvider.intType; |
| 10654 sc.Token operator = node.operator; | 10937 this._numType = typeProvider.numType; |
| 10655 bool isAmpAmp = identical(operator.type, sc.TokenType.AMPERSAND_AMPERSAND); | 10938 this._stringType = typeProvider.stringType; |
| 10656 bool isBarBar = identical(operator.type, sc.TokenType.BAR_BAR); | 10939 } |
| 10657 if (isAmpAmp || isBarBar) { | 10940 Object visitAnnotation(Annotation node) { |
| 10658 Expression lhsCondition = node.leftOperand; | 10941 super.visitAnnotation(node); |
| 10659 ValidResult lhsResult = getConstantBooleanValue(lhsCondition); | 10942 Element element = node.element; |
| 10660 if (lhsResult != null) { | 10943 if (element is ConstructorElement) { |
| 10661 if (identical(lhsResult, ValidResult.RESULT_TRUE) && isBarBar) { | 10944 ConstructorElement constructorElement = element as ConstructorElement; |
| 10662 _errorReporter.reportError2(HintCode.DEAD_CODE, node.rightOperand, [])
; | 10945 if (!constructorElement.isConst) { |
| 10663 safelyVisit(lhsCondition); | 10946 _errorReporter.reportError2(CompileTimeErrorCode.NON_CONSTANT_ANNOTATION
_CONSTRUCTOR, node, []); |
| 10664 return null; | |
| 10665 } else if (identical(lhsResult, ValidResult.RESULT_FALSE) && isAmpAmp) { | |
| 10666 _errorReporter.reportError2(HintCode.DEAD_CODE, node.rightOperand, [])
; | |
| 10667 safelyVisit(lhsCondition); | |
| 10668 return null; | |
| 10669 } | |
| 10670 } | |
| 10671 } | |
| 10672 return super.visitBinaryExpression(node); | |
| 10673 } | |
| 10674 | |
| 10675 /** | |
| 10676 * For each [Block], this method reports and error on all statements between t
he end of the | |
| 10677 * block and the first return statement (assuming there it is not at the end o
f the block.) | |
| 10678 * | |
| 10679 * @param node the block to evaluate | |
| 10680 */ | |
| 10681 Object visitBlock(Block node) { | |
| 10682 NodeList<Statement> statements = node.statements; | |
| 10683 int size = statements.length; | |
| 10684 for (int i = 0; i < size; i++) { | |
| 10685 Statement currentStatement = statements[i]; | |
| 10686 safelyVisit(currentStatement); | |
| 10687 if (currentStatement is ReturnStatement && i != size - 1) { | |
| 10688 Statement nextStatement = statements[i + 1]; | |
| 10689 Statement lastStatement = statements[size - 1]; | |
| 10690 int offset = nextStatement.offset; | |
| 10691 int length = lastStatement.end - offset; | |
| 10692 _errorReporter.reportError3(HintCode.DEAD_CODE, offset, length, []); | |
| 10693 return null; | 10947 return null; |
| 10694 } | 10948 } |
| 10695 } | 10949 ArgumentList argumentList = node.arguments; |
| 10696 return null; | 10950 if (argumentList == null) { |
| 10697 } | 10951 _errorReporter.reportError2(CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCT
OR_ARGUMENTS, node, []); |
| 10698 Object visitConditionalExpression(ConditionalExpression node) { | |
| 10699 Expression conditionExpression = node.condition; | |
| 10700 ValidResult result = getConstantBooleanValue(conditionExpression); | |
| 10701 if (result != null) { | |
| 10702 if (identical(result, ValidResult.RESULT_TRUE)) { | |
| 10703 _errorReporter.reportError2(HintCode.DEAD_CODE, node.elseExpression, [])
; | |
| 10704 safelyVisit(node.thenExpression); | |
| 10705 return null; | 10952 return null; |
| 10953 } |
| 10954 validateConstantArguments(argumentList); |
| 10955 } |
| 10956 return null; |
| 10957 } |
| 10958 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 10959 if (node.constKeyword != null) { |
| 10960 validateInitializers(node); |
| 10961 } |
| 10962 validateDefaultValues(node.parameters); |
| 10963 return super.visitConstructorDeclaration(node); |
| 10964 } |
| 10965 Object visitFunctionExpression(FunctionExpression node) { |
| 10966 super.visitFunctionExpression(node); |
| 10967 validateDefaultValues(node.parameters); |
| 10968 return null; |
| 10969 } |
| 10970 Object visitInstanceCreationExpression(InstanceCreationExpression node) { |
| 10971 validateConstantArguments2(node); |
| 10972 return super.visitInstanceCreationExpression(node); |
| 10973 } |
| 10974 Object visitListLiteral(ListLiteral node) { |
| 10975 super.visitListLiteral(node); |
| 10976 if (node.modifier != null) { |
| 10977 for (Expression element in node.elements) { |
| 10978 validate(element, CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT); |
| 10979 } |
| 10980 } |
| 10981 return null; |
| 10982 } |
| 10983 Object visitMapLiteral(MapLiteral node) { |
| 10984 super.visitMapLiteral(node); |
| 10985 bool isConst = node.modifier != null; |
| 10986 bool reportEqualKeys = true; |
| 10987 Set<Object> keys = new Set<Object>(); |
| 10988 List<Expression> invalidKeys = new List<Expression>(); |
| 10989 for (MapLiteralEntry entry in node.entries) { |
| 10990 Expression key = entry.key; |
| 10991 if (isConst) { |
| 10992 EvaluationResultImpl result = validate(key, CompileTimeErrorCode.NON_CON
STANT_MAP_KEY); |
| 10993 validate(entry.value, CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE); |
| 10994 if (result is ValidResult) { |
| 10995 Object value = ((result as ValidResult)).value; |
| 10996 if (keys.contains(value)) { |
| 10997 invalidKeys.add(key); |
| 10998 } else { |
| 10999 javaSetAdd(keys, value); |
| 11000 } |
| 11001 } |
| 10706 } else { | 11002 } else { |
| 10707 _errorReporter.reportError2(HintCode.DEAD_CODE, node.thenExpression, [])
; | 11003 EvaluationResultImpl result = key.accept(new ConstantVisitor()); |
| 10708 safelyVisit(node.elseExpression); | 11004 if (result is ValidResult) { |
| 10709 return null; | 11005 Object value = ((result as ValidResult)).value; |
| 10710 } | 11006 if (keys.contains(value)) { |
| 10711 } | 11007 invalidKeys.add(key); |
| 10712 return super.visitConditionalExpression(node); | 11008 } else { |
| 10713 } | 11009 javaSetAdd(keys, value); |
| 10714 Object visitIfStatement(IfStatement node) { | 11010 } |
| 10715 Expression conditionExpression = node.condition; | 11011 } else { |
| 10716 ValidResult result = getConstantBooleanValue(conditionExpression); | 11012 reportEqualKeys = false; |
| 10717 if (result != null) { | 11013 } |
| 10718 if (identical(result, ValidResult.RESULT_TRUE)) { | 11014 } |
| 10719 Statement elseStatement = node.elseStatement; | 11015 } |
| 10720 if (elseStatement != null) { | 11016 if (reportEqualKeys) { |
| 10721 _errorReporter.reportError2(HintCode.DEAD_CODE, elseStatement, []); | 11017 for (Expression key in invalidKeys) { |
| 10722 safelyVisit(node.thenStatement); | 11018 _errorReporter.reportError2(StaticWarningCode.EQUAL_KEYS_IN_MAP, key, []
); |
| 10723 return null; | 11019 } |
| 10724 } | 11020 } |
| 10725 } else { | 11021 return null; |
| 10726 _errorReporter.reportError2(HintCode.DEAD_CODE, node.thenStatement, []); | 11022 } |
| 10727 safelyVisit(node.elseStatement); | 11023 Object visitMethodDeclaration(MethodDeclaration node) { |
| 10728 return null; | 11024 super.visitMethodDeclaration(node); |
| 10729 } | 11025 validateDefaultValues(node.parameters); |
| 10730 } | 11026 return null; |
| 10731 return super.visitIfStatement(node); | 11027 } |
| 10732 } | 11028 Object visitSwitchCase(SwitchCase node) { |
| 10733 Object visitTryStatement(TryStatement node) { | 11029 super.visitSwitchCase(node); |
| 10734 safelyVisit(node.body); | 11030 validate(node.expression, CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION)
; |
| 10735 safelyVisit(node.finallyClause); | 11031 return null; |
| 10736 NodeList<CatchClause> catchClauses = node.catchClauses; | 11032 } |
| 10737 int numOfCatchClauses = catchClauses.length; | 11033 Object visitVariableDeclaration(VariableDeclaration node) { |
| 10738 List<Type2> visitedTypes = new List<Type2>(); | 11034 super.visitVariableDeclaration(node); |
| 10739 for (int i = 0; i < numOfCatchClauses; i++) { | 11035 Expression initializer = node.initializer; |
| 10740 CatchClause catchClause = catchClauses[i]; | 11036 if (initializer != null && node.isConst) { |
| 10741 if (catchClause.onKeyword != null) { | 11037 VariableElementImpl element = node.element as VariableElementImpl; |
| 10742 TypeName typeName = catchClause.exceptionType; | 11038 EvaluationResultImpl result = element.evaluationResult; |
| 10743 if (typeName != null && typeName.type != null) { | 11039 if (result == null) { |
| 10744 Type2 currentType = typeName.type; | 11040 result = validate(initializer, CompileTimeErrorCode.CONST_INITIALIZED_WI
TH_NON_CONSTANT_VALUE); |
| 10745 if (currentType.isObject) { | 11041 element.evaluationResult = result; |
| 10746 safelyVisit(catchClause); | 11042 } else if (result is ErrorResult) { |
| 10747 if (i + 1 != numOfCatchClauses) { | 11043 reportErrors(result, CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CON
STANT_VALUE); |
| 10748 CatchClause nextCatchClause = catchClauses[i + 1]; | 11044 } |
| 10749 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; | 11045 } |
| 10750 int offset = nextCatchClause.offset; | 11046 return null; |
| 10751 int length = lastCatchClause.end - offset; | 11047 } |
| 10752 _errorReporter.reportError3(HintCode.DEAD_CODE_CATCH_FOLLOWING_CAT
CH, offset, length, []); | 11048 |
| 10753 return null; | 11049 /** |
| 10754 } | 11050 * Return `true` if the given value is the result of evaluating an expression
whose value is |
| 10755 } | 11051 * a valid key in a const map literal. Keys in const map literals must be eith
er a string, number, |
| 10756 for (Type2 type in visitedTypes) { | 11052 * boolean, list, map, or null. |
| 10757 if (currentType.isSubtypeOf(type)) { | 11053 * |
| 10758 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; | 11054 * @param value |
| 10759 int offset = catchClause.offset; | 11055 * @return `true` if the given value is a valid key in a const map literal |
| 10760 int length = lastCatchClause.end - offset; | 11056 */ |
| 10761 _errorReporter.reportError3(HintCode.DEAD_CODE_ON_CATCH_SUBTYPE, o
ffset, length, [currentType.displayName, type.displayName]); | 11057 bool isValidConstMapKey(Object value) => true; |
| 10762 return null; | 11058 |
| 10763 } | 11059 /** |
| 10764 } | 11060 * If the given result represents one or more errors, report those errors. Exc
ept for special |
| 10765 visitedTypes.add(currentType); | 11061 * cases, use the given error code rather than the one reported in the error. |
| 10766 } | 11062 * |
| 10767 safelyVisit(catchClause); | 11063 * @param result the result containing any errors that need to be reported |
| 10768 } else { | 11064 * @param errorCode the error code to be used if the result represents an erro
r |
| 10769 safelyVisit(catchClause); | 11065 */ |
| 10770 if (i + 1 != numOfCatchClauses) { | 11066 void reportErrors(EvaluationResultImpl result, ErrorCode errorCode2) { |
| 10771 CatchClause nextCatchClause = catchClauses[i + 1]; | 11067 if (result is ErrorResult) { |
| 10772 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; | 11068 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) { |
| 10773 int offset = nextCatchClause.offset; | 11069 ErrorCode dataErrorCode = data.errorCode; |
| 10774 int length = lastCatchClause.end - offset; | 11070 if (identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCE
PTION) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE)
|| identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRIN
G) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL) || ide
ntical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_INT) || identical(dat
aErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM)) { |
| 10775 _errorReporter.reportError3(HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH,
offset, length, []); | 11071 _errorReporter.reportError2(dataErrorCode, data.node, []); |
| 10776 return null; | 11072 } else { |
| 10777 } | 11073 _errorReporter.reportError2(errorCode2, data.node, []); |
| 10778 } | 11074 } |
| 10779 } | 11075 } |
| 10780 return null; | 11076 } |
| 10781 } | 11077 } |
| 10782 Object visitWhileStatement(WhileStatement node) { | 11078 |
| 10783 Expression conditionExpression = node.condition; | 11079 /** |
| 10784 safelyVisit(conditionExpression); | 11080 * Validate that the given expression is a compile time constant. Return the v
alue of the compile |
| 10785 ValidResult result = getConstantBooleanValue(conditionExpression); | 11081 * time constant, or `null` if the expression is not a compile time constant. |
| 10786 if (result != null) { | 11082 * |
| 10787 if (identical(result, ValidResult.RESULT_FALSE)) { | 11083 * @param expression the expression to be validated |
| 10788 _errorReporter.reportError2(HintCode.DEAD_CODE, node.body, []); | 11084 * @param errorCode the error code to be used if the expression is not a compi
le time constant |
| 10789 return null; | 11085 * @return the value of the compile time constant |
| 10790 } | 11086 */ |
| 10791 } | 11087 EvaluationResultImpl validate(Expression expression, ErrorCode errorCode) { |
| 10792 safelyVisit(node.body); | 11088 EvaluationResultImpl result = expression.accept(new ConstantVisitor()); |
| 10793 return null; | 11089 reportErrors(result, errorCode); |
| 10794 } | 11090 return result; |
| 10795 | 11091 } |
| 10796 /** | 11092 |
| 10797 * Given some [Expression], this method returns [ValidResult#RESULT_TRUE] if i
t is | 11093 /** |
| 10798 * `true`, [ValidResult#RESULT_FALSE] if it is `false`, or `null` if the | 11094 * Validate that if the passed arguments are constant expressions. |
| 10799 * expression is not a constant boolean value. | 11095 * |
| 10800 * | 11096 * @param argumentList the argument list to evaluate |
| 10801 * @param expression the expression to evaluate | 11097 */ |
| 10802 * @return [ValidResult#RESULT_TRUE] if it is `true`, [ValidResult#RESULT_FALS
E] | 11098 void validateConstantArguments(ArgumentList argumentList) { |
| 10803 * if it is `false`, or `null` if the expression is not a constant boo
lean | 11099 for (Expression argument in argumentList.arguments) { |
| 10804 * value | 11100 if (argument is NamedExpression) { |
| 10805 */ | 11101 argument = ((argument as NamedExpression)).expression; |
| 10806 ValidResult getConstantBooleanValue(Expression expression) { | 11102 } |
| 10807 if (expression is BooleanLiteral) { | 11103 validate(argument, CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT); |
| 10808 if (((expression as BooleanLiteral)).value) { | 11104 } |
| 10809 return ValidResult.RESULT_TRUE; | 11105 } |
| 10810 } else { | 11106 |
| 10811 return ValidResult.RESULT_FALSE; | 11107 /** |
| 10812 } | 11108 * Validate that if the passed instance creation is 'const' then all its argum
ents are constant |
| 10813 } else { | 11109 * expressions. |
| 10814 EvaluationResultImpl result = expression.accept(new ConstantVisitor()); | 11110 * |
| 10815 if (identical(result, ValidResult.RESULT_TRUE)) { | 11111 * @param node the instance creation evaluate |
| 10816 return ValidResult.RESULT_TRUE; | 11112 */ |
| 10817 } else if (identical(result, ValidResult.RESULT_FALSE)) { | 11113 void validateConstantArguments2(InstanceCreationExpression node) { |
| 10818 return ValidResult.RESULT_FALSE; | 11114 if (!node.isConst) { |
| 10819 } | 11115 return; |
| 10820 return null; | 11116 } |
| 10821 } | 11117 ArgumentList argumentList = node.argumentList; |
| 10822 } | 11118 if (argumentList == null) { |
| 10823 | 11119 return; |
| 10824 /** | 11120 } |
| 10825 * If the given node is not `null`, visit this instance of the dead code verif
ier. | 11121 validateConstantArguments(argumentList); |
| 10826 * | 11122 } |
| 10827 * @param node the node to be visited | 11123 |
| 10828 */ | 11124 /** |
| 10829 void safelyVisit(ASTNode node) { | 11125 * Validate that the default value associated with each of the parameters in t
he given list is a |
| 10830 if (node != null) { | 11126 * compile time constant. |
| 10831 node.accept(this); | 11127 * |
| 10832 } | 11128 * @param parameters the list of parameters to be validated |
| 11129 */ |
| 11130 void validateDefaultValues(FormalParameterList parameters2) { |
| 11131 if (parameters2 == null) { |
| 11132 return; |
| 11133 } |
| 11134 for (FormalParameter parameter in parameters2.parameters) { |
| 11135 if (parameter is DefaultFormalParameter) { |
| 11136 DefaultFormalParameter defaultParameter = parameter as DefaultFormalPara
meter; |
| 11137 Expression defaultValue = defaultParameter.defaultValue; |
| 11138 if (defaultValue != null) { |
| 11139 EvaluationResultImpl result = validate(defaultValue, CompileTimeErrorC
ode.NON_CONSTANT_DEFAULT_VALUE); |
| 11140 VariableElementImpl element = parameter.element as VariableElementImpl
; |
| 11141 element.evaluationResult = result; |
| 11142 } |
| 11143 } |
| 11144 } |
| 11145 } |
| 11146 |
| 11147 /** |
| 11148 * Validates that the given expression is a compile time constant. |
| 11149 * |
| 11150 * @param parameterElements the elements of parameters of constant constructor
, they are |
| 11151 * considered as a valid potentially constant expressions |
| 11152 * @param expression the expression to validate |
| 11153 */ |
| 11154 void validateInitializerExpression(List<ParameterElement> parameterElements, E
xpression expression) { |
| 11155 EvaluationResultImpl result = expression.accept(new ConstantVisitor_10(this,
parameterElements)); |
| 11156 reportErrors(result, CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER)
; |
| 11157 } |
| 11158 |
| 11159 /** |
| 11160 * Validates that all of the arguments of a constructor initializer are compil
e time constants. |
| 11161 * |
| 11162 * @param parameterElements the elements of parameters of constant constructor
, they are |
| 11163 * considered as a valid potentially constant expressions |
| 11164 * @param argumentList the argument list to validate |
| 11165 */ |
| 11166 void validateInitializerInvocationArguments(List<ParameterElement> parameterEl
ements, ArgumentList argumentList) { |
| 11167 if (argumentList == null) { |
| 11168 return; |
| 11169 } |
| 11170 for (Expression argument in argumentList.arguments) { |
| 11171 validateInitializerExpression(parameterElements, argument); |
| 11172 } |
| 11173 } |
| 11174 |
| 11175 /** |
| 11176 * Validates that the expressions of the given initializers (of a constant con
structor) are all |
| 11177 * compile time constants. |
| 11178 * |
| 11179 * @param constructor the constant constructor declaration to validate |
| 11180 */ |
| 11181 void validateInitializers(ConstructorDeclaration constructor) { |
| 11182 List<ParameterElement> parameterElements = constructor.parameters.parameterE
lements; |
| 11183 NodeList<ConstructorInitializer> initializers = constructor.initializers; |
| 11184 for (ConstructorInitializer initializer in initializers) { |
| 11185 if (initializer is ConstructorFieldInitializer) { |
| 11186 ConstructorFieldInitializer fieldInitializer = initializer as Constructo
rFieldInitializer; |
| 11187 validateInitializerExpression(parameterElements, fieldInitializer.expres
sion); |
| 11188 } |
| 11189 if (initializer is RedirectingConstructorInvocation) { |
| 11190 RedirectingConstructorInvocation invocation = initializer as Redirecting
ConstructorInvocation; |
| 11191 validateInitializerInvocationArguments(parameterElements, invocation.arg
umentList); |
| 11192 } |
| 11193 if (initializer is SuperConstructorInvocation) { |
| 11194 SuperConstructorInvocation invocation = initializer as SuperConstructorI
nvocation; |
| 11195 validateInitializerInvocationArguments(parameterElements, invocation.arg
umentList); |
| 11196 } |
| 11197 } |
| 11198 } |
| 11199 } |
| 11200 class ConstantVisitor_10 extends ConstantVisitor { |
| 11201 final ConstantVerifier ConstantVerifier_this; |
| 11202 List<ParameterElement> parameterElements; |
| 11203 ConstantVisitor_10(this.ConstantVerifier_this, this.parameterElements) : super
(); |
| 11204 EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) { |
| 11205 Element element = node.element; |
| 11206 for (ParameterElement parameterElement in parameterElements) { |
| 11207 if (identical(parameterElement, element) && parameterElement != null) { |
| 11208 Type2 type = parameterElement.type; |
| 11209 if (type != null) { |
| 11210 if (type.isDynamic) { |
| 11211 return ValidResult.RESULT_DYNAMIC; |
| 11212 } |
| 11213 if (type.isSubtypeOf(ConstantVerifier_this._boolType)) { |
| 11214 return ValidResult.RESULT_BOOL; |
| 11215 } |
| 11216 if (type.isSubtypeOf(ConstantVerifier_this._intType)) { |
| 11217 return ValidResult.RESULT_INT; |
| 11218 } |
| 11219 if (type.isSubtypeOf(ConstantVerifier_this._numType)) { |
| 11220 return ValidResult.RESULT_NUM; |
| 11221 } |
| 11222 if (type.isSubtypeOf(ConstantVerifier_this._stringType)) { |
| 11223 return ValidResult.RESULT_STRING; |
| 11224 } |
| 11225 } |
| 11226 return ValidResult.RESULT_OBJECT; |
| 11227 } |
| 11228 } |
| 11229 return super.visitSimpleIdentifier(node); |
| 10833 } | 11230 } |
| 10834 } | 11231 } |
| 10835 /** | 11232 /** |
| 10836 * Instances of the class `ErrorVerifier` traverse an AST structure looking for
additional | 11233 * Instances of the class `ErrorVerifier` traverse an AST structure looking for
additional |
| 10837 * errors and warnings not covered by the parser and resolver. | 11234 * errors and warnings not covered by the parser and resolver. |
| 10838 * | 11235 * |
| 10839 * @coverage dart.engine.resolver | 11236 * @coverage dart.engine.resolver |
| 10840 */ | 11237 */ |
| 10841 class ErrorVerifier extends RecursiveASTVisitor<Object> { | 11238 class ErrorVerifier extends RecursiveASTVisitor<Object> { |
| 10842 | 11239 |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11038 } | 11435 } |
| 11039 Object visitAssignmentExpression(AssignmentExpression node) { | 11436 Object visitAssignmentExpression(AssignmentExpression node) { |
| 11040 sc.Token operator = node.operator; | 11437 sc.Token operator = node.operator; |
| 11041 sc.TokenType operatorType = operator.type; | 11438 sc.TokenType operatorType = operator.type; |
| 11042 if (identical(operatorType, sc.TokenType.EQ)) { | 11439 if (identical(operatorType, sc.TokenType.EQ)) { |
| 11043 checkForInvalidAssignment2(node.leftHandSide, node.rightHandSide); | 11440 checkForInvalidAssignment2(node.leftHandSide, node.rightHandSide); |
| 11044 } else { | 11441 } else { |
| 11045 checkForInvalidAssignment(node); | 11442 checkForInvalidAssignment(node); |
| 11046 } | 11443 } |
| 11047 checkForAssignmentToFinal(node); | 11444 checkForAssignmentToFinal(node); |
| 11445 checkForArgumentTypeNotAssignable2(node.rightHandSide); |
| 11048 return super.visitAssignmentExpression(node); | 11446 return super.visitAssignmentExpression(node); |
| 11049 } | 11447 } |
| 11050 Object visitBinaryExpression(BinaryExpression node) { | 11448 Object visitBinaryExpression(BinaryExpression node) { |
| 11051 checkForArgumentTypeNotAssignable2(node.rightOperand); | 11449 checkForArgumentTypeNotAssignable2(node.rightOperand); |
| 11052 return super.visitBinaryExpression(node); | 11450 return super.visitBinaryExpression(node); |
| 11053 } | 11451 } |
| 11054 Object visitCatchClause(CatchClause node) { | 11452 Object visitCatchClause(CatchClause node) { |
| 11055 bool previousIsInCatchClause = _isInCatchClause; | 11453 bool previousIsInCatchClause = _isInCatchClause; |
| 11056 try { | 11454 try { |
| 11057 _isInCatchClause = true; | 11455 _isInCatchClause = true; |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11324 return super.visitMethodDeclaration(node); | 11722 return super.visitMethodDeclaration(node); |
| 11325 } finally { | 11723 } finally { |
| 11326 _enclosingFunction = previousFunction; | 11724 _enclosingFunction = previousFunction; |
| 11327 _isInStaticMethod = false; | 11725 _isInStaticMethod = false; |
| 11328 } | 11726 } |
| 11329 } | 11727 } |
| 11330 Object visitMethodInvocation(MethodInvocation node) { | 11728 Object visitMethodInvocation(MethodInvocation node) { |
| 11331 checkForStaticAccessToInstanceMember(node.target, node.methodName); | 11729 checkForStaticAccessToInstanceMember(node.target, node.methodName); |
| 11332 return super.visitMethodInvocation(node); | 11730 return super.visitMethodInvocation(node); |
| 11333 } | 11731 } |
| 11732 Object visitNativeClause(NativeClause node) { |
| 11733 if (!_isInSystemLibrary) { |
| 11734 _errorReporter.reportError2(ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE,
node, []); |
| 11735 } |
| 11736 return super.visitNativeClause(node); |
| 11737 } |
| 11334 Object visitNativeFunctionBody(NativeFunctionBody node) { | 11738 Object visitNativeFunctionBody(NativeFunctionBody node) { |
| 11335 checkForNativeFunctionBodyInNonSDKCode(node); | 11739 checkForNativeFunctionBodyInNonSDKCode(node); |
| 11336 return super.visitNativeFunctionBody(node); | 11740 return super.visitNativeFunctionBody(node); |
| 11337 } | 11741 } |
| 11338 Object visitPostfixExpression(PostfixExpression node) { | 11742 Object visitPostfixExpression(PostfixExpression node) { |
| 11339 checkForAssignmentToFinal2(node.operand); | 11743 checkForAssignmentToFinal2(node.operand); |
| 11744 checkForIntNotAssignable(node.operand); |
| 11340 return super.visitPostfixExpression(node); | 11745 return super.visitPostfixExpression(node); |
| 11341 } | 11746 } |
| 11342 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 11747 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 11343 if (node.parent is! Annotation) { | 11748 if (node.parent is! Annotation) { |
| 11344 checkForStaticAccessToInstanceMember(node.prefix, node.identifier); | 11749 checkForStaticAccessToInstanceMember(node.prefix, node.identifier); |
| 11345 } | 11750 } |
| 11346 return super.visitPrefixedIdentifier(node); | 11751 return super.visitPrefixedIdentifier(node); |
| 11347 } | 11752 } |
| 11348 Object visitPrefixExpression(PrefixExpression node) { | 11753 Object visitPrefixExpression(PrefixExpression node) { |
| 11349 if (node.operator.type.isIncrementOperator) { | 11754 if (node.operator.type.isIncrementOperator) { |
| 11350 checkForAssignmentToFinal2(node.operand); | 11755 checkForAssignmentToFinal2(node.operand); |
| 11351 } | 11756 } |
| 11757 checkForIntNotAssignable(node.operand); |
| 11352 return super.visitPrefixExpression(node); | 11758 return super.visitPrefixExpression(node); |
| 11353 } | 11759 } |
| 11354 Object visitPropertyAccess(PropertyAccess node) { | 11760 Object visitPropertyAccess(PropertyAccess node) { |
| 11355 Expression target = node.realTarget; | 11761 Expression target = node.realTarget; |
| 11356 checkForStaticAccessToInstanceMember(target, node.propertyName); | 11762 checkForStaticAccessToInstanceMember(target, node.propertyName); |
| 11357 return super.visitPropertyAccess(node); | 11763 return super.visitPropertyAccess(node); |
| 11358 } | 11764 } |
| 11359 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation
node) { | 11765 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation
node) { |
| 11360 _isInConstructorInitializer = true; | 11766 _isInConstructorInitializer = true; |
| 11361 try { | 11767 try { |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11850 */ | 12256 */ |
| 11851 bool checkForAllRedirectConstructorErrorCodes(ConstructorDeclaration node) { | 12257 bool checkForAllRedirectConstructorErrorCodes(ConstructorDeclaration node) { |
| 11852 ConstructorName redirectedNode = node.redirectedConstructor; | 12258 ConstructorName redirectedNode = node.redirectedConstructor; |
| 11853 if (redirectedNode == null) { | 12259 if (redirectedNode == null) { |
| 11854 return false; | 12260 return false; |
| 11855 } | 12261 } |
| 11856 ConstructorElement redirectedElement = redirectedNode.element; | 12262 ConstructorElement redirectedElement = redirectedNode.element; |
| 11857 if (redirectedElement == null) { | 12263 if (redirectedElement == null) { |
| 11858 TypeName constructorTypeName = redirectedNode.type; | 12264 TypeName constructorTypeName = redirectedNode.type; |
| 11859 Type2 redirectedType = constructorTypeName.type; | 12265 Type2 redirectedType = constructorTypeName.type; |
| 11860 if (redirectedType != null && redirectedType.element != null && redirected
Type.element != DynamicElementImpl.instance) { | 12266 if (redirectedType != null && redirectedType.element != null && !redirecte
dType.isDynamic) { |
| 11861 String constructorStrName = constructorTypeName.name.name; | 12267 String constructorStrName = constructorTypeName.name.name; |
| 11862 if (redirectedNode.name != null) { | 12268 if (redirectedNode.name != null) { |
| 11863 constructorStrName += ".${redirectedNode.name.name}"; | 12269 constructorStrName += ".${redirectedNode.name.name}"; |
| 11864 } | 12270 } |
| 11865 _errorReporter.reportError2(StaticWarningCode.REDIRECT_TO_MISSING_CONSTR
UCTOR, redirectedNode, [constructorStrName, redirectedType.displayName]); | 12271 _errorReporter.reportError2(StaticWarningCode.REDIRECT_TO_MISSING_CONSTR
UCTOR, redirectedNode, [constructorStrName, redirectedType.displayName]); |
| 11866 return true; | 12272 return true; |
| 11867 } | 12273 } |
| 11868 return false; | 12274 return false; |
| 11869 } | 12275 } |
| 11870 FunctionType redirectedType = redirectedElement.type; | 12276 FunctionType redirectedType = redirectedElement.type; |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12003 return false; | 12409 return false; |
| 12004 } | 12410 } |
| 12005 ErrorCode errorCode; | 12411 ErrorCode errorCode; |
| 12006 if (_isInConstInstanceCreation || _isEnclosingConstructorConst) { | 12412 if (_isInConstInstanceCreation || _isEnclosingConstructorConst) { |
| 12007 errorCode = CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE; | 12413 errorCode = CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE; |
| 12008 } else { | 12414 } else { |
| 12009 errorCode = StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE; | 12415 errorCode = StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE; |
| 12010 } | 12416 } |
| 12011 ParameterElement staticParameterElement = argument.staticParameterElement; | 12417 ParameterElement staticParameterElement = argument.staticParameterElement; |
| 12012 Type2 staticParameterType = staticParameterElement == null ? null : staticPa
rameterElement.type; | 12418 Type2 staticParameterType = staticParameterElement == null ? null : staticPa
rameterElement.type; |
| 12013 ParameterElement propagatedParameterElement = argument.parameterElement; | 12419 ParameterElement propagatedParameterElement = argument.propagatedParameterEl
ement; |
| 12014 Type2 propagatedParameterType = propagatedParameterElement == null ? null :
propagatedParameterElement.type; | 12420 Type2 propagatedParameterType = propagatedParameterElement == null ? null :
propagatedParameterElement.type; |
| 12015 return checkForArgumentTypeNotAssignable3(argument, staticParameterType, pro
pagatedParameterType, errorCode); | 12421 return checkForArgumentTypeNotAssignable3(argument, staticParameterType, pro
pagatedParameterType, errorCode); |
| 12016 } | 12422 } |
| 12017 | 12423 |
| 12018 /** | 12424 /** |
| 12019 * This verifies that the passed expression can be assigned to its correspondi
ng parameters. | 12425 * This verifies that the passed expression can be assigned to its correspondi
ng parameters. |
| 12020 * | 12426 * |
| 12021 * @param expression the expression to evaluate | 12427 * @param expression the expression to evaluate |
| 12022 * @param expectedStaticType the expected static type | 12428 * @param expectedStaticType the expected static type |
| 12023 * @param expectedPropagatedType the expected propagated type, may be `null` | 12429 * @param expectedPropagatedType the expected propagated type, may be `null` |
| 12024 * @return `true` if and only if an error code is generated on the passed node | 12430 * @return `true` if and only if an error code is generated on the passed node |
| 12025 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE | 12431 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE |
| 12026 * @see CompileTimeErrorCode#ARGUMENT_TYPE_NOT_ASSIGNABLE | 12432 * @see CompileTimeErrorCode#ARGUMENT_TYPE_NOT_ASSIGNABLE |
| 12027 */ | 12433 */ |
| 12028 bool checkForArgumentTypeNotAssignable3(Expression expression, Type2 expectedS
taticType, Type2 expectedPropagatedType, ErrorCode errorCode) { | 12434 bool checkForArgumentTypeNotAssignable3(Expression expression, Type2 expectedS
taticType, Type2 expectedPropagatedType, ErrorCode errorCode) => checkForArgumen
tTypeNotAssignable4(expression, expectedStaticType, getStaticType(expression), e
xpectedPropagatedType, expression.propagatedType, errorCode); |
| 12029 Type2 staticArgumentType = getStaticType(expression); | 12435 |
| 12030 if (staticArgumentType == null || expectedStaticType == null) { | 12436 /** |
| 12437 * This verifies that the passed expression can be assigned to its correspondi
ng parameters. |
| 12438 * |
| 12439 * @param expression the expression to evaluate |
| 12440 * @param expectedStaticType the expected static type of the parameter |
| 12441 * @param actualStaticType the actual static type of the argument |
| 12442 * @param expectedPropagatedType the expected propagated type of the parameter
, may be |
| 12443 * `null` |
| 12444 * @param actualPropagatedType the expected propagated type of the parameter,
may be `null` |
| 12445 * @return `true` if and only if an error code is generated on the passed node |
| 12446 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE |
| 12447 * @see CompileTimeErrorCode#ARGUMENT_TYPE_NOT_ASSIGNABLE |
| 12448 */ |
| 12449 bool checkForArgumentTypeNotAssignable4(Expression expression, Type2 expectedS
taticType, Type2 actualStaticType, Type2 expectedPropagatedType, Type2 actualPro
pagatedType, ErrorCode errorCode) { |
| 12450 if (actualStaticType == null || expectedStaticType == null) { |
| 12031 return false; | 12451 return false; |
| 12032 } | 12452 } |
| 12033 if (_strictMode) { | 12453 if (_strictMode) { |
| 12034 if (staticArgumentType.isAssignableTo(expectedStaticType)) { | 12454 if (actualStaticType.isAssignableTo(expectedStaticType)) { |
| 12035 return false; | 12455 return false; |
| 12036 } | 12456 } |
| 12037 _errorReporter.reportError2(errorCode, expression, [ | 12457 _errorReporter.reportError2(errorCode, expression, [ |
| 12038 staticArgumentType.displayName, | 12458 actualStaticType.displayName, |
| 12039 expectedStaticType.displayName]); | 12459 expectedStaticType.displayName]); |
| 12040 return true; | 12460 return true; |
| 12041 } | 12461 } |
| 12042 Type2 propagatedArgumentType = getPropagatedType(expression); | 12462 if (actualPropagatedType == null || expectedPropagatedType == null) { |
| 12043 if (propagatedArgumentType == null || expectedPropagatedType == null) { | 12463 if (actualStaticType.isAssignableTo(expectedStaticType)) { |
| 12044 if (staticArgumentType.isAssignableTo(expectedStaticType)) { | |
| 12045 return false; | 12464 return false; |
| 12046 } | 12465 } |
| 12047 _errorReporter.reportError2(errorCode, expression, [ | 12466 _errorReporter.reportError2(errorCode, expression, [ |
| 12048 staticArgumentType.displayName, | 12467 actualStaticType.displayName, |
| 12049 expectedStaticType.displayName]); | 12468 expectedStaticType.displayName]); |
| 12050 return true; | 12469 return true; |
| 12051 } | 12470 } |
| 12052 if (staticArgumentType.isAssignableTo(expectedStaticType) || staticArgumentT
ype.isAssignableTo(expectedPropagatedType) || propagatedArgumentType.isAssignabl
eTo(expectedStaticType) || propagatedArgumentType.isAssignableTo(expectedPropaga
tedType)) { | 12471 if (actualStaticType.isAssignableTo(expectedStaticType) || actualStaticType.
isAssignableTo(expectedPropagatedType) || actualPropagatedType.isAssignableTo(ex
pectedStaticType) || actualPropagatedType.isAssignableTo(expectedPropagatedType)
) { |
| 12053 return false; | 12472 return false; |
| 12054 } | 12473 } |
| 12055 _errorReporter.reportError2(errorCode, expression, [ | 12474 _errorReporter.reportError2(errorCode, expression, [ |
| 12056 (propagatedArgumentType == null ? staticArgumentType : propagatedArgumen
tType).displayName, | 12475 (actualPropagatedType == null ? actualStaticType : actualPropagatedType)
.displayName, |
| 12057 (expectedPropagatedType == null ? expectedStaticType : expectedPropagate
dType).displayName]); | 12476 (expectedPropagatedType == null ? expectedStaticType : expectedPropagate
dType).displayName]); |
| 12058 return true; | 12477 return true; |
| 12059 } | 12478 } |
| 12060 | 12479 |
| 12061 /** | 12480 /** |
| 12062 * This verifies that left hand side of the passed assignment expression is no
t final. | 12481 * This verifies that left hand side of the passed assignment expression is no
t final. |
| 12063 * | 12482 * |
| 12064 * @param node the assignment expression to evaluate | 12483 * @param node the assignment expression to evaluate |
| 12065 * @return `true` if and only if an error code is generated on the passed node | 12484 * @return `true` if and only if an error code is generated on the passed node |
| 12066 * @see StaticWarningCode#ASSIGNMENT_TO_FINAL | 12485 * @see StaticWarningCode#ASSIGNMENT_TO_FINAL |
| 12067 */ | 12486 */ |
| 12068 bool checkForAssignmentToFinal(AssignmentExpression node) { | 12487 bool checkForAssignmentToFinal(AssignmentExpression node) { |
| 12069 Expression leftExpression = node.leftHandSide; | 12488 Expression leftExpression = node.leftHandSide; |
| 12070 return checkForAssignmentToFinal2(leftExpression); | 12489 return checkForAssignmentToFinal2(leftExpression); |
| 12071 } | 12490 } |
| 12072 | 12491 |
| 12073 /** | 12492 /** |
| 12074 * This verifies that the passed expression is not final. | 12493 * This verifies that the passed expression is not final. |
| 12075 * | 12494 * |
| 12076 * @param node the expression to evaluate | 12495 * @param node the expression to evaluate |
| 12077 * @return `true` if and only if an error code is generated on the passed node | 12496 * @return `true` if and only if an error code is generated on the passed node |
| 12497 * @see StaticWarningCode#ASSIGNMENT_TO_CONST |
| 12078 * @see StaticWarningCode#ASSIGNMENT_TO_FINAL | 12498 * @see StaticWarningCode#ASSIGNMENT_TO_FINAL |
| 12079 * @see StaticWarningCode#ASSIGNMENT_TO_METHOD | 12499 * @see StaticWarningCode#ASSIGNMENT_TO_METHOD |
| 12080 */ | 12500 */ |
| 12081 bool checkForAssignmentToFinal2(Expression expression) { | 12501 bool checkForAssignmentToFinal2(Expression expression) { |
| 12082 Element element = null; | 12502 Element element = null; |
| 12083 if (expression is Identifier) { | 12503 if (expression is Identifier) { |
| 12084 element = ((expression as Identifier)).element; | 12504 element = ((expression as Identifier)).element; |
| 12085 } | 12505 } |
| 12086 if (expression is PropertyAccess) { | 12506 if (expression is PropertyAccess) { |
| 12087 element = ((expression as PropertyAccess)).propertyName.element; | 12507 element = ((expression as PropertyAccess)).propertyName.element; |
| 12088 } | 12508 } |
| 12509 if (element is PropertyAccessorElement) { |
| 12510 PropertyAccessorElement accessor = element as PropertyAccessorElement; |
| 12511 element = accessor.variable; |
| 12512 } |
| 12089 if (element is VariableElement) { | 12513 if (element is VariableElement) { |
| 12090 VariableElement leftVar = element as VariableElement; | 12514 VariableElement variable = element as VariableElement; |
| 12091 if (leftVar.isFinal) { | 12515 if (variable.isConst) { |
| 12516 _errorReporter.reportError2(StaticWarningCode.ASSIGNMENT_TO_CONST, expre
ssion, []); |
| 12517 return true; |
| 12518 } |
| 12519 if (variable.isFinal) { |
| 12092 _errorReporter.reportError2(StaticWarningCode.ASSIGNMENT_TO_FINAL, expre
ssion, []); | 12520 _errorReporter.reportError2(StaticWarningCode.ASSIGNMENT_TO_FINAL, expre
ssion, []); |
| 12093 return true; | 12521 return true; |
| 12094 } | 12522 } |
| 12095 return false; | |
| 12096 } | |
| 12097 if (element is PropertyAccessorElement) { | |
| 12098 PropertyAccessorElement leftAccessor = element as PropertyAccessorElement; | |
| 12099 if (!leftAccessor.isSetter) { | |
| 12100 _errorReporter.reportError2(StaticWarningCode.ASSIGNMENT_TO_FINAL, expre
ssion, []); | |
| 12101 return true; | |
| 12102 } | |
| 12103 return false; | 12523 return false; |
| 12104 } | 12524 } |
| 12105 if (element is MethodElement) { | 12525 if (element is MethodElement) { |
| 12106 _errorReporter.reportError2(StaticWarningCode.ASSIGNMENT_TO_METHOD, expres
sion, []); | 12526 _errorReporter.reportError2(StaticWarningCode.ASSIGNMENT_TO_METHOD, expres
sion, []); |
| 12107 return true; | 12527 return true; |
| 12108 } | 12528 } |
| 12109 return false; | 12529 return false; |
| 12110 } | 12530 } |
| 12111 | 12531 |
| 12112 /** | 12532 /** |
| (...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12857 if (staticType.isAssignableTo(fieldType)) { | 13277 if (staticType.isAssignableTo(fieldType)) { |
| 12858 return false; | 13278 return false; |
| 12859 } else if (_strictMode) { | 13279 } else if (_strictMode) { |
| 12860 if (_isEnclosingConstructorConst) { | 13280 if (_isEnclosingConstructorConst) { |
| 12861 _errorReporter.reportError2(CompileTimeErrorCode.CONST_FIELD_INITIALIZER
_NOT_ASSIGNABLE, expression, [staticType.displayName, fieldType.displayName]); | 13281 _errorReporter.reportError2(CompileTimeErrorCode.CONST_FIELD_INITIALIZER
_NOT_ASSIGNABLE, expression, [staticType.displayName, fieldType.displayName]); |
| 12862 } else { | 13282 } else { |
| 12863 _errorReporter.reportError2(StaticWarningCode.FIELD_INITIALIZER_NOT_ASSI
GNABLE, expression, [staticType.displayName, fieldType.displayName]); | 13283 _errorReporter.reportError2(StaticWarningCode.FIELD_INITIALIZER_NOT_ASSI
GNABLE, expression, [staticType.displayName, fieldType.displayName]); |
| 12864 } | 13284 } |
| 12865 return true; | 13285 return true; |
| 12866 } | 13286 } |
| 12867 Type2 propagatedType = getPropagatedType(expression); | 13287 Type2 propagatedType = expression.propagatedType; |
| 12868 if (propagatedType != null && propagatedType.isAssignableTo(fieldType)) { | 13288 if (propagatedType != null && propagatedType.isAssignableTo(fieldType)) { |
| 12869 return false; | 13289 return false; |
| 12870 } | 13290 } |
| 12871 if (_isEnclosingConstructorConst) { | 13291 if (_isEnclosingConstructorConst) { |
| 12872 _errorReporter.reportError2(CompileTimeErrorCode.CONST_FIELD_INITIALIZER_N
OT_ASSIGNABLE, expression, [ | 13292 _errorReporter.reportError2(CompileTimeErrorCode.CONST_FIELD_INITIALIZER_N
OT_ASSIGNABLE, expression, [ |
| 12873 (propagatedType == null ? staticType : propagatedType).displayName, | 13293 (propagatedType == null ? staticType : propagatedType).displayName, |
| 12874 fieldType.displayName]); | 13294 fieldType.displayName]); |
| 12875 } else { | 13295 } else { |
| 12876 _errorReporter.reportError2(StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGN
ABLE, expression, [ | 13296 _errorReporter.reportError2(StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGN
ABLE, expression, [ |
| 12877 (propagatedType == null ? staticType : propagatedType).displayName, | 13297 (propagatedType == null ? staticType : propagatedType).displayName, |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13106 */ | 13526 */ |
| 13107 bool checkForInconsistentCaseExpressionTypes(SwitchStatement node) { | 13527 bool checkForInconsistentCaseExpressionTypes(SwitchStatement node) { |
| 13108 NodeList<SwitchMember> switchMembers = node.members; | 13528 NodeList<SwitchMember> switchMembers = node.members; |
| 13109 bool foundError = false; | 13529 bool foundError = false; |
| 13110 Type2 firstType = null; | 13530 Type2 firstType = null; |
| 13111 for (SwitchMember switchMember in switchMembers) { | 13531 for (SwitchMember switchMember in switchMembers) { |
| 13112 if (switchMember is SwitchCase) { | 13532 if (switchMember is SwitchCase) { |
| 13113 SwitchCase switchCase = switchMember as SwitchCase; | 13533 SwitchCase switchCase = switchMember as SwitchCase; |
| 13114 Expression expression = switchCase.expression; | 13534 Expression expression = switchCase.expression; |
| 13115 if (firstType == null) { | 13535 if (firstType == null) { |
| 13116 firstType = getBestType(expression); | 13536 firstType = expression.bestType; |
| 13117 } else { | 13537 } else { |
| 13118 Type2 nType = getBestType(expression); | 13538 Type2 nType = expression.bestType; |
| 13119 if (firstType != nType) { | 13539 if (firstType != nType) { |
| 13120 _errorReporter.reportError2(CompileTimeErrorCode.INCONSISTENT_CASE_E
XPRESSION_TYPES, expression, [expression.toSource(), firstType.displayName]); | 13540 _errorReporter.reportError2(CompileTimeErrorCode.INCONSISTENT_CASE_E
XPRESSION_TYPES, expression, [expression.toSource(), firstType.displayName]); |
| 13121 foundError = true; | 13541 foundError = true; |
| 13122 } | 13542 } |
| 13123 } | 13543 } |
| 13124 } | 13544 } |
| 13125 } | 13545 } |
| 13126 if (!foundError) { | 13546 if (!foundError) { |
| 13127 checkForCaseExpressionTypeImplementsEquals(node, firstType); | 13547 checkForCaseExpressionTypeImplementsEquals(node, firstType); |
| 13128 } | 13548 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 13142 if (errors == null || errors.isEmpty) { | 13562 if (errors == null || errors.isEmpty) { |
| 13143 return false; | 13563 return false; |
| 13144 } | 13564 } |
| 13145 for (AnalysisError error in errors) { | 13565 for (AnalysisError error in errors) { |
| 13146 _errorReporter.reportError(error); | 13566 _errorReporter.reportError(error); |
| 13147 } | 13567 } |
| 13148 return true; | 13568 return true; |
| 13149 } | 13569 } |
| 13150 | 13570 |
| 13151 /** | 13571 /** |
| 13572 * This verifies that an 'int' can be assigned to the parameter corresponding
to the given |
| 13573 * expression. This is used for prefix and postfix expressions where the argum
ent value is |
| 13574 * implicit. |
| 13575 * |
| 13576 * @param argument the expression to which the operator is being applied |
| 13577 * @return `true` if and only if an error code is generated on the passed node |
| 13578 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE |
| 13579 * @see CompileTimeErrorCode#ARGUMENT_TYPE_NOT_ASSIGNABLE |
| 13580 */ |
| 13581 bool checkForIntNotAssignable(Expression argument) { |
| 13582 if (argument == null) { |
| 13583 return false; |
| 13584 } |
| 13585 ErrorCode errorCode; |
| 13586 if (_isInConstInstanceCreation || _isEnclosingConstructorConst) { |
| 13587 errorCode = CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE; |
| 13588 } else { |
| 13589 errorCode = StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE; |
| 13590 } |
| 13591 ParameterElement staticParameterElement = argument.staticParameterElement; |
| 13592 Type2 staticParameterType = staticParameterElement == null ? null : staticPa
rameterElement.type; |
| 13593 ParameterElement propagatedParameterElement = argument.propagatedParameterEl
ement; |
| 13594 Type2 propagatedParameterType = propagatedParameterElement == null ? null :
propagatedParameterElement.type; |
| 13595 return checkForArgumentTypeNotAssignable4(argument, staticParameterType, _ty
peProvider.intType, propagatedParameterType, _typeProvider.intType, errorCode); |
| 13596 } |
| 13597 |
| 13598 /** |
| 13152 * Given an assignment using a compound assignment operator, this verifies tha
t the given | 13599 * Given an assignment using a compound assignment operator, this verifies tha
t the given |
| 13153 * assignment is valid. | 13600 * assignment is valid. |
| 13154 * | 13601 * |
| 13155 * @param node the assignment expression being tested | 13602 * @param node the assignment expression being tested |
| 13156 * @return `true` if and only if an error code is generated on the passed node | 13603 * @return `true` if and only if an error code is generated on the passed node |
| 13157 * @see StaticTypeWarningCode#INVALID_ASSIGNMENT | 13604 * @see StaticTypeWarningCode#INVALID_ASSIGNMENT |
| 13158 */ | 13605 */ |
| 13159 bool checkForInvalidAssignment(AssignmentExpression node) { | 13606 bool checkForInvalidAssignment(AssignmentExpression node) { |
| 13160 Expression lhs = node.leftHandSide; | 13607 Expression lhs = node.leftHandSide; |
| 13161 if (lhs == null) { | 13608 if (lhs == null) { |
| 13162 return false; | 13609 return false; |
| 13163 } | 13610 } |
| 13164 VariableElement leftElement = getVariableElement(lhs); | 13611 VariableElement leftElement = getVariableElement(lhs); |
| 13165 Type2 leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.ty
pe; | 13612 Type2 leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.ty
pe; |
| 13166 MethodElement invokedMethod = node.element; | 13613 MethodElement invokedMethod = node.staticElement; |
| 13167 if (invokedMethod == null) { | 13614 if (invokedMethod == null) { |
| 13168 return false; | 13615 return false; |
| 13169 } | 13616 } |
| 13170 Type2 rightType = invokedMethod.type.returnType; | 13617 Type2 rightType = invokedMethod.type.returnType; |
| 13171 if (leftType == null || rightType == null) { | 13618 if (leftType == null || rightType == null) { |
| 13172 return false; | 13619 return false; |
| 13173 } | 13620 } |
| 13174 if (!rightType.isAssignableTo(leftType)) { | 13621 if (!rightType.isAssignableTo(leftType)) { |
| 13175 _errorReporter.reportError2(StaticTypeWarningCode.INVALID_ASSIGNMENT, node
.rightHandSide, [rightType.displayName, leftType.displayName]); | 13622 _errorReporter.reportError2(StaticTypeWarningCode.INVALID_ASSIGNMENT, node
.rightHandSide, [rightType.displayName, leftType.displayName]); |
| 13176 return true; | 13623 return true; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 13187 * @see StaticTypeWarningCode#INVALID_ASSIGNMENT | 13634 * @see StaticTypeWarningCode#INVALID_ASSIGNMENT |
| 13188 */ | 13635 */ |
| 13189 bool checkForInvalidAssignment2(Expression lhs, Expression rhs) { | 13636 bool checkForInvalidAssignment2(Expression lhs, Expression rhs) { |
| 13190 if (lhs == null || rhs == null) { | 13637 if (lhs == null || rhs == null) { |
| 13191 return false; | 13638 return false; |
| 13192 } | 13639 } |
| 13193 VariableElement leftElement = getVariableElement(lhs); | 13640 VariableElement leftElement = getVariableElement(lhs); |
| 13194 Type2 leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.ty
pe; | 13641 Type2 leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.ty
pe; |
| 13195 Type2 staticRightType = getStaticType(rhs); | 13642 Type2 staticRightType = getStaticType(rhs); |
| 13196 bool isStaticAssignable = staticRightType.isAssignableTo(leftType); | 13643 bool isStaticAssignable = staticRightType.isAssignableTo(leftType); |
| 13197 Type2 propagatedRightType = getPropagatedType(rhs); | 13644 Type2 propagatedRightType = rhs.propagatedType; |
| 13198 if (_strictMode || propagatedRightType == null) { | 13645 if (_strictMode || propagatedRightType == null) { |
| 13199 if (!isStaticAssignable) { | 13646 if (!isStaticAssignable) { |
| 13200 _errorReporter.reportError2(StaticTypeWarningCode.INVALID_ASSIGNMENT, rh
s, [staticRightType.displayName, leftType.displayName]); | 13647 _errorReporter.reportError2(StaticTypeWarningCode.INVALID_ASSIGNMENT, rh
s, [staticRightType.displayName, leftType.displayName]); |
| 13201 return true; | 13648 return true; |
| 13202 } | 13649 } |
| 13203 } else { | 13650 } else { |
| 13204 bool isPropagatedAssignable = propagatedRightType.isAssignableTo(leftType)
; | 13651 bool isPropagatedAssignable = propagatedRightType.isAssignableTo(leftType)
; |
| 13205 if (!isStaticAssignable && !isPropagatedAssignable) { | 13652 if (!isStaticAssignable && !isPropagatedAssignable) { |
| 13206 _errorReporter.reportError2(StaticTypeWarningCode.INVALID_ASSIGNMENT, rh
s, [staticRightType.displayName, leftType.displayName]); | 13653 _errorReporter.reportError2(StaticTypeWarningCode.INVALID_ASSIGNMENT, rh
s, [staticRightType.displayName, leftType.displayName]); |
| 13207 return true; | 13654 return true; |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13567 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE | 14014 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE |
| 13568 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO | 14015 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO |
| 13569 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE | 14016 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE |
| 13570 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR | 14017 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR |
| 13571 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLU
S | 14018 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLU
S |
| 13572 */ | 14019 */ |
| 13573 bool checkForNonAbstractClassInheritsAbstractMember(ClassDeclaration node) { | 14020 bool checkForNonAbstractClassInheritsAbstractMember(ClassDeclaration node) { |
| 13574 if (_enclosingClass.isAbstract) { | 14021 if (_enclosingClass.isAbstract) { |
| 13575 return false; | 14022 return false; |
| 13576 } | 14023 } |
| 13577 Set<ExecutableElement> missingOverrides = new Set<ExecutableElement>(); | 14024 List<MethodElement> methods = _enclosingClass.methods; |
| 14025 List<PropertyAccessorElement> accessors = _enclosingClass.accessors; |
| 13578 Set<String> methodsInEnclosingClass = new Set<String>(); | 14026 Set<String> methodsInEnclosingClass = new Set<String>(); |
| 13579 Set<String> accessorsInEnclosingClass = new Set<String>(); | 14027 Set<String> accessorsInEnclosingClass = new Set<String>(); |
| 13580 List<MethodElement> methods = _enclosingClass.methods; | |
| 13581 for (MethodElement method in methods) { | 14028 for (MethodElement method in methods) { |
| 13582 javaSetAdd(methodsInEnclosingClass, method.name); | 14029 javaSetAdd(methodsInEnclosingClass, method.name); |
| 13583 } | 14030 } |
| 13584 List<PropertyAccessorElement> accessors = _enclosingClass.accessors; | |
| 13585 for (PropertyAccessorElement accessor in accessors) { | 14031 for (PropertyAccessorElement accessor in accessors) { |
| 13586 javaSetAdd(accessorsInEnclosingClass, accessor.name); | 14032 javaSetAdd(accessorsInEnclosingClass, accessor.name); |
| 13587 } | 14033 } |
| 14034 if (methodsInEnclosingClass.contains(ElementResolver.NO_SUCH_METHOD_METHOD_N
AME)) { |
| 14035 return false; |
| 14036 } |
| 14037 Set<ExecutableElement> missingOverrides = new Set<ExecutableElement>(); |
| 14038 Map<String, ExecutableElement> membersInheritedFromInterfaces = _inheritance
Manager.getMapOfMembersInheritedFromInterfaces(_enclosingClass); |
| 13588 Map<String, ExecutableElement> membersInheritedFromSuperclasses = _inheritan
ceManager.getMapOfMembersInheritedFromClasses(_enclosingClass); | 14039 Map<String, ExecutableElement> membersInheritedFromSuperclasses = _inheritan
ceManager.getMapOfMembersInheritedFromClasses(_enclosingClass); |
| 13589 for (MapEntry<String, ExecutableElement> entry in getMapEntrySet(membersInhe
ritedFromSuperclasses)) { | |
| 13590 ExecutableElement executableElt = entry.getValue(); | |
| 13591 if (executableElt is MethodElement) { | |
| 13592 MethodElement methodElt = executableElt as MethodElement; | |
| 13593 if (methodElt.isAbstract) { | |
| 13594 String methodName = entry.getKey(); | |
| 13595 if (!methodsInEnclosingClass.contains(methodName)) { | |
| 13596 javaSetAdd(missingOverrides, executableElt); | |
| 13597 } | |
| 13598 } | |
| 13599 } else if (executableElt is PropertyAccessorElement) { | |
| 13600 PropertyAccessorElement propertyAccessorElt = executableElt as PropertyA
ccessorElement; | |
| 13601 if (propertyAccessorElt.isAbstract) { | |
| 13602 String accessorName = entry.getKey(); | |
| 13603 if (!accessorsInEnclosingClass.contains(accessorName)) { | |
| 13604 javaSetAdd(missingOverrides, executableElt); | |
| 13605 } | |
| 13606 } | |
| 13607 } | |
| 13608 } | |
| 13609 Map<String, ExecutableElement> membersInheritedFromInterfaces = _inheritance
Manager.getMapOfMembersInheritedFromInterfaces(_enclosingClass); | |
| 13610 for (MapEntry<String, ExecutableElement> entry in getMapEntrySet(membersInhe
ritedFromInterfaces)) { | 14040 for (MapEntry<String, ExecutableElement> entry in getMapEntrySet(membersInhe
ritedFromInterfaces)) { |
| 13611 ExecutableElement executableElt = entry.getValue(); | 14041 ExecutableElement executableElt = entry.getValue(); |
| 13612 ExecutableElement elt = membersInheritedFromSuperclasses[executableElt.nam
e]; | 14042 ExecutableElement elt = membersInheritedFromSuperclasses[executableElt.nam
e]; |
| 13613 if (elt != null) { | 14043 if (elt != null) { |
| 13614 if (elt is MethodElement && !((elt as MethodElement)).isAbstract) { | 14044 if (elt is MethodElement && !((elt as MethodElement)).isAbstract) { |
| 13615 continue; | 14045 continue; |
| 13616 } else if (elt is PropertyAccessorElement && !((elt as PropertyAccessorE
lement)).isAbstract) { | 14046 } else if (elt is PropertyAccessorElement && !((elt as PropertyAccessorE
lement)).isAbstract) { |
| 13617 continue; | 14047 continue; |
| 13618 } | 14048 } |
| 13619 } | 14049 } |
| 13620 if (executableElt is MethodElement) { | 14050 if (executableElt is MethodElement) { |
| 13621 String methodName = entry.getKey(); | 14051 String methodName = entry.getKey(); |
| 13622 if (!methodsInEnclosingClass.contains(methodName)) { | 14052 if (!methodsInEnclosingClass.contains(methodName) && !memberHasConcreteM
ethodImplementationInSuperclassChain(_enclosingClass, methodName, new List<Class
Element>())) { |
| 13623 javaSetAdd(missingOverrides, executableElt); | 14053 javaSetAdd(missingOverrides, executableElt); |
| 13624 } | 14054 } |
| 13625 } else if (executableElt is PropertyAccessorElement) { | 14055 } else if (executableElt is PropertyAccessorElement) { |
| 13626 String accessorName = entry.getKey(); | 14056 String accessorName = entry.getKey(); |
| 13627 if (!accessorsInEnclosingClass.contains(accessorName)) { | 14057 if (!accessorsInEnclosingClass.contains(accessorName) && !memberHasConcr
eteAccessorImplementationInSuperclassChain(_enclosingClass, accessorName, new Li
st<ClassElement>())) { |
| 13628 javaSetAdd(missingOverrides, executableElt); | 14058 javaSetAdd(missingOverrides, executableElt); |
| 13629 } | 14059 } |
| 13630 } | 14060 } |
| 13631 } | 14061 } |
| 13632 int missingOverridesSize = missingOverrides.length; | 14062 int missingOverridesSize = missingOverrides.length; |
| 13633 if (missingOverridesSize == 0) { | 14063 if (missingOverridesSize == 0) { |
| 13634 return false; | 14064 return false; |
| 13635 } | 14065 } |
| 13636 List<ExecutableElement> missingOverridesArray = new List.from(missingOverrid
es); | 14066 List<ExecutableElement> missingOverridesArray = new List.from(missingOverrid
es); |
| 13637 List<String> stringMembersArrayListSet = new List<String>(); | 14067 List<String> stringMembersArrayListSet = new List<String>(); |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13898 JavaStringBuilder builder = new JavaStringBuilder(); | 14328 JavaStringBuilder builder = new JavaStringBuilder(); |
| 13899 for (int i = 0; i < listLength; i++) { | 14329 for (int i = 0; i < listLength; i++) { |
| 13900 builder.append(list[i].displayName); | 14330 builder.append(list[i].displayName); |
| 13901 if (i != listLength - 1) { | 14331 if (i != listLength - 1) { |
| 13902 builder.append(separator); | 14332 builder.append(separator); |
| 13903 } | 14333 } |
| 13904 } | 14334 } |
| 13905 _errorReporter.reportError3(CompileTimeErrorCode.RECURSIVE_INTERFACE_INH
ERITANCE, _enclosingClass.nameOffset, enclosingClassName.length, [enclosingClass
Name, builder.toString()]); | 14335 _errorReporter.reportError3(CompileTimeErrorCode.RECURSIVE_INTERFACE_INH
ERITANCE, _enclosingClass.nameOffset, enclosingClassName.length, [enclosingClass
Name, builder.toString()]); |
| 13906 return true; | 14336 return true; |
| 13907 } else if (list.length == 2) { | 14337 } else if (list.length == 2) { |
| 13908 ErrorCode errorCode = supertype != null && _enclosingClass == supertype.
element ? CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS
: CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS; | 14338 ErrorCode errorCode = (supertype != null && _enclosingClass == supertype
.element ? CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTEND
S : CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS) a
s ErrorCode; |
| 13909 _errorReporter.reportError3(errorCode, _enclosingClass.nameOffset, enclo
singClassName.length, [enclosingClassName]); | 14339 _errorReporter.reportError3(errorCode, _enclosingClass.nameOffset, enclo
singClassName.length, [enclosingClassName]); |
| 13910 return true; | 14340 return true; |
| 13911 } | 14341 } |
| 13912 } | 14342 } |
| 13913 for (int i = 1; i < list.length - 1; i++) { | 14343 for (int i = 1; i < list.length - 1; i++) { |
| 13914 if (classElt == list[i]) { | 14344 if (classElt == list[i]) { |
| 13915 list.removeAt(list.length - 1); | 14345 list.removeAt(list.length - 1); |
| 13916 return false; | 14346 return false; |
| 13917 } | 14347 } |
| 13918 } | 14348 } |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14108 if (staticReturnType.isVoid || staticReturnType.isDynamic || identical(sta
ticReturnType, BottomTypeImpl.instance)) { | 14538 if (staticReturnType.isVoid || staticReturnType.isDynamic || identical(sta
ticReturnType, BottomTypeImpl.instance)) { |
| 14109 return false; | 14539 return false; |
| 14110 } | 14540 } |
| 14111 _errorReporter.reportError2(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
returnExpression, [ | 14541 _errorReporter.reportError2(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
returnExpression, [ |
| 14112 staticReturnType.displayName, | 14542 staticReturnType.displayName, |
| 14113 expectedReturnType.displayName, | 14543 expectedReturnType.displayName, |
| 14114 _enclosingFunction.displayName]); | 14544 _enclosingFunction.displayName]); |
| 14115 return true; | 14545 return true; |
| 14116 } | 14546 } |
| 14117 bool isStaticAssignable = staticReturnType.isAssignableTo(expectedReturnType
); | 14547 bool isStaticAssignable = staticReturnType.isAssignableTo(expectedReturnType
); |
| 14118 Type2 propagatedReturnType = getPropagatedType(returnExpression); | 14548 Type2 propagatedReturnType = returnExpression.propagatedType; |
| 14119 if (_strictMode || propagatedReturnType == null) { | 14549 if (_strictMode || propagatedReturnType == null) { |
| 14120 if (isStaticAssignable) { | 14550 if (isStaticAssignable) { |
| 14121 return false; | 14551 return false; |
| 14122 } | 14552 } |
| 14123 _errorReporter.reportError2(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
returnExpression, [ | 14553 _errorReporter.reportError2(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
returnExpression, [ |
| 14124 staticReturnType.displayName, | 14554 staticReturnType.displayName, |
| 14125 expectedReturnType.displayName, | 14555 expectedReturnType.displayName, |
| 14126 _enclosingFunction.displayName]); | 14556 _enclosingFunction.displayName]); |
| 14127 return true; | 14557 return true; |
| 14128 } else { | 14558 } else { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14196 | 14626 |
| 14197 /** | 14627 /** |
| 14198 * This verifies that the passed function type alias does not reference itself
directly. | 14628 * This verifies that the passed function type alias does not reference itself
directly. |
| 14199 * | 14629 * |
| 14200 * @param node the function type alias to evaluate | 14630 * @param node the function type alias to evaluate |
| 14201 * @return `true` if and only if an error code is generated on the passed node | 14631 * @return `true` if and only if an error code is generated on the passed node |
| 14202 * @see CompileTimeErrorCode#TYPE_ALIAS_CANNOT_REFERENCE_ITSELF | 14632 * @see CompileTimeErrorCode#TYPE_ALIAS_CANNOT_REFERENCE_ITSELF |
| 14203 */ | 14633 */ |
| 14204 bool checkForTypeAliasCannotReferenceItself_function(FunctionTypeAlias node) { | 14634 bool checkForTypeAliasCannotReferenceItself_function(FunctionTypeAlias node) { |
| 14205 FunctionTypeAliasElement element = node.element; | 14635 FunctionTypeAliasElement element = node.element; |
| 14206 if (!hasFunctionTypeAliasSelfReference(element)) { | 14636 if (!hasTypedefSelfReference(element)) { |
| 14207 return false; | 14637 return false; |
| 14208 } | 14638 } |
| 14209 _errorReporter.reportError2(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE
_ITSELF, node, []); | 14639 _errorReporter.reportError2(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE
_ITSELF, node, []); |
| 14210 return true; | 14640 return true; |
| 14211 } | 14641 } |
| 14212 | 14642 |
| 14213 /** | 14643 /** |
| 14214 * This verifies that the given class type alias does not reference itself. | 14644 * This verifies that the given class type alias does not reference itself. |
| 14215 * | 14645 * |
| 14216 * @return `true` if and only if an error code is generated on the passed node | 14646 * @return `true` if and only if an error code is generated on the passed node |
| 14217 * @see CompileTimeErrorCode#TYPE_ALIAS_CANNOT_REFERENCE_ITSELF | 14647 * @see CompileTimeErrorCode#TYPE_ALIAS_CANNOT_REFERENCE_ITSELF |
| 14218 */ | 14648 */ |
| 14219 bool checkForTypeAliasCannotReferenceItself_mixin(ClassTypeAlias node) { | 14649 bool checkForTypeAliasCannotReferenceItself_mixin(ClassTypeAlias node) { |
| 14220 ClassElement element = node.element; | 14650 ClassElement element = node.element; |
| 14221 if (!hasClassTypeAliasSelfReference(element, new Set<ClassElement>())) { | 14651 if (!hasTypedefSelfReference(element)) { |
| 14222 return false; | 14652 return false; |
| 14223 } | 14653 } |
| 14224 _errorReporter.reportError2(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE
_ITSELF, node, []); | 14654 _errorReporter.reportError2(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE
_ITSELF, node, []); |
| 14225 return true; | 14655 return true; |
| 14226 } | 14656 } |
| 14227 | 14657 |
| 14228 /** | 14658 /** |
| 14229 * This verifies that the type arguments in the passed type name are all withi
n their bounds. | 14659 * This verifies that the type arguments in the passed type name are all withi
n their bounds. |
| 14230 * | 14660 * |
| 14231 * @param node the [TypeName] to evaluate | 14661 * @param node the [TypeName] to evaluate |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14425 for (TypeName interfaceNode in implementsClause.interfaces) { | 14855 for (TypeName interfaceNode in implementsClause.interfaces) { |
| 14426 if (interfaceNode.type == superType) { | 14856 if (interfaceNode.type == superType) { |
| 14427 hasProblem = true; | 14857 hasProblem = true; |
| 14428 _errorReporter.reportError2(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS,
interfaceNode, [superType.displayName]); | 14858 _errorReporter.reportError2(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS,
interfaceNode, [superType.displayName]); |
| 14429 } | 14859 } |
| 14430 } | 14860 } |
| 14431 return hasProblem; | 14861 return hasProblem; |
| 14432 } | 14862 } |
| 14433 | 14863 |
| 14434 /** | 14864 /** |
| 14435 * Return the propagated type of the given expression, or the static type if t
here is no | |
| 14436 * propagated type information. | |
| 14437 * | |
| 14438 * @param expression the expression whose type is to be returned | |
| 14439 * @return the propagated or static type of the given expression, whichever is
best | |
| 14440 */ | |
| 14441 Type2 getBestType(Expression expression) { | |
| 14442 Type2 type = getPropagatedType(expression); | |
| 14443 if (type == null) { | |
| 14444 type = getStaticType(expression); | |
| 14445 } | |
| 14446 return type; | |
| 14447 } | |
| 14448 | |
| 14449 /** | |
| 14450 * Returns the Type (return type) for a given getter. | 14865 * Returns the Type (return type) for a given getter. |
| 14451 * | 14866 * |
| 14452 * @param propertyAccessorElement | 14867 * @param propertyAccessorElement |
| 14453 * @return The type of the given getter. | 14868 * @return The type of the given getter. |
| 14454 */ | 14869 */ |
| 14455 Type2 getGetterType(PropertyAccessorElement propertyAccessorElement) { | 14870 Type2 getGetterType(PropertyAccessorElement propertyAccessorElement) { |
| 14456 FunctionType functionType = propertyAccessorElement.type; | 14871 FunctionType functionType = propertyAccessorElement.type; |
| 14457 if (functionType != null) { | 14872 if (functionType != null) { |
| 14458 return functionType.returnType; | 14873 return functionType.returnType; |
| 14459 } else { | 14874 } else { |
| 14460 return null; | 14875 return null; |
| 14461 } | 14876 } |
| 14462 } | 14877 } |
| 14463 | 14878 |
| 14464 /** | 14879 /** |
| 14465 * Return the propagated type of the given expression that is to be used for t
ype analysis. | |
| 14466 * | |
| 14467 * @param expression the expression whose type is to be returned | |
| 14468 * @return the propagated type of the given expression | |
| 14469 */ | |
| 14470 Type2 getPropagatedType(Expression expression) => expression.propagatedType; | |
| 14471 | |
| 14472 /** | |
| 14473 * Returns the Type (first and only parameter) for a given setter. | 14880 * Returns the Type (first and only parameter) for a given setter. |
| 14474 * | 14881 * |
| 14475 * @param propertyAccessorElement | 14882 * @param propertyAccessorElement |
| 14476 * @return The type of the given setter. | 14883 * @return The type of the given setter. |
| 14477 */ | 14884 */ |
| 14478 Type2 getSetterType(PropertyAccessorElement propertyAccessorElement) { | 14885 Type2 getSetterType(PropertyAccessorElement propertyAccessorElement) { |
| 14479 List<ParameterElement> setterParameters = propertyAccessorElement.parameters
; | 14886 List<ParameterElement> setterParameters = propertyAccessorElement.parameters
; |
| 14480 if (setterParameters.length == 0) { | 14887 if (setterParameters.length == 0) { |
| 14481 return null; | 14888 return null; |
| 14482 } | 14889 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 14508 if (expression is Identifier) { | 14915 if (expression is Identifier) { |
| 14509 Element element = ((expression as Identifier)).element; | 14916 Element element = ((expression as Identifier)).element; |
| 14510 if (element is VariableElement) { | 14917 if (element is VariableElement) { |
| 14511 return element as VariableElement; | 14918 return element as VariableElement; |
| 14512 } | 14919 } |
| 14513 } | 14920 } |
| 14514 return null; | 14921 return null; |
| 14515 } | 14922 } |
| 14516 | 14923 |
| 14517 /** | 14924 /** |
| 14518 * @return <code>true</code> if given [ClassElement] has direct or indirect re
ference to | |
| 14519 * itself using only other typedef [ClassElement]s. | |
| 14520 */ | |
| 14521 bool hasClassTypeAliasSelfReference(ClassElement element2, Set<ClassElement> s
eenMixins) { | |
| 14522 if (seenMixins.contains(element2)) { | |
| 14523 return true; | |
| 14524 } | |
| 14525 javaSetAdd(seenMixins, element2); | |
| 14526 for (InterfaceType mixin in element2.mixins) { | |
| 14527 ClassElement mixinElement = mixin.element; | |
| 14528 if (!mixinElement.isTypedef) { | |
| 14529 continue; | |
| 14530 } | |
| 14531 if (hasClassTypeAliasSelfReference(mixinElement, seenMixins)) { | |
| 14532 return true; | |
| 14533 } | |
| 14534 } | |
| 14535 return false; | |
| 14536 } | |
| 14537 | |
| 14538 /** | |
| 14539 * Checks if "target" is referenced by "current". | |
| 14540 */ | |
| 14541 bool hasFunctionTypeAliasReference(Set<FunctionTypeAliasElement> visited, Func
tionTypeAliasElement target, Element currentElement) { | |
| 14542 if (currentElement is! FunctionTypeAliasElement) { | |
| 14543 return false; | |
| 14544 } | |
| 14545 FunctionTypeAliasElement current = currentElement as FunctionTypeAliasElemen
t; | |
| 14546 if (target == current) { | |
| 14547 return true; | |
| 14548 } | |
| 14549 if (visited.contains(current)) { | |
| 14550 return false; | |
| 14551 } | |
| 14552 javaSetAdd(visited, current); | |
| 14553 return hasFunctionTypeAliasReference2(visited, target, current); | |
| 14554 } | |
| 14555 | |
| 14556 /** | |
| 14557 * Checks if "target" is referenced by "current". | |
| 14558 */ | |
| 14559 bool hasFunctionTypeAliasReference2(Set<FunctionTypeAliasElement> visited, Fun
ctionTypeAliasElement target, FunctionTypeAliasElement current) { | |
| 14560 FunctionType type = current.type; | |
| 14561 Set<Type2> referencedTypes = new Set(); | |
| 14562 if (type != null) { | |
| 14563 for (TypeVariableElement typeVariable in current.typeVariables) { | |
| 14564 Type2 bound = typeVariable.bound; | |
| 14565 javaSetAdd(referencedTypes, bound); | |
| 14566 } | |
| 14567 javaSetAdd(referencedTypes, type.returnType); | |
| 14568 for (ParameterElement parameter in type.parameters) { | |
| 14569 javaSetAdd(referencedTypes, parameter.type); | |
| 14570 } | |
| 14571 } | |
| 14572 for (Type2 referencedType in referencedTypes) { | |
| 14573 if (referencedType != null && hasFunctionTypeAliasReference(visited, targe
t, referencedType.element)) { | |
| 14574 return true; | |
| 14575 } | |
| 14576 } | |
| 14577 return false; | |
| 14578 } | |
| 14579 | |
| 14580 /** | |
| 14581 * @return <code>true</code> if given [FunctionTypeAliasElement] has direct or
indirect | |
| 14582 * reference to itself using other [FunctionTypeAliasElement]s. | |
| 14583 */ | |
| 14584 bool hasFunctionTypeAliasSelfReference(FunctionTypeAliasElement target) { | |
| 14585 Set<FunctionTypeAliasElement> visited = new Set(); | |
| 14586 return hasFunctionTypeAliasReference2(visited, target, target); | |
| 14587 } | |
| 14588 | |
| 14589 /** | |
| 14590 * @return `true` if the given constructor redirects to itself, directly or in
directly | 14925 * @return `true` if the given constructor redirects to itself, directly or in
directly |
| 14591 */ | 14926 */ |
| 14592 bool hasRedirectingFactoryConstructorCycle(ConstructorElement element) { | 14927 bool hasRedirectingFactoryConstructorCycle(ConstructorElement element) { |
| 14593 Set<ConstructorElement> constructors = new Set<ConstructorElement>(); | 14928 Set<ConstructorElement> constructors = new Set<ConstructorElement>(); |
| 14594 ConstructorElement current = element; | 14929 ConstructorElement current = element; |
| 14595 while (current != null) { | 14930 while (current != null) { |
| 14596 if (constructors.contains(current)) { | 14931 if (constructors.contains(current)) { |
| 14597 return identical(current, element); | 14932 return identical(current, element); |
| 14598 } | 14933 } |
| 14599 javaSetAdd(constructors, current); | 14934 javaSetAdd(constructors, current); |
| 14600 current = current.redirectedConstructor; | 14935 current = current.redirectedConstructor; |
| 14601 if (current is ConstructorMember) { | 14936 if (current is ConstructorMember) { |
| 14602 current = ((current as ConstructorMember)).baseElement; | 14937 current = ((current as ConstructorMember)).baseElement; |
| 14603 } | 14938 } |
| 14604 } | 14939 } |
| 14605 return false; | 14940 return false; |
| 14606 } | 14941 } |
| 14607 | 14942 |
| 14608 /** | 14943 /** |
| 14944 * @return <code>true</code> if given [Element] has direct or indirect referen
ce to itself |
| 14945 * form anywhere except [ClassElement] or type variable bounds. |
| 14946 */ |
| 14947 bool hasTypedefSelfReference(Element target) { |
| 14948 Set<Element> checked = new Set<Element>(); |
| 14949 List<Element> toCheck = new List<Element>(); |
| 14950 toCheck.add(target); |
| 14951 bool firstIteration = true; |
| 14952 while (true) { |
| 14953 Element current; |
| 14954 while (true) { |
| 14955 if (toCheck.isEmpty) { |
| 14956 return false; |
| 14957 } |
| 14958 current = toCheck.removeAt(toCheck.length - 1); |
| 14959 if (target == current) { |
| 14960 if (firstIteration) { |
| 14961 firstIteration = false; |
| 14962 break; |
| 14963 } else { |
| 14964 return true; |
| 14965 } |
| 14966 } |
| 14967 if (current != null && !checked.contains(current)) { |
| 14968 break; |
| 14969 } |
| 14970 } |
| 14971 current.accept(new GeneralizingElementVisitor_11(target, toCheck)); |
| 14972 javaSetAdd(checked, current); |
| 14973 } |
| 14974 } |
| 14975 |
| 14976 /** |
| 14609 * @return `true` if the given [ASTNode] is the part of constant constructor | 14977 * @return `true` if the given [ASTNode] is the part of constant constructor |
| 14610 * invocation. | 14978 * invocation. |
| 14611 */ | 14979 */ |
| 14612 bool isInConstConstructorInvocation(ASTNode node) { | 14980 bool isInConstConstructorInvocation(ASTNode node) { |
| 14613 InstanceCreationExpression creation = node.getAncestor(InstanceCreationExpre
ssion); | 14981 InstanceCreationExpression creation = node.getAncestor(InstanceCreationExpre
ssion); |
| 14614 if (creation == null) { | 14982 if (creation == null) { |
| 14615 return false; | 14983 return false; |
| 14616 } | 14984 } |
| 14617 return creation.isConst; | 14985 return creation.isConst; |
| 14618 } | 14986 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 14633 if (n is ConstructorFieldInitializer) { | 15001 if (n is ConstructorFieldInitializer) { |
| 14634 return false; | 15002 return false; |
| 14635 } | 15003 } |
| 14636 if (n is MethodDeclaration) { | 15004 if (n is MethodDeclaration) { |
| 14637 MethodDeclaration method = n as MethodDeclaration; | 15005 MethodDeclaration method = n as MethodDeclaration; |
| 14638 return !method.isStatic; | 15006 return !method.isStatic; |
| 14639 } | 15007 } |
| 14640 } | 15008 } |
| 14641 return false; | 15009 return false; |
| 14642 } | 15010 } |
| 15011 |
| 15012 /** |
| 15013 * Return `true` iff the passed [ClassElement] has a concrete implementation o
f the |
| 15014 * passed accessor name in the superclass chain. |
| 15015 */ |
| 15016 bool memberHasConcreteAccessorImplementationInSuperclassChain(ClassElement cla
ssElement, String accessorName, List<ClassElement> superclassChain) { |
| 15017 if (superclassChain.contains(classElement)) { |
| 15018 return false; |
| 15019 } else { |
| 15020 superclassChain.add(classElement); |
| 15021 } |
| 15022 for (PropertyAccessorElement accessor in classElement.accessors) { |
| 15023 if (accessor.name == accessorName) { |
| 15024 if (!accessor.isAbstract) { |
| 15025 return true; |
| 15026 } |
| 15027 } |
| 15028 } |
| 15029 for (InterfaceType mixinType in classElement.mixins) { |
| 15030 if (mixinType != null) { |
| 15031 ClassElement mixinElement = mixinType.element; |
| 15032 if (mixinElement != null) { |
| 15033 for (PropertyAccessorElement accessor in mixinElement.accessors) { |
| 15034 if (accessor.name == accessorName) { |
| 15035 if (!accessor.isAbstract) { |
| 15036 return true; |
| 15037 } |
| 15038 } |
| 15039 } |
| 15040 } |
| 15041 } |
| 15042 } |
| 15043 InterfaceType superType = classElement.supertype; |
| 15044 if (superType != null) { |
| 15045 ClassElement superClassElt = superType.element; |
| 15046 if (superClassElt != null) { |
| 15047 return memberHasConcreteAccessorImplementationInSuperclassChain(superCla
ssElt, accessorName, superclassChain); |
| 15048 } |
| 15049 } |
| 15050 return false; |
| 15051 } |
| 15052 |
| 15053 /** |
| 15054 * Return `true` iff the passed [ClassElement] has a concrete implementation o
f the |
| 15055 * passed method name in the superclass chain. |
| 15056 */ |
| 15057 bool memberHasConcreteMethodImplementationInSuperclassChain(ClassElement class
Element, String methodName, List<ClassElement> superclassChain) { |
| 15058 if (superclassChain.contains(classElement)) { |
| 15059 return false; |
| 15060 } else { |
| 15061 superclassChain.add(classElement); |
| 15062 } |
| 15063 for (MethodElement method in classElement.methods) { |
| 15064 if (method.name == methodName) { |
| 15065 if (!method.isAbstract) { |
| 15066 return true; |
| 15067 } |
| 15068 } |
| 15069 } |
| 15070 for (InterfaceType mixinType in classElement.mixins) { |
| 15071 if (mixinType != null) { |
| 15072 ClassElement mixinElement = mixinType.element; |
| 15073 if (mixinElement != null) { |
| 15074 for (MethodElement method in mixinElement.methods) { |
| 15075 if (method.name == methodName) { |
| 15076 if (!method.isAbstract) { |
| 15077 return true; |
| 15078 } |
| 15079 } |
| 15080 } |
| 15081 } |
| 15082 } |
| 15083 } |
| 15084 InterfaceType superType = classElement.supertype; |
| 15085 if (superType != null) { |
| 15086 ClassElement superClassElt = superType.element; |
| 15087 if (superClassElt != null) { |
| 15088 return memberHasConcreteMethodImplementationInSuperclassChain(superClass
Elt, methodName, superclassChain); |
| 15089 } |
| 15090 } |
| 15091 return false; |
| 15092 } |
| 14643 } | 15093 } |
| 14644 /** | 15094 /** |
| 14645 * This enum holds one of four states of a field initialization state through a
constructor | 15095 * This enum holds one of four states of a field initialization state through a
constructor |
| 14646 * signature, not initialized, initialized in the field declaration, initialized
in the field | 15096 * signature, not initialized, initialized in the field declaration, initialized
in the field |
| 14647 * formal, and finally, initialized in the initializers list. | 15097 * formal, and finally, initialized in the initializers list. |
| 14648 */ | 15098 */ |
| 14649 class INIT_STATE implements Comparable<INIT_STATE> { | 15099 class INIT_STATE implements Enum<INIT_STATE> { |
| 14650 static final INIT_STATE NOT_INIT = new INIT_STATE('NOT_INIT', 0); | 15100 static final INIT_STATE NOT_INIT = new INIT_STATE('NOT_INIT', 0); |
| 14651 static final INIT_STATE INIT_IN_DECLARATION = new INIT_STATE('INIT_IN_DECLARAT
ION', 1); | 15101 static final INIT_STATE INIT_IN_DECLARATION = new INIT_STATE('INIT_IN_DECLARAT
ION', 1); |
| 14652 static final INIT_STATE INIT_IN_FIELD_FORMAL = new INIT_STATE('INIT_IN_FIELD_F
ORMAL', 2); | 15102 static final INIT_STATE INIT_IN_FIELD_FORMAL = new INIT_STATE('INIT_IN_FIELD_F
ORMAL', 2); |
| 14653 static final INIT_STATE INIT_IN_INITIALIZERS = new INIT_STATE('INIT_IN_INITIAL
IZERS', 3); | 15103 static final INIT_STATE INIT_IN_INITIALIZERS = new INIT_STATE('INIT_IN_INITIAL
IZERS', 3); |
| 14654 static final List<INIT_STATE> values = [ | 15104 static final List<INIT_STATE> values = [ |
| 14655 NOT_INIT, | 15105 NOT_INIT, |
| 14656 INIT_IN_DECLARATION, | 15106 INIT_IN_DECLARATION, |
| 14657 INIT_IN_FIELD_FORMAL, | 15107 INIT_IN_FIELD_FORMAL, |
| 14658 INIT_IN_INITIALIZERS]; | 15108 INIT_IN_INITIALIZERS]; |
| 14659 | 15109 |
| 14660 /// The name of this enum constant, as declared in the enum declaration. | 15110 /// The name of this enum constant, as declared in the enum declaration. |
| 14661 final String name; | 15111 final String name; |
| 14662 | 15112 |
| 14663 /// The position in the enum declaration. | 15113 /// The position in the enum declaration. |
| 14664 final int ordinal; | 15114 final int ordinal; |
| 14665 INIT_STATE(this.name, this.ordinal); | 15115 INIT_STATE(this.name, this.ordinal); |
| 14666 int compareTo(INIT_STATE other) => ordinal - other.ordinal; | 15116 int compareTo(INIT_STATE other) => ordinal - other.ordinal; |
| 14667 int get hashCode => ordinal; | 15117 int get hashCode => ordinal; |
| 14668 String toString() => name; | 15118 String toString() => name; |
| 14669 } | 15119 } |
| 14670 /** | 15120 class GeneralizingElementVisitor_11 extends GeneralizingElementVisitor<Object> { |
| 14671 * Instances of the class `HintVerifier` traverse an AST structure looking for a
dditional | 15121 Element target; |
| 14672 * additional suggestions not mentioned in the Dart Language Specification. | 15122 List<Element> toCheck; |
| 14673 * | 15123 GeneralizingElementVisitor_11(this.target, this.toCheck) : super(); |
| 14674 * @coverage dart.engine.resolver | 15124 bool _inClass = false; |
| 14675 */ | 15125 Object visitClassElement(ClassElement element) { |
| 14676 class HintVerifier { | 15126 addTypeToCheck(element.supertype); |
| 14677 DeadCodeVerifier _deadCodeVerifier; | 15127 for (InterfaceType mixin in element.mixins) { |
| 14678 HintVerifier(AnalysisContext context, ErrorReporter errorReporter) { | 15128 addTypeToCheck(mixin); |
| 14679 _deadCodeVerifier = new DeadCodeVerifier(errorReporter); | 15129 } |
| 15130 _inClass = !element.isTypedef; |
| 15131 try { |
| 15132 return super.visitClassElement(element); |
| 15133 } finally { |
| 15134 _inClass = false; |
| 15135 } |
| 14680 } | 15136 } |
| 14681 void visitCompilationUnit(CompilationUnit node) { | 15137 Object visitExecutableElement(ExecutableElement element) { |
| 14682 node.accept(_deadCodeVerifier); | 15138 if (element.isSynthetic) { |
| 15139 return null; |
| 15140 } |
| 15141 addTypeToCheck(element.returnType); |
| 15142 return super.visitExecutableElement(element); |
| 15143 } |
| 15144 Object visitFunctionTypeAliasElement(FunctionTypeAliasElement element) { |
| 15145 addTypeToCheck(element.returnType); |
| 15146 return super.visitFunctionTypeAliasElement(element); |
| 15147 } |
| 15148 Object visitParameterElement(ParameterElement element) { |
| 15149 addTypeToCheck(element.type); |
| 15150 return super.visitParameterElement(element); |
| 15151 } |
| 15152 Object visitTypeVariableElement(TypeVariableElement element) => null; |
| 15153 Object visitVariableElement(VariableElement element) { |
| 15154 addTypeToCheck(element.type); |
| 15155 return super.visitVariableElement(element); |
| 15156 } |
| 15157 void addTypeToCheck(Type2 type) { |
| 15158 if (type == null) { |
| 15159 return; |
| 15160 } |
| 15161 Element element = type.element; |
| 15162 if (_inClass && target == element) { |
| 15163 return; |
| 15164 } |
| 15165 toCheck.add(element); |
| 15166 if (type is InterfaceType) { |
| 15167 InterfaceType interfaceType = type as InterfaceType; |
| 15168 for (Type2 typeArgument in interfaceType.typeArguments) { |
| 15169 addTypeToCheck(typeArgument); |
| 15170 } |
| 15171 } |
| 14683 } | 15172 } |
| 14684 } | 15173 } |
| 14685 /** | 15174 /** |
| 14686 * Instances of the class `PubVerifier` traverse an AST structure looking for de
viations from | |
| 14687 * pub best practices. | |
| 14688 */ | |
| 14689 class PubVerifier extends RecursiveASTVisitor<Object> { | |
| 14690 static String _PUBSPEC_YAML = "pubspec.yaml"; | |
| 14691 | |
| 14692 /** | |
| 14693 * The analysis context containing the sources to be analyzed | |
| 14694 */ | |
| 14695 AnalysisContext _context; | |
| 14696 | |
| 14697 /** | |
| 14698 * The error reporter by which errors will be reported. | |
| 14699 */ | |
| 14700 ErrorReporter _errorReporter; | |
| 14701 PubVerifier(AnalysisContext context, ErrorReporter errorReporter) { | |
| 14702 this._context = context; | |
| 14703 this._errorReporter = errorReporter; | |
| 14704 } | |
| 14705 Object visitImportDirective(ImportDirective directive) { | |
| 14706 return null; | |
| 14707 } | |
| 14708 | |
| 14709 /** | |
| 14710 * This verifies that the passed file import directive is not contained in a s
ource inside a | |
| 14711 * package "lib" directory hierarchy referencing a source outside that package
"lib" directory | |
| 14712 * hierarchy. | |
| 14713 * | |
| 14714 * @param uriLiteral the import URL (not `null`) | |
| 14715 * @param path the file path being verified (not `null`) | |
| 14716 * @return `true` if and only if an error code is generated on the passed node | |
| 14717 * @see PubSuggestionCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE | |
| 14718 */ | |
| 14719 bool checkForFileImportInsideLibReferencesFileOutside(StringLiteral uriLiteral
, String path) { | |
| 14720 Source source = getSource(uriLiteral); | |
| 14721 String fullName = getSourceFullName(source); | |
| 14722 if (fullName != null) { | |
| 14723 int pathIndex = 0; | |
| 14724 int fullNameIndex = fullName.length; | |
| 14725 while (pathIndex < path.length && JavaString.startsWithBefore(path, "../",
pathIndex)) { | |
| 14726 fullNameIndex = JavaString.lastIndexOf(fullName, '/', fullNameIndex); | |
| 14727 if (fullNameIndex < 4) { | |
| 14728 return false; | |
| 14729 } | |
| 14730 if (JavaString.startsWithBefore(fullName, "/lib", fullNameIndex - 4)) { | |
| 14731 String relativePubspecPath = path.substring(0, pathIndex + 3) + _PUBSP
EC_YAML; | |
| 14732 Source pubspecSource = _context.sourceFactory.resolveUri(source, relat
ivePubspecPath); | |
| 14733 if (pubspecSource.exists()) { | |
| 14734 _errorReporter.reportError2(PubSuggestionCode.FILE_IMPORT_INSIDE_LIB
_REFERENCES_FILE_OUTSIDE, uriLiteral, []); | |
| 14735 } | |
| 14736 return true; | |
| 14737 } | |
| 14738 pathIndex += 3; | |
| 14739 } | |
| 14740 } | |
| 14741 return false; | |
| 14742 } | |
| 14743 | |
| 14744 /** | |
| 14745 * This verifies that the passed file import directive is not contained in a s
ource outside a | |
| 14746 * package "lib" directory hierarchy referencing a source inside that package
"lib" directory | |
| 14747 * hierarchy. | |
| 14748 * | |
| 14749 * @param uriLiteral the import URL (not `null`) | |
| 14750 * @param path the file path being verified (not `null`) | |
| 14751 * @return `true` if and only if an error code is generated on the passed node | |
| 14752 * @see PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE | |
| 14753 */ | |
| 14754 bool checkForFileImportOutsideLibReferencesFileInside(StringLiteral uriLiteral
, String path) { | |
| 14755 if (path.startsWith("lib/")) { | |
| 14756 if (checkForFileImportOutsideLibReferencesFileInside2(uriLiteral, path, 0)
) { | |
| 14757 return true; | |
| 14758 } | |
| 14759 } | |
| 14760 int pathIndex = path.indexOf("/lib/"); | |
| 14761 while (pathIndex != -1) { | |
| 14762 if (checkForFileImportOutsideLibReferencesFileInside2(uriLiteral, path, pa
thIndex + 1)) { | |
| 14763 return true; | |
| 14764 } | |
| 14765 pathIndex = JavaString.indexOf(path, "/lib/", pathIndex + 4); | |
| 14766 } | |
| 14767 return false; | |
| 14768 } | |
| 14769 bool checkForFileImportOutsideLibReferencesFileInside2(StringLiteral uriLitera
l, String path, int pathIndex) { | |
| 14770 Source source = getSource(uriLiteral); | |
| 14771 String relativePubspecPath = path.substring(0, pathIndex) + _PUBSPEC_YAML; | |
| 14772 Source pubspecSource = _context.sourceFactory.resolveUri(source, relativePub
specPath); | |
| 14773 if (!pubspecSource.exists()) { | |
| 14774 return false; | |
| 14775 } | |
| 14776 String fullName = getSourceFullName(source); | |
| 14777 if (fullName != null) { | |
| 14778 if (!fullName.contains("/lib/")) { | |
| 14779 _errorReporter.reportError2(PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_RE
FERENCES_FILE_INSIDE, uriLiteral, []); | |
| 14780 return true; | |
| 14781 } | |
| 14782 } | |
| 14783 return false; | |
| 14784 } | |
| 14785 | |
| 14786 /** | |
| 14787 * This verifies that the passed package import directive does not contain "..
" | |
| 14788 * | |
| 14789 * @param uriLiteral the import URL (not `null`) | |
| 14790 * @param path the path to be validated (not `null`) | |
| 14791 * @return `true` if and only if an error code is generated on the passed node | |
| 14792 * @see PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT | |
| 14793 */ | |
| 14794 bool checkForPackageImportContainsDotDot(StringLiteral uriLiteral, String path
) { | |
| 14795 if (path.startsWith("../") || path.contains("/../")) { | |
| 14796 _errorReporter.reportError2(PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_
DOT, uriLiteral, []); | |
| 14797 return true; | |
| 14798 } | |
| 14799 return false; | |
| 14800 } | |
| 14801 | |
| 14802 /** | |
| 14803 * Answer the source associated with the compilation unit containing the given
AST node. | |
| 14804 * | |
| 14805 * @param node the node (not `null`) | |
| 14806 * @return the source or `null` if it could not be determined | |
| 14807 */ | |
| 14808 Source getSource(ASTNode node) { | |
| 14809 Source source = null; | |
| 14810 CompilationUnit unit = node.getAncestor(CompilationUnit); | |
| 14811 if (unit != null) { | |
| 14812 CompilationUnitElement element = unit.element; | |
| 14813 if (element != null) { | |
| 14814 source = element.source; | |
| 14815 } | |
| 14816 } | |
| 14817 return source; | |
| 14818 } | |
| 14819 | |
| 14820 /** | |
| 14821 * Answer the full name of the given source. The returned value will have all | |
| 14822 * [File#separatorChar] replace by '/'. | |
| 14823 * | |
| 14824 * @param source the source | |
| 14825 * @return the full name or `null` if it could not be determined | |
| 14826 */ | |
| 14827 String getSourceFullName(Source source) { | |
| 14828 if (source != null) { | |
| 14829 String fullName = source.fullName; | |
| 14830 if (fullName != null) { | |
| 14831 return fullName.replaceAll(r'\', '/'); | |
| 14832 } | |
| 14833 } | |
| 14834 return null; | |
| 14835 } | |
| 14836 } | |
| 14837 /** | |
| 14838 * The enumeration `ResolverErrorCode` defines the error codes used for errors d
etected by the | 15175 * The enumeration `ResolverErrorCode` defines the error codes used for errors d
etected by the |
| 14839 * resolver. The convention for this class is for the name of the error code to
indicate the problem | 15176 * resolver. The convention for this class is for the name of the error code to
indicate the problem |
| 14840 * that caused the error to be generated and for the error message to explain wh
at is wrong and, | 15177 * that caused the error to be generated and for the error message to explain wh
at is wrong and, |
| 14841 * when appropriate, how the problem can be corrected. | 15178 * when appropriate, how the problem can be corrected. |
| 14842 * | 15179 * |
| 14843 * @coverage dart.engine.resolver | 15180 * @coverage dart.engine.resolver |
| 14844 */ | 15181 */ |
| 14845 class ResolverErrorCode implements Comparable<ResolverErrorCode>, ErrorCode { | 15182 class ResolverErrorCode implements Enum<ResolverErrorCode>, ErrorCode { |
| 14846 static final ResolverErrorCode BREAK_LABEL_ON_SWITCH_MEMBER = new ResolverErro
rCode('BREAK_LABEL_ON_SWITCH_MEMBER', 0, ErrorType.COMPILE_TIME_ERROR, "Break la
bel resolves to case or default statement"); | 15183 static final ResolverErrorCode BREAK_LABEL_ON_SWITCH_MEMBER = new ResolverErro
rCode('BREAK_LABEL_ON_SWITCH_MEMBER', 0, ErrorType.COMPILE_TIME_ERROR, "Break la
bel resolves to case or default statement"); |
| 14847 static final ResolverErrorCode CONTINUE_LABEL_ON_SWITCH = new ResolverErrorCod
e('CONTINUE_LABEL_ON_SWITCH', 1, ErrorType.COMPILE_TIME_ERROR, "A continue label
resolves to switch, must be loop or switch member"); | 15184 static final ResolverErrorCode CONTINUE_LABEL_ON_SWITCH = new ResolverErrorCod
e('CONTINUE_LABEL_ON_SWITCH', 1, ErrorType.COMPILE_TIME_ERROR, "A continue label
resolves to switch, must be loop or switch member"); |
| 14848 static final ResolverErrorCode MISSING_LIBRARY_DIRECTIVE_WITH_PART = new Resol
verErrorCode('MISSING_LIBRARY_DIRECTIVE_WITH_PART', 2, ErrorType.COMPILE_TIME_ER
ROR, "Libraries that have parts must have a library directive"); | 15185 static final ResolverErrorCode MISSING_LIBRARY_DIRECTIVE_WITH_PART = new Resol
verErrorCode('MISSING_LIBRARY_DIRECTIVE_WITH_PART', 2, ErrorType.COMPILE_TIME_ER
ROR, "Libraries that have parts must have a library directive"); |
| 14849 static final List<ResolverErrorCode> values = [ | 15186 static final List<ResolverErrorCode> values = [ |
| 14850 BREAK_LABEL_ON_SWITCH_MEMBER, | 15187 BREAK_LABEL_ON_SWITCH_MEMBER, |
| 14851 CONTINUE_LABEL_ON_SWITCH, | 15188 CONTINUE_LABEL_ON_SWITCH, |
| 14852 MISSING_LIBRARY_DIRECTIVE_WITH_PART]; | 15189 MISSING_LIBRARY_DIRECTIVE_WITH_PART]; |
| 14853 | 15190 |
| 14854 /// The name of this enum constant, as declared in the enum declaration. | 15191 /// The name of this enum constant, as declared in the enum declaration. |
| 14855 final String name; | 15192 final String name; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 14877 this._type = type; | 15214 this._type = type; |
| 14878 this._message = message; | 15215 this._message = message; |
| 14879 } | 15216 } |
| 14880 ErrorSeverity get errorSeverity => _type.severity; | 15217 ErrorSeverity get errorSeverity => _type.severity; |
| 14881 String get message => _message; | 15218 String get message => _message; |
| 14882 ErrorType get type => _type; | 15219 ErrorType get type => _type; |
| 14883 int compareTo(ResolverErrorCode other) => ordinal - other.ordinal; | 15220 int compareTo(ResolverErrorCode other) => ordinal - other.ordinal; |
| 14884 int get hashCode => ordinal; | 15221 int get hashCode => ordinal; |
| 14885 String toString() => name; | 15222 String toString() => name; |
| 14886 } | 15223 } |
| OLD | NEW |