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 library dart2js.resolution; | 5 library dart2js.resolution; |
6 | 6 |
7 import 'dart:collection' show Queue; | 7 import 'dart:collection' show Queue; |
8 | 8 |
9 import '../common/names.dart' show | 9 import '../common/names.dart' show |
10 Identifiers; | 10 Identifiers; |
11 import '../common/resolution.dart' show | 11 import '../common/resolution.dart' show |
12 Parsing, | 12 Parsing, |
13 Resolution; | 13 Resolution, |
| 14 ResolutionWorldImpact; |
14 import '../common/tasks.dart' show | 15 import '../common/tasks.dart' show |
15 CompilerTask, | 16 CompilerTask, |
16 DeferredAction; | 17 DeferredAction; |
17 import '../compiler.dart' show | 18 import '../compiler.dart' show |
18 Compiler; | 19 Compiler; |
19 import '../compile_time_constants.dart' show | 20 import '../compile_time_constants.dart' show |
20 ConstantCompiler; | 21 ConstantCompiler; |
21 import '../constants/values.dart' show | 22 import '../constants/values.dart' show |
22 ConstantValue; | 23 ConstantValue; |
23 import '../dart_types.dart'; | 24 import '../dart_types.dart'; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 final ConstantCompiler constantCompiler; | 70 final ConstantCompiler constantCompiler; |
70 | 71 |
71 ResolverTask(Compiler compiler, this.constantCompiler) : super(compiler); | 72 ResolverTask(Compiler compiler, this.constantCompiler) : super(compiler); |
72 | 73 |
73 String get name => 'Resolver'; | 74 String get name => 'Resolver'; |
74 | 75 |
75 Resolution get resolution => compiler.resolution; | 76 Resolution get resolution => compiler.resolution; |
76 | 77 |
77 Parsing get parsing => compiler.parsing; | 78 Parsing get parsing => compiler.parsing; |
78 | 79 |
79 WorldImpact resolve(Element element) { | 80 ResolutionWorldImpact resolve(Element element) { |
80 return measure(() { | 81 return measure(() { |
81 if (Elements.isErroneous(element)) { | 82 if (Elements.isErroneous(element)) { |
82 // TODO(johnniwinther): Add a predicate for this. | 83 // TODO(johnniwinther): Add a predicate for this. |
83 assert(invariant(element, element is! ErroneousElement, | 84 assert(invariant(element, element is! ErroneousElement, |
84 message: "Element $element expected to have parse errors.")); | 85 message: "Element $element expected to have parse errors.")); |
85 _ensureTreeElements(element); | 86 _ensureTreeElements(element); |
86 return const WorldImpact(); | 87 return const ResolutionWorldImpact(); |
87 } | 88 } |
88 | 89 |
89 WorldImpact processMetadata([WorldImpact result]) { | 90 WorldImpact processMetadata([WorldImpact result]) { |
90 for (MetadataAnnotation metadata in element.implementation.metadata) { | 91 for (MetadataAnnotation metadata in element.implementation.metadata) { |
91 metadata.ensureResolved(resolution); | 92 metadata.ensureResolved(resolution); |
92 } | 93 } |
93 return result; | 94 return result; |
94 } | 95 } |
95 | 96 |
96 ElementKind kind = element.kind; | 97 ElementKind kind = element.kind; |
97 if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) || | 98 if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) || |
98 identical(kind, ElementKind.FUNCTION) || | 99 identical(kind, ElementKind.FUNCTION) || |
99 identical(kind, ElementKind.GETTER) || | 100 identical(kind, ElementKind.GETTER) || |
100 identical(kind, ElementKind.SETTER)) { | 101 identical(kind, ElementKind.SETTER)) { |
101 return processMetadata(resolveMethodElement(element)); | 102 return processMetadata(resolveMethodElement(element)); |
102 } | 103 } |
103 | 104 |
104 if (identical(kind, ElementKind.FIELD)) { | 105 if (identical(kind, ElementKind.FIELD)) { |
105 return processMetadata(resolveField(element)); | 106 return processMetadata(resolveField(element)); |
106 } | 107 } |
107 if (element.isClass) { | 108 if (element.isClass) { |
108 ClassElement cls = element; | 109 ClassElement cls = element; |
109 cls.ensureResolved(resolution); | 110 cls.ensureResolved(resolution); |
110 return processMetadata(const WorldImpact()); | 111 return processMetadata(const ResolutionWorldImpact()); |
111 } else if (element.isTypedef) { | 112 } else if (element.isTypedef) { |
112 TypedefElement typdef = element; | 113 TypedefElement typdef = element; |
113 return processMetadata(resolveTypedef(typdef)); | 114 return processMetadata(resolveTypedef(typdef)); |
114 } | 115 } |
115 | 116 |
116 compiler.unimplemented(element, "resolve($element)"); | 117 compiler.unimplemented(element, "resolve($element)"); |
117 }); | 118 }); |
118 } | 119 } |
119 | 120 |
120 void resolveRedirectingConstructor(InitializerResolver resolver, | 121 void resolveRedirectingConstructor(InitializerResolver resolver, |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 } | 278 } |
278 | 279 |
279 return registry.worldImpact; | 280 return registry.worldImpact; |
280 }); | 281 }); |
281 | 282 |
282 } | 283 } |
283 | 284 |
284 WorldImpact resolveMethodElement(FunctionElementX element) { | 285 WorldImpact resolveMethodElement(FunctionElementX element) { |
285 assert(invariant(element, element.isDeclaration)); | 286 assert(invariant(element, element.isDeclaration)); |
286 return compiler.withCurrentElement(element, () { | 287 return compiler.withCurrentElement(element, () { |
287 if (compiler.enqueuer.resolution.hasBeenResolved(element)) { | 288 if (compiler.enqueuer.resolution.hasBeenProcessed(element)) { |
288 // TODO(karlklose): Remove the check for [isConstructor]. [elememts] | 289 // TODO(karlklose): Remove the check for [isConstructor]. [elememts] |
289 // should never be non-null, not even for constructors. | 290 // should never be non-null, not even for constructors. |
290 assert(invariant(element, element.isConstructor, | 291 assert(invariant(element, element.isConstructor, |
291 message: 'Non-constructor element $element ' | 292 message: 'Non-constructor element $element ' |
292 'has already been analyzed.')); | 293 'has already been analyzed.')); |
293 return const WorldImpact(); | 294 return const ResolutionWorldImpact(); |
294 } | 295 } |
295 if (element.isSynthesized) { | 296 if (element.isSynthesized) { |
296 if (element.isGenerativeConstructor) { | 297 if (element.isGenerativeConstructor) { |
297 ResolutionRegistry registry = | 298 ResolutionRegistry registry = |
298 new ResolutionRegistry(compiler, _ensureTreeElements(element)); | 299 new ResolutionRegistry(compiler, _ensureTreeElements(element)); |
299 ConstructorElement constructor = element.asFunctionElement(); | 300 ConstructorElement constructor = element.asFunctionElement(); |
300 ConstructorElement target = constructor.definingConstructor; | 301 ConstructorElement target = constructor.definingConstructor; |
301 // Ensure the signature of the synthesized element is | 302 // Ensure the signature of the synthesized element is |
302 // resolved. This is the only place where the resolver is | 303 // resolved. This is the only place where the resolver is |
303 // seeing this element. | 304 // seeing this element. |
304 element.computeType(resolution); | 305 element.computeType(resolution); |
305 if (!target.isErroneous) { | 306 if (!target.isErroneous) { |
306 registry.registerStaticUse(target); | 307 registry.registerStaticUse(target); |
307 registry.registerImplicitSuperCall(target); | 308 registry.registerImplicitSuperCall(target); |
308 } | 309 } |
309 return registry.worldImpact; | 310 return registry.worldImpact; |
310 } else { | 311 } else { |
311 assert(element.isDeferredLoaderGetter || element.isErroneous); | 312 assert(element.isDeferredLoaderGetter || element.isErroneous); |
312 _ensureTreeElements(element); | 313 _ensureTreeElements(element); |
313 return const WorldImpact(); | 314 return const ResolutionWorldImpact(); |
314 } | 315 } |
315 } else { | 316 } else { |
316 element.parseNode(resolution.parsing); | 317 element.parseNode(resolution.parsing); |
317 element.computeType(resolution); | 318 element.computeType(resolution); |
318 FunctionElementX implementation = element; | 319 FunctionElementX implementation = element; |
319 if (element.isExternal) { | 320 if (element.isExternal) { |
320 implementation = compiler.backend.resolveExternalFunction(element); | 321 implementation = compiler.backend.resolveExternalFunction(element); |
321 } | 322 } |
322 return resolveMethodElementImplementation( | 323 return resolveMethodElementImplementation( |
323 implementation, implementation.node); | 324 implementation, implementation.node); |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 if (member.isGenerativeConstructor && !member.isSynthesized) { | 709 if (member.isGenerativeConstructor && !member.isSynthesized) { |
709 compiler.reportErrorMessage( | 710 compiler.reportErrorMessage( |
710 member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR); | 711 member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR); |
711 } else { | 712 } else { |
712 // Get the resolution tree and check that the resolved member | 713 // Get the resolution tree and check that the resolved member |
713 // doesn't use 'super'. This is the part of the 'super' mixin | 714 // doesn't use 'super'. This is the part of the 'super' mixin |
714 // check that happens when a function is resolved before the | 715 // check that happens when a function is resolved before the |
715 // mixin application has been performed. | 716 // mixin application has been performed. |
716 // TODO(johnniwinther): Obtain the [TreeElements] for [member] | 717 // TODO(johnniwinther): Obtain the [TreeElements] for [member] |
717 // differently. | 718 // differently. |
718 if (compiler.enqueuer.resolution.hasBeenResolved(member)) { | 719 if (compiler.enqueuer.resolution.hasBeenProcessed(member)) { |
719 checkMixinSuperUses( | 720 checkMixinSuperUses( |
720 member.resolvedAst.elements, | 721 member.resolvedAst.elements, |
721 mixinApplication, | 722 mixinApplication, |
722 mixin); | 723 mixin); |
723 } | 724 } |
724 } | 725 } |
725 }); | 726 }); |
726 } | 727 } |
727 | 728 |
728 void checkMixinSuperUses(TreeElements resolutionTree, | 729 void checkMixinSuperUses(TreeElements resolutionTree, |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 FunctionExpression node = element.parseNode(parsing); | 986 FunctionExpression node = element.parseNode(parsing); |
986 return measure(() => SignatureResolver.analyze( | 987 return measure(() => SignatureResolver.analyze( |
987 compiler, node.parameters, node.returnType, element, | 988 compiler, node.parameters, node.returnType, element, |
988 new ResolutionRegistry(compiler, _ensureTreeElements(element)), | 989 new ResolutionRegistry(compiler, _ensureTreeElements(element)), |
989 defaultValuesError: defaultValuesError, | 990 defaultValuesError: defaultValuesError, |
990 createRealParameters: true)); | 991 createRealParameters: true)); |
991 }); | 992 }); |
992 } | 993 } |
993 | 994 |
994 WorldImpact resolveTypedef(TypedefElementX element) { | 995 WorldImpact resolveTypedef(TypedefElementX element) { |
995 if (element.isResolved) return const WorldImpact(); | 996 if (element.isResolved) return const ResolutionWorldImpact(); |
996 compiler.world.allTypedefs.add(element); | 997 compiler.world.allTypedefs.add(element); |
997 return _resolveTypeDeclaration(element, () { | 998 return _resolveTypeDeclaration(element, () { |
998 ResolutionRegistry registry = new ResolutionRegistry( | 999 ResolutionRegistry registry = new ResolutionRegistry( |
999 compiler, _ensureTreeElements(element)); | 1000 compiler, _ensureTreeElements(element)); |
1000 return compiler.withCurrentElement(element, () { | 1001 return compiler.withCurrentElement(element, () { |
1001 return measure(() { | 1002 return measure(() { |
1002 assert(element.resolutionState == STATE_NOT_STARTED); | 1003 assert(element.resolutionState == STATE_NOT_STARTED); |
1003 element.resolutionState = STATE_STARTED; | 1004 element.resolutionState = STATE_STARTED; |
1004 Typedef node = element.parseNode(parsing); | 1005 Typedef node = element.parseNode(parsing); |
1005 TypedefResolverVisitor visitor = | 1006 TypedefResolverVisitor visitor = |
(...skipping 27 matching lines...) Expand all Loading... |
1033 node.accept(visitor); | 1034 node.accept(visitor); |
1034 // TODO(johnniwinther): Avoid passing the [TreeElements] to | 1035 // TODO(johnniwinther): Avoid passing the [TreeElements] to |
1035 // [compileMetadata]. | 1036 // [compileMetadata]. |
1036 annotation.constant = | 1037 annotation.constant = |
1037 constantCompiler.compileMetadata(annotation, node, registry.mapping); | 1038 constantCompiler.compileMetadata(annotation, node, registry.mapping); |
1038 constantCompiler.evaluate(annotation.constant); | 1039 constantCompiler.evaluate(annotation.constant); |
1039 // TODO(johnniwinther): Register the relation between the annotation | 1040 // TODO(johnniwinther): Register the relation between the annotation |
1040 // and the annotated element instead. This will allow the backend to | 1041 // and the annotated element instead. This will allow the backend to |
1041 // retrieve the backend constant and only register metadata on the | 1042 // retrieve the backend constant and only register metadata on the |
1042 // elements for which it is needed. (Issue 17732). | 1043 // elements for which it is needed. (Issue 17732). |
1043 registry.registerMetadataConstant(annotation, annotatedElement); | 1044 registry.registerMetadataConstant(annotation); |
1044 annotation.resolutionState = STATE_DONE; | 1045 annotation.resolutionState = STATE_DONE; |
1045 })); | 1046 })); |
1046 } | 1047 } |
1047 | 1048 |
1048 List<MetadataAnnotation> resolveMetadata(Element element, | 1049 List<MetadataAnnotation> resolveMetadata(Element element, |
1049 VariableDefinitions node) { | 1050 VariableDefinitions node) { |
1050 List<MetadataAnnotation> metadata = <MetadataAnnotation>[]; | 1051 List<MetadataAnnotation> metadata = <MetadataAnnotation>[]; |
1051 for (Metadata annotation in node.metadata.nodes) { | 1052 for (Metadata annotation in node.metadata.nodes) { |
1052 ParameterMetadataAnnotation metadataAnnotation = | 1053 ParameterMetadataAnnotation metadataAnnotation = |
1053 new ParameterMetadataAnnotation(annotation); | 1054 new ParameterMetadataAnnotation(annotation); |
(...skipping 19 matching lines...) Expand all Loading... |
1073 TreeElements get treeElements { | 1074 TreeElements get treeElements { |
1074 assert(invariant(this, _treeElements !=null, | 1075 assert(invariant(this, _treeElements !=null, |
1075 message: "TreeElements have not been computed for $this.")); | 1076 message: "TreeElements have not been computed for $this.")); |
1076 return _treeElements; | 1077 return _treeElements; |
1077 } | 1078 } |
1078 | 1079 |
1079 void reuseElement() { | 1080 void reuseElement() { |
1080 _treeElements = null; | 1081 _treeElements = null; |
1081 } | 1082 } |
1082 } | 1083 } |
OLD | NEW |