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