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 |