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 '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/resolution.dart' show Feature; | 8 import '../common/resolution.dart' show Feature, Resolution; |
9 import '../compiler.dart' show Compiler; | |
10 import '../core_types.dart' show CoreClasses, CoreTypes; | 9 import '../core_types.dart' show CoreClasses, CoreTypes; |
11 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
12 import '../elements/elements.dart'; | 11 import '../elements/elements.dart'; |
13 import '../elements/modelx.dart' | 12 import '../elements/modelx.dart' |
14 show | 13 show |
15 BaseClassElementX, | 14 BaseClassElementX, |
16 ErroneousElementX, | 15 ErroneousElementX, |
17 MixinApplicationElementX, | 16 MixinApplicationElementX, |
18 SynthesizedConstructorElementX, | 17 SynthesizedConstructorElementX, |
19 TypeVariableElementX, | 18 TypeVariableElementX, |
20 UnnamedMixinApplicationElementX; | 19 UnnamedMixinApplicationElementX; |
21 import '../ordered_typeset.dart' show OrderedTypeSet, OrderedTypeSetBuilder; | 20 import '../ordered_typeset.dart' show OrderedTypeSet, OrderedTypeSetBuilder; |
22 import '../tree/tree.dart'; | 21 import '../tree/tree.dart'; |
23 import '../util/util.dart' show Link, Setlet; | 22 import '../util/util.dart' show Link, Setlet; |
24 import '../universe/call_structure.dart' show CallStructure; | 23 import '../universe/call_structure.dart' show CallStructure; |
25 | 24 |
26 import 'enum_creator.dart'; | 25 import 'enum_creator.dart'; |
27 import 'members.dart' show lookupInScope; | 26 import 'members.dart' show lookupInScope; |
28 import 'registry.dart' show ResolutionRegistry; | 27 import 'registry.dart' show ResolutionRegistry; |
29 import 'resolution_common.dart' show CommonResolverVisitor, MappingVisitor; | 28 import 'resolution_common.dart' show CommonResolverVisitor, MappingVisitor; |
30 import 'scope.dart' show Scope, TypeDeclarationScope; | 29 import 'scope.dart' show Scope, TypeDeclarationScope; |
31 | 30 |
32 class TypeDefinitionVisitor extends MappingVisitor<DartType> { | 31 class TypeDefinitionVisitor extends MappingVisitor<DartType> { |
33 Scope scope; | 32 Scope scope; |
34 final TypeDeclarationElement enclosingElement; | 33 final TypeDeclarationElement enclosingElement; |
35 TypeDeclarationElement get element => enclosingElement; | 34 TypeDeclarationElement get element => enclosingElement; |
36 | 35 |
37 TypeDefinitionVisitor(Compiler compiler, TypeDeclarationElement element, | 36 TypeDefinitionVisitor(Resolution resolution, TypeDeclarationElement element, |
38 ResolutionRegistry registry) | 37 ResolutionRegistry registry) |
39 : this.enclosingElement = element, | 38 : this.enclosingElement = element, |
40 scope = Scope.buildEnclosingScope(element), | 39 scope = Scope.buildEnclosingScope(element), |
41 super(compiler, registry); | 40 super(resolution, registry); |
42 | 41 |
43 CoreTypes get coreTypes => compiler.coreTypes; | 42 CoreTypes get coreTypes => resolution.coreTypes; |
44 | 43 |
45 DartType get objectType => coreTypes.objectType; | 44 DartType get objectType => coreTypes.objectType; |
46 | 45 |
47 void resolveTypeVariableBounds(NodeList node) { | 46 void resolveTypeVariableBounds(NodeList node) { |
48 if (node == null) return; | 47 if (node == null) return; |
49 | 48 |
50 Setlet<String> nameSet = new Setlet<String>(); | 49 Setlet<String> nameSet = new Setlet<String>(); |
51 // Resolve the bounds of type variables. | 50 // Resolve the bounds of type variables. |
52 Iterator<DartType> types = element.typeVariables.iterator; | 51 Iterator<DartType> types = element.typeVariables.iterator; |
53 Link<Node> nodeLink = node.nodes; | 52 Link<Node> nodeLink = node.nodes; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 * this may lead to cycles. | 110 * this may lead to cycles. |
112 * | 111 * |
113 * This visitor can assume that the supertypes have already been | 112 * This visitor can assume that the supertypes have already been |
114 * resolved, but it cannot call [ResolverTask.resolveClass] directly | 113 * resolved, but it cannot call [ResolverTask.resolveClass] directly |
115 * or indirectly (through [ClassElement.ensureResolved]) for any other | 114 * or indirectly (through [ClassElement.ensureResolved]) for any other |
116 * types. | 115 * types. |
117 */ | 116 */ |
118 class ClassResolverVisitor extends TypeDefinitionVisitor { | 117 class ClassResolverVisitor extends TypeDefinitionVisitor { |
119 BaseClassElementX get element => enclosingElement; | 118 BaseClassElementX get element => enclosingElement; |
120 | 119 |
121 ClassResolverVisitor( | 120 ClassResolverVisitor(Resolution resolution, ClassElement classElement, |
122 Compiler compiler, ClassElement classElement, ResolutionRegistry registry) | 121 ResolutionRegistry registry) |
123 : super(compiler, classElement, registry); | 122 : super(resolution, classElement, registry); |
124 | 123 |
125 DartType visitClassNode(ClassNode node) { | 124 DartType visitClassNode(ClassNode node) { |
126 if (element == null) { | 125 if (element == null) { |
127 throw reporter.internalError(node, 'element is null'); | 126 throw reporter.internalError(node, 'element is null'); |
128 } | 127 } |
129 if (element.resolutionState != STATE_STARTED) { | 128 if (element.resolutionState != STATE_STARTED) { |
130 throw reporter.internalError( | 129 throw reporter.internalError( |
131 element, 'cyclic resolution of class $element'); | 130 element, 'cyclic resolution of class $element'); |
132 } | 131 } |
133 | 132 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 .signatureApplies(superConstructor.functionSignature)) { | 204 .signatureApplies(superConstructor.functionSignature)) { |
206 MessageKind kind = MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT; | 205 MessageKind kind = MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT; |
207 reporter.reportErrorMessage(node, kind); | 206 reporter.reportErrorMessage(node, kind); |
208 superMember = new ErroneousElementX(kind, {}, '', element); | 207 superMember = new ErroneousElementX(kind, {}, '', element); |
209 } | 208 } |
210 } | 209 } |
211 FunctionElement constructor = | 210 FunctionElement constructor = |
212 new SynthesizedConstructorElementX.forDefault(superMember, element); | 211 new SynthesizedConstructorElementX.forDefault(superMember, element); |
213 if (superMember.isMalformed) { | 212 if (superMember.isMalformed) { |
214 ErroneousElement erroneousElement = superMember; | 213 ErroneousElement erroneousElement = superMember; |
215 compiler.registerCompiletimeError( | 214 resolution.registerCompileTimeError( |
216 constructor, | 215 constructor, |
217 reporter.createMessage(node, erroneousElement.messageKind, | 216 reporter.createMessage(node, erroneousElement.messageKind, |
218 erroneousElement.messageArguments)); | 217 erroneousElement.messageArguments)); |
219 } | 218 } |
220 element.setDefaultConstructor(constructor, reporter); | 219 element.setDefaultConstructor(constructor, reporter); |
221 } | 220 } |
222 return element.computeType(resolution); | 221 return element.computeType(resolution); |
223 } | 222 } |
224 | 223 |
225 @override | 224 @override |
(...skipping 10 matching lines...) Expand all Loading... |
236 element.supertype = objectType; | 235 element.supertype = objectType; |
237 element.interfaces = const Link<DartType>(); | 236 element.interfaces = const Link<DartType>(); |
238 calculateAllSupertypes(element); | 237 calculateAllSupertypes(element); |
239 | 238 |
240 if (node.names.nodes.isEmpty) { | 239 if (node.names.nodes.isEmpty) { |
241 reporter.reportErrorMessage( | 240 reporter.reportErrorMessage( |
242 node, MessageKind.EMPTY_ENUM_DECLARATION, {'enumName': element.name}); | 241 node, MessageKind.EMPTY_ENUM_DECLARATION, {'enumName': element.name}); |
243 } | 242 } |
244 | 243 |
245 EnumCreator creator = | 244 EnumCreator creator = |
246 new EnumCreator(reporter, compiler.coreTypes, element); | 245 new EnumCreator(reporter, resolution.coreTypes, element); |
247 creator.createMembers(); | 246 creator.createMembers(); |
248 return enumType; | 247 return enumType; |
249 } | 248 } |
250 | 249 |
251 /// Resolves the mixed type for [mixinNode] and checks that the mixin type | 250 /// Resolves the mixed type for [mixinNode] and checks that the mixin type |
252 /// is a valid, non-blacklisted interface type. The mixin type is returned. | 251 /// is a valid, non-blacklisted interface type. The mixin type is returned. |
253 DartType checkMixinType(TypeAnnotation mixinNode) { | 252 DartType checkMixinType(TypeAnnotation mixinNode) { |
254 DartType mixinType = resolveType(mixinNode); | 253 DartType mixinType = resolveType(mixinNode); |
255 if (isBlackListed(mixinType)) { | 254 if (isBlackListed(mixinType)) { |
256 reporter.reportErrorMessage( | 255 reporter.reportErrorMessage( |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 } | 296 } |
298 doApplyMixinTo(element, supertype, checkMixinType(link.head)); | 297 doApplyMixinTo(element, supertype, checkMixinType(link.head)); |
299 return element.computeType(resolution); | 298 return element.computeType(resolution); |
300 } | 299 } |
301 | 300 |
302 DartType applyMixin(DartType supertype, DartType mixinType, Node node) { | 301 DartType applyMixin(DartType supertype, DartType mixinType, Node node) { |
303 String superName = supertype.name; | 302 String superName = supertype.name; |
304 String mixinName = mixinType.name; | 303 String mixinName = mixinType.name; |
305 MixinApplicationElementX mixinApplication = | 304 MixinApplicationElementX mixinApplication = |
306 new UnnamedMixinApplicationElementX("${superName}+${mixinName}", | 305 new UnnamedMixinApplicationElementX("${superName}+${mixinName}", |
307 element, compiler.idGenerator.getNextFreeId(), node); | 306 element, resolution.idGenerator.getNextFreeId(), node); |
308 // Create synthetic type variables for the mixin application. | 307 // Create synthetic type variables for the mixin application. |
309 List<DartType> typeVariables = <DartType>[]; | 308 List<DartType> typeVariables = <DartType>[]; |
310 int index = 0; | 309 int index = 0; |
311 for (TypeVariableType type in element.typeVariables) { | 310 for (TypeVariableType type in element.typeVariables) { |
312 TypeVariableElementX typeVariableElement = new TypeVariableElementX( | 311 TypeVariableElementX typeVariableElement = new TypeVariableElementX( |
313 type.name, mixinApplication, index, type.element.node); | 312 type.name, mixinApplication, index, type.element.node); |
314 TypeVariableType typeVariable = new TypeVariableType(typeVariableElement); | 313 TypeVariableType typeVariable = new TypeVariableType(typeVariableElement); |
315 typeVariables.add(typeVariable); | 314 typeVariables.add(typeVariable); |
316 index++; | 315 index++; |
317 } | 316 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 constructor.computeType(resolution); | 352 constructor.computeType(resolution); |
354 return constructor; | 353 return constructor; |
355 } | 354 } |
356 | 355 |
357 void doApplyMixinTo(MixinApplicationElementX mixinApplication, | 356 void doApplyMixinTo(MixinApplicationElementX mixinApplication, |
358 DartType supertype, DartType mixinType) { | 357 DartType supertype, DartType mixinType) { |
359 Node node = mixinApplication.parseNode(resolution.parsingContext); | 358 Node node = mixinApplication.parseNode(resolution.parsingContext); |
360 | 359 |
361 if (mixinApplication.supertype != null) { | 360 if (mixinApplication.supertype != null) { |
362 // [supertype] is not null if there was a cycle. | 361 // [supertype] is not null if there was a cycle. |
363 assert(invariant(node, compiler.compilationFailed)); | 362 assert(invariant(node, reporter.hasReportedError)); |
364 supertype = mixinApplication.supertype; | 363 supertype = mixinApplication.supertype; |
365 assert(invariant(node, supertype.isObject)); | 364 assert(invariant(node, supertype.isObject)); |
366 } else { | 365 } else { |
367 mixinApplication.supertype = supertype; | 366 mixinApplication.supertype = supertype; |
368 } | 367 } |
369 | 368 |
370 // Named mixin application may have an 'implements' clause. | 369 // Named mixin application may have an 'implements' clause. |
371 NamedMixinApplication namedMixinApplication = | 370 NamedMixinApplication namedMixinApplication = |
372 node.asNamedMixinApplication(); | 371 node.asNamedMixinApplication(); |
373 Link<DartType> interfaces = (namedMixinApplication != null) | 372 Link<DartType> interfaces = (namedMixinApplication != null) |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 * first. | 537 * first. |
539 */ | 538 */ |
540 void calculateAllSupertypes(BaseClassElementX cls) { | 539 void calculateAllSupertypes(BaseClassElementX cls) { |
541 if (cls.allSupertypesAndSelf != null) return; | 540 if (cls.allSupertypesAndSelf != null) return; |
542 final DartType supertype = cls.supertype; | 541 final DartType supertype = cls.supertype; |
543 if (supertype != null) { | 542 if (supertype != null) { |
544 cls.allSupertypesAndSelf = new OrderedTypeSetBuilder(cls, | 543 cls.allSupertypesAndSelf = new OrderedTypeSetBuilder(cls, |
545 reporter: reporter, objectType: coreTypes.objectType) | 544 reporter: reporter, objectType: coreTypes.objectType) |
546 .createOrderedTypeSet(supertype, cls.interfaces); | 545 .createOrderedTypeSet(supertype, cls.interfaces); |
547 } else { | 546 } else { |
548 assert(cls == compiler.coreClasses.objectClass); | 547 assert(cls == resolution.coreClasses.objectClass); |
549 cls.allSupertypesAndSelf = | 548 cls.allSupertypesAndSelf = |
550 new OrderedTypeSet.singleton(cls.computeType(resolution)); | 549 new OrderedTypeSet.singleton(cls.computeType(resolution)); |
551 } | 550 } |
552 } | 551 } |
553 | 552 |
554 isBlackListed(DartType type) { | 553 isBlackListed(DartType type) { |
555 LibraryElement lib = element.library; | 554 LibraryElement lib = element.library; |
556 return !identical(lib, compiler.coreLibrary) && | 555 return !identical(lib, resolution.coreLibrary) && |
557 !resolution.target.isTargetSpecificLibrary(lib) && | 556 !resolution.target.isTargetSpecificLibrary(lib) && |
558 (type.isDynamic || | 557 (type.isDynamic || |
559 type == coreTypes.boolType || | 558 type == coreTypes.boolType || |
560 type == coreTypes.numType || | 559 type == coreTypes.numType || |
561 type == coreTypes.intType || | 560 type == coreTypes.intType || |
562 type == coreTypes.doubleType || | 561 type == coreTypes.doubleType || |
563 type == coreTypes.stringType || | 562 type == coreTypes.stringType || |
564 type == coreTypes.nullType); | 563 type == coreTypes.nullType); |
565 } | 564 } |
566 } | 565 } |
567 | 566 |
568 class ClassSupertypeResolver extends CommonResolverVisitor { | 567 class ClassSupertypeResolver extends CommonResolverVisitor { |
569 Scope context; | 568 Scope context; |
570 ClassElement classElement; | 569 ClassElement classElement; |
571 | 570 |
572 ClassSupertypeResolver(Compiler compiler, ClassElement cls) | 571 ClassSupertypeResolver(Resolution resolution, ClassElement cls) |
573 : context = Scope.buildEnclosingScope(cls), | 572 : context = Scope.buildEnclosingScope(cls), |
574 this.classElement = cls, | 573 this.classElement = cls, |
575 super(compiler); | 574 super(resolution); |
576 | 575 |
577 CoreClasses get coreClasses => compiler.coreClasses; | 576 CoreClasses get coreClasses => resolution.coreClasses; |
578 | 577 |
579 void loadSupertype(ClassElement element, Node from) { | 578 void loadSupertype(ClassElement element, Node from) { |
580 if (!element.isResolved) { | 579 if (!element.isResolved) { |
581 compiler.resolver.loadSupertypes(element, from); | 580 resolution.resolver.loadSupertypes(element, from); |
582 element.ensureResolved(resolution); | 581 element.ensureResolved(resolution); |
583 } | 582 } |
584 } | 583 } |
585 | 584 |
586 void visitNodeList(NodeList node) { | 585 void visitNodeList(NodeList node) { |
587 if (node != null) { | 586 if (node != null) { |
588 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 587 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
589 link.head.accept(this); | 588 link.head.accept(this); |
590 } | 589 } |
591 } | 590 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 Identifier selector = node.selector.asIdentifier(); | 644 Identifier selector = node.selector.asIdentifier(); |
646 var e = prefixElement.lookupLocalMember(selector.source); | 645 var e = prefixElement.lookupLocalMember(selector.source); |
647 if (e == null || !e.impliesType) { | 646 if (e == null || !e.impliesType) { |
648 reporter.reportErrorMessage(node.selector, | 647 reporter.reportErrorMessage(node.selector, |
649 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.selector}); | 648 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.selector}); |
650 return; | 649 return; |
651 } | 650 } |
652 loadSupertype(e, node); | 651 loadSupertype(e, node); |
653 } | 652 } |
654 } | 653 } |
OLD | NEW |