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