| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 dart2js.resolution.class_hierarchy; | 5 library dart2js.resolution.class_hierarchy; |
| 6 | 6 |
| 7 import '../compiler.dart' show | 7 import '../compiler.dart' show |
| 8 Compiler; | 8 Compiler; |
| 9 import '../dart_types.dart'; | 9 import '../dart_types.dart'; |
| 10 import '../diagnostics/invariant.dart' show | 10 import '../diagnostics/invariant.dart' show |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 // Resolve the bounds of type variables. | 61 // Resolve the bounds of type variables. |
| 62 Iterator<DartType> types = element.typeVariables.iterator; | 62 Iterator<DartType> types = element.typeVariables.iterator; |
| 63 Link<Node> nodeLink = node.nodes; | 63 Link<Node> nodeLink = node.nodes; |
| 64 while (!nodeLink.isEmpty) { | 64 while (!nodeLink.isEmpty) { |
| 65 types.moveNext(); | 65 types.moveNext(); |
| 66 TypeVariableType typeVariable = types.current; | 66 TypeVariableType typeVariable = types.current; |
| 67 String typeName = typeVariable.name; | 67 String typeName = typeVariable.name; |
| 68 TypeVariable typeNode = nodeLink.head; | 68 TypeVariable typeNode = nodeLink.head; |
| 69 registry.useType(typeNode, typeVariable); | 69 registry.useType(typeNode, typeVariable); |
| 70 if (nameSet.contains(typeName)) { | 70 if (nameSet.contains(typeName)) { |
| 71 compiler.reportErrorMessage( | 71 reporter.reportErrorMessage( |
| 72 typeNode, | 72 typeNode, |
| 73 MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, | 73 MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, |
| 74 {'typeVariableName': typeName}); | 74 {'typeVariableName': typeName}); |
| 75 } | 75 } |
| 76 nameSet.add(typeName); | 76 nameSet.add(typeName); |
| 77 | 77 |
| 78 TypeVariableElementX variableElement = typeVariable.element; | 78 TypeVariableElementX variableElement = typeVariable.element; |
| 79 if (typeNode.bound != null) { | 79 if (typeNode.bound != null) { |
| 80 DartType boundType = typeResolver.resolveTypeAnnotation( | 80 DartType boundType = typeResolver.resolveTypeAnnotation( |
| 81 this, typeNode.bound); | 81 this, typeNode.bound); |
| 82 variableElement.boundCache = boundType; | 82 variableElement.boundCache = boundType; |
| 83 | 83 |
| 84 void checkTypeVariableBound() { | 84 void checkTypeVariableBound() { |
| 85 Link<TypeVariableElement> seenTypeVariables = | 85 Link<TypeVariableElement> seenTypeVariables = |
| 86 const Link<TypeVariableElement>(); | 86 const Link<TypeVariableElement>(); |
| 87 seenTypeVariables = seenTypeVariables.prepend(variableElement); | 87 seenTypeVariables = seenTypeVariables.prepend(variableElement); |
| 88 DartType bound = boundType; | 88 DartType bound = boundType; |
| 89 while (bound.isTypeVariable) { | 89 while (bound.isTypeVariable) { |
| 90 TypeVariableElement element = bound.element; | 90 TypeVariableElement element = bound.element; |
| 91 if (seenTypeVariables.contains(element)) { | 91 if (seenTypeVariables.contains(element)) { |
| 92 if (identical(element, variableElement)) { | 92 if (identical(element, variableElement)) { |
| 93 // Only report an error on the checked type variable to avoid | 93 // Only report an error on the checked type variable to avoid |
| 94 // generating multiple errors for the same cyclicity. | 94 // generating multiple errors for the same cyclicity. |
| 95 compiler.reportWarningMessage( | 95 reporter.reportWarningMessage( |
| 96 typeNode.name, | 96 typeNode.name, |
| 97 MessageKind.CYCLIC_TYPE_VARIABLE, | 97 MessageKind.CYCLIC_TYPE_VARIABLE, |
| 98 {'typeVariableName': variableElement.name}); | 98 {'typeVariableName': variableElement.name}); |
| 99 } | 99 } |
| 100 break; | 100 break; |
| 101 } | 101 } |
| 102 seenTypeVariables = seenTypeVariables.prepend(element); | 102 seenTypeVariables = seenTypeVariables.prepend(element); |
| 103 bound = element.bound; | 103 bound = element.bound; |
| 104 } | 104 } |
| 105 } | 105 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 128 class ClassResolverVisitor extends TypeDefinitionVisitor { | 128 class ClassResolverVisitor extends TypeDefinitionVisitor { |
| 129 BaseClassElementX get element => enclosingElement; | 129 BaseClassElementX get element => enclosingElement; |
| 130 | 130 |
| 131 ClassResolverVisitor(Compiler compiler, | 131 ClassResolverVisitor(Compiler compiler, |
| 132 ClassElement classElement, | 132 ClassElement classElement, |
| 133 ResolutionRegistry registry) | 133 ResolutionRegistry registry) |
| 134 : super(compiler, classElement, registry); | 134 : super(compiler, classElement, registry); |
| 135 | 135 |
| 136 DartType visitClassNode(ClassNode node) { | 136 DartType visitClassNode(ClassNode node) { |
| 137 if (element == null) { | 137 if (element == null) { |
| 138 throw compiler.internalError(node, 'element is null'); | 138 throw reporter.internalError(node, 'element is null'); |
| 139 } | 139 } |
| 140 if (element.resolutionState != STATE_STARTED) { | 140 if (element.resolutionState != STATE_STARTED) { |
| 141 throw compiler.internalError(element, | 141 throw reporter.internalError(element, |
| 142 'cyclic resolution of class $element'); | 142 'cyclic resolution of class $element'); |
| 143 } | 143 } |
| 144 | 144 |
| 145 element.computeType(resolution); | 145 element.computeType(resolution); |
| 146 scope = new TypeDeclarationScope(scope, element); | 146 scope = new TypeDeclarationScope(scope, element); |
| 147 // TODO(ahe): It is not safe to call resolveTypeVariableBounds yet. | 147 // TODO(ahe): It is not safe to call resolveTypeVariableBounds yet. |
| 148 // As a side-effect, this may get us back here trying to | 148 // As a side-effect, this may get us back here trying to |
| 149 // resolve this class again. | 149 // resolve this class again. |
| 150 resolveTypeVariableBounds(node.typeParameters); | 150 resolveTypeVariableBounds(node.typeParameters); |
| 151 | 151 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 168 } | 168 } |
| 169 // If the super type isn't specified, we provide a default. The language | 169 // If the super type isn't specified, we provide a default. The language |
| 170 // specifies [Object] but the backend can pick a specific 'implementation' | 170 // specifies [Object] but the backend can pick a specific 'implementation' |
| 171 // of Object - the JavaScript backend chooses between Object and | 171 // of Object - the JavaScript backend chooses between Object and |
| 172 // Interceptor. | 172 // Interceptor. |
| 173 if (element.supertype == null) { | 173 if (element.supertype == null) { |
| 174 ClassElement superElement = registry.defaultSuperclass(element); | 174 ClassElement superElement = registry.defaultSuperclass(element); |
| 175 // Avoid making the superclass (usually Object) extend itself. | 175 // Avoid making the superclass (usually Object) extend itself. |
| 176 if (element != superElement) { | 176 if (element != superElement) { |
| 177 if (superElement == null) { | 177 if (superElement == null) { |
| 178 compiler.internalError(node, | 178 reporter.internalError(node, |
| 179 "Cannot resolve default superclass for $element."); | 179 "Cannot resolve default superclass for $element."); |
| 180 } else { | 180 } else { |
| 181 superElement.ensureResolved(resolution); | 181 superElement.ensureResolved(resolution); |
| 182 } | 182 } |
| 183 element.supertype = superElement.computeType(resolution); | 183 element.supertype = superElement.computeType(resolution); |
| 184 } | 184 } |
| 185 } | 185 } |
| 186 | 186 |
| 187 if (element.interfaces == null) { | 187 if (element.interfaces == null) { |
| 188 element.interfaces = resolveInterfaces(node.interfaces, node.superclass); | 188 element.interfaces = resolveInterfaces(node.interfaces, node.superclass); |
| 189 } else { | 189 } else { |
| 190 assert(invariant(element, element.hasIncompleteHierarchy)); | 190 assert(invariant(element, element.hasIncompleteHierarchy)); |
| 191 } | 191 } |
| 192 calculateAllSupertypes(element); | 192 calculateAllSupertypes(element); |
| 193 | 193 |
| 194 if (!element.hasConstructor) { | 194 if (!element.hasConstructor) { |
| 195 Element superMember = element.superclass.localLookup(''); | 195 Element superMember = element.superclass.localLookup(''); |
| 196 if (superMember == null || !superMember.isGenerativeConstructor) { | 196 if (superMember == null || !superMember.isGenerativeConstructor) { |
| 197 MessageKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR; | 197 MessageKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR; |
| 198 Map arguments = {'constructorName': ''}; | 198 Map arguments = {'constructorName': ''}; |
| 199 // TODO(ahe): Why is this a compile-time error? Or if it is an error, | 199 // TODO(ahe): Why is this a compile-time error? Or if it is an error, |
| 200 // why do we bother to registerThrowNoSuchMethod below? | 200 // why do we bother to registerThrowNoSuchMethod below? |
| 201 compiler.reportErrorMessage(node, kind, arguments); | 201 reporter.reportErrorMessage(node, kind, arguments); |
| 202 superMember = new ErroneousElementX( | 202 superMember = new ErroneousElementX( |
| 203 kind, arguments, '', element); | 203 kind, arguments, '', element); |
| 204 registry.registerThrowNoSuchMethod(); | 204 registry.registerThrowNoSuchMethod(); |
| 205 } else { | 205 } else { |
| 206 ConstructorElement superConstructor = superMember; | 206 ConstructorElement superConstructor = superMember; |
| 207 superConstructor.computeType(resolution); | 207 superConstructor.computeType(resolution); |
| 208 if (!CallStructure.NO_ARGS.signatureApplies( | 208 if (!CallStructure.NO_ARGS.signatureApplies( |
| 209 superConstructor.functionSignature)) { | 209 superConstructor.functionSignature)) { |
| 210 MessageKind kind = MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT; | 210 MessageKind kind = MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT; |
| 211 compiler.reportErrorMessage(node, kind); | 211 reporter.reportErrorMessage(node, kind); |
| 212 superMember = new ErroneousElementX(kind, {}, '', element); | 212 superMember = new ErroneousElementX(kind, {}, '', element); |
| 213 } | 213 } |
| 214 } | 214 } |
| 215 FunctionElement constructor = | 215 FunctionElement constructor = |
| 216 new SynthesizedConstructorElementX.forDefault(superMember, element); | 216 new SynthesizedConstructorElementX.forDefault(superMember, element); |
| 217 if (superMember.isErroneous) { | 217 if (superMember.isErroneous) { |
| 218 compiler.elementsWithCompileTimeErrors.add(constructor); | 218 compiler.elementsWithCompileTimeErrors.add(constructor); |
| 219 } | 219 } |
| 220 element.setDefaultConstructor(constructor, compiler); | 220 element.setDefaultConstructor(constructor, reporter); |
| 221 } | 221 } |
| 222 return element.computeType(resolution); | 222 return element.computeType(resolution); |
| 223 } | 223 } |
| 224 | 224 |
| 225 @override | 225 @override |
| 226 DartType visitEnum(Enum node) { | 226 DartType visitEnum(Enum node) { |
| 227 if (element == null) { | 227 if (element == null) { |
| 228 throw compiler.internalError(node, 'element is null'); | 228 throw reporter.internalError(node, 'element is null'); |
| 229 } | 229 } |
| 230 if (element.resolutionState != STATE_STARTED) { | 230 if (element.resolutionState != STATE_STARTED) { |
| 231 throw compiler.internalError(element, | 231 throw reporter.internalError(element, |
| 232 'cyclic resolution of class $element'); | 232 'cyclic resolution of class $element'); |
| 233 } | 233 } |
| 234 | 234 |
| 235 InterfaceType enumType = element.computeType(resolution); | 235 InterfaceType enumType = element.computeType(resolution); |
| 236 element.supertype = compiler.coreTypes.objectType; | 236 element.supertype = compiler.coreTypes.objectType; |
| 237 element.interfaces = const Link<DartType>(); | 237 element.interfaces = const Link<DartType>(); |
| 238 calculateAllSupertypes(element); | 238 calculateAllSupertypes(element); |
| 239 | 239 |
| 240 if (node.names.nodes.isEmpty) { | 240 if (node.names.nodes.isEmpty) { |
| 241 compiler.reportErrorMessage( | 241 reporter.reportErrorMessage( |
| 242 node, | 242 node, |
| 243 MessageKind.EMPTY_ENUM_DECLARATION, | 243 MessageKind.EMPTY_ENUM_DECLARATION, |
| 244 {'enumName': element.name}); | 244 {'enumName': element.name}); |
| 245 } | 245 } |
| 246 | 246 |
| 247 EnumCreator creator = new EnumCreator(compiler, element); | 247 EnumCreator creator = |
| 248 new EnumCreator(reporter, compiler.coreTypes, element); |
| 248 creator.createMembers(); | 249 creator.createMembers(); |
| 249 return enumType; | 250 return enumType; |
| 250 } | 251 } |
| 251 | 252 |
| 252 /// Resolves the mixed type for [mixinNode] and checks that the the mixin type | 253 /// Resolves the mixed type for [mixinNode] and checks that the the mixin type |
| 253 /// is a valid, non-blacklisted interface type. The mixin type is returned. | 254 /// is a valid, non-blacklisted interface type. The mixin type is returned. |
| 254 DartType checkMixinType(TypeAnnotation mixinNode) { | 255 DartType checkMixinType(TypeAnnotation mixinNode) { |
| 255 DartType mixinType = resolveType(mixinNode); | 256 DartType mixinType = resolveType(mixinNode); |
| 256 if (isBlackListed(mixinType)) { | 257 if (isBlackListed(mixinType)) { |
| 257 compiler.reportErrorMessage( | 258 reporter.reportErrorMessage( |
| 258 mixinNode, | 259 mixinNode, |
| 259 MessageKind.CANNOT_MIXIN, | 260 MessageKind.CANNOT_MIXIN, |
| 260 {'type': mixinType}); | 261 {'type': mixinType}); |
| 261 } else if (mixinType.isTypeVariable) { | 262 } else if (mixinType.isTypeVariable) { |
| 262 compiler.reportErrorMessage( | 263 reporter.reportErrorMessage( |
| 263 mixinNode, | 264 mixinNode, |
| 264 MessageKind.CLASS_NAME_EXPECTED); | 265 MessageKind.CLASS_NAME_EXPECTED); |
| 265 } else if (mixinType.isMalformed) { | 266 } else if (mixinType.isMalformed) { |
| 266 compiler.reportErrorMessage( | 267 reporter.reportErrorMessage( |
| 267 mixinNode, | 268 mixinNode, |
| 268 MessageKind.CANNOT_MIXIN_MALFORMED, | 269 MessageKind.CANNOT_MIXIN_MALFORMED, |
| 269 {'className': element.name, 'malformedType': mixinType}); | 270 {'className': element.name, 'malformedType': mixinType}); |
| 270 } else if (mixinType.isEnumType) { | 271 } else if (mixinType.isEnumType) { |
| 271 compiler.reportErrorMessage( | 272 reporter.reportErrorMessage( |
| 272 mixinNode, | 273 mixinNode, |
| 273 MessageKind.CANNOT_MIXIN_ENUM, | 274 MessageKind.CANNOT_MIXIN_ENUM, |
| 274 {'className': element.name, 'enumType': mixinType}); | 275 {'className': element.name, 'enumType': mixinType}); |
| 275 } | 276 } |
| 276 return mixinType; | 277 return mixinType; |
| 277 } | 278 } |
| 278 | 279 |
| 279 DartType visitNamedMixinApplication(NamedMixinApplication node) { | 280 DartType visitNamedMixinApplication(NamedMixinApplication node) { |
| 280 if (element == null) { | 281 if (element == null) { |
| 281 throw compiler.internalError(node, 'element is null'); | 282 throw reporter.internalError(node, 'element is null'); |
| 282 } | 283 } |
| 283 if (element.resolutionState != STATE_STARTED) { | 284 if (element.resolutionState != STATE_STARTED) { |
| 284 throw compiler.internalError(element, | 285 throw reporter.internalError(element, |
| 285 'cyclic resolution of class $element'); | 286 'cyclic resolution of class $element'); |
| 286 } | 287 } |
| 287 | 288 |
| 288 if (identical(node.classKeyword.stringValue, 'typedef')) { | 289 if (identical(node.classKeyword.stringValue, 'typedef')) { |
| 289 // TODO(aprelev@gmail.com): Remove this deprecation diagnostic | 290 // TODO(aprelev@gmail.com): Remove this deprecation diagnostic |
| 290 // together with corresponding TODO in parser.dart. | 291 // together with corresponding TODO in parser.dart. |
| 291 compiler.reportWarningMessage( | 292 reporter.reportWarningMessage( |
| 292 node.classKeyword, | 293 node.classKeyword, |
| 293 MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX); | 294 MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX); |
| 294 } | 295 } |
| 295 | 296 |
| 296 element.computeType(resolution); | 297 element.computeType(resolution); |
| 297 scope = new TypeDeclarationScope(scope, element); | 298 scope = new TypeDeclarationScope(scope, element); |
| 298 resolveTypeVariableBounds(node.typeParameters); | 299 resolveTypeVariableBounds(node.typeParameters); |
| 299 | 300 |
| 300 // Generate anonymous mixin application elements for the | 301 // Generate anonymous mixin application elements for the |
| 301 // intermediate mixin applications (excluding the last). | 302 // intermediate mixin applications (excluding the last). |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 DartType mixinType) { | 437 DartType mixinType) { |
| 437 ClassElement mixin = mixinType.element; | 438 ClassElement mixin = mixinType.element; |
| 438 mixin.ensureResolved(resolution); | 439 mixin.ensureResolved(resolution); |
| 439 | 440 |
| 440 // Check for cycles in the mixin chain. | 441 // Check for cycles in the mixin chain. |
| 441 ClassElement previous = mixinApplication; // For better error messages. | 442 ClassElement previous = mixinApplication; // For better error messages. |
| 442 ClassElement current = mixin; | 443 ClassElement current = mixin; |
| 443 while (current != null && current.isMixinApplication) { | 444 while (current != null && current.isMixinApplication) { |
| 444 MixinApplicationElement currentMixinApplication = current; | 445 MixinApplicationElement currentMixinApplication = current; |
| 445 if (currentMixinApplication == mixinApplication) { | 446 if (currentMixinApplication == mixinApplication) { |
| 446 compiler.reportErrorMessage( | 447 reporter.reportErrorMessage( |
| 447 mixinApplication, | 448 mixinApplication, |
| 448 MessageKind.ILLEGAL_MIXIN_CYCLE, | 449 MessageKind.ILLEGAL_MIXIN_CYCLE, |
| 449 {'mixinName1': current.name, 'mixinName2': previous.name}); | 450 {'mixinName1': current.name, 'mixinName2': previous.name}); |
| 450 // We have found a cycle in the mixin chain. Return null as | 451 // We have found a cycle in the mixin chain. Return null as |
| 451 // the mixin for this application to avoid getting into | 452 // the mixin for this application to avoid getting into |
| 452 // infinite recursion when traversing members. | 453 // infinite recursion when traversing members. |
| 453 return null; | 454 return null; |
| 454 } | 455 } |
| 455 previous = current; | 456 previous = current; |
| 456 current = currentMixinApplication.mixin; | 457 current = currentMixinApplication.mixin; |
| 457 } | 458 } |
| 458 registry.registerMixinUse(mixinApplication, mixin); | 459 registry.registerMixinUse(mixinApplication, mixin); |
| 459 return mixinType; | 460 return mixinType; |
| 460 } | 461 } |
| 461 | 462 |
| 462 DartType resolveType(TypeAnnotation node) { | 463 DartType resolveType(TypeAnnotation node) { |
| 463 return typeResolver.resolveTypeAnnotation(this, node); | 464 return typeResolver.resolveTypeAnnotation(this, node); |
| 464 } | 465 } |
| 465 | 466 |
| 466 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) { | 467 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) { |
| 467 DartType supertype = resolveType(superclass); | 468 DartType supertype = resolveType(superclass); |
| 468 if (supertype != null) { | 469 if (supertype != null) { |
| 469 if (supertype.isMalformed) { | 470 if (supertype.isMalformed) { |
| 470 compiler.reportErrorMessage( | 471 reporter.reportErrorMessage( |
| 471 superclass, | 472 superclass, |
| 472 MessageKind.CANNOT_EXTEND_MALFORMED, | 473 MessageKind.CANNOT_EXTEND_MALFORMED, |
| 473 {'className': element.name, 'malformedType': supertype}); | 474 {'className': element.name, 'malformedType': supertype}); |
| 474 return objectType; | 475 return objectType; |
| 475 } else if (supertype.isEnumType) { | 476 } else if (supertype.isEnumType) { |
| 476 compiler.reportErrorMessage( | 477 reporter.reportErrorMessage( |
| 477 superclass, | 478 superclass, |
| 478 MessageKind.CANNOT_EXTEND_ENUM, | 479 MessageKind.CANNOT_EXTEND_ENUM, |
| 479 {'className': element.name, 'enumType': supertype}); | 480 {'className': element.name, 'enumType': supertype}); |
| 480 return objectType; | 481 return objectType; |
| 481 } else if (!supertype.isInterfaceType) { | 482 } else if (!supertype.isInterfaceType) { |
| 482 compiler.reportErrorMessage( | 483 reporter.reportErrorMessage( |
| 483 superclass.typeName, | 484 superclass.typeName, |
| 484 MessageKind.CLASS_NAME_EXPECTED); | 485 MessageKind.CLASS_NAME_EXPECTED); |
| 485 return objectType; | 486 return objectType; |
| 486 } else if (isBlackListed(supertype)) { | 487 } else if (isBlackListed(supertype)) { |
| 487 compiler.reportErrorMessage( | 488 reporter.reportErrorMessage( |
| 488 superclass, | 489 superclass, |
| 489 MessageKind.CANNOT_EXTEND, | 490 MessageKind.CANNOT_EXTEND, |
| 490 {'type': supertype}); | 491 {'type': supertype}); |
| 491 return objectType; | 492 return objectType; |
| 492 } | 493 } |
| 493 } | 494 } |
| 494 return supertype; | 495 return supertype; |
| 495 } | 496 } |
| 496 | 497 |
| 497 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) { | 498 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) { |
| 498 Link<DartType> result = const Link<DartType>(); | 499 Link<DartType> result = const Link<DartType>(); |
| 499 if (interfaces == null) return result; | 500 if (interfaces == null) return result; |
| 500 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { | 501 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { |
| 501 DartType interfaceType = resolveType(link.head); | 502 DartType interfaceType = resolveType(link.head); |
| 502 if (interfaceType != null) { | 503 if (interfaceType != null) { |
| 503 if (interfaceType.isMalformed) { | 504 if (interfaceType.isMalformed) { |
| 504 compiler.reportErrorMessage( | 505 reporter.reportErrorMessage( |
| 505 superclass, | 506 superclass, |
| 506 MessageKind.CANNOT_IMPLEMENT_MALFORMED, | 507 MessageKind.CANNOT_IMPLEMENT_MALFORMED, |
| 507 {'className': element.name, 'malformedType': interfaceType}); | 508 {'className': element.name, 'malformedType': interfaceType}); |
| 508 } else if (interfaceType.isEnumType) { | 509 } else if (interfaceType.isEnumType) { |
| 509 compiler.reportErrorMessage( | 510 reporter.reportErrorMessage( |
| 510 superclass, | 511 superclass, |
| 511 MessageKind.CANNOT_IMPLEMENT_ENUM, | 512 MessageKind.CANNOT_IMPLEMENT_ENUM, |
| 512 {'className': element.name, 'enumType': interfaceType}); | 513 {'className': element.name, 'enumType': interfaceType}); |
| 513 } else if (!interfaceType.isInterfaceType) { | 514 } else if (!interfaceType.isInterfaceType) { |
| 514 // TODO(johnniwinther): Handle dynamic. | 515 // TODO(johnniwinther): Handle dynamic. |
| 515 TypeAnnotation typeAnnotation = link.head; | 516 TypeAnnotation typeAnnotation = link.head; |
| 516 compiler.reportErrorMessage( | 517 reporter.reportErrorMessage( |
| 517 typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED); | 518 typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED); |
| 518 } else { | 519 } else { |
| 519 if (interfaceType == element.supertype) { | 520 if (interfaceType == element.supertype) { |
| 520 compiler.reportErrorMessage( | 521 reporter.reportErrorMessage( |
| 521 superclass, | 522 superclass, |
| 522 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, | 523 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, |
| 523 {'type': interfaceType}); | 524 {'type': interfaceType}); |
| 524 compiler.reportErrorMessage( | 525 reporter.reportErrorMessage( |
| 525 link.head, | 526 link.head, |
| 526 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, | 527 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, |
| 527 {'type': interfaceType}); | 528 {'type': interfaceType}); |
| 528 } | 529 } |
| 529 if (result.contains(interfaceType)) { | 530 if (result.contains(interfaceType)) { |
| 530 compiler.reportErrorMessage( | 531 reporter.reportErrorMessage( |
| 531 link.head, | 532 link.head, |
| 532 MessageKind.DUPLICATE_IMPLEMENTS, | 533 MessageKind.DUPLICATE_IMPLEMENTS, |
| 533 {'type': interfaceType}); | 534 {'type': interfaceType}); |
| 534 } | 535 } |
| 535 result = result.prepend(interfaceType); | 536 result = result.prepend(interfaceType); |
| 536 if (isBlackListed(interfaceType)) { | 537 if (isBlackListed(interfaceType)) { |
| 537 compiler.reportErrorMessage( | 538 reporter.reportErrorMessage( |
| 538 link.head, | 539 link.head, |
| 539 MessageKind.CANNOT_IMPLEMENT, | 540 MessageKind.CANNOT_IMPLEMENT, |
| 540 {'type': interfaceType}); | 541 {'type': interfaceType}); |
| 541 } | 542 } |
| 542 } | 543 } |
| 543 } | 544 } |
| 544 } | 545 } |
| 545 return result; | 546 return result; |
| 546 } | 547 } |
| 547 | 548 |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 node.superclass.accept(this); | 672 node.superclass.accept(this); |
| 672 visitNodeList(node.mixins); | 673 visitNodeList(node.mixins); |
| 673 visitNodeList(node.interfaces); | 674 visitNodeList(node.interfaces); |
| 674 } | 675 } |
| 675 | 676 |
| 676 void visitTypeAnnotation(TypeAnnotation node) { | 677 void visitTypeAnnotation(TypeAnnotation node) { |
| 677 node.typeName.accept(this); | 678 node.typeName.accept(this); |
| 678 } | 679 } |
| 679 | 680 |
| 680 void visitIdentifier(Identifier node) { | 681 void visitIdentifier(Identifier node) { |
| 681 Element element = lookupInScope(compiler, node, context, node.source); | 682 Element element = lookupInScope(reporter, node, context, node.source); |
| 682 if (element != null && element.isClass) { | 683 if (element != null && element.isClass) { |
| 683 loadSupertype(element, node); | 684 loadSupertype(element, node); |
| 684 } | 685 } |
| 685 } | 686 } |
| 686 | 687 |
| 687 void visitSend(Send node) { | 688 void visitSend(Send node) { |
| 688 Identifier prefix = node.receiver.asIdentifier(); | 689 Identifier prefix = node.receiver.asIdentifier(); |
| 689 if (prefix == null) { | 690 if (prefix == null) { |
| 690 compiler.reportErrorMessage( | 691 reporter.reportErrorMessage( |
| 691 node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); | 692 node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); |
| 692 return; | 693 return; |
| 693 } | 694 } |
| 694 Element element = lookupInScope(compiler, prefix, context, prefix.source); | 695 Element element = lookupInScope(reporter, prefix, context, prefix.source); |
| 695 if (element == null || !identical(element.kind, ElementKind.PREFIX)) { | 696 if (element == null || !identical(element.kind, ElementKind.PREFIX)) { |
| 696 compiler.reportErrorMessage( | 697 reporter.reportErrorMessage( |
| 697 node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); | 698 node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); |
| 698 return; | 699 return; |
| 699 } | 700 } |
| 700 PrefixElement prefixElement = element; | 701 PrefixElement prefixElement = element; |
| 701 Identifier selector = node.selector.asIdentifier(); | 702 Identifier selector = node.selector.asIdentifier(); |
| 702 var e = prefixElement.lookupLocalMember(selector.source); | 703 var e = prefixElement.lookupLocalMember(selector.source); |
| 703 if (e == null || !e.impliesType) { | 704 if (e == null || !e.impliesType) { |
| 704 compiler.reportErrorMessage( | 705 reporter.reportErrorMessage( |
| 705 node.selector, | 706 node.selector, |
| 706 MessageKind.CANNOT_RESOLVE_TYPE, | 707 MessageKind.CANNOT_RESOLVE_TYPE, |
| 707 {'typeName': node.selector}); | 708 {'typeName': node.selector}); |
| 708 return; | 709 return; |
| 709 } | 710 } |
| 710 loadSupertype(e, node); | 711 loadSupertype(e, node); |
| 711 } | 712 } |
| 712 } | 713 } |
| OLD | NEW |