OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library analyzer.src.generated.resolver; | 5 library analyzer.src.generated.resolver; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/ast/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
(...skipping 7468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7479 } | 7479 } |
7480 } | 7480 } |
7481 return resolvedParameters; | 7481 return resolvedParameters; |
7482 } | 7482 } |
7483 } | 7483 } |
7484 | 7484 |
7485 /** | 7485 /** |
7486 * The abstract class `ScopedVisitor` maintains name and label scopes as an AST
structure is | 7486 * The abstract class `ScopedVisitor` maintains name and label scopes as an AST
structure is |
7487 * being visited. | 7487 * being visited. |
7488 */ | 7488 */ |
| 7489 /** |
| 7490 * The abstract class `ScopedVisitor` maintains name and label scopes as an AST
structure is |
| 7491 * being visited. |
| 7492 */ |
7489 abstract class ScopedVisitor extends UnifyingAstVisitor<Object> { | 7493 abstract class ScopedVisitor extends UnifyingAstVisitor<Object> { |
7490 /** | 7494 /** |
7491 * The element for the library containing the compilation unit being visited. | 7495 * The element for the library containing the compilation unit being visited. |
7492 */ | 7496 */ |
7493 final LibraryElement definingLibrary; | 7497 final LibraryElement definingLibrary; |
7494 | 7498 |
7495 /** | 7499 /** |
7496 * The source representing the compilation unit being visited. | 7500 * The source representing the compilation unit being visited. |
7497 */ | 7501 */ |
7498 final Source source; | 7502 final Source source; |
(...skipping 860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8359 /** | 8363 /** |
8360 * Helper for resolving [TypeName]s. | 8364 * Helper for resolving [TypeName]s. |
8361 * | 8365 * |
8362 * The client must set [nameScope] before calling [resolveTypeName]. | 8366 * The client must set [nameScope] before calling [resolveTypeName]. |
8363 */ | 8367 */ |
8364 class TypeNameResolver { | 8368 class TypeNameResolver { |
8365 final TypeSystem typeSystem; | 8369 final TypeSystem typeSystem; |
8366 final DartType dynamicType; | 8370 final DartType dynamicType; |
8367 final DartType undefinedType; | 8371 final DartType undefinedType; |
8368 final LibraryElement definingLibrary; | 8372 final LibraryElement definingLibrary; |
8369 final ErrorReporter errorReporter; | 8373 final Source source; |
| 8374 final AnalysisErrorListener errorListener; |
8370 | 8375 |
8371 Scope nameScope; | 8376 Scope nameScope; |
8372 | 8377 |
8373 TypeNameResolver(this.typeSystem, TypeProvider typeProvider, | 8378 TypeNameResolver(this.typeSystem, TypeProvider typeProvider, |
8374 this.definingLibrary, this.errorReporter) | 8379 this.definingLibrary, this.source, this.errorListener) |
8375 : dynamicType = typeProvider.dynamicType, | 8380 : dynamicType = typeProvider.dynamicType, |
8376 undefinedType = typeProvider.undefinedType; | 8381 undefinedType = typeProvider.undefinedType; |
8377 | 8382 |
8378 /** | 8383 /** |
| 8384 * Report an error with the given error code and arguments. |
| 8385 * |
| 8386 * @param errorCode the error code of the error to be reported |
| 8387 * @param node the node specifying the location of the error |
| 8388 * @param arguments the arguments to the error, used to compose the error mess
age |
| 8389 */ |
| 8390 void reportErrorForNode(ErrorCode errorCode, AstNode node, |
| 8391 [List<Object> arguments]) { |
| 8392 errorListener.onError(new AnalysisError( |
| 8393 source, node.offset, node.length, errorCode, arguments)); |
| 8394 } |
| 8395 |
| 8396 /** |
8379 * Resolve the given [TypeName] - set its element and static type. Only the | 8397 * Resolve the given [TypeName] - set its element and static type. Only the |
8380 * given [node] is resolved, all its children must be already resolved. | 8398 * given [node] is resolved, all its children must be already resolved. |
8381 * | 8399 * |
8382 * The client must set [nameScope] before calling [resolveTypeName]. | 8400 * The client must set [nameScope] before calling [resolveTypeName]. |
8383 */ | 8401 */ |
8384 void resolveTypeName(TypeName node) { | 8402 void resolveTypeName(TypeName node) { |
8385 Identifier typeName = node.name; | 8403 Identifier typeName = node.name; |
8386 _setElement(typeName, null); // Clear old Elements from previous run. | 8404 _setElement(typeName, null); // Clear old Elements from previous run. |
8387 TypeArgumentList argumentList = node.typeArguments; | 8405 TypeArgumentList argumentList = node.typeArguments; |
8388 Element element = nameScope.lookup(typeName, definingLibrary); | 8406 Element element = nameScope.lookup(typeName, definingLibrary); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8427 PrefixedIdentifier prefixedIdentifier = | 8445 PrefixedIdentifier prefixedIdentifier = |
8428 typeName as PrefixedIdentifier; | 8446 typeName as PrefixedIdentifier; |
8429 SimpleIdentifier prefix = prefixedIdentifier.prefix; | 8447 SimpleIdentifier prefix = prefixedIdentifier.prefix; |
8430 element = nameScope.lookup(prefix, definingLibrary); | 8448 element = nameScope.lookup(prefix, definingLibrary); |
8431 if (element is PrefixElement) { | 8449 if (element is PrefixElement) { |
8432 AstNode grandParent = parent.parent; | 8450 AstNode grandParent = parent.parent; |
8433 if (grandParent is InstanceCreationExpression && | 8451 if (grandParent is InstanceCreationExpression && |
8434 grandParent.isConst) { | 8452 grandParent.isConst) { |
8435 // If, if this is a const expression, then generate a | 8453 // If, if this is a const expression, then generate a |
8436 // CompileTimeErrorCode.CONST_WITH_NON_TYPE error. | 8454 // CompileTimeErrorCode.CONST_WITH_NON_TYPE error. |
8437 errorReporter.reportErrorForNode( | 8455 reportErrorForNode( |
8438 CompileTimeErrorCode.CONST_WITH_NON_TYPE, | 8456 CompileTimeErrorCode.CONST_WITH_NON_TYPE, |
8439 prefixedIdentifier.identifier, | 8457 prefixedIdentifier.identifier, |
8440 [prefixedIdentifier.identifier.name]); | 8458 [prefixedIdentifier.identifier.name]); |
8441 } else { | 8459 } else { |
8442 // Else, if this expression is a new expression, report a | 8460 // Else, if this expression is a new expression, report a |
8443 // NEW_WITH_NON_TYPE warning. | 8461 // NEW_WITH_NON_TYPE warning. |
8444 errorReporter.reportErrorForNode( | 8462 reportErrorForNode( |
8445 StaticWarningCode.NEW_WITH_NON_TYPE, | 8463 StaticWarningCode.NEW_WITH_NON_TYPE, |
8446 prefixedIdentifier.identifier, | 8464 prefixedIdentifier.identifier, |
8447 [prefixedIdentifier.identifier.name]); | 8465 [prefixedIdentifier.identifier.name]); |
8448 } | 8466 } |
8449 _setElement(prefix, element); | 8467 _setElement(prefix, element); |
8450 return; | 8468 return; |
8451 } else if (element != null) { | 8469 } else if (element != null) { |
8452 // | 8470 // |
8453 // Rewrite the constructor name. The parser, when it sees a | 8471 // Rewrite the constructor name. The parser, when it sees a |
8454 // constructor named "a.b", cannot tell whether "a" is a prefix and | 8472 // constructor named "a.b", cannot tell whether "a" is a prefix and |
(...skipping 12 matching lines...) Expand all Loading... |
8467 // check element | 8485 // check element |
8468 bool elementValid = element is! MultiplyDefinedElement; | 8486 bool elementValid = element is! MultiplyDefinedElement; |
8469 if (elementValid && | 8487 if (elementValid && |
8470 element is! ClassElement && | 8488 element is! ClassElement && |
8471 _isTypeNameInInstanceCreationExpression(node)) { | 8489 _isTypeNameInInstanceCreationExpression(node)) { |
8472 SimpleIdentifier typeNameSimple = _getTypeSimpleIdentifier(typeName); | 8490 SimpleIdentifier typeNameSimple = _getTypeSimpleIdentifier(typeName); |
8473 InstanceCreationExpression creation = | 8491 InstanceCreationExpression creation = |
8474 node.parent.parent as InstanceCreationExpression; | 8492 node.parent.parent as InstanceCreationExpression; |
8475 if (creation.isConst) { | 8493 if (creation.isConst) { |
8476 if (element == null) { | 8494 if (element == null) { |
8477 errorReporter.reportErrorForNode( | 8495 reportErrorForNode( |
8478 CompileTimeErrorCode.UNDEFINED_CLASS, typeNameSimple, [typeName]); | 8496 CompileTimeErrorCode.UNDEFINED_CLASS, typeNameSimple, [typeName]); |
8479 } else { | 8497 } else { |
8480 errorReporter.reportErrorForNode( | 8498 reportErrorForNode(CompileTimeErrorCode.CONST_WITH_NON_TYPE, |
8481 CompileTimeErrorCode.CONST_WITH_NON_TYPE, | 8499 typeNameSimple, [typeName]); |
8482 typeNameSimple, | |
8483 [typeName]); | |
8484 } | 8500 } |
8485 elementValid = false; | 8501 elementValid = false; |
8486 } else { | 8502 } else { |
8487 if (element != null) { | 8503 if (element != null) { |
8488 errorReporter.reportErrorForNode( | 8504 reportErrorForNode( |
8489 StaticWarningCode.NEW_WITH_NON_TYPE, typeNameSimple, [typeName]); | 8505 StaticWarningCode.NEW_WITH_NON_TYPE, typeNameSimple, [typeName]); |
8490 elementValid = false; | 8506 elementValid = false; |
8491 } | 8507 } |
8492 } | 8508 } |
8493 } | 8509 } |
8494 if (elementValid && element == null) { | 8510 if (elementValid && element == null) { |
8495 // We couldn't resolve the type name. | 8511 // We couldn't resolve the type name. |
8496 // TODO(jwren) Consider moving the check for | 8512 // TODO(jwren) Consider moving the check for |
8497 // CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE from the | 8513 // CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE from the |
8498 // ErrorVerifier, so that we don't have two errors on a built in | 8514 // ErrorVerifier, so that we don't have two errors on a built in |
8499 // identifier being used as a class name. | 8515 // identifier being used as a class name. |
8500 // See CompileTimeErrorCodeTest.test_builtInIdentifierAsType(). | 8516 // See CompileTimeErrorCodeTest.test_builtInIdentifierAsType(). |
8501 SimpleIdentifier typeNameSimple = _getTypeSimpleIdentifier(typeName); | 8517 SimpleIdentifier typeNameSimple = _getTypeSimpleIdentifier(typeName); |
8502 RedirectingConstructorKind redirectingConstructorKind; | 8518 RedirectingConstructorKind redirectingConstructorKind; |
8503 if (_isBuiltInIdentifier(node) && _isTypeAnnotation(node)) { | 8519 if (_isBuiltInIdentifier(node) && _isTypeAnnotation(node)) { |
8504 errorReporter.reportErrorForNode( | 8520 reportErrorForNode(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, |
8505 CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, | 8521 typeName, [typeName.name]); |
8506 typeName, | |
8507 [typeName.name]); | |
8508 } else if (typeNameSimple.name == "boolean") { | 8522 } else if (typeNameSimple.name == "boolean") { |
8509 errorReporter.reportErrorForNode( | 8523 reportErrorForNode( |
8510 StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, typeNameSimple, []); | 8524 StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, typeNameSimple, []); |
8511 } else if (_isTypeNameInCatchClause(node)) { | 8525 } else if (_isTypeNameInCatchClause(node)) { |
8512 errorReporter.reportErrorForNode( | 8526 reportErrorForNode(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, |
8513 StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, | |
8514 typeName, | |
8515 [typeName.name]); | 8527 [typeName.name]); |
8516 } else if (_isTypeNameInAsExpression(node)) { | 8528 } else if (_isTypeNameInAsExpression(node)) { |
8517 errorReporter.reportErrorForNode( | 8529 reportErrorForNode( |
8518 StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]); | 8530 StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]); |
8519 } else if (_isTypeNameInIsExpression(node)) { | 8531 } else if (_isTypeNameInIsExpression(node)) { |
8520 errorReporter.reportErrorForNode( | 8532 reportErrorForNode(StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME, |
8521 StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME, | 8533 typeName, [typeName.name]); |
8522 typeName, | |
8523 [typeName.name]); | |
8524 } else if ((redirectingConstructorKind = | 8534 } else if ((redirectingConstructorKind = |
8525 _getRedirectingConstructorKind(node)) != | 8535 _getRedirectingConstructorKind(node)) != |
8526 null) { | 8536 null) { |
8527 ErrorCode errorCode = | 8537 ErrorCode errorCode = |
8528 (redirectingConstructorKind == RedirectingConstructorKind.CONST | 8538 (redirectingConstructorKind == RedirectingConstructorKind.CONST |
8529 ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS | 8539 ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS |
8530 : StaticWarningCode.REDIRECT_TO_NON_CLASS); | 8540 : StaticWarningCode.REDIRECT_TO_NON_CLASS); |
8531 errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]); | 8541 reportErrorForNode(errorCode, typeName, [typeName.name]); |
8532 } else if (_isTypeNameInTypeArgumentList(node)) { | 8542 } else if (_isTypeNameInTypeArgumentList(node)) { |
8533 errorReporter.reportErrorForNode( | 8543 reportErrorForNode(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, |
8534 StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, | 8544 typeName, [typeName.name]); |
8535 typeName, | |
8536 [typeName.name]); | |
8537 } else { | 8545 } else { |
8538 errorReporter.reportErrorForNode( | 8546 reportErrorForNode( |
8539 StaticWarningCode.UNDEFINED_CLASS, typeName, [typeName.name]); | 8547 StaticWarningCode.UNDEFINED_CLASS, typeName, [typeName.name]); |
8540 } | 8548 } |
8541 elementValid = false; | 8549 elementValid = false; |
8542 } | 8550 } |
8543 if (!elementValid) { | 8551 if (!elementValid) { |
8544 if (element is MultiplyDefinedElement) { | 8552 if (element is MultiplyDefinedElement) { |
8545 _setElement(typeName, element); | 8553 _setElement(typeName, element); |
8546 } | 8554 } |
8547 typeName.staticType = undefinedType; | 8555 typeName.staticType = undefinedType; |
8548 node.type = undefinedType; | 8556 node.type = undefinedType; |
(...skipping 17 matching lines...) Expand all Loading... |
8566 } else if (element is MultiplyDefinedElement) { | 8574 } else if (element is MultiplyDefinedElement) { |
8567 List<Element> elements = element.conflictingElements; | 8575 List<Element> elements = element.conflictingElements; |
8568 type = _getTypeWhenMultiplyDefined(elements); | 8576 type = _getTypeWhenMultiplyDefined(elements); |
8569 if (type != null) { | 8577 if (type != null) { |
8570 node.type = type; | 8578 node.type = type; |
8571 } | 8579 } |
8572 } else { | 8580 } else { |
8573 // The name does not represent a type. | 8581 // The name does not represent a type. |
8574 RedirectingConstructorKind redirectingConstructorKind; | 8582 RedirectingConstructorKind redirectingConstructorKind; |
8575 if (_isTypeNameInCatchClause(node)) { | 8583 if (_isTypeNameInCatchClause(node)) { |
8576 errorReporter.reportErrorForNode( | 8584 reportErrorForNode(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, |
8577 StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, | |
8578 typeName, | |
8579 [typeName.name]); | 8585 [typeName.name]); |
8580 } else if (_isTypeNameInAsExpression(node)) { | 8586 } else if (_isTypeNameInAsExpression(node)) { |
8581 errorReporter.reportErrorForNode( | 8587 reportErrorForNode( |
8582 StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]); | 8588 StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]); |
8583 } else if (_isTypeNameInIsExpression(node)) { | 8589 } else if (_isTypeNameInIsExpression(node)) { |
8584 errorReporter.reportErrorForNode( | 8590 reportErrorForNode(StaticWarningCode.TYPE_TEST_WITH_NON_TYPE, typeName, |
8585 StaticWarningCode.TYPE_TEST_WITH_NON_TYPE, | |
8586 typeName, | |
8587 [typeName.name]); | 8591 [typeName.name]); |
8588 } else if ((redirectingConstructorKind = | 8592 } else if ((redirectingConstructorKind = |
8589 _getRedirectingConstructorKind(node)) != | 8593 _getRedirectingConstructorKind(node)) != |
8590 null) { | 8594 null) { |
8591 ErrorCode errorCode = | 8595 ErrorCode errorCode = |
8592 (redirectingConstructorKind == RedirectingConstructorKind.CONST | 8596 (redirectingConstructorKind == RedirectingConstructorKind.CONST |
8593 ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS | 8597 ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS |
8594 : StaticWarningCode.REDIRECT_TO_NON_CLASS); | 8598 : StaticWarningCode.REDIRECT_TO_NON_CLASS); |
8595 errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]); | 8599 reportErrorForNode(errorCode, typeName, [typeName.name]); |
8596 } else if (_isTypeNameInTypeArgumentList(node)) { | 8600 } else if (_isTypeNameInTypeArgumentList(node)) { |
8597 errorReporter.reportErrorForNode( | 8601 reportErrorForNode(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, |
8598 StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, | 8602 typeName, [typeName.name]); |
8599 typeName, | |
8600 [typeName.name]); | |
8601 } else { | 8603 } else { |
8602 AstNode parent = typeName.parent; | 8604 AstNode parent = typeName.parent; |
8603 while (parent is TypeName) { | 8605 while (parent is TypeName) { |
8604 parent = parent.parent; | 8606 parent = parent.parent; |
8605 } | 8607 } |
8606 if (parent is ExtendsClause || | 8608 if (parent is ExtendsClause || |
8607 parent is ImplementsClause || | 8609 parent is ImplementsClause || |
8608 parent is WithClause || | 8610 parent is WithClause || |
8609 parent is ClassTypeAlias) { | 8611 parent is ClassTypeAlias) { |
8610 // Ignored. The error will be reported elsewhere. | 8612 // Ignored. The error will be reported elsewhere. |
8611 } else { | 8613 } else { |
8612 errorReporter.reportErrorForNode( | 8614 reportErrorForNode( |
8613 StaticWarningCode.NOT_A_TYPE, typeName, [typeName.name]); | 8615 StaticWarningCode.NOT_A_TYPE, typeName, [typeName.name]); |
8614 } | 8616 } |
8615 } | 8617 } |
8616 typeName.staticType = dynamicType; | 8618 typeName.staticType = dynamicType; |
8617 node.type = dynamicType; | 8619 node.type = dynamicType; |
8618 return; | 8620 return; |
8619 } | 8621 } |
8620 if (argumentList != null) { | 8622 if (argumentList != null) { |
8621 NodeList<TypeName> arguments = argumentList.arguments; | 8623 NodeList<TypeName> arguments = argumentList.arguments; |
8622 int argumentCount = arguments.length; | 8624 int argumentCount = arguments.length; |
8623 List<DartType> parameters = typeSystem.typeFormalsAsTypes(type); | 8625 List<DartType> parameters = typeSystem.typeFormalsAsTypes(type); |
8624 int parameterCount = parameters.length; | 8626 int parameterCount = parameters.length; |
8625 List<DartType> typeArguments = new List<DartType>(parameterCount); | 8627 List<DartType> typeArguments = new List<DartType>(parameterCount); |
8626 if (argumentCount == parameterCount) { | 8628 if (argumentCount == parameterCount) { |
8627 for (int i = 0; i < parameterCount; i++) { | 8629 for (int i = 0; i < parameterCount; i++) { |
8628 TypeName argumentTypeName = arguments[i]; | 8630 TypeName argumentTypeName = arguments[i]; |
8629 DartType argumentType = _getType(argumentTypeName); | 8631 DartType argumentType = _getType(argumentTypeName); |
8630 if (argumentType == null) { | 8632 if (argumentType == null) { |
8631 argumentType = dynamicType; | 8633 argumentType = dynamicType; |
8632 } | 8634 } |
8633 typeArguments[i] = argumentType; | 8635 typeArguments[i] = argumentType; |
8634 } | 8636 } |
8635 } else { | 8637 } else { |
8636 errorReporter.reportErrorForNode( | 8638 reportErrorForNode(_getInvalidTypeParametersErrorCode(node), node, |
8637 _getInvalidTypeParametersErrorCode(node), | |
8638 node, | |
8639 [typeName.name, parameterCount, argumentCount]); | 8639 [typeName.name, parameterCount, argumentCount]); |
8640 for (int i = 0; i < parameterCount; i++) { | 8640 for (int i = 0; i < parameterCount; i++) { |
8641 typeArguments[i] = dynamicType; | 8641 typeArguments[i] = dynamicType; |
8642 } | 8642 } |
8643 } | 8643 } |
8644 type = typeSystem.instantiateType(type, typeArguments); | 8644 type = typeSystem.instantiateType(type, typeArguments); |
8645 } else { | 8645 } else { |
8646 type = typeSystem.instantiateToBounds(type); | 8646 type = typeSystem.instantiateToBounds(type); |
8647 } | 8647 } |
8648 typeName.staticType = type; | 8648 typeName.staticType = type; |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9078 * | 9078 * |
9079 * @param element the element whose type might have been overridden | 9079 * @param element the element whose type might have been overridden |
9080 * @param type the overridden type of the given element | 9080 * @param type the overridden type of the given element |
9081 */ | 9081 */ |
9082 void setType(VariableElement element, DartType type) { | 9082 void setType(VariableElement element, DartType type) { |
9083 _overridenTypes[element] = type; | 9083 _overridenTypes[element] = type; |
9084 } | 9084 } |
9085 } | 9085 } |
9086 | 9086 |
9087 /** | 9087 /** |
| 9088 * This class resolves bounds of type parameters of classes, class and function |
| 9089 * type aliases. |
| 9090 */ |
| 9091 class TypeParameterBoundsResolver { |
| 9092 final TypeProvider typeProvider; |
| 9093 final LibraryElement library; |
| 9094 final Source source; |
| 9095 final AnalysisErrorListener errorListener; |
| 9096 |
| 9097 Scope libraryScope = null; |
| 9098 TypeNameResolver typeNameResolver = null; |
| 9099 |
| 9100 TypeParameterBoundsResolver( |
| 9101 this.typeProvider, this.library, this.source, this.errorListener); |
| 9102 |
| 9103 /** |
| 9104 * Resolve bounds of type parameters of classes, class and function type |
| 9105 * aliases. |
| 9106 */ |
| 9107 void resolveTypeBounds(CompilationUnit unit) { |
| 9108 for (CompilationUnitMember unitMember in unit.declarations) { |
| 9109 if (unitMember is ClassDeclaration) { |
| 9110 _resolveTypeParameters(unitMember.typeParameters, |
| 9111 () => new TypeParameterScope(libraryScope, unitMember.element)); |
| 9112 } else if (unitMember is ClassTypeAlias) { |
| 9113 _resolveTypeParameters(unitMember.typeParameters, |
| 9114 () => new TypeParameterScope(libraryScope, unitMember.element)); |
| 9115 } else if (unitMember is FunctionTypeAlias) { |
| 9116 _resolveTypeParameters(unitMember.typeParameters, |
| 9117 () => new FunctionTypeScope(libraryScope, unitMember.element)); |
| 9118 } |
| 9119 } |
| 9120 } |
| 9121 |
| 9122 void _resolveTypeName(TypeName typeName) { |
| 9123 typeName.typeArguments?.arguments?.forEach(_resolveTypeName); |
| 9124 typeNameResolver.resolveTypeName(typeName); |
| 9125 // TODO(scheglov) report error when don't apply type bounds for type bounds |
| 9126 } |
| 9127 |
| 9128 void _resolveTypeParameters( |
| 9129 TypeParameterList typeParameters, Scope createTypeParametersScope()) { |
| 9130 if (typeParameters != null) { |
| 9131 Scope typeParametersScope = null; |
| 9132 for (TypeParameter typeParameter in typeParameters.typeParameters) { |
| 9133 TypeName bound = typeParameter.bound; |
| 9134 if (bound != null) { |
| 9135 libraryScope ??= new LibraryScope(library, errorListener); |
| 9136 typeParametersScope ??= createTypeParametersScope(); |
| 9137 typeNameResolver ??= new TypeNameResolver(new TypeSystemImpl(), |
| 9138 typeProvider, library, source, errorListener); |
| 9139 typeNameResolver.nameScope = typeParametersScope; |
| 9140 _resolveTypeName(bound); |
| 9141 Element typeParameterElement = typeParameter.name.staticElement; |
| 9142 if (typeParameterElement is TypeParameterElementImpl) { |
| 9143 typeParameterElement.bound = bound.type; |
| 9144 } |
| 9145 } |
| 9146 } |
| 9147 } |
| 9148 } |
| 9149 } |
| 9150 |
| 9151 /** |
9088 * Instances of the class `TypePromotionManager` manage the ability to promote t
ypes of local | 9152 * Instances of the class `TypePromotionManager` manage the ability to promote t
ypes of local |
9089 * variables and formal parameters from their declared types based on control fl
ow. | 9153 * variables and formal parameters from their declared types based on control fl
ow. |
9090 */ | 9154 */ |
9091 class TypePromotionManager { | 9155 class TypePromotionManager { |
9092 /** | 9156 /** |
9093 * The current promotion scope, or `null` if no scope has been entered. | 9157 * The current promotion scope, or `null` if no scope has been entered. |
9094 */ | 9158 */ |
9095 TypePromotionManager_TypePromoteScope currentScope; | 9159 TypePromotionManager_TypePromoteScope currentScope; |
9096 | 9160 |
9097 /** | 9161 /** |
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9698 TypeResolverVisitor(LibraryElement definingLibrary, Source source, | 9762 TypeResolverVisitor(LibraryElement definingLibrary, Source source, |
9699 TypeProvider typeProvider, AnalysisErrorListener errorListener, | 9763 TypeProvider typeProvider, AnalysisErrorListener errorListener, |
9700 {Scope nameScope}) | 9764 {Scope nameScope}) |
9701 : super(definingLibrary, source, typeProvider, errorListener, | 9765 : super(definingLibrary, source, typeProvider, errorListener, |
9702 nameScope: nameScope) { | 9766 nameScope: nameScope) { |
9703 _dynamicType = typeProvider.dynamicType; | 9767 _dynamicType = typeProvider.dynamicType; |
9704 _undefinedType = typeProvider.undefinedType; | 9768 _undefinedType = typeProvider.undefinedType; |
9705 _strongMode = definingLibrary.context.analysisOptions.strongMode; | 9769 _strongMode = definingLibrary.context.analysisOptions.strongMode; |
9706 _typeSystem = TypeSystem.create(definingLibrary.context); | 9770 _typeSystem = TypeSystem.create(definingLibrary.context); |
9707 _typeNameResolver = new TypeNameResolver( | 9771 _typeNameResolver = new TypeNameResolver( |
9708 _typeSystem, typeProvider, definingLibrary, errorReporter); | 9772 _typeSystem, typeProvider, definingLibrary, source, errorListener); |
9709 } | 9773 } |
9710 | 9774 |
9711 @override | 9775 @override |
9712 Object visitAnnotation(Annotation node) { | 9776 Object visitAnnotation(Annotation node) { |
9713 // | 9777 // |
9714 // Visit annotations, if the annotation is @proxy, on a class, and "proxy" | 9778 // Visit annotations, if the annotation is @proxy, on a class, and "proxy" |
9715 // resolves to the proxy annotation in dart.core, then resolve the | 9779 // resolves to the proxy annotation in dart.core, then resolve the |
9716 // ElementAnnotation. | 9780 // ElementAnnotation. |
9717 // | 9781 // |
9718 // Element resolution is done in the ElementResolver, and this work will be | 9782 // Element resolution is done in the ElementResolver, and this work will be |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10040 Object visitTypeName(TypeName node) { | 10104 Object visitTypeName(TypeName node) { |
10041 super.visitTypeName(node); | 10105 super.visitTypeName(node); |
10042 _typeNameResolver.nameScope = this.nameScope; | 10106 _typeNameResolver.nameScope = this.nameScope; |
10043 _typeNameResolver.resolveTypeName(node); | 10107 _typeNameResolver.resolveTypeName(node); |
10044 return null; | 10108 return null; |
10045 } | 10109 } |
10046 | 10110 |
10047 @override | 10111 @override |
10048 Object visitTypeParameter(TypeParameter node) { | 10112 Object visitTypeParameter(TypeParameter node) { |
10049 super.visitTypeParameter(node); | 10113 super.visitTypeParameter(node); |
10050 TypeName bound = node.bound; | 10114 AstNode parent2 = node.parent?.parent; |
10051 if (bound != null) { | 10115 if (parent2 is ClassDeclaration || |
10052 TypeParameterElementImpl typeParameter = | 10116 parent2 is ClassTypeAlias || |
10053 node.name.staticElement as TypeParameterElementImpl; | 10117 parent2 is FunctionTypeAlias) { |
10054 if (typeParameter != null) { | 10118 // Bounds of parameters of classes and function type aliases are |
10055 typeParameter.bound = bound.type; | 10119 // already resolved. |
| 10120 } else { |
| 10121 TypeName bound = node.bound; |
| 10122 if (bound != null) { |
| 10123 TypeParameterElementImpl typeParameter = |
| 10124 node.name.staticElement as TypeParameterElementImpl; |
| 10125 if (typeParameter != null) { |
| 10126 typeParameter.bound = bound.type; |
| 10127 } |
10056 } | 10128 } |
10057 } | 10129 } |
10058 return null; | 10130 return null; |
10059 } | 10131 } |
10060 | 10132 |
10061 @override | 10133 @override |
10062 Object visitVariableDeclaration(VariableDeclaration node) { | 10134 Object visitVariableDeclaration(VariableDeclaration node) { |
10063 super.visitVariableDeclaration(node); | 10135 super.visitVariableDeclaration(node); |
10064 DartType declaredType; | 10136 DartType declaredType; |
10065 TypeName typeName = (node.parent as VariableDeclarationList).type; | 10137 TypeName typeName = (node.parent as VariableDeclarationList).type; |
(...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10852 return null; | 10924 return null; |
10853 } | 10925 } |
10854 if (identical(node.staticElement, variable)) { | 10926 if (identical(node.staticElement, variable)) { |
10855 if (node.inSetterContext()) { | 10927 if (node.inSetterContext()) { |
10856 result = true; | 10928 result = true; |
10857 } | 10929 } |
10858 } | 10930 } |
10859 return null; | 10931 return null; |
10860 } | 10932 } |
10861 } | 10933 } |
OLD | NEW |