OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 part of resolution; | 5 part of resolution; |
6 | 6 |
7 abstract class TreeElements { | 7 abstract class TreeElements { |
8 Element get currentElement; | 8 Element get currentElement; |
9 Set<Node> get superUses; | 9 Set<Node> get superUses; |
10 | 10 |
(...skipping 2950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2961 if (nameSet.contains(typeName)) { | 2961 if (nameSet.contains(typeName)) { |
2962 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, | 2962 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, |
2963 {'typeVariableName': typeName}); | 2963 {'typeVariableName': typeName}); |
2964 } | 2964 } |
2965 nameSet.add(typeName); | 2965 nameSet.add(typeName); |
2966 | 2966 |
2967 TypeVariableElement variableElement = typeVariable.element; | 2967 TypeVariableElement variableElement = typeVariable.element; |
2968 if (typeNode.bound != null) { | 2968 if (typeNode.bound != null) { |
2969 DartType boundType = typeResolver.resolveTypeAnnotation( | 2969 DartType boundType = typeResolver.resolveTypeAnnotation( |
2970 typeNode.bound, scope, element, onFailure: warning); | 2970 typeNode.bound, scope, element, onFailure: warning); |
2971 if (boundType != null && boundType.element == variableElement) { | 2971 variableElement.bound = boundType; |
2972 // TODO(johnniwinther): Check for more general cycles, like | 2972 |
2973 // [: <A extends B, B extends C, C extends B> :]. | 2973 void checkTypeVariableBound() { |
2974 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, | 2974 Link<TypeVariableElement> seenTypeVariables = |
2975 {'typeVariableName': variableElement.name}); | 2975 const Link<TypeVariableElement>(); |
2976 } else if (boundType != null) { | 2976 seenTypeVariables = seenTypeVariables.prepend(variableElement); |
2977 variableElement.bound = boundType; | 2977 DartType bound = boundType; |
2978 } else { | 2978 while (bound.element.isTypeVariable()) { |
2979 // TODO(johnniwinther): Should be an erroneous type. | 2979 TypeVariableElement element = bound.element; |
2980 variableElement.bound = compiler.objectClass.computeType(compiler); | 2980 if (seenTypeVariables.contains(element)) { |
| 2981 if (identical(element, variableElement)) { |
| 2982 // Only report an error on the checked type variable to avoid |
| 2983 // generating multiple errors for the same cyclicity. |
| 2984 warning(typeNode.name, MessageKind.CYCLIC_TYPE_VARIABLE, |
| 2985 {'typeVariableName': variableElement.name}); |
| 2986 } |
| 2987 break; |
| 2988 } |
| 2989 seenTypeVariables = seenTypeVariables.prepend(element); |
| 2990 bound = element.bound; |
| 2991 } |
2981 } | 2992 } |
| 2993 compiler.enqueuer.resolution.addPostProcessAction( |
| 2994 element, checkTypeVariableBound); |
2982 } else { | 2995 } else { |
2983 variableElement.bound = compiler.objectClass.computeType(compiler); | 2996 variableElement.bound = compiler.objectClass.computeType(compiler); |
2984 } | 2997 } |
2985 nodeLink = nodeLink.tail; | 2998 nodeLink = nodeLink.tail; |
2986 typeLink = typeLink.tail; | 2999 typeLink = typeLink.tail; |
2987 } | 3000 } |
2988 assert(typeLink.isEmpty); | 3001 assert(typeLink.isEmpty); |
2989 } | 3002 } |
2990 } | 3003 } |
2991 | 3004 |
(...skipping 835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3827 return e; | 3840 return e; |
3828 } | 3841 } |
3829 | 3842 |
3830 /// Assumed to be called by [resolveRedirectingFactory]. | 3843 /// Assumed to be called by [resolveRedirectingFactory]. |
3831 Element visitReturn(Return node) { | 3844 Element visitReturn(Return node) { |
3832 Node expression = node.expression; | 3845 Node expression = node.expression; |
3833 return finishConstructorReference(visit(expression), | 3846 return finishConstructorReference(visit(expression), |
3834 expression, expression); | 3847 expression, expression); |
3835 } | 3848 } |
3836 } | 3849 } |
OLD | NEW |