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

Side by Side Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 1329743005: Abstract over the type system. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Cleanup small issues Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library engine.resolver; 5 library engine.resolver;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'ast.dart'; 9 import 'ast.dart';
10 import 'constant.dart'; 10 import 'constant.dart';
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 */ 66 */
67 final ErrorReporter _errorReporter; 67 final ErrorReporter _errorReporter;
68 68
69 /** 69 /**
70 * The type Future<Null>, which is needed for determining whether it is safe 70 * The type Future<Null>, which is needed for determining whether it is safe
71 * to have a bare "return;" in an async method. 71 * to have a bare "return;" in an async method.
72 */ 72 */
73 final InterfaceType _futureNullType; 73 final InterfaceType _futureNullType;
74 74
75 /** 75 /**
76 * The type system primitives
77 */
78 TypeSystem _typeSystem;
79
80 /**
76 * Create a new instance of the [BestPracticesVerifier]. 81 * Create a new instance of the [BestPracticesVerifier].
77 * 82 *
78 * @param errorReporter the error reporter 83 * @param errorReporter the error reporter
79 */ 84 */
80 BestPracticesVerifier(this._errorReporter, TypeProvider typeProvider) 85 BestPracticesVerifier(
86 this._errorReporter, TypeProvider typeProvider, this._typeSystem)
81 : _futureNullType = typeProvider.futureNullType; 87 : _futureNullType = typeProvider.futureNullType;
82 88
83 @override 89 @override
84 Object visitArgumentList(ArgumentList node) { 90 Object visitArgumentList(ArgumentList node) {
85 _checkForArgumentTypesNotAssignableInList(node); 91 _checkForArgumentTypesNotAssignableInList(node);
86 return super.visitArgumentList(node); 92 return super.visitArgumentList(node);
87 } 93 }
88 94
89 @override 95 @override
90 Object visitAsExpression(AsExpression node) { 96 Object visitAsExpression(AsExpression node) {
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 Expression expression, 303 Expression expression,
298 DartType expectedStaticType, 304 DartType expectedStaticType,
299 DartType actualStaticType, 305 DartType actualStaticType,
300 DartType expectedPropagatedType, 306 DartType expectedPropagatedType,
301 DartType actualPropagatedType, 307 DartType actualPropagatedType,
302 ErrorCode hintCode) { 308 ErrorCode hintCode) {
303 // 309 //
304 // Warning case: test static type information 310 // Warning case: test static type information
305 // 311 //
306 if (actualStaticType != null && expectedStaticType != null) { 312 if (actualStaticType != null && expectedStaticType != null) {
307 if (!actualStaticType.isAssignableTo(expectedStaticType)) { 313 if (!_typeSystem.isAssignableTo(actualStaticType, expectedStaticType)) {
308 // A warning was created in the ErrorVerifier, return false, don't 314 // A warning was created in the ErrorVerifier, return false, don't
309 // create a hint when a warning has already been created. 315 // create a hint when a warning has already been created.
310 return false; 316 return false;
311 } 317 }
312 } 318 }
313 // 319 //
314 // Hint case: test propagated type information 320 // Hint case: test propagated type information
315 // 321 //
316 // Compute the best types to use. 322 // Compute the best types to use.
317 DartType expectedBestType = expectedPropagatedType != null 323 DartType expectedBestType = expectedPropagatedType != null
318 ? expectedPropagatedType 324 ? expectedPropagatedType
319 : expectedStaticType; 325 : expectedStaticType;
320 DartType actualBestType = 326 DartType actualBestType =
321 actualPropagatedType != null ? actualPropagatedType : actualStaticType; 327 actualPropagatedType != null ? actualPropagatedType : actualStaticType;
322 if (actualBestType != null && expectedBestType != null) { 328 if (actualBestType != null && expectedBestType != null) {
323 if (!actualBestType.isAssignableTo(expectedBestType)) { 329 if (!_typeSystem.isAssignableTo(actualBestType, expectedBestType)) {
324 _errorReporter.reportTypeErrorForNode( 330 _errorReporter.reportTypeErrorForNode(
325 hintCode, expression, [actualBestType, expectedBestType]); 331 hintCode, expression, [actualBestType, expectedBestType]);
326 return true; 332 return true;
327 } 333 }
328 } 334 }
329 return false; 335 return false;
330 } 336 }
331 337
332 /** 338 /**
333 * This verifies that the passed argument can be assigned to its corresponding parameter. 339 * This verifies that the passed argument can be assigned to its corresponding parameter.
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 */ 518 */
513 bool _checkForInvalidAssignment(Expression lhs, Expression rhs) { 519 bool _checkForInvalidAssignment(Expression lhs, Expression rhs) {
514 if (lhs == null || rhs == null) { 520 if (lhs == null || rhs == null) {
515 return false; 521 return false;
516 } 522 }
517 VariableElement leftVariableElement = ErrorVerifier.getVariableElement(lhs); 523 VariableElement leftVariableElement = ErrorVerifier.getVariableElement(lhs);
518 DartType leftType = (leftVariableElement == null) 524 DartType leftType = (leftVariableElement == null)
519 ? ErrorVerifier.getStaticType(lhs) 525 ? ErrorVerifier.getStaticType(lhs)
520 : leftVariableElement.type; 526 : leftVariableElement.type;
521 DartType staticRightType = ErrorVerifier.getStaticType(rhs); 527 DartType staticRightType = ErrorVerifier.getStaticType(rhs);
522 if (!staticRightType.isAssignableTo(leftType)) { 528 if (!_typeSystem.isAssignableTo(staticRightType, leftType)) {
523 // The warning was generated on this rhs 529 // The warning was generated on this rhs
524 return false; 530 return false;
525 } 531 }
526 // Test for, and then generate the hint 532 // Test for, and then generate the hint
527 DartType bestRightType = rhs.bestType; 533 DartType bestRightType = rhs.bestType;
528 if (leftType != null && bestRightType != null) { 534 if (leftType != null && bestRightType != null) {
529 if (!bestRightType.isAssignableTo(leftType)) { 535 if (!_typeSystem.isAssignableTo(bestRightType, leftType)) {
530 _errorReporter.reportTypeErrorForNode( 536 _errorReporter.reportTypeErrorForNode(
531 HintCode.INVALID_ASSIGNMENT, rhs, [bestRightType, leftType]); 537 HintCode.INVALID_ASSIGNMENT, rhs, [bestRightType, leftType]);
532 return true; 538 return true;
533 } 539 }
534 } 540 }
535 return false; 541 return false;
536 } 542 }
537 543
538 /** 544 /**
539 * Check that the imported library does not define a loadLibrary function. The import has already 545 * Check that the imported library does not define a loadLibrary function. The import has already
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 if (body.isGenerator) { 592 if (body.isGenerator) {
587 return false; 593 return false;
588 } 594 }
589 // Check that the type is resolvable, and is not "void" 595 // Check that the type is resolvable, and is not "void"
590 DartType returnTypeType = returnType.type; 596 DartType returnTypeType = returnType.type;
591 if (returnTypeType == null || returnTypeType.isVoid) { 597 if (returnTypeType == null || returnTypeType.isVoid) {
592 return false; 598 return false;
593 } 599 }
594 // For async, give no hint if Future<Null> is assignable to the return 600 // For async, give no hint if Future<Null> is assignable to the return
595 // type. 601 // type.
596 if (body.isAsynchronous && _futureNullType.isAssignableTo(returnTypeType)) { 602 if (body.isAsynchronous &&
603 _typeSystem.isAssignableTo(_futureNullType, returnTypeType)) {
597 return false; 604 return false;
598 } 605 }
599 // Check the block for a return statement, if not, create the hint 606 // Check the block for a return statement, if not, create the hint
600 BlockFunctionBody blockFunctionBody = body as BlockFunctionBody; 607 BlockFunctionBody blockFunctionBody = body as BlockFunctionBody;
601 if (!ExitDetector.exits(blockFunctionBody)) { 608 if (!ExitDetector.exits(blockFunctionBody)) {
602 _errorReporter.reportErrorForNode( 609 _errorReporter.reportErrorForNode(
603 HintCode.MISSING_RETURN, returnType, [returnTypeType.displayName]); 610 HintCode.MISSING_RETURN, returnType, [returnTypeType.displayName]);
604 return true; 611 return true;
605 } 612 }
606 return false; 613 return false;
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 * The error reporter by which errors will be reported. 839 * The error reporter by which errors will be reported.
833 */ 840 */
834 final ErrorReporter _errorReporter; 841 final ErrorReporter _errorReporter;
835 842
836 /** 843 /**
837 * The type provider used to access the known types. 844 * The type provider used to access the known types.
838 */ 845 */
839 final TypeProvider _typeProvider; 846 final TypeProvider _typeProvider;
840 847
841 /** 848 /**
849 * The type system in use.
850 */
851 final TypeSystem _typeSystem;
852
853 /**
842 * The set of variables declared using '-D' on the command line. 854 * The set of variables declared using '-D' on the command line.
843 */ 855 */
844 final DeclaredVariables declaredVariables; 856 final DeclaredVariables declaredVariables;
845 857
846 /** 858 /**
847 * The type representing the type 'bool'. 859 * The type representing the type 'bool'.
848 */ 860 */
849 InterfaceType _boolType; 861 InterfaceType _boolType;
850 862
851 /** 863 /**
(...skipping 15 matching lines...) Expand all
867 * The current library that is being analyzed. 879 * The current library that is being analyzed.
868 */ 880 */
869 final LibraryElement _currentLibrary; 881 final LibraryElement _currentLibrary;
870 882
871 /** 883 /**
872 * Initialize a newly created constant verifier. 884 * Initialize a newly created constant verifier.
873 * 885 *
874 * @param errorReporter the error reporter by which errors will be reported 886 * @param errorReporter the error reporter by which errors will be reported
875 */ 887 */
876 ConstantVerifier(this._errorReporter, this._currentLibrary, 888 ConstantVerifier(this._errorReporter, this._currentLibrary,
877 this._typeProvider, this.declaredVariables) { 889 this._typeProvider, this._typeSystem, this.declaredVariables) {
878 this._boolType = _typeProvider.boolType; 890 this._boolType = _typeProvider.boolType;
879 this._intType = _typeProvider.intType; 891 this._intType = _typeProvider.intType;
880 this._numType = _typeProvider.numType; 892 this._numType = _typeProvider.numType;
881 this._stringType = _typeProvider.stringType; 893 this._stringType = _typeProvider.stringType;
882 } 894 }
883 895
884 @override 896 @override
885 Object visitAnnotation(Annotation node) { 897 Object visitAnnotation(Annotation node) {
886 super.visitAnnotation(node); 898 super.visitAnnotation(node);
887 // check annotation creation 899 // check annotation creation
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 } 937 }
926 938
927 @override 939 @override
928 Object visitInstanceCreationExpression(InstanceCreationExpression node) { 940 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
929 if (node.isConst) { 941 if (node.isConst) {
930 // We need to evaluate the constant to see if any errors occur during its 942 // We need to evaluate the constant to see if any errors occur during its
931 // evaluation. 943 // evaluation.
932 ConstructorElement constructor = node.staticElement; 944 ConstructorElement constructor = node.staticElement;
933 if (constructor != null) { 945 if (constructor != null) {
934 ConstantEvaluationEngine evaluationEngine = 946 ConstantEvaluationEngine evaluationEngine =
935 new ConstantEvaluationEngine(_typeProvider, declaredVariables); 947 new ConstantEvaluationEngine(
948 _typeProvider, _typeSystem, declaredVariables);
936 ConstantVisitor constantVisitor = 949 ConstantVisitor constantVisitor =
937 new ConstantVisitor(evaluationEngine, _errorReporter); 950 new ConstantVisitor(evaluationEngine, _errorReporter);
938 evaluationEngine.evaluateConstructorCall( 951 evaluationEngine.evaluateConstructorCall(
939 node, 952 node,
940 node.argumentList.arguments, 953 node.argumentList.arguments,
941 constructor, 954 constructor,
942 constantVisitor, 955 constantVisitor,
943 _errorReporter); 956 _errorReporter);
944 } 957 }
945 } 958 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 [type.displayName]); 1012 [type.displayName]);
1000 } 1013 }
1001 } 1014 }
1002 } else { 1015 } else {
1003 // Note: we throw the errors away because this isn't actually a const. 1016 // Note: we throw the errors away because this isn't actually a const.
1004 AnalysisErrorListener errorListener = 1017 AnalysisErrorListener errorListener =
1005 AnalysisErrorListener.NULL_LISTENER; 1018 AnalysisErrorListener.NULL_LISTENER;
1006 ErrorReporter subErrorReporter = 1019 ErrorReporter subErrorReporter =
1007 new ErrorReporter(errorListener, _errorReporter.source); 1020 new ErrorReporter(errorListener, _errorReporter.source);
1008 DartObjectImpl result = key.accept(new ConstantVisitor( 1021 DartObjectImpl result = key.accept(new ConstantVisitor(
1009 new ConstantEvaluationEngine(_typeProvider, declaredVariables), 1022 new ConstantEvaluationEngine(
1023 _typeProvider, _typeSystem, declaredVariables),
1010 subErrorReporter)); 1024 subErrorReporter));
1011 if (result != null) { 1025 if (result != null) {
1012 if (keys.contains(result)) { 1026 if (keys.contains(result)) {
1013 invalidKeys.add(key); 1027 invalidKeys.add(key);
1014 } else { 1028 } else {
1015 keys.add(result); 1029 keys.add(result);
1016 } 1030 }
1017 } else { 1031 } else {
1018 reportEqualKeys = false; 1032 reportEqualKeys = false;
1019 } 1033 }
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1205 * 1219 *
1206 * @param expression the expression to be validated 1220 * @param expression the expression to be validated
1207 * @param errorCode the error code to be used if the expression is not a compi le time constant 1221 * @param errorCode the error code to be used if the expression is not a compi le time constant
1208 * @return the value of the compile time constant 1222 * @return the value of the compile time constant
1209 */ 1223 */
1210 DartObjectImpl _validate(Expression expression, ErrorCode errorCode) { 1224 DartObjectImpl _validate(Expression expression, ErrorCode errorCode) {
1211 RecordingErrorListener errorListener = new RecordingErrorListener(); 1225 RecordingErrorListener errorListener = new RecordingErrorListener();
1212 ErrorReporter subErrorReporter = 1226 ErrorReporter subErrorReporter =
1213 new ErrorReporter(errorListener, _errorReporter.source); 1227 new ErrorReporter(errorListener, _errorReporter.source);
1214 DartObjectImpl result = expression.accept(new ConstantVisitor( 1228 DartObjectImpl result = expression.accept(new ConstantVisitor(
1215 new ConstantEvaluationEngine(_typeProvider, declaredVariables), 1229 new ConstantEvaluationEngine(
1230 _typeProvider, _typeSystem, declaredVariables),
1216 subErrorReporter)); 1231 subErrorReporter));
1217 _reportErrors(errorListener.errors, errorCode); 1232 _reportErrors(errorListener.errors, errorCode);
1218 return result; 1233 return result;
1219 } 1234 }
1220 1235
1221 /** 1236 /**
1222 * Validate that if the passed arguments are constant expressions. 1237 * Validate that if the passed arguments are constant expressions.
1223 * 1238 *
1224 * @param argumentList the argument list to evaluate 1239 * @param argumentList the argument list to evaluate
1225 */ 1240 */
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 Expression initializer = variableDeclaration.initializer; 1329 Expression initializer = variableDeclaration.initializer;
1315 if (initializer != null) { 1330 if (initializer != null) {
1316 // Ignore any errors produced during validation--if the constant 1331 // Ignore any errors produced during validation--if the constant
1317 // can't be eavluated we'll just report a single error. 1332 // can't be eavluated we'll just report a single error.
1318 AnalysisErrorListener errorListener = 1333 AnalysisErrorListener errorListener =
1319 AnalysisErrorListener.NULL_LISTENER; 1334 AnalysisErrorListener.NULL_LISTENER;
1320 ErrorReporter subErrorReporter = 1335 ErrorReporter subErrorReporter =
1321 new ErrorReporter(errorListener, _errorReporter.source); 1336 new ErrorReporter(errorListener, _errorReporter.source);
1322 DartObjectImpl result = initializer.accept(new ConstantVisitor( 1337 DartObjectImpl result = initializer.accept(new ConstantVisitor(
1323 new ConstantEvaluationEngine( 1338 new ConstantEvaluationEngine(
1324 _typeProvider, declaredVariables), 1339 _typeProvider, _typeSystem, declaredVariables),
1325 subErrorReporter)); 1340 subErrorReporter));
1326 if (result == null) { 1341 if (result == null) {
1327 _errorReporter.reportErrorForNode( 1342 _errorReporter.reportErrorForNode(
1328 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZE D_BY_NON_CONST, 1343 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZE D_BY_NON_CONST,
1329 errorSite, 1344 errorSite,
1330 [variableDeclaration.name.name]); 1345 [variableDeclaration.name.name]);
1331 } 1346 }
1332 } 1347 }
1333 } 1348 }
1334 } 1349 }
1335 } 1350 }
1336 } 1351 }
1337 } 1352 }
1338 1353
1339 /** 1354 /**
1340 * Validates that the given expression is a compile time constant. 1355 * Validates that the given expression is a compile time constant.
1341 * 1356 *
1342 * @param parameterElements the elements of parameters of constant constructor , they are 1357 * @param parameterElements the elements of parameters of constant constructor , they are
1343 * considered as a valid potentially constant expressions 1358 * considered as a valid potentially constant expressions
1344 * @param expression the expression to validate 1359 * @param expression the expression to validate
1345 */ 1360 */
1346 void _validateInitializerExpression( 1361 void _validateInitializerExpression(
1347 List<ParameterElement> parameterElements, Expression expression) { 1362 List<ParameterElement> parameterElements, Expression expression) {
1348 RecordingErrorListener errorListener = new RecordingErrorListener(); 1363 RecordingErrorListener errorListener = new RecordingErrorListener();
1349 ErrorReporter subErrorReporter = 1364 ErrorReporter subErrorReporter =
1350 new ErrorReporter(errorListener, _errorReporter.source); 1365 new ErrorReporter(errorListener, _errorReporter.source);
1351 DartObjectImpl result = expression.accept( 1366 DartObjectImpl result = expression.accept(
1352 new _ConstantVerifier_validateInitializerExpression(_typeProvider, 1367 new _ConstantVerifier_validateInitializerExpression(
1353 subErrorReporter, this, parameterElements, declaredVariables)); 1368 _typeProvider,
1369 _typeSystem,
1370 subErrorReporter,
1371 this,
1372 parameterElements,
1373 declaredVariables));
1354 _reportErrors(errorListener.errors, 1374 _reportErrors(errorListener.errors,
1355 CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER); 1375 CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER);
1356 if (result != null) { 1376 if (result != null) {
1357 _reportErrorIfFromDeferredLibrary(expression, 1377 _reportErrorIfFromDeferredLibrary(expression,
1358 CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_L IBRARY); 1378 CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_L IBRARY);
1359 } 1379 }
1360 } 1380 }
1361 1381
1362 /** 1382 /**
1363 * Validates that all of the arguments of a constructor initializer are compil e time constants. 1383 * Validates that all of the arguments of a constructor initializer are compil e time constants.
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 * Instances of the class `DeadCodeVerifier` traverse an AST structure looking f or cases of 1488 * Instances of the class `DeadCodeVerifier` traverse an AST structure looking f or cases of
1469 * [HintCode.DEAD_CODE]. 1489 * [HintCode.DEAD_CODE].
1470 */ 1490 */
1471 class DeadCodeVerifier extends RecursiveAstVisitor<Object> { 1491 class DeadCodeVerifier extends RecursiveAstVisitor<Object> {
1472 /** 1492 /**
1473 * The error reporter by which errors will be reported. 1493 * The error reporter by which errors will be reported.
1474 */ 1494 */
1475 final ErrorReporter _errorReporter; 1495 final ErrorReporter _errorReporter;
1476 1496
1477 /** 1497 /**
1498 * The type system for this visitor
1499 */
1500 final TypeSystem _typeSystem;
1501
1502 /**
1478 * Create a new instance of the [DeadCodeVerifier]. 1503 * Create a new instance of the [DeadCodeVerifier].
1479 * 1504 *
1480 * @param errorReporter the error reporter 1505 * @param errorReporter the error reporter
1481 */ 1506 */
1482 DeadCodeVerifier(this._errorReporter); 1507 DeadCodeVerifier(this._errorReporter, this._typeSystem);
1483 1508
1484 @override 1509 @override
1485 Object visitBinaryExpression(BinaryExpression node) { 1510 Object visitBinaryExpression(BinaryExpression node) {
1486 sc.Token operator = node.operator; 1511 sc.Token operator = node.operator;
1487 bool isAmpAmp = operator.type == sc.TokenType.AMPERSAND_AMPERSAND; 1512 bool isAmpAmp = operator.type == sc.TokenType.AMPERSAND_AMPERSAND;
1488 bool isBarBar = operator.type == sc.TokenType.BAR_BAR; 1513 bool isBarBar = operator.type == sc.TokenType.BAR_BAR;
1489 if (isAmpAmp || isBarBar) { 1514 if (isAmpAmp || isBarBar) {
1490 Expression lhsCondition = node.leftOperand; 1515 Expression lhsCondition = node.leftOperand;
1491 if (!_isDebugConstant(lhsCondition)) { 1516 if (!_isDebugConstant(lhsCondition)) {
1492 EvaluationResultImpl lhsResult = _getConstantBooleanValue(lhsCondition); 1517 EvaluationResultImpl lhsResult = _getConstantBooleanValue(lhsCondition);
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1637 CatchClause nextCatchClause = catchClauses[i + 1]; 1662 CatchClause nextCatchClause = catchClauses[i + 1];
1638 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; 1663 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1];
1639 int offset = nextCatchClause.offset; 1664 int offset = nextCatchClause.offset;
1640 int length = lastCatchClause.end - offset; 1665 int length = lastCatchClause.end - offset;
1641 _errorReporter.reportErrorForOffset( 1666 _errorReporter.reportErrorForOffset(
1642 HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, offset, length); 1667 HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, offset, length);
1643 return null; 1668 return null;
1644 } 1669 }
1645 } 1670 }
1646 for (DartType type in visitedTypes) { 1671 for (DartType type in visitedTypes) {
1647 if (currentType.isSubtypeOf(type)) { 1672 if (_typeSystem.isSubtypeOf(currentType, type)) {
1648 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; 1673 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1];
1649 int offset = catchClause.offset; 1674 int offset = catchClause.offset;
1650 int length = lastCatchClause.end - offset; 1675 int length = lastCatchClause.end - offset;
1651 _errorReporter.reportErrorForOffset( 1676 _errorReporter.reportErrorForOffset(
1652 HintCode.DEAD_CODE_ON_CATCH_SUBTYPE, 1677 HintCode.DEAD_CODE_ON_CATCH_SUBTYPE,
1653 offset, 1678 offset,
1654 length, 1679 length,
1655 [currentType.displayName, type.displayName]); 1680 [currentType.displayName, type.displayName]);
1656 return null; 1681 return null;
1657 } 1682 }
(...skipping 3134 matching lines...) Expand 10 before | Expand all | Expand 10 after
4792 } 4817 }
4793 _library.accept(new UnusedLocalElementsVerifier( 4818 _library.accept(new UnusedLocalElementsVerifier(
4794 _errorListener, _usedLocalElementsVisitor.usedElements)); 4819 _errorListener, _usedLocalElementsVisitor.usedElements));
4795 }); 4820 });
4796 } 4821 }
4797 4822
4798 void _generateForCompilationUnit(CompilationUnit unit, Source source) { 4823 void _generateForCompilationUnit(CompilationUnit unit, Source source) {
4799 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source); 4824 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source);
4800 unit.accept(_usedImportedElementsVisitor); 4825 unit.accept(_usedImportedElementsVisitor);
4801 // dead code analysis 4826 // dead code analysis
4802 unit.accept(new DeadCodeVerifier(errorReporter)); 4827 unit.accept(new DeadCodeVerifier(errorReporter, _context.typeSystem));
4803 unit.accept(_usedLocalElementsVisitor); 4828 unit.accept(_usedLocalElementsVisitor);
4804 // dart2js analysis 4829 // dart2js analysis
4805 if (_enableDart2JSHints) { 4830 if (_enableDart2JSHints) {
4806 unit.accept(new Dart2JSVerifier(errorReporter)); 4831 unit.accept(new Dart2JSVerifier(errorReporter));
4807 } 4832 }
4808 // Dart best practices 4833 // Dart best practices
4809 unit.accept( 4834 unit.accept(new BestPracticesVerifier(
4810 new BestPracticesVerifier(errorReporter, _context.typeProvider)); 4835 errorReporter, _context.typeProvider, _context.typeSystem));
4811 unit.accept(new OverrideVerifier(errorReporter, _manager)); 4836 unit.accept(new OverrideVerifier(errorReporter, _manager));
4812 // Find to-do comments 4837 // Find to-do comments
4813 new ToDoFinder(errorReporter).findIn(unit); 4838 new ToDoFinder(errorReporter).findIn(unit);
4814 // pub analysis 4839 // pub analysis
4815 // TODO(danrubel/jwren) Commented out until bugs in the pub verifier are 4840 // TODO(danrubel/jwren) Commented out until bugs in the pub verifier are
4816 // fixed 4841 // fixed
4817 // unit.accept(new PubVerifier(context, errorReporter)); 4842 // unit.accept(new PubVerifier(context, errorReporter));
4818 } 4843 }
4819 } 4844 }
4820 4845
(...skipping 1440 matching lines...) Expand 10 before | Expand all | Expand 10 after
6261 for (int i = 0; i < numOfEltsWithMatchingNames; i++) { 6286 for (int i = 0; i < numOfEltsWithMatchingNames; i++) {
6262 executableElementTypes[i] = elements[i].type; 6287 executableElementTypes[i] = elements[i].type;
6263 } 6288 }
6264 List<int> subtypesOfAllOtherTypesIndexes = new List<int>(); 6289 List<int> subtypesOfAllOtherTypesIndexes = new List<int>();
6265 for (int i = 0; i < numOfEltsWithMatchingNames; i++) { 6290 for (int i = 0; i < numOfEltsWithMatchingNames; i++) {
6266 FunctionType subtype = executableElementTypes[i]; 6291 FunctionType subtype = executableElementTypes[i];
6267 if (subtype == null) { 6292 if (subtype == null) {
6268 continue; 6293 continue;
6269 } 6294 }
6270 bool subtypeOfAllTypes = true; 6295 bool subtypeOfAllTypes = true;
6296 TypeSystem typeSystem = _library.context.typeSystem;
6271 for (int j = 0; 6297 for (int j = 0;
6272 j < numOfEltsWithMatchingNames && subtypeOfAllTypes; 6298 j < numOfEltsWithMatchingNames && subtypeOfAllTypes;
6273 j++) { 6299 j++) {
6274 if (i != j) { 6300 if (i != j) {
6275 if (!subtype.isSubtypeOf(executableElementTypes[j])) { 6301 if (!typeSystem.isSubtypeOf(
6302 subtype, executableElementTypes[j])) {
6276 subtypeOfAllTypes = false; 6303 subtypeOfAllTypes = false;
6277 break; 6304 break;
6278 } 6305 }
6279 } 6306 }
6280 } 6307 }
6281 if (subtypeOfAllTypes) { 6308 if (subtypeOfAllTypes) {
6282 subtypesOfAllOtherTypesIndexes.add(i); 6309 subtypesOfAllOtherTypesIndexes.add(i);
6283 } 6310 }
6284 } 6311 }
6285 // 6312 //
(...skipping 1277 matching lines...) Expand 10 before | Expand all | Expand 10 after
7563 * The object representing the async library. 7590 * The object representing the async library.
7564 */ 7591 */
7565 Library _asyncLibrary; 7592 Library _asyncLibrary;
7566 7593
7567 /** 7594 /**
7568 * The object used to access the types from the core library. 7595 * The object used to access the types from the core library.
7569 */ 7596 */
7570 TypeProvider _typeProvider; 7597 TypeProvider _typeProvider;
7571 7598
7572 /** 7599 /**
7600 * The type system in use for the library
7601 */
7602 TypeSystem _typeSystem;
7603
7604 /**
7573 * A table mapping library sources to the information being maintained for tho se libraries. 7605 * A table mapping library sources to the information being maintained for tho se libraries.
7574 */ 7606 */
7575 HashMap<Source, Library> _libraryMap = new HashMap<Source, Library>(); 7607 HashMap<Source, Library> _libraryMap = new HashMap<Source, Library>();
7576 7608
7577 /** 7609 /**
7578 * A collection containing the libraries that are being resolved together. 7610 * A collection containing the libraries that are being resolved together.
7579 */ 7611 */
7580 Set<Library> _librariesInCycles; 7612 Set<Library> _librariesInCycles;
7581 7613
7582 /** 7614 /**
(...skipping 22 matching lines...) Expand all
7605 * @return an array containing the libraries that were resolved 7637 * @return an array containing the libraries that were resolved
7606 */ 7638 */
7607 Set<Library> get resolvedLibraries => _librariesInCycles; 7639 Set<Library> get resolvedLibraries => _librariesInCycles;
7608 7640
7609 /** 7641 /**
7610 * The object used to access the types from the core library. 7642 * The object used to access the types from the core library.
7611 */ 7643 */
7612 TypeProvider get typeProvider => _typeProvider; 7644 TypeProvider get typeProvider => _typeProvider;
7613 7645
7614 /** 7646 /**
7647 * The type system in use.
7648 */
7649 TypeSystem get typeSystem => _typeSystem;
7650
7651 /**
7615 * Create an object to represent the information about the library defined by the compilation unit 7652 * Create an object to represent the information about the library defined by the compilation unit
7616 * with the given source. 7653 * with the given source.
7617 * 7654 *
7618 * @param librarySource the source of the library's defining compilation unit 7655 * @param librarySource the source of the library's defining compilation unit
7619 * @return the library object that was created 7656 * @return the library object that was created
7620 * @throws AnalysisException if the library source is not valid 7657 * @throws AnalysisException if the library source is not valid
7621 */ 7658 */
7622 Library createLibrary(Source librarySource) { 7659 Library createLibrary(Source librarySource) {
7623 Library library = 7660 Library library =
7624 new Library(analysisContext, _errorListener, librarySource); 7661 new Library(analysisContext, _errorListener, librarySource);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
7689 LibraryElement coreElement = _coreLibrary.libraryElement; 7726 LibraryElement coreElement = _coreLibrary.libraryElement;
7690 if (coreElement == null) { 7727 if (coreElement == null) {
7691 throw new AnalysisException("Could not resolve dart:core"); 7728 throw new AnalysisException("Could not resolve dart:core");
7692 } 7729 }
7693 LibraryElement asyncElement = _asyncLibrary.libraryElement; 7730 LibraryElement asyncElement = _asyncLibrary.libraryElement;
7694 if (asyncElement == null) { 7731 if (asyncElement == null) {
7695 throw new AnalysisException("Could not resolve dart:async"); 7732 throw new AnalysisException("Could not resolve dart:async");
7696 } 7733 }
7697 _buildDirectiveModels(); 7734 _buildDirectiveModels();
7698 _typeProvider = new TypeProviderImpl(coreElement, asyncElement); 7735 _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
7736 _typeSystem = TypeSystem.create(analysisContext);
7699 _buildTypeHierarchies(); 7737 _buildTypeHierarchies();
7700 // 7738 //
7701 // Perform resolution and type analysis. 7739 // Perform resolution and type analysis.
7702 // 7740 //
7703 // TODO(brianwilkerson) Decide whether we want to resolve all of the 7741 // TODO(brianwilkerson) Decide whether we want to resolve all of the
7704 // libraries or whether we want to only resolve the target library. 7742 // libraries or whether we want to only resolve the target library.
7705 // The advantage to resolving everything is that we have already done part 7743 // The advantage to resolving everything is that we have already done part
7706 // of the work so we'll avoid duplicated effort. The disadvantage of 7744 // of the work so we'll avoid duplicated effort. The disadvantage of
7707 // resolving everything is that we might do extra work that we don't 7745 // resolving everything is that we might do extra work that we don't
7708 // really care about. Another possibility is to add a parameter to this 7746 // really care about. Another possibility is to add a parameter to this
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
7767 LibraryElement coreElement = _coreLibrary.libraryElement; 7805 LibraryElement coreElement = _coreLibrary.libraryElement;
7768 if (coreElement == null) { 7806 if (coreElement == null) {
7769 throw new AnalysisException("Could not resolve dart:core"); 7807 throw new AnalysisException("Could not resolve dart:core");
7770 } 7808 }
7771 LibraryElement asyncElement = _asyncLibrary.libraryElement; 7809 LibraryElement asyncElement = _asyncLibrary.libraryElement;
7772 if (asyncElement == null) { 7810 if (asyncElement == null) {
7773 throw new AnalysisException("Could not resolve dart:async"); 7811 throw new AnalysisException("Could not resolve dart:async");
7774 } 7812 }
7775 _buildDirectiveModels(); 7813 _buildDirectiveModels();
7776 _typeProvider = new TypeProviderImpl(coreElement, asyncElement); 7814 _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
7815 _typeSystem = TypeSystem.create(analysisContext);
7777 _buildEnumMembers(); 7816 _buildEnumMembers();
7778 _buildTypeHierarchies(); 7817 _buildTypeHierarchies();
7779 // 7818 //
7780 // Perform resolution and type analysis. 7819 // Perform resolution and type analysis.
7781 // 7820 //
7782 // TODO(brianwilkerson) Decide whether we want to resolve all of the 7821 // TODO(brianwilkerson) Decide whether we want to resolve all of the
7783 // libraries or whether we want to only resolve the target library. The 7822 // libraries or whether we want to only resolve the target library. The
7784 // advantage to resolving everything is that we have already done part of 7823 // advantage to resolving everything is that we have already done part of
7785 // the work so we'll avoid duplicated effort. The disadvantage of 7824 // the work so we'll avoid duplicated effort. The disadvantage of
7786 // resolving everything is that we might do extra work that we don't 7825 // resolving everything is that we might do extra work that we don't
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
8279 } 8318 }
8280 return identifiers; 8319 return identifiers;
8281 } 8320 }
8282 8321
8283 /** 8322 /**
8284 * Compute a value for all of the constants in the libraries being analyzed. 8323 * Compute a value for all of the constants in the libraries being analyzed.
8285 */ 8324 */
8286 void _performConstantEvaluation() { 8325 void _performConstantEvaluation() {
8287 PerformanceStatistics.resolve.makeCurrentWhile(() { 8326 PerformanceStatistics.resolve.makeCurrentWhile(() {
8288 ConstantValueComputer computer = new ConstantValueComputer( 8327 ConstantValueComputer computer = new ConstantValueComputer(
8289 analysisContext, _typeProvider, analysisContext.declaredVariables); 8328 analysisContext,
8329 _typeProvider,
8330 _typeSystem,
8331 analysisContext.declaredVariables);
8290 for (Library library in _librariesInCycles) { 8332 for (Library library in _librariesInCycles) {
8291 for (Source source in library.compilationUnitSources) { 8333 for (Source source in library.compilationUnitSources) {
8292 try { 8334 try {
8293 CompilationUnit unit = library.getAST(source); 8335 CompilationUnit unit = library.getAST(source);
8294 if (unit != null) { 8336 if (unit != null) {
8295 computer.add(unit, source, library.librarySource); 8337 computer.add(unit, source, library.librarySource);
8296 } 8338 }
8297 } on AnalysisException catch (exception, stackTrace) { 8339 } on AnalysisException catch (exception, stackTrace) {
8298 AnalysisEngine.instance.logger.logError( 8340 AnalysisEngine.instance.logger.logError(
8299 "Internal Error: Could not access AST for ${source.fullName} dur ing constant evaluation", 8341 "Internal Error: Could not access AST for ${source.fullName} dur ing constant evaluation",
8300 new CaughtException(exception, stackTrace)); 8342 new CaughtException(exception, stackTrace));
8301 } 8343 }
8302 } 8344 }
8303 } 8345 }
8304 computer.computeValues(); 8346 computer.computeValues();
8305 // As a temporary workaround for issue 21572, run ConstantVerifier now. 8347 // As a temporary workaround for issue 21572, run ConstantVerifier now.
8306 // TODO(paulberry): remove this workaround once issue 21572 is fixed. 8348 // TODO(paulberry): remove this workaround once issue 21572 is fixed.
8307 for (Library library in _librariesInCycles) { 8349 for (Library library in _librariesInCycles) {
8308 for (Source source in library.compilationUnitSources) { 8350 for (Source source in library.compilationUnitSources) {
8309 try { 8351 try {
8310 CompilationUnit unit = library.getAST(source); 8352 CompilationUnit unit = library.getAST(source);
8311 ErrorReporter errorReporter = 8353 ErrorReporter errorReporter =
8312 new ErrorReporter(_errorListener, source); 8354 new ErrorReporter(_errorListener, source);
8313 ConstantVerifier constantVerifier = new ConstantVerifier( 8355 ConstantVerifier constantVerifier = new ConstantVerifier(
8314 errorReporter, 8356 errorReporter,
8315 library.libraryElement, 8357 library.libraryElement,
8316 _typeProvider, 8358 _typeProvider,
8359 _typeSystem,
8317 analysisContext.declaredVariables); 8360 analysisContext.declaredVariables);
8318 unit.accept(constantVerifier); 8361 unit.accept(constantVerifier);
8319 } on AnalysisException catch (exception, stackTrace) { 8362 } on AnalysisException catch (exception, stackTrace) {
8320 AnalysisEngine.instance.logger.logError( 8363 AnalysisEngine.instance.logger.logError(
8321 "Internal Error: Could not access AST for ${source.fullName} " 8364 "Internal Error: Could not access AST for ${source.fullName} "
8322 "during constant verification", 8365 "during constant verification",
8323 new CaughtException(exception, stackTrace)); 8366 new CaughtException(exception, stackTrace));
8324 } 8367 }
8325 } 8368 }
8326 } 8369 }
(...skipping 12 matching lines...) Expand all
8339 for (Source source in library.compilationUnitSources) { 8382 for (Source source in library.compilationUnitSources) {
8340 CompilationUnit ast = library.getAST(source); 8383 CompilationUnit ast = library.getAST(source);
8341 ast.accept(new VariableResolverVisitor(library.libraryElement, source, 8384 ast.accept(new VariableResolverVisitor(library.libraryElement, source,
8342 _typeProvider, library.errorListener, 8385 _typeProvider, library.errorListener,
8343 nameScope: library.libraryScope)); 8386 nameScope: library.libraryScope));
8344 ResolverVisitorFactory visitorFactory = 8387 ResolverVisitorFactory visitorFactory =
8345 analysisContext.resolverVisitorFactory; 8388 analysisContext.resolverVisitorFactory;
8346 ResolverVisitor visitor = visitorFactory != null 8389 ResolverVisitor visitor = visitorFactory != null
8347 ? visitorFactory(library, source, _typeProvider) 8390 ? visitorFactory(library, source, _typeProvider)
8348 : new ResolverVisitor(library.libraryElement, source, _typeProvider, 8391 : new ResolverVisitor(library.libraryElement, source, _typeProvider,
8349 library.errorListener, 8392 _typeSystem, library.errorListener,
8350 nameScope: library.libraryScope, 8393 nameScope: library.libraryScope,
8351 inheritanceManager: library.inheritanceManager); 8394 inheritanceManager: library.inheritanceManager);
8352 ast.accept(visitor); 8395 ast.accept(visitor);
8353 } 8396 }
8354 }); 8397 });
8355 } 8398 }
8356 8399
8357 /** 8400 /**
8358 * Return the result of resolving the URI of the given URI-based directive aga inst the URI of the 8401 * Return the result of resolving the URI of the given URI-based directive aga inst the URI of the
8359 * given library, or `null` if the URI is not valid. 8402 * given library, or `null` if the URI is not valid.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
8412 * The object representing the async library. 8455 * The object representing the async library.
8413 */ 8456 */
8414 ResolvableLibrary _asyncLibrary; 8457 ResolvableLibrary _asyncLibrary;
8415 8458
8416 /** 8459 /**
8417 * The object used to access the types from the core library. 8460 * The object used to access the types from the core library.
8418 */ 8461 */
8419 TypeProvider _typeProvider; 8462 TypeProvider _typeProvider;
8420 8463
8421 /** 8464 /**
8465 * The type system in use for the library
8466 */
8467 TypeSystem _typeSystem;
8468
8469 /**
8422 * A table mapping library sources to the information being maintained for tho se libraries. 8470 * A table mapping library sources to the information being maintained for tho se libraries.
8423 */ 8471 */
8424 HashMap<Source, ResolvableLibrary> _libraryMap = 8472 HashMap<Source, ResolvableLibrary> _libraryMap =
8425 new HashMap<Source, ResolvableLibrary>(); 8473 new HashMap<Source, ResolvableLibrary>();
8426 8474
8427 /** 8475 /**
8428 * A collection containing the libraries that are being resolved together. 8476 * A collection containing the libraries that are being resolved together.
8429 */ 8477 */
8430 List<ResolvableLibrary> _librariesInCycle; 8478 List<ResolvableLibrary> _librariesInCycle;
8431 8479
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
8501 LibraryElement coreElement = _coreLibrary.libraryElement; 8549 LibraryElement coreElement = _coreLibrary.libraryElement;
8502 if (coreElement == null) { 8550 if (coreElement == null) {
8503 missingCoreLibrary(analysisContext, _coreLibrarySource); 8551 missingCoreLibrary(analysisContext, _coreLibrarySource);
8504 } 8552 }
8505 LibraryElement asyncElement = _asyncLibrary.libraryElement; 8553 LibraryElement asyncElement = _asyncLibrary.libraryElement;
8506 if (asyncElement == null) { 8554 if (asyncElement == null) {
8507 missingAsyncLibrary(analysisContext, _asyncLibrarySource); 8555 missingAsyncLibrary(analysisContext, _asyncLibrarySource);
8508 } 8556 }
8509 _buildDirectiveModels(); 8557 _buildDirectiveModels();
8510 _typeProvider = new TypeProviderImpl(coreElement, asyncElement); 8558 _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
8559 _typeSystem = TypeSystem.create(analysisContext);
8511 _buildEnumMembers(); 8560 _buildEnumMembers();
8512 _buildTypeHierarchies(); 8561 _buildTypeHierarchies();
8513 // 8562 //
8514 // Perform resolution and type analysis. 8563 // Perform resolution and type analysis.
8515 // 8564 //
8516 // TODO(brianwilkerson) Decide whether we want to resolve all of the 8565 // TODO(brianwilkerson) Decide whether we want to resolve all of the
8517 // libraries or whether we want to only resolve the target library. The 8566 // libraries or whether we want to only resolve the target library. The
8518 // advantage to resolving everything is that we have already done part of 8567 // advantage to resolving everything is that we have already done part of
8519 // the work so we'll avoid duplicated effort. The disadvantage of 8568 // the work so we'll avoid duplicated effort. The disadvantage of
8520 // resolving everything is that we might do extra work that we don't 8569 // resolving everything is that we might do extra work that we don't
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
8774 } 8823 }
8775 return identifiers; 8824 return identifiers;
8776 } 8825 }
8777 8826
8778 /** 8827 /**
8779 * Compute a value for all of the constants in the libraries being analyzed. 8828 * Compute a value for all of the constants in the libraries being analyzed.
8780 */ 8829 */
8781 void _performConstantEvaluation() { 8830 void _performConstantEvaluation() {
8782 PerformanceStatistics.resolve.makeCurrentWhile(() { 8831 PerformanceStatistics.resolve.makeCurrentWhile(() {
8783 ConstantValueComputer computer = new ConstantValueComputer( 8832 ConstantValueComputer computer = new ConstantValueComputer(
8784 analysisContext, _typeProvider, analysisContext.declaredVariables); 8833 analysisContext,
8834 _typeProvider,
8835 _typeSystem,
8836 analysisContext.declaredVariables);
8785 for (ResolvableLibrary library in _librariesInCycle) { 8837 for (ResolvableLibrary library in _librariesInCycle) {
8786 for (ResolvableCompilationUnit unit 8838 for (ResolvableCompilationUnit unit
8787 in library.resolvableCompilationUnits) { 8839 in library.resolvableCompilationUnits) {
8788 CompilationUnit ast = unit.compilationUnit; 8840 CompilationUnit ast = unit.compilationUnit;
8789 if (ast != null) { 8841 if (ast != null) {
8790 computer.add(ast, unit.source, library.librarySource); 8842 computer.add(ast, unit.source, library.librarySource);
8791 } 8843 }
8792 } 8844 }
8793 } 8845 }
8794 computer.computeValues(); 8846 computer.computeValues();
8795 // As a temporary workaround for issue 21572, run ConstantVerifier now. 8847 // As a temporary workaround for issue 21572, run ConstantVerifier now.
8796 // TODO(paulberry): remove this workaround once issue 21572 is fixed. 8848 // TODO(paulberry): remove this workaround once issue 21572 is fixed.
8797 for (ResolvableLibrary library in _librariesInCycle) { 8849 for (ResolvableLibrary library in _librariesInCycle) {
8798 for (ResolvableCompilationUnit unit 8850 for (ResolvableCompilationUnit unit
8799 in library.resolvableCompilationUnits) { 8851 in library.resolvableCompilationUnits) {
8800 CompilationUnit ast = unit.compilationUnit; 8852 CompilationUnit ast = unit.compilationUnit;
8801 ErrorReporter errorReporter = 8853 ErrorReporter errorReporter =
8802 new ErrorReporter(_errorListener, unit.source); 8854 new ErrorReporter(_errorListener, unit.source);
8803 ConstantVerifier constantVerifier = new ConstantVerifier( 8855 ConstantVerifier constantVerifier = new ConstantVerifier(
8804 errorReporter, 8856 errorReporter,
8805 library.libraryElement, 8857 library.libraryElement,
8806 _typeProvider, 8858 _typeProvider,
8859 _typeSystem,
8807 analysisContext.declaredVariables); 8860 analysisContext.declaredVariables);
8808 ast.accept(constantVerifier); 8861 ast.accept(constantVerifier);
8809 } 8862 }
8810 } 8863 }
8811 }); 8864 });
8812 } 8865 }
8813 8866
8814 /** 8867 /**
8815 * Resolve the identifiers and perform type analysis in the libraries in the c urrent cycle. 8868 * Resolve the identifiers and perform type analysis in the libraries in the c urrent cycle.
8816 * 8869 *
(...skipping 15 matching lines...) Expand all
8832 */ 8885 */
8833 void _resolveReferencesAndTypesInLibrary(ResolvableLibrary library) { 8886 void _resolveReferencesAndTypesInLibrary(ResolvableLibrary library) {
8834 PerformanceStatistics.resolve.makeCurrentWhile(() { 8887 PerformanceStatistics.resolve.makeCurrentWhile(() {
8835 for (ResolvableCompilationUnit unit 8888 for (ResolvableCompilationUnit unit
8836 in library.resolvableCompilationUnits) { 8889 in library.resolvableCompilationUnits) {
8837 Source source = unit.source; 8890 Source source = unit.source;
8838 CompilationUnit ast = unit.compilationUnit; 8891 CompilationUnit ast = unit.compilationUnit;
8839 ast.accept(new VariableResolverVisitor(library.libraryElement, source, 8892 ast.accept(new VariableResolverVisitor(library.libraryElement, source,
8840 _typeProvider, library.libraryScope.errorListener, 8893 _typeProvider, library.libraryScope.errorListener,
8841 nameScope: library.libraryScope)); 8894 nameScope: library.libraryScope));
8842 ResolverVisitor visitor = new ResolverVisitor(library.libraryElement, 8895 ResolverVisitor visitor = new ResolverVisitor(
8843 source, _typeProvider, library._libraryScope.errorListener, 8896 library.libraryElement,
8897 source,
8898 _typeProvider,
8899 _typeSystem,
8900 library._libraryScope.errorListener,
8844 nameScope: library._libraryScope, 8901 nameScope: library._libraryScope,
8845 inheritanceManager: library.inheritanceManager); 8902 inheritanceManager: library.inheritanceManager);
8846 ast.accept(visitor); 8903 ast.accept(visitor);
8847 } 8904 }
8848 }); 8905 });
8849 } 8906 }
8850 8907
8851 /** 8908 /**
8852 * Report that the async library could not be resolved in the given 8909 * Report that the async library could not be resolved in the given
8853 * [analysisContext] and throw an exception. [asyncLibrarySource] is the sour ce 8910 * [analysisContext] and throw an exception. [asyncLibrarySource] is the sour ce
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after
9582 * listener that will be informed of any errors that are found during 9639 * listener that will be informed of any errors that are found during
9583 * resolution. The [nameScope] is the scope used to resolve identifiers in the 9640 * resolution. The [nameScope] is the scope used to resolve identifiers in the
9584 * node that will first be visited. If `null` or unspecified, a new 9641 * node that will first be visited. If `null` or unspecified, a new
9585 * [LibraryScope] will be created based on [definingLibrary] and 9642 * [LibraryScope] will be created based on [definingLibrary] and
9586 * [typeProvider]. The [inheritanceManager] is used to perform inheritance 9643 * [typeProvider]. The [inheritanceManager] is used to perform inheritance
9587 * lookups. If `null` or unspecified, a new [InheritanceManager] will be 9644 * lookups. If `null` or unspecified, a new [InheritanceManager] will be
9588 * created based on [definingLibrary]. The [typeAnalyzerFactory] is used to 9645 * created based on [definingLibrary]. The [typeAnalyzerFactory] is used to
9589 * create the type analyzer. If `null` or unspecified, a type analyzer of 9646 * create the type analyzer. If `null` or unspecified, a type analyzer of
9590 * type [StaticTypeAnalyzer] will be created. 9647 * type [StaticTypeAnalyzer] will be created.
9591 */ 9648 */
9592 PartialResolverVisitor(LibraryElement definingLibrary, Source source, 9649 PartialResolverVisitor(
9593 TypeProvider typeProvider, AnalysisErrorListener errorListener, 9650 LibraryElement definingLibrary,
9651 Source source,
9652 TypeProvider typeProvider,
9653 TypeSystem typeSystem,
9654 AnalysisErrorListener errorListener,
9594 {Scope nameScope, 9655 {Scope nameScope,
9595 InheritanceManager inheritanceManager, 9656 InheritanceManager inheritanceManager,
9596 StaticTypeAnalyzerFactory typeAnalyzerFactory}) 9657 StaticTypeAnalyzerFactory typeAnalyzerFactory})
9597 : strongMode = definingLibrary.context.analysisOptions.strongMode, 9658 : strongMode = definingLibrary.context.analysisOptions.strongMode,
9598 super(definingLibrary, source, typeProvider, 9659 super(definingLibrary, source, typeProvider, typeSystem,
9599 new DisablableErrorListener(errorListener)); 9660 new DisablableErrorListener(errorListener));
9600 9661
9601 @override 9662 @override
9602 Object visitBlockFunctionBody(BlockFunctionBody node) { 9663 Object visitBlockFunctionBody(BlockFunctionBody node) {
9603 if (_shouldBeSkipped(node)) { 9664 if (_shouldBeSkipped(node)) {
9604 return null; 9665 return null;
9605 } 9666 }
9606 return super.visitBlockFunctionBody(node); 9667 return super.visitBlockFunctionBody(node);
9607 } 9668 }
9608 9669
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
10287 * listener that will be informed of any errors that are found during 10348 * listener that will be informed of any errors that are found during
10288 * resolution. The [nameScope] is the scope used to resolve identifiers in the 10349 * resolution. The [nameScope] is the scope used to resolve identifiers in the
10289 * node that will first be visited. If `null` or unspecified, a new 10350 * node that will first be visited. If `null` or unspecified, a new
10290 * [LibraryScope] will be created based on [definingLibrary] and 10351 * [LibraryScope] will be created based on [definingLibrary] and
10291 * [typeProvider]. The [inheritanceManager] is used to perform inheritance 10352 * [typeProvider]. The [inheritanceManager] is used to perform inheritance
10292 * lookups. If `null` or unspecified, a new [InheritanceManager] will be 10353 * lookups. If `null` or unspecified, a new [InheritanceManager] will be
10293 * created based on [definingLibrary]. The [typeAnalyzerFactory] is used to 10354 * created based on [definingLibrary]. The [typeAnalyzerFactory] is used to
10294 * create the type analyzer. If `null` or unspecified, a type analyzer of 10355 * create the type analyzer. If `null` or unspecified, a type analyzer of
10295 * type [StaticTypeAnalyzer] will be created. 10356 * type [StaticTypeAnalyzer] will be created.
10296 */ 10357 */
10297 ResolverVisitor(LibraryElement definingLibrary, Source source, 10358 ResolverVisitor(
10298 TypeProvider typeProvider, AnalysisErrorListener errorListener, 10359 LibraryElement definingLibrary,
10360 Source source,
10361 TypeProvider typeProvider,
10362 TypeSystem typeSystem,
10363 AnalysisErrorListener errorListener,
10299 {Scope nameScope, 10364 {Scope nameScope,
10300 InheritanceManager inheritanceManager, 10365 InheritanceManager inheritanceManager,
10301 StaticTypeAnalyzerFactory typeAnalyzerFactory}) 10366 StaticTypeAnalyzerFactory typeAnalyzerFactory})
10302 : super(definingLibrary, source, typeProvider, errorListener, 10367 : super(definingLibrary, source, typeProvider, errorListener,
10303 nameScope: nameScope) { 10368 nameScope: nameScope) {
10304 if (inheritanceManager == null) { 10369 if (inheritanceManager == null) {
10305 this._inheritanceManager = new InheritanceManager(definingLibrary); 10370 this._inheritanceManager = new InheritanceManager(definingLibrary);
10306 } else { 10371 } else {
10307 this._inheritanceManager = inheritanceManager; 10372 this._inheritanceManager = inheritanceManager;
10308 } 10373 }
10309 this.elementResolver = new ElementResolver(this); 10374 this.elementResolver = new ElementResolver(this);
10310 if (typeAnalyzerFactory == null) { 10375 if (typeAnalyzerFactory == null) {
10311 this.typeAnalyzer = new StaticTypeAnalyzer(this); 10376 this.typeAnalyzer = new StaticTypeAnalyzer(this, typeSystem);
10312 } else { 10377 } else {
10313 this.typeAnalyzer = typeAnalyzerFactory(this); 10378 this.typeAnalyzer = typeAnalyzerFactory(this);
10314 } 10379 }
10315 } 10380 }
10316 10381
10317 /** 10382 /**
10318 * Initialize a newly created visitor to resolve the nodes in a compilation un it. 10383 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
10319 * 10384 *
10320 * @param library the library containing the compilation unit being resolved 10385 * @param library the library containing the compilation unit being resolved
10321 * @param source the source representing the compilation unit being visited 10386 * @param source the source representing the compilation unit being visited
10322 * @param typeProvider the object used to access the types from the core libra ry 10387 * @param typeProvider the object used to access the types from the core libra ry
10323 * 10388 *
10324 * Deprecated. Please use unnamed constructor instead. 10389 * Deprecated. Please use unnamed constructor instead.
10325 */ 10390 */
10326 @deprecated 10391 @deprecated
10327 ResolverVisitor.con1( 10392 ResolverVisitor.con1(Library library, Source source,
10328 Library library, Source source, TypeProvider typeProvider, 10393 TypeProvider typeProvider, TypeSystem typeSystem,
10329 {StaticTypeAnalyzerFactory typeAnalyzerFactory}) 10394 {StaticTypeAnalyzerFactory typeAnalyzerFactory})
10330 : this( 10395 : this(library.libraryElement, source, typeProvider, typeSystem,
10331 library.libraryElement, source, typeProvider, library.errorListener, 10396 library.errorListener,
10332 nameScope: library.libraryScope, 10397 nameScope: library.libraryScope,
10333 inheritanceManager: library.inheritanceManager, 10398 inheritanceManager: library.inheritanceManager,
10334 typeAnalyzerFactory: typeAnalyzerFactory); 10399 typeAnalyzerFactory: typeAnalyzerFactory);
10335 10400
10336 /** 10401 /**
10337 * Return the element representing the function containing the current node, o r `null` if 10402 * Return the element representing the function containing the current node, o r `null` if
10338 * the current node is not contained in a function. 10403 * the current node is not contained in a function.
10339 * 10404 *
10340 * @return the element representing the function containing the current node 10405 * @return the element representing the function containing the current node
10341 */ 10406 */
(...skipping 4547 matching lines...) Expand 10 before | Expand all | Expand 10 after
14889 } 14954 }
14890 14955
14891 /** 14956 /**
14892 * The interface `TypeSystem` defines the behavior of an object representing 14957 * The interface `TypeSystem` defines the behavior of an object representing
14893 * the type system. This provides a common location to put methods that act on 14958 * the type system. This provides a common location to put methods that act on
14894 * types but may need access to more global data structures, and it paves the 14959 * types but may need access to more global data structures, and it paves the
14895 * way for a possible future where we may wish to make the type system 14960 * way for a possible future where we may wish to make the type system
14896 * pluggable. 14961 * pluggable.
14897 */ 14962 */
14898 abstract class TypeSystem { 14963 abstract class TypeSystem {
14899 /** 14964 /* Create either a strong mode or regular type system based on context.
Brian Wilkerson 2015/09/16 14:00:45 nit: Why is this (and several other places) just a
Leaf 2015/09/16 21:07:55 Because I'm not very used to using doc comment con
14900 * Return the [TypeProvider] associated with this [TypeSystem].
14901 */ 14965 */
14902 TypeProvider get typeProvider; 14966 static TypeSystem create(AnalysisContext context) {
14967 return (context.analysisOptions.strongMode)
14968 ? new StrongTypeSystemImpl()
14969 : new TypeSystemImpl();
14970 }
14903 14971
14904 /** 14972 /**
14905 * Compute the least upper bound of two types. 14973 * Compute the least upper bound of two types.
14906 */ 14974 */
14907 DartType getLeastUpperBound(DartType type1, DartType type2); 14975 DartType getLeastUpperBound(
14976 TypeProvider typeProvider, DartType type1, DartType type2);
14977
14978 /**
14979 * Return `true` if the [leftType] is assignable to the [rightType] (that is,
14980 * if leftType <==> rightType).
14981 */
14982 bool isAssignableTo(DartType leftType, DartType rightType);
14908 14983
14909 /** 14984 /**
14910 * Return `true` if the [leftType] is a subtype of the [rightType] (that is, 14985 * Return `true` if the [leftType] is a subtype of the [rightType] (that is,
14911 * if leftType <: rightType). 14986 * if leftType <: rightType).
14912 */ 14987 */
14913 bool isSubtypeOf(DartType leftType, DartType rightType); 14988 bool isSubtypeOf(DartType leftType, DartType rightType);
14914 } 14989 }
14915 14990
14916 /** 14991 /**
14917 * Implementation of [TypeSystem] using the rules in the Dart specification. 14992 * Implementation of [TypeSystem] using the rules in the Dart specification.
14918 */ 14993 */
14919 class TypeSystemImpl implements TypeSystem { 14994 class TypeSystemImpl implements TypeSystem {
14920 @override 14995 TypeSystemImpl();
14921 final TypeProvider typeProvider;
14922
14923 TypeSystemImpl(this.typeProvider);
14924 14996
14925 @override 14997 @override
14926 DartType getLeastUpperBound(DartType type1, DartType type2) { 14998 DartType getLeastUpperBound(
14999 TypeProvider typeProvider, DartType type1, DartType type2) {
14927 // The least upper bound relation is reflexive. 15000 // The least upper bound relation is reflexive.
14928 if (identical(type1, type2)) { 15001 if (identical(type1, type2)) {
14929 return type1; 15002 return type1;
14930 } 15003 }
14931 // The least upper bound of dynamic and any type T is dynamic. 15004 // The least upper bound of dynamic and any type T is dynamic.
14932 if (type1.isDynamic) { 15005 if (type1.isDynamic) {
14933 return type1; 15006 return type1;
14934 } 15007 }
14935 if (type2.isDynamic) { 15008 if (type2.isDynamic) {
14936 return type2; 15009 return type2;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
14995 } 15068 }
14996 return result; 15069 return result;
14997 } else { 15070 } else {
14998 // Should never happen. As a defensive measure, return the dynamic type. 15071 // Should never happen. As a defensive measure, return the dynamic type.
14999 assert(false); 15072 assert(false);
15000 return typeProvider.dynamicType; 15073 return typeProvider.dynamicType;
15001 } 15074 }
15002 } 15075 }
15003 15076
15004 @override 15077 @override
15078 bool isAssignableTo(DartType leftType, DartType rightType) {
15079 return leftType.isAssignableTo(rightType);
15080 }
15081
15082 @override
15005 bool isSubtypeOf(DartType leftType, DartType rightType) { 15083 bool isSubtypeOf(DartType leftType, DartType rightType) {
15006 return leftType.isSubtypeOf(rightType); 15084 return leftType.isSubtypeOf(rightType);
15007 } 15085 }
15008 } 15086 }
15009 15087
15088 typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<Element> visited);
15089 typedef bool _SubtypeChecker<T>(T t1, T t2);
15090
15091 /**
15092 * Implementation of [TypeSystem] using the strong mode rules.
Brian Wilkerson 2015/09/16 14:00:45 We should either document the strong mode semantic
Leaf 2015/09/16 21:07:55 Done.
15093 */
15094 class StrongTypeSystemImpl implements TypeSystem {
15095 StrongTypeSystemImpl();
15096
15097 final _specTypeSystem = new TypeSystemImpl();
15098
15099 @override
15100 DartType getLeastUpperBound(
15101 TypeProvider typeProvider, DartType type1, DartType type2) {
15102 // TODO(leafp): Implement a strong mode version of this.
15103 return _specTypeSystem.getLeastUpperBound(typeProvider, type1, type2);
15104 }
15105
15106 @override
15107 bool isAssignableTo(DartType toType, DartType fromType) {
15108 // An actual subtype
15109 if (isSubtypeOf(fromType, toType)) {
15110 return true;
15111 }
15112
15113 // Don't allow implicit downcasts between function types
15114 // and call method objects, as these will almost always fail.
15115 if ((fromType is FunctionType && _getCallMethodType(toType) != null) ||
15116 (toType is FunctionType && _getCallMethodType(fromType) != null)) {
15117 return false;
15118 }
15119
15120 // If the subtype relation goes the other way, allow the implicit downcast.
15121 // TODO(leafp): Emit warnings and hints for these in some way.
15122 // TODO(leafp): Consider adding a flag to disable these? Or just rely on
15123 // --warnings-as-errors?
15124 if (isSubtypeOf(toType, fromType) ||
15125 _specTypeSystem.isAssignableTo(toType, fromType)) {
15126 // TODO(leafp): error if type is known to be exact (literal,
15127 // instance creation).
15128 // TODO(leafp): Warn on composite downcast.
15129 // TODO(leafp): hint on object/dynamic downcast.
15130 // TODO(leafp): Consider allowing assignment casts.
15131 return true;
15132 }
15133
15134 return false;
15135 }
15136
15137 bool _isBottom(DartType t, {bool dynamicIsBottom: false}) {
15138 if (t.isDynamic && dynamicIsBottom) return true;
15139 if (t.isBottom) return true;
Brian Wilkerson 2015/09/16 14:00:45 nit: Why not just "return t.isBottom;"?
Leaf 2015/09/16 21:07:55 Done.
15140 return false;
15141 }
15142
15143 bool _isTop(DartType t, {bool dynamicIsBottom: false}) {
15144 if (t.isDynamic && !dynamicIsBottom) return true;
15145 if (t.isObject) return true;
Brian Wilkerson 2015/09/16 14:00:45 nit: Similarly, why not just "return t.isObject;"?
Leaf 2015/09/16 21:07:55 Done.
15146 return false;
15147 }
15148
15149 /// Given a type t, if t is an interface type with a call method
15150 /// defined, return the function type for the call method, otherwise
15151 /// return null.
15152 FunctionType _getCallMethodType(DartType t) {
15153 if (t is InterfaceType) {
15154 ClassElement element = t.element;
15155 InheritanceManager manager = new InheritanceManager(element.library);
15156 FunctionType callType = manager.lookupMemberType(t, "call");
15157 return callType;
15158 }
15159 return null;
15160 }
15161
15162 /* Check that f1 is a subtype of f2.
Brian Wilkerson 2015/09/16 14:00:45 nit: This should be a doc comment and 'f1' and 'f2
Leaf 2015/09/16 21:07:55 Done.
15163 * [fuzzyArrows] indicates whether or not the f1 and f2 should be
15164 * treated as fuzzy arrow types (and hence dynamic parameters to f2 treated as
15165 * bottom).
15166 */
15167 bool _isFunctionSubtypeOf(FunctionType f1, FunctionType f2,
15168 {bool fuzzyArrows: true}) {
15169 final r1s = f1.normalParameterTypes;
15170 final o1s = f1.optionalParameterTypes;
15171 final n1s = f1.namedParameterTypes;
15172 final r2s = f2.normalParameterTypes;
15173 final o2s = f2.optionalParameterTypes;
15174 final n2s = f2.namedParameterTypes;
15175 final ret1 = f1.returnType;
15176 final ret2 = f2.returnType;
15177
15178 // A -> B <: C -> D if C <: A and
15179 // either D is void or B <: D
15180 if (!ret2.isVoid && !isSubtypeOf(ret1, ret2)) {
15181 return false;
15182 }
15183
15184 // Reject if one has named and the other has optional
15185 if (n1s.length > 0 && o2s.length > 0) {
15186 return false;
15187 }
15188 if (n2s.length > 0 && o1s.length > 0) {
15189 return false;
15190 }
15191
15192 // Rebind _isSubtypeOf for convenience
15193 _SubtypeChecker<DartType> parameterSubtype = (DartType t1, DartType t2) =>
15194 _isSubtypeOf(t1, t2, null, dynamicIsBottom: fuzzyArrows);
15195
15196 // f2 has named parameters
15197 if (n2s.length > 0) {
15198 // Check that every named parameter in f2 has a match in f1
15199 for (String k2 in n2s.keys) {
15200 if (!n1s.containsKey(k2)) {
15201 return false;
15202 }
15203 if (!parameterSubtype(n2s[k2], n1s[k2])) {
15204 return false;
15205 }
15206 }
15207 }
15208 // If we get here, we either have no named parameters,
15209 // or else the named parameters match and we have no optional
15210 // parameters
15211
15212 // If f1 has more required parameters, reject
15213 if (r1s.length > r2s.length) {
15214 return false;
15215 }
15216
15217 // If f2 has more required + optional parameters, reject
15218 if (r2s.length + o2s.length > r1s.length + o1s.length) {
15219 return false;
15220 }
15221
15222 // The parameter lists must look like the following at this point
15223 // where rrr is a region of required, and ooo is a region of optionals.
15224 // f1: rrr ooo ooo ooo
15225 // f2: rrr rrr ooo
15226 int rr = r1s.length; // required in both
15227 int or = r2s.length - r1s.length; // optional in f1, required in f2
15228 int oo = o2s.length; // optional in both
15229
15230 for (int i = 0; i < rr; ++i) {
15231 if (!parameterSubtype(r2s[i], r1s[i])) {
15232 return false;
15233 }
15234 }
15235 for (int i = 0, j = rr; i < or; ++i, ++j) {
15236 if (!parameterSubtype(r2s[j], o1s[i])) {
15237 return false;
15238 }
15239 }
15240 for (int i = or, j = 0; i < oo; ++i, ++j) {
15241 if (!parameterSubtype(o2s[j], o1s[i])) {
15242 return false;
15243 }
15244 }
15245 return true;
15246 }
15247
15248 // Guard against loops in the class hierarchy
15249 _GuardedSubtypeChecker<DartType> _guard(
15250 _GuardedSubtypeChecker<DartType> check) {
15251 return (DartType t1, DartType t2, Set<Element> visited) {
15252 Element element = t1.element;
15253 if (visited == null) {
15254 visited = new HashSet<Element>();
15255 }
15256 if (element == null || !visited.add(element)) {
15257 return false;
15258 }
15259 try {
15260 return check(t1, t2, visited);
15261 } finally {
15262 visited.remove(element);
15263 }
15264 };
15265 }
15266
15267 bool _isInterfaceSubtypeOf(
Brian Wilkerson 2015/09/16 14:00:45 nit: Add doc comment?
Leaf 2015/09/16 21:07:55 Is the recommendation to use doc comments for ever
Brian Wilkerson 2015/09/16 22:54:51 My personal recommendation :-) is to use doc comme
15268 InterfaceType i1, InterfaceType i2, Set<Element> visited) {
15269 // Guard recursive calls
15270 _GuardedSubtypeChecker<InterfaceType> guardedInterfaceSubtype =
15271 _guard(_isInterfaceSubtypeOf);
15272
15273 if (i1 == i2) {
15274 return true;
15275 }
15276
15277 if (i1.element == i2.element) {
15278 List<DartType> tArgs1 = i1.typeArguments;
15279 List<DartType> tArgs2 = i2.typeArguments;
15280
15281 assert(tArgs1.length == tArgs2.length);
15282
15283 for (int i = 0; i < tArgs1.length; i++) {
15284 DartType t1 = tArgs1[i];
15285 DartType t2 = tArgs2[i];
15286 if (!isSubtypeOf(t1, t2)) {
15287 return false;
15288 }
15289 }
15290 return true;
15291 }
15292
15293 if (i2.isDartCoreFunction && i1.element.getMethod("call") != null) {
15294 return true;
15295 }
15296
15297 if (i1.isObject) {
15298 return false;
15299 }
15300
15301 if (guardedInterfaceSubtype(i1.superclass, i2, visited)) {
15302 return true;
15303 }
15304
15305 for (final parent in i1.interfaces) {
15306 if (guardedInterfaceSubtype(parent, i2, visited)) {
15307 return true;
15308 }
15309 }
15310
15311 for (final parent in i1.mixins) {
15312 if (guardedInterfaceSubtype(parent, i2, visited)) {
15313 return true;
15314 }
15315 }
15316
15317 return false;
15318 }
15319
15320 bool _isSubtypeOf(DartType t1, DartType t2, Set<Element> visited,
15321 {bool dynamicIsBottom: false}) {
15322 // Guard recursive calls
15323 _GuardedSubtypeChecker<DartType> guardedSubtype = _guard(_isSubtypeOf);
15324
15325 if (t1 == t2) {
15326 return true;
15327 }
15328
15329 // The types are void, dynamic, bottom, interface types, function types
15330 // and type parameters. We proceed by eliminating these different classes
15331 // from consideration.
15332
15333 // Trivially true.
15334 if (_isTop(t2, dynamicIsBottom: dynamicIsBottom) ||
15335 _isBottom(t1, dynamicIsBottom: dynamicIsBottom)) {
15336 return true;
15337 }
15338
15339 // Trivially false.
15340 if (_isTop(t1, dynamicIsBottom: dynamicIsBottom) ||
15341 _isBottom(t2, dynamicIsBottom: dynamicIsBottom)) {
15342 return false;
15343 }
15344
15345 // S <: T where S is a type variable
15346 // T is not dynamic or object (handled above)
15347 // S != T (handled above)
15348 // So only true if bound of S is S' and
15349 // S' <: T
15350 if (t1 is TypeParameterType) {
15351 DartType bound = t1.element.bound;
15352 if (bound == null) return false;
15353 return guardedSubtype(bound, t2, visited);
15354 }
15355
15356 if (t2 is TypeParameterType) {
15357 return false;
15358 }
15359
15360 if (t1.isVoid || t2.isVoid) {
15361 return false;
15362 }
15363
15364 // We've eliminated void, dynamic, bottom, and type parameters. The only
15365 // cases are the combinations of interface type and function type.
15366
15367 // A function type can only subtype an interface type if
15368 // the interface type is Function
15369 if (t1 is FunctionType && t2 is InterfaceType) {
15370 return t2.isDartCoreFunction;
15371 }
15372
15373 // An interface type can only subtype a function type if
15374 // the interface type declares a call method with a type
15375 // which is a super type of the function type.
15376 if (t1 is InterfaceType && t2 is FunctionType) {
15377 var callType = _getCallMethodType(t1);
15378 return (callType != null) && _isFunctionSubtypeOf(callType, t2);
15379 }
15380
15381 // Two interface types
15382 if (t1 is InterfaceType && t2 is InterfaceType) {
15383 return _isInterfaceSubtypeOf(t1, t2, visited);
15384 }
15385
15386 return _isFunctionSubtypeOf(t1 as FunctionType, t2 as FunctionType);
15387 }
15388
15389 @override
15390 bool isSubtypeOf(DartType leftType, DartType rightType) {
15391 return _isSubtypeOf(leftType, rightType, null);
15392 }
15393 }
15394
15010 /** 15395 /**
15011 * Instances of the class [UnusedLocalElementsVerifier] traverse an element 15396 * Instances of the class [UnusedLocalElementsVerifier] traverse an element
15012 * structure looking for cases of [HintCode.UNUSED_ELEMENT], 15397 * structure looking for cases of [HintCode.UNUSED_ELEMENT],
15013 * [HintCode.UNUSED_FIELD], [HintCode.UNUSED_LOCAL_VARIABLE], etc. 15398 * [HintCode.UNUSED_FIELD], [HintCode.UNUSED_LOCAL_VARIABLE], etc.
15014 */ 15399 */
15015 class UnusedLocalElementsVerifier extends RecursiveElementVisitor { 15400 class UnusedLocalElementsVerifier extends RecursiveElementVisitor {
15016 /** 15401 /**
15017 * The error listener to which errors will be reported. 15402 * The error listener to which errors will be reported.
15018 */ 15403 */
15019 final AnalysisErrorListener _errorListener; 15404 final AnalysisErrorListener _errorListener;
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
15402 } 15787 }
15403 return null; 15788 return null;
15404 } 15789 }
15405 } 15790 }
15406 15791
15407 class _ConstantVerifier_validateInitializerExpression extends ConstantVisitor { 15792 class _ConstantVerifier_validateInitializerExpression extends ConstantVisitor {
15408 final ConstantVerifier verifier; 15793 final ConstantVerifier verifier;
15409 15794
15410 List<ParameterElement> parameterElements; 15795 List<ParameterElement> parameterElements;
15411 15796
15797 TypeSystem _typeSystem;
15798
15412 _ConstantVerifier_validateInitializerExpression( 15799 _ConstantVerifier_validateInitializerExpression(
15413 TypeProvider typeProvider, 15800 TypeProvider typeProvider,
15801 TypeSystem typeSystem,
15414 ErrorReporter errorReporter, 15802 ErrorReporter errorReporter,
15415 this.verifier, 15803 this.verifier,
15416 this.parameterElements, 15804 this.parameterElements,
15417 DeclaredVariables declaredVariables) 15805 DeclaredVariables declaredVariables)
15418 : super(new ConstantEvaluationEngine(typeProvider, declaredVariables), 15806 : _typeSystem = typeSystem,
15807 super(
15808 new ConstantEvaluationEngine(
15809 typeProvider, typeSystem, declaredVariables),
15419 errorReporter); 15810 errorReporter);
15420 15811
15421 @override 15812 @override
15422 DartObjectImpl visitSimpleIdentifier(SimpleIdentifier node) { 15813 DartObjectImpl visitSimpleIdentifier(SimpleIdentifier node) {
15423 Element element = node.staticElement; 15814 Element element = node.staticElement;
15424 for (ParameterElement parameterElement in parameterElements) { 15815 for (ParameterElement parameterElement in parameterElements) {
15425 if (identical(parameterElement, element) && parameterElement != null) { 15816 if (identical(parameterElement, element) && parameterElement != null) {
15426 DartType type = parameterElement.type; 15817 DartType type = parameterElement.type;
15427 if (type != null) { 15818 if (type != null) {
15428 if (type.isDynamic) { 15819 if (type.isDynamic) {
15429 return new DartObjectImpl( 15820 return new DartObjectImpl(
15430 verifier._typeProvider.objectType, DynamicState.DYNAMIC_STATE); 15821 verifier._typeProvider.objectType, DynamicState.DYNAMIC_STATE);
15431 } else if (type.isSubtypeOf(verifier._boolType)) { 15822 } else if (_typeSystem.isSubtypeOf(type, verifier._boolType)) {
15432 return new DartObjectImpl( 15823 return new DartObjectImpl(
15433 verifier._typeProvider.boolType, BoolState.UNKNOWN_VALUE); 15824 verifier._typeProvider.boolType, BoolState.UNKNOWN_VALUE);
15434 } else if (type.isSubtypeOf(verifier._typeProvider.doubleType)) { 15825 } else if (_typeSystem.isSubtypeOf(
15826 type, verifier._typeProvider.doubleType)) {
15435 return new DartObjectImpl( 15827 return new DartObjectImpl(
15436 verifier._typeProvider.doubleType, DoubleState.UNKNOWN_VALUE); 15828 verifier._typeProvider.doubleType, DoubleState.UNKNOWN_VALUE);
15437 } else if (type.isSubtypeOf(verifier._intType)) { 15829 } else if (_typeSystem.isSubtypeOf(type, verifier._intType)) {
15438 return new DartObjectImpl( 15830 return new DartObjectImpl(
15439 verifier._typeProvider.intType, IntState.UNKNOWN_VALUE); 15831 verifier._typeProvider.intType, IntState.UNKNOWN_VALUE);
15440 } else if (type.isSubtypeOf(verifier._numType)) { 15832 } else if (_typeSystem.isSubtypeOf(type, verifier._numType)) {
15441 return new DartObjectImpl( 15833 return new DartObjectImpl(
15442 verifier._typeProvider.numType, NumState.UNKNOWN_VALUE); 15834 verifier._typeProvider.numType, NumState.UNKNOWN_VALUE);
15443 } else if (type.isSubtypeOf(verifier._stringType)) { 15835 } else if (_typeSystem.isSubtypeOf(type, verifier._stringType)) {
15444 return new DartObjectImpl( 15836 return new DartObjectImpl(
15445 verifier._typeProvider.stringType, StringState.UNKNOWN_VALUE); 15837 verifier._typeProvider.stringType, StringState.UNKNOWN_VALUE);
15446 } 15838 }
15447 // 15839 //
15448 // We don't test for other types of objects (such as List, Map, 15840 // We don't test for other types of objects (such as List, Map,
15449 // Function or Type) because there are no operations allowed on such 15841 // Function or Type) because there are no operations allowed on such
15450 // types other than '==' and '!=', which means that we don't need to 15842 // types other than '==' and '!=', which means that we don't need to
15451 // know the type when there is no specific data about the state of 15843 // know the type when there is no specific data about the state of
15452 // such objects. 15844 // such objects.
15453 // 15845 //
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
15566 nonFields.add(node); 15958 nonFields.add(node);
15567 return null; 15959 return null;
15568 } 15960 }
15569 15961
15570 @override 15962 @override
15571 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); 15963 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this);
15572 15964
15573 @override 15965 @override
15574 Object visitWithClause(WithClause node) => null; 15966 Object visitWithClause(WithClause node) => null;
15575 } 15967 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698