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 part of resolution; | 5 part of resolution; |
6 | 6 |
7 class ResolverTask extends CompilerTask { | 7 class ResolverTask extends CompilerTask { |
8 final ConstantCompiler constantCompiler; | 8 final ConstantCompiler constantCompiler; |
9 | 9 |
10 ResolverTask(Compiler compiler, this.constantCompiler) : super(compiler); | 10 ResolverTask(Compiler compiler, this.constantCompiler) : super(compiler); |
11 | 11 |
12 String get name => 'Resolver'; | 12 String get name => 'Resolver'; |
13 | 13 |
14 TreeElements resolve(Element element) { | 14 WorldImpact resolve(Element element) { |
15 return measure(() { | 15 return measure(() { |
16 if (Elements.isErroneous(element)) return null; | 16 if (Elements.isErroneous(element)) return null; |
17 | 17 |
18 processMetadata([result]) { | 18 WorldImpact processMetadata([WorldImpact result]) { |
19 for (MetadataAnnotation metadata in element.metadata) { | 19 for (MetadataAnnotation metadata in element.metadata) { |
20 metadata.ensureResolved(compiler); | 20 metadata.ensureResolved(compiler); |
21 } | 21 } |
22 return result; | 22 return result; |
23 } | 23 } |
24 | 24 |
25 ElementKind kind = element.kind; | 25 ElementKind kind = element.kind; |
26 if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) || | 26 if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) || |
27 identical(kind, ElementKind.FUNCTION) || | 27 identical(kind, ElementKind.FUNCTION) || |
28 identical(kind, ElementKind.GETTER) || | 28 identical(kind, ElementKind.GETTER) || |
29 identical(kind, ElementKind.SETTER)) { | 29 identical(kind, ElementKind.SETTER)) { |
30 return processMetadata(resolveMethodElement(element)); | 30 return processMetadata(resolveMethodElement(element)); |
31 } | 31 } |
32 | 32 |
33 if (identical(kind, ElementKind.FIELD)) { | 33 if (identical(kind, ElementKind.FIELD)) { |
34 return processMetadata(resolveField(element)); | 34 return processMetadata(resolveField(element)); |
35 } | 35 } |
36 if (element.isClass) { | 36 if (element.isClass) { |
37 ClassElement cls = element; | 37 ClassElement cls = element; |
38 cls.ensureResolved(compiler); | 38 cls.ensureResolved(compiler); |
39 return processMetadata(); | 39 return processMetadata(const WorldImpact()); |
40 } else if (element.isTypedef) { | 40 } else if (element.isTypedef) { |
41 TypedefElement typdef = element; | 41 TypedefElement typdef = element; |
42 return processMetadata(resolveTypedef(typdef)); | 42 return processMetadata(resolveTypedef(typdef)); |
43 } | 43 } |
44 | 44 |
45 compiler.unimplemented(element, "resolve($element)"); | 45 compiler.unimplemented(element, "resolve($element)"); |
46 }); | 46 }); |
47 } | 47 } |
48 | 48 |
49 void resolveRedirectingConstructor(InitializerResolver resolver, | 49 void resolveRedirectingConstructor(InitializerResolver resolver, |
(...skipping 12 matching lines...) Expand all Loading... |
62 resolver.visitor.error(node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE); | 62 resolver.visitor.error(node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE); |
63 return; | 63 return; |
64 } | 64 } |
65 seen.add(redirection); | 65 seen.add(redirection); |
66 redirection = resolver.visitor.resolveConstructorRedirection(redirection); | 66 redirection = resolver.visitor.resolveConstructorRedirection(redirection); |
67 } | 67 } |
68 } | 68 } |
69 | 69 |
70 static void processAsyncMarker(Compiler compiler, | 70 static void processAsyncMarker(Compiler compiler, |
71 BaseFunctionElementX element, | 71 BaseFunctionElementX element, |
72 Registry registry) { | 72 ResolutionRegistry registry) { |
73 FunctionExpression functionExpression = element.node; | 73 FunctionExpression functionExpression = element.node; |
74 AsyncModifier asyncModifier = functionExpression.asyncModifier; | 74 AsyncModifier asyncModifier = functionExpression.asyncModifier; |
75 if (asyncModifier != null) { | 75 if (asyncModifier != null) { |
76 | 76 |
77 if (asyncModifier.isAsynchronous) { | 77 if (asyncModifier.isAsynchronous) { |
78 element.asyncMarker = asyncModifier.isYielding | 78 element.asyncMarker = asyncModifier.isYielding |
79 ? AsyncMarker.ASYNC_STAR : AsyncMarker.ASYNC; | 79 ? AsyncMarker.ASYNC_STAR : AsyncMarker.ASYNC; |
80 } else { | 80 } else { |
81 element.asyncMarker = AsyncMarker.SYNC_STAR; | 81 element.asyncMarker = AsyncMarker.SYNC_STAR; |
82 } | 82 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 | 119 |
120 bool _isNativeClassOrExtendsNativeClass(ClassElement classElement) { | 120 bool _isNativeClassOrExtendsNativeClass(ClassElement classElement) { |
121 assert(classElement != null); | 121 assert(classElement != null); |
122 while (classElement != null) { | 122 while (classElement != null) { |
123 if (classElement.isNative) return true; | 123 if (classElement.isNative) return true; |
124 classElement = classElement.superclass; | 124 classElement = classElement.superclass; |
125 } | 125 } |
126 return false; | 126 return false; |
127 } | 127 } |
128 | 128 |
129 TreeElements resolveMethodElementImplementation( | 129 WorldImpact resolveMethodElementImplementation( |
130 FunctionElement element, FunctionExpression tree) { | 130 FunctionElement element, FunctionExpression tree) { |
131 return compiler.withCurrentElement(element, () { | 131 return compiler.withCurrentElement(element, () { |
132 if (element.isExternal && tree.hasBody()) { | 132 if (element.isExternal && tree.hasBody()) { |
133 error(element, | 133 error(element, |
134 MessageKind.EXTERNAL_WITH_BODY, | 134 MessageKind.EXTERNAL_WITH_BODY, |
135 {'functionName': element.name}); | 135 {'functionName': element.name}); |
136 } | 136 } |
137 if (element.isConstructor) { | 137 if (element.isConstructor) { |
138 if (tree.returnType != null) { | 138 if (tree.returnType != null) { |
139 error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE); | 139 error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 } | 187 } |
188 } | 188 } |
189 | 189 |
190 // TODO(9631): support noSuchMethod on native classes. | 190 // TODO(9631): support noSuchMethod on native classes. |
191 if (Elements.isInstanceMethod(element) && | 191 if (Elements.isInstanceMethod(element) && |
192 element.name == Compiler.NO_SUCH_METHOD && | 192 element.name == Compiler.NO_SUCH_METHOD && |
193 _isNativeClassOrExtendsNativeClass(enclosingClass)) { | 193 _isNativeClassOrExtendsNativeClass(enclosingClass)) { |
194 error(tree, MessageKind.NO_SUCH_METHOD_IN_NATIVE); | 194 error(tree, MessageKind.NO_SUCH_METHOD_IN_NATIVE); |
195 } | 195 } |
196 | 196 |
197 return resolutionTree; | 197 return registry.worldImpact; |
198 }); | 198 }); |
199 | 199 |
200 } | 200 } |
201 | 201 |
202 TreeElements resolveMethodElement(FunctionElementX element) { | 202 WorldImpact resolveMethodElement(FunctionElementX element) { |
203 assert(invariant(element, element.isDeclaration)); | 203 assert(invariant(element, element.isDeclaration)); |
204 return compiler.withCurrentElement(element, () { | 204 return compiler.withCurrentElement(element, () { |
205 if (compiler.enqueuer.resolution.hasBeenResolved(element)) { | 205 if (compiler.enqueuer.resolution.hasBeenResolved(element)) { |
206 // TODO(karlklose): Remove the check for [isConstructor]. [elememts] | 206 // TODO(karlklose): Remove the check for [isConstructor]. [elememts] |
207 // should never be non-null, not even for constructors. | 207 // should never be non-null, not even for constructors. |
208 assert(invariant(element, element.isConstructor, | 208 assert(invariant(element, element.isConstructor, |
209 message: 'Non-constructor element $element ' | 209 message: 'Non-constructor element $element ' |
210 'has already been analyzed.')); | 210 'has already been analyzed.')); |
211 return element.resolvedAst.elements; | 211 return const WorldImpact(); |
212 } | 212 } |
213 if (element.isSynthesized) { | 213 if (element.isSynthesized) { |
214 if (element.isGenerativeConstructor) { | 214 if (element.isGenerativeConstructor) { |
215 ResolutionRegistry registry = | 215 ResolutionRegistry registry = |
216 new ResolutionRegistry(compiler, element); | 216 new ResolutionRegistry(compiler, element); |
217 ConstructorElement constructor = element.asFunctionElement(); | 217 ConstructorElement constructor = element.asFunctionElement(); |
218 ConstructorElement target = constructor.definingConstructor; | 218 ConstructorElement target = constructor.definingConstructor; |
219 // Ensure the signature of the synthesized element is | 219 // Ensure the signature of the synthesized element is |
220 // resolved. This is the only place where the resolver is | 220 // resolved. This is the only place where the resolver is |
221 // seeing this element. | 221 // seeing this element. |
222 element.computeSignature(compiler); | 222 element.computeSignature(compiler); |
223 if (!target.isErroneous) { | 223 if (!target.isErroneous) { |
224 registry.registerStaticUse(target); | 224 registry.registerStaticUse(target); |
225 registry.registerImplicitSuperCall(target); | 225 registry.registerImplicitSuperCall(target); |
226 } | 226 } |
227 return registry.mapping; | 227 return registry.worldImpact; |
228 } else { | 228 } else { |
229 assert(element.isDeferredLoaderGetter || element.isErroneous); | 229 assert(element.isDeferredLoaderGetter || element.isErroneous); |
230 return _ensureTreeElements(element); | 230 _ensureTreeElements(element); |
| 231 return const WorldImpact(); |
231 } | 232 } |
232 } else { | 233 } else { |
233 element.parseNode(compiler); | 234 element.parseNode(compiler); |
234 element.computeType(compiler); | 235 element.computeType(compiler); |
235 FunctionElementX implementation = element; | 236 FunctionElementX implementation = element; |
236 if (element.isExternal) { | 237 if (element.isExternal) { |
237 implementation = compiler.backend.resolveExternalFunction(element); | 238 implementation = compiler.backend.resolveExternalFunction(element); |
238 } | 239 } |
239 return resolveMethodElementImplementation( | 240 return resolveMethodElementImplementation( |
240 implementation, implementation.node); | 241 implementation, implementation.node); |
241 } | 242 } |
242 }); | 243 }); |
243 } | 244 } |
244 | 245 |
245 /// Creates a [ResolverVisitor] for resolving an AST in context of [element]. | 246 /// Creates a [ResolverVisitor] for resolving an AST in context of [element]. |
246 /// If [useEnclosingScope] is `true` then the initial scope of the visitor | 247 /// If [useEnclosingScope] is `true` then the initial scope of the visitor |
247 /// does not include inner scope of [element]. | 248 /// does not include inner scope of [element]. |
248 /// | 249 /// |
249 /// This method should only be used by this library (or tests of | 250 /// This method should only be used by this library (or tests of |
250 /// this library). | 251 /// this library). |
251 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) { | 252 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) { |
252 return new ResolverVisitor(compiler, element, | 253 return new ResolverVisitor(compiler, element, |
253 new ResolutionRegistry(compiler, element), | 254 new ResolutionRegistry(compiler, element), |
254 useEnclosingScope: useEnclosingScope); | 255 useEnclosingScope: useEnclosingScope); |
255 } | 256 } |
256 | 257 |
257 TreeElements resolveField(FieldElementX element) { | 258 WorldImpact resolveField(FieldElementX element) { |
258 VariableDefinitions tree = element.parseNode(compiler); | 259 VariableDefinitions tree = element.parseNode(compiler); |
259 if(element.modifiers.isStatic && element.isTopLevel) { | 260 if(element.modifiers.isStatic && element.isTopLevel) { |
260 error(element.modifiers.getStatic(), | 261 error(element.modifiers.getStatic(), |
261 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); | 262 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); |
262 } | 263 } |
263 ResolverVisitor visitor = visitorFor(element); | 264 ResolverVisitor visitor = visitorFor(element); |
264 ResolutionRegistry registry = visitor.registry; | 265 ResolutionRegistry registry = visitor.registry; |
265 // TODO(johnniwinther): Maybe remove this when placeholderCollector migrates | 266 // TODO(johnniwinther): Maybe remove this when placeholderCollector migrates |
266 // to the backend ast. | 267 // to the backend ast. |
267 registry.defineElement(tree.definitions.nodes.head, element); | 268 registry.defineElement(tree.definitions.nodes.head, element); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 // TODO(johnniwinther): Determine the const-ness eagerly to avoid | 301 // TODO(johnniwinther): Determine the const-ness eagerly to avoid |
301 // unnecessary registrations. | 302 // unnecessary registrations. |
302 registry.registerLazyField(); | 303 registry.registerLazyField(); |
303 } | 304 } |
304 } | 305 } |
305 } | 306 } |
306 | 307 |
307 // Perform various checks as side effect of "computing" the type. | 308 // Perform various checks as side effect of "computing" the type. |
308 element.computeType(compiler); | 309 element.computeType(compiler); |
309 | 310 |
310 return registry.mapping; | 311 return registry.worldImpact; |
311 } | 312 } |
312 | 313 |
313 DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) { | 314 DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) { |
314 DartType type = resolveReturnType(element, annotation); | 315 DartType type = resolveReturnType(element, annotation); |
315 if (type.isVoid) { | 316 if (type.isVoid) { |
316 error(annotation, MessageKind.VOID_NOT_ALLOWED); | 317 error(annotation, MessageKind.VOID_NOT_ALLOWED); |
317 } | 318 } |
318 return type; | 319 return type; |
319 } | 320 } |
320 | 321 |
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 FunctionExpression node = | 880 FunctionExpression node = |
880 compiler.parser.measure(() => element.parseNode(compiler)); | 881 compiler.parser.measure(() => element.parseNode(compiler)); |
881 return measure(() => SignatureResolver.analyze( | 882 return measure(() => SignatureResolver.analyze( |
882 compiler, node.parameters, node.returnType, element, | 883 compiler, node.parameters, node.returnType, element, |
883 new ResolutionRegistry(compiler, element), | 884 new ResolutionRegistry(compiler, element), |
884 defaultValuesError: defaultValuesError, | 885 defaultValuesError: defaultValuesError, |
885 createRealParameters: true)); | 886 createRealParameters: true)); |
886 }); | 887 }); |
887 } | 888 } |
888 | 889 |
889 TreeElements resolveTypedef(TypedefElementX element) { | 890 WorldImpact resolveTypedef(TypedefElementX element) { |
890 if (element.isResolved) return element.treeElements; | 891 if (element.isResolved) return const WorldImpact(); |
891 compiler.world.allTypedefs.add(element); | 892 compiler.world.allTypedefs.add(element); |
892 return _resolveTypeDeclaration(element, () { | 893 return _resolveTypeDeclaration(element, () { |
893 ResolutionRegistry registry = new ResolutionRegistry(compiler, element); | 894 ResolutionRegistry registry = new ResolutionRegistry(compiler, element); |
894 return compiler.withCurrentElement(element, () { | 895 return compiler.withCurrentElement(element, () { |
895 return measure(() { | 896 return measure(() { |
896 assert(element.resolutionState == STATE_NOT_STARTED); | 897 assert(element.resolutionState == STATE_NOT_STARTED); |
897 element.resolutionState = STATE_STARTED; | 898 element.resolutionState = STATE_STARTED; |
898 Typedef node = | 899 Typedef node = |
899 compiler.parser.measure(() => element.parseNode(compiler)); | 900 compiler.parser.measure(() => element.parseNode(compiler)); |
900 TypedefResolverVisitor visitor = | 901 TypedefResolverVisitor visitor = |
901 new TypedefResolverVisitor(compiler, element, registry); | 902 new TypedefResolverVisitor(compiler, element, registry); |
902 visitor.visit(node); | 903 visitor.visit(node); |
903 element.resolutionState = STATE_DONE; | 904 element.resolutionState = STATE_DONE; |
904 return registry.mapping; | 905 return registry.worldImpact; |
905 }); | 906 }); |
906 }); | 907 }); |
907 }); | 908 }); |
908 } | 909 } |
909 | 910 |
910 void resolveMetadataAnnotation(MetadataAnnotationX annotation) { | 911 void resolveMetadataAnnotation(MetadataAnnotationX annotation) { |
911 compiler.withCurrentElement(annotation.annotatedElement, () => measure(() { | 912 compiler.withCurrentElement(annotation.annotatedElement, () => measure(() { |
912 assert(annotation.resolutionState == STATE_NOT_STARTED); | 913 assert(annotation.resolutionState == STATE_NOT_STARTED); |
913 annotation.resolutionState = STATE_STARTED; | 914 annotation.resolutionState = STATE_STARTED; |
914 | 915 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1040 | 1041 |
1041 void reportDuplicateDefinition(String name, | 1042 void reportDuplicateDefinition(String name, |
1042 Spannable definition, | 1043 Spannable definition, |
1043 Spannable existing) { | 1044 Spannable existing) { |
1044 compiler.reportError(definition, | 1045 compiler.reportError(definition, |
1045 MessageKind.DUPLICATE_DEFINITION, {'name': name}); | 1046 MessageKind.DUPLICATE_DEFINITION, {'name': name}); |
1046 compiler.reportInfo(existing, | 1047 compiler.reportInfo(existing, |
1047 MessageKind.EXISTING_DEFINITION, {'name': name}); | 1048 MessageKind.EXISTING_DEFINITION, {'name': name}); |
1048 } | 1049 } |
1049 } | 1050 } |
OLD | NEW |