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.dart'; | 9 import '../common.dart'; |
10 import '../common/names.dart' show Identifiers; | 10 import '../common/names.dart' show Identifiers; |
11 import '../common/resolution.dart' | 11 import '../common/resolution.dart' |
12 show Feature, ParsingContext, Resolution, ResolutionImpact; | 12 show Feature, ParsingContext, Resolution, ResolutionImpact, Target; |
13 import '../common/tasks.dart' show CompilerTask; | 13 import '../common/tasks.dart' show CompilerTask, Measurer; |
14 import '../compile_time_constants.dart' show ConstantCompiler; | 14 import '../compile_time_constants.dart' show ConstantCompiler; |
15 import '../compiler.dart' show Compiler; | |
16 import '../constants/expressions.dart' | 15 import '../constants/expressions.dart' |
17 show | 16 show |
18 ConstantExpression, | 17 ConstantExpression, |
19 ConstantExpressionKind, | 18 ConstantExpressionKind, |
20 ConstructedConstantExpression, | 19 ConstructedConstantExpression, |
21 ErroneousConstantExpression; | 20 ErroneousConstantExpression; |
22 import '../constants/values.dart' show ConstantValue; | 21 import '../constants/values.dart' show ConstantValue; |
23 import '../core_types.dart' show CoreClasses, CoreTypes; | 22 import '../core_types.dart' show CoreClasses, CoreTypes; |
24 import '../dart_types.dart'; | 23 import '../dart_types.dart'; |
25 import '../elements/elements.dart'; | 24 import '../elements/elements.dart'; |
26 import '../elements/modelx.dart' | 25 import '../elements/modelx.dart' |
27 show | 26 show |
28 BaseClassElementX, | 27 BaseClassElementX, |
29 BaseFunctionElementX, | 28 BaseFunctionElementX, |
30 ConstructorElementX, | 29 ConstructorElementX, |
31 FieldElementX, | 30 FieldElementX, |
32 FunctionElementX, | 31 FunctionElementX, |
33 GetterElementX, | 32 GetterElementX, |
34 MetadataAnnotationX, | 33 MetadataAnnotationX, |
35 MixinApplicationElementX, | 34 MixinApplicationElementX, |
36 ParameterMetadataAnnotation, | 35 ParameterMetadataAnnotation, |
37 SetterElementX, | 36 SetterElementX, |
38 TypedefElementX; | 37 TypedefElementX; |
38 import '../enqueue.dart'; | |
39 import '../options.dart'; | |
39 import '../tokens/token.dart' | 40 import '../tokens/token.dart' |
40 show | 41 show |
41 isBinaryOperator, | 42 isBinaryOperator, |
42 isMinusOperator, | 43 isMinusOperator, |
43 isTernaryOperator, | 44 isTernaryOperator, |
44 isUnaryOperator, | 45 isUnaryOperator, |
45 isUserDefinableOperator; | 46 isUserDefinableOperator; |
46 import '../tree/tree.dart'; | 47 import '../tree/tree.dart'; |
47 import '../universe/call_structure.dart' show CallStructure; | 48 import '../universe/call_structure.dart' show CallStructure; |
48 import '../universe/use.dart' show StaticUse, TypeUse; | 49 import '../universe/use.dart' show StaticUse, TypeUse; |
49 import '../universe/world_impact.dart' show WorldImpact; | 50 import '../universe/world_impact.dart' show WorldImpact; |
50 import '../util/util.dart' show Link, Setlet; | 51 import '../util/util.dart' show Link, Setlet; |
52 import '../world.dart'; | |
51 import 'class_hierarchy.dart'; | 53 import 'class_hierarchy.dart'; |
52 import 'class_members.dart' show MembersCreator; | 54 import 'class_members.dart' show MembersCreator; |
53 import 'constructors.dart'; | 55 import 'constructors.dart'; |
54 import 'members.dart'; | 56 import 'members.dart'; |
55 import 'registry.dart'; | 57 import 'registry.dart'; |
56 import 'resolution_result.dart'; | 58 import 'resolution_result.dart'; |
57 import 'scope.dart' show MutableScope; | |
58 import 'signatures.dart'; | 59 import 'signatures.dart'; |
59 import 'tree_elements.dart'; | 60 import 'tree_elements.dart'; |
60 import 'typedefs.dart'; | 61 import 'typedefs.dart'; |
61 | 62 |
62 class ResolverTask extends CompilerTask { | 63 class ResolverTask extends CompilerTask { |
63 final ConstantCompiler constantCompiler; | 64 final ConstantCompiler constantCompiler; |
64 final Compiler compiler; | 65 final Resolution resolution; |
66 final World world; | |
65 | 67 |
66 ResolverTask(Compiler compiler, this.constantCompiler) | 68 ResolverTask( |
67 : compiler = compiler, | 69 this.resolution, this.constantCompiler, this.world, Measurer measurer) |
68 super(compiler.measurer); | 70 : super(measurer); |
69 | 71 |
70 String get name => 'Resolver'; | 72 String get name => 'Resolver'; |
71 | 73 |
72 DiagnosticReporter get reporter => compiler.reporter; | 74 DiagnosticReporter get reporter => resolution.reporter; |
73 | 75 Target get target => resolution.target; |
74 Resolution get resolution => compiler.resolution; | 76 CoreTypes get coreTypes => resolution.coreTypes; |
75 | 77 CoreClasses get coreClasses => resolution.coreClasses; |
76 ParsingContext get parsingContext => compiler.parsingContext; | 78 ParsingContext get parsingContext => resolution.parsingContext; |
77 | 79 CompilerOptions get options => resolution.options; |
78 CoreClasses get coreClasses => compiler.coreClasses; | 80 ResolutionEnqueuer get enqueuer => resolution.enqueuer; |
79 | |
80 CoreTypes get coreTypes => compiler.coreTypes; | |
81 | 81 |
82 ResolutionImpact resolve(Element element) { | 82 ResolutionImpact resolve(Element element) { |
83 return measure(() { | 83 return measure(() { |
84 if (Elements.isMalformed(element)) { | 84 if (Elements.isMalformed(element)) { |
85 // TODO(johnniwinther): Add a predicate for this. | 85 // TODO(johnniwinther): Add a predicate for this. |
86 assert(invariant(element, element is! ErroneousElement, | 86 assert(invariant(element, element is! ErroneousElement, |
87 message: "Element $element expected to have parse errors.")); | 87 message: "Element $element expected to have parse errors.")); |
88 _ensureTreeElements(element); | 88 _ensureTreeElements(element); |
89 return const ResolutionImpact(); | 89 return const ResolutionImpact(); |
90 } | 90 } |
(...skipping 17 matching lines...) Expand all Loading... | |
108 } | 108 } |
109 if (element.isClass) { | 109 if (element.isClass) { |
110 ClassElement cls = element; | 110 ClassElement cls = element; |
111 cls.ensureResolved(resolution); | 111 cls.ensureResolved(resolution); |
112 return processMetadata(const ResolutionImpact()); | 112 return processMetadata(const ResolutionImpact()); |
113 } else if (element.isTypedef) { | 113 } else if (element.isTypedef) { |
114 TypedefElement typdef = element; | 114 TypedefElement typdef = element; |
115 return processMetadata(resolveTypedef(typdef)); | 115 return processMetadata(resolveTypedef(typdef)); |
116 } | 116 } |
117 | 117 |
118 compiler.unimplemented(element, "resolve($element)"); | 118 reporter.internalError(element, "resolve($element) not implemented."); |
119 }); | 119 }); |
120 } | 120 } |
121 | 121 |
122 void resolveRedirectingConstructor(InitializerResolver resolver, Node node, | 122 void resolveRedirectingConstructor(InitializerResolver resolver, Node node, |
123 FunctionElement constructor, FunctionElement redirection) { | 123 FunctionElement constructor, FunctionElement redirection) { |
124 assert(invariant(node, constructor.isImplementation, | 124 assert(invariant(node, constructor.isImplementation, |
125 message: 'Redirecting constructors must be resolved on implementation ' | 125 message: 'Redirecting constructors must be resolved on implementation ' |
126 'elements.')); | 126 'elements.')); |
127 Setlet<FunctionElement> seen = new Setlet<FunctionElement>(); | 127 Setlet<FunctionElement> seen = new Setlet<FunctionElement>(); |
128 seen.add(constructor); | 128 seen.add(constructor); |
129 while (redirection != null) { | 129 while (redirection != null) { |
130 // Ensure that we follow redirections through implementation elements. | 130 // Ensure that we follow redirections through implementation elements. |
131 redirection = redirection.implementation; | 131 redirection = redirection.implementation; |
132 if (redirection.isError) { | 132 if (redirection.isError) { |
133 break; | 133 break; |
134 } | 134 } |
135 if (seen.contains(redirection)) { | 135 if (seen.contains(redirection)) { |
136 reporter.reportErrorMessage( | 136 reporter.reportErrorMessage( |
137 node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE); | 137 node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE); |
138 return; | 138 return; |
139 } | 139 } |
140 seen.add(redirection); | 140 seen.add(redirection); |
141 redirection = resolver.visitor.resolveConstructorRedirection(redirection); | 141 redirection = resolver.visitor.resolveConstructorRedirection(redirection); |
142 } | 142 } |
143 } | 143 } |
144 | 144 |
145 static void processAsyncMarker(Compiler compiler, | 145 static void processAsyncMarker(Resolution resolution, |
146 BaseFunctionElementX element, ResolutionRegistry registry) { | 146 BaseFunctionElementX element, ResolutionRegistry registry) { |
147 DiagnosticReporter reporter = compiler.reporter; | 147 DiagnosticReporter reporter = resolution.reporter; |
148 Resolution resolution = compiler.resolution; | 148 CoreClasses coreClasses = resolution.coreClasses; |
149 CoreClasses coreClasses = compiler.coreClasses; | |
150 FunctionExpression functionExpression = element.node; | 149 FunctionExpression functionExpression = element.node; |
151 AsyncModifier asyncModifier = functionExpression.asyncModifier; | 150 AsyncModifier asyncModifier = functionExpression.asyncModifier; |
152 if (asyncModifier != null) { | 151 if (asyncModifier != null) { |
153 if (!compiler.backend.supportsAsyncAwait) { | 152 if (asyncModifier.isAsynchronous) { |
Johnni Winther
2016/07/08 08:05:39
Ditto.
Harry Terkelsen
2016/07/18 17:35:58
Done.
| |
154 reporter.reportErrorMessage(functionExpression.asyncModifier, | 153 element.asyncMarker = asyncModifier.isYielding |
155 MessageKind.ASYNC_AWAIT_NOT_SUPPORTED); | 154 ? AsyncMarker.ASYNC_STAR |
155 : AsyncMarker.ASYNC; | |
156 } else { | 156 } else { |
157 if (asyncModifier.isAsynchronous) { | 157 element.asyncMarker = AsyncMarker.SYNC_STAR; |
158 element.asyncMarker = asyncModifier.isYielding | 158 } |
159 ? AsyncMarker.ASYNC_STAR | 159 if (element.isAbstract) { |
160 : AsyncMarker.ASYNC; | 160 reporter.reportErrorMessage( |
161 } else { | 161 asyncModifier, |
162 element.asyncMarker = AsyncMarker.SYNC_STAR; | 162 MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD, |
163 } | 163 {'modifier': element.asyncMarker}); |
164 if (element.isAbstract) { | 164 } else if (element.isConstructor) { |
165 reporter.reportErrorMessage( | |
166 asyncModifier, | |
167 MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR, | |
168 {'modifier': element.asyncMarker}); | |
169 } else { | |
170 if (element.isSetter) { | |
165 reporter.reportErrorMessage( | 171 reporter.reportErrorMessage( |
166 asyncModifier, | 172 asyncModifier, |
167 MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD, | 173 MessageKind.ASYNC_MODIFIER_ON_SETTER, |
168 {'modifier': element.asyncMarker}); | 174 {'modifier': element.asyncMarker}); |
169 } else if (element.isConstructor) { | 175 } |
176 if (functionExpression.body.asReturn() != null && | |
177 element.asyncMarker.isYielding) { | |
170 reporter.reportErrorMessage( | 178 reporter.reportErrorMessage( |
171 asyncModifier, | 179 asyncModifier, |
172 MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR, | 180 MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY, |
173 {'modifier': element.asyncMarker}); | 181 {'modifier': element.asyncMarker}); |
174 } else { | |
175 if (element.isSetter) { | |
176 reporter.reportErrorMessage( | |
177 asyncModifier, | |
178 MessageKind.ASYNC_MODIFIER_ON_SETTER, | |
179 {'modifier': element.asyncMarker}); | |
180 } | |
181 if (functionExpression.body.asReturn() != null && | |
182 element.asyncMarker.isYielding) { | |
183 reporter.reportErrorMessage( | |
184 asyncModifier, | |
185 MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY, | |
186 {'modifier': element.asyncMarker}); | |
187 } | |
188 } | 182 } |
189 switch (element.asyncMarker) { | 183 } |
190 case AsyncMarker.ASYNC: | 184 switch (element.asyncMarker) { |
191 registry.registerFeature(Feature.ASYNC); | 185 case AsyncMarker.ASYNC: |
192 coreClasses.futureClass.ensureResolved(resolution); | 186 registry.registerFeature(Feature.ASYNC); |
193 break; | 187 coreClasses.futureClass.ensureResolved(resolution); |
194 case AsyncMarker.ASYNC_STAR: | 188 break; |
195 registry.registerFeature(Feature.ASYNC_STAR); | 189 case AsyncMarker.ASYNC_STAR: |
196 coreClasses.streamClass.ensureResolved(resolution); | 190 registry.registerFeature(Feature.ASYNC_STAR); |
197 break; | 191 coreClasses.streamClass.ensureResolved(resolution); |
198 case AsyncMarker.SYNC_STAR: | 192 break; |
199 registry.registerFeature(Feature.SYNC_STAR); | 193 case AsyncMarker.SYNC_STAR: |
200 coreClasses.iterableClass.ensureResolved(resolution); | 194 registry.registerFeature(Feature.SYNC_STAR); |
201 break; | 195 coreClasses.iterableClass.ensureResolved(resolution); |
202 } | 196 break; |
203 } | 197 } |
204 } | 198 } |
205 } | 199 } |
206 | 200 |
207 bool _isNativeClassOrExtendsNativeClass(ClassElement classElement) { | 201 bool _isNativeClassOrExtendsNativeClass(ClassElement classElement) { |
208 assert(classElement != null); | 202 assert(classElement != null); |
209 while (classElement != null) { | 203 while (classElement != null) { |
210 if (compiler.backend.isNative(classElement)) return true; | 204 if (target.isNative(classElement)) return true; |
211 classElement = classElement.superclass; | 205 classElement = classElement.superclass; |
212 } | 206 } |
213 return false; | 207 return false; |
214 } | 208 } |
215 | 209 |
216 WorldImpact resolveMethodElementImplementation( | 210 WorldImpact resolveMethodElementImplementation( |
217 FunctionElement element, FunctionExpression tree) { | 211 FunctionElement element, FunctionExpression tree) { |
218 return reporter.withCurrentElement(element, () { | 212 return reporter.withCurrentElement(element, () { |
219 if (element.isExternal && tree.hasBody) { | 213 if (element.isExternal && tree.hasBody) { |
220 reporter.reportErrorMessage(element, MessageKind.EXTERNAL_WITH_BODY, | 214 reporter.reportErrorMessage(element, MessageKind.EXTERNAL_WITH_BODY, |
(...skipping 11 matching lines...) Expand all Loading... | |
232 } else if (!tree.isRedirectingFactory) { | 226 } else if (!tree.isRedirectingFactory) { |
233 reporter.reportErrorMessage(tree, MessageKind.CONST_FACTORY); | 227 reporter.reportErrorMessage(tree, MessageKind.CONST_FACTORY); |
234 } | 228 } |
235 } | 229 } |
236 } | 230 } |
237 | 231 |
238 ResolverVisitor visitor = visitorFor(element); | 232 ResolverVisitor visitor = visitorFor(element); |
239 ResolutionRegistry registry = visitor.registry; | 233 ResolutionRegistry registry = visitor.registry; |
240 registry.defineFunction(tree, element); | 234 registry.defineFunction(tree, element); |
241 visitor.setupFunction(tree, element); // Modifies the scope. | 235 visitor.setupFunction(tree, element); // Modifies the scope. |
242 processAsyncMarker(compiler, element, registry); | 236 processAsyncMarker(resolution, element, registry); |
243 | 237 |
244 if (element.isGenerativeConstructor) { | 238 if (element.isGenerativeConstructor) { |
245 // Even if there is no initializer list we still have to do the | 239 // Even if there is no initializer list we still have to do the |
246 // resolution in case there is an implicit super constructor call. | 240 // resolution in case there is an implicit super constructor call. |
247 InitializerResolver resolver = | 241 InitializerResolver resolver = |
248 new InitializerResolver(visitor, element, tree); | 242 new InitializerResolver(visitor, element, tree); |
249 FunctionElement redirection = resolver.resolveInitializers( | 243 FunctionElement redirection = resolver.resolveInitializers( |
250 enableInitializingFormalAccess: | 244 enableInitializingFormalAccess: |
251 compiler.options.enableInitializingFormalAccess); | 245 options.enableInitializingFormalAccess); |
252 if (redirection != null) { | 246 if (redirection != null) { |
253 resolveRedirectingConstructor(resolver, tree, element, redirection); | 247 resolveRedirectingConstructor(resolver, tree, element, redirection); |
254 } | 248 } |
255 } else if (tree.initializers != null) { | 249 } else if (tree.initializers != null) { |
256 reporter.reportErrorMessage( | 250 reporter.reportErrorMessage( |
257 tree, MessageKind.FUNCTION_WITH_INITIALIZER); | 251 tree, MessageKind.FUNCTION_WITH_INITIALIZER); |
258 } | 252 } |
259 | 253 |
260 if (!compiler.options.analyzeSignaturesOnly || | 254 if (!options.analyzeSignaturesOnly || tree.isRedirectingFactory) { |
261 tree.isRedirectingFactory) { | |
262 // We need to analyze the redirecting factory bodies to ensure that | 255 // We need to analyze the redirecting factory bodies to ensure that |
263 // we can analyze compile-time constants. | 256 // we can analyze compile-time constants. |
264 visitor.visit(tree.body); | 257 visitor.visit(tree.body); |
265 } | 258 } |
266 | 259 |
267 // Get the resolution tree and check that the resolved | 260 // Get the resolution tree and check that the resolved |
268 // function doesn't use 'super' if it is mixed into another | 261 // function doesn't use 'super' if it is mixed into another |
269 // class. This is the part of the 'super' mixin check that | 262 // class. This is the part of the 'super' mixin check that |
270 // happens when a function is resolved after the mixin | 263 // happens when a function is resolved after the mixin |
271 // application has been performed. | 264 // application has been performed. |
272 TreeElements resolutionTree = registry.mapping; | 265 TreeElements resolutionTree = registry.mapping; |
273 ClassElement enclosingClass = element.enclosingClass; | 266 ClassElement enclosingClass = element.enclosingClass; |
274 if (enclosingClass != null) { | 267 if (enclosingClass != null) { |
275 // TODO(johnniwinther): Find another way to obtain mixin uses. | 268 // TODO(johnniwinther): Find another way to obtain mixin uses. |
276 Iterable<MixinApplicationElement> mixinUses = | 269 Iterable<MixinApplicationElement> mixinUses = |
277 compiler.world.allMixinUsesOf(enclosingClass); | 270 world.allMixinUsesOf(enclosingClass); |
278 ClassElement mixin = enclosingClass; | 271 ClassElement mixin = enclosingClass; |
279 for (MixinApplicationElement mixinApplication in mixinUses) { | 272 for (MixinApplicationElement mixinApplication in mixinUses) { |
280 checkMixinSuperUses(resolutionTree, mixinApplication, mixin); | 273 checkMixinSuperUses(resolutionTree, mixinApplication, mixin); |
281 } | 274 } |
282 } | 275 } |
283 | 276 |
284 // TODO(9631): support noSuchMethod on native classes. | 277 // TODO(9631): support noSuchMethod on native classes. |
285 if (element.isFunction && | 278 if (element.isFunction && |
286 element.isInstanceMember && | 279 element.isInstanceMember && |
287 element.name == Identifiers.noSuchMethod_ && | 280 element.name == Identifiers.noSuchMethod_ && |
288 _isNativeClassOrExtendsNativeClass(enclosingClass)) { | 281 _isNativeClassOrExtendsNativeClass(enclosingClass)) { |
289 reporter.reportErrorMessage(tree, MessageKind.NO_SUCH_METHOD_IN_NATIVE); | 282 reporter.reportErrorMessage(tree, MessageKind.NO_SUCH_METHOD_IN_NATIVE); |
290 } | 283 } |
291 | 284 |
292 resolution.target.resolveNativeElement(element, registry.worldImpact); | 285 resolution.target.resolveNativeElement(element, registry.worldImpact); |
293 | 286 |
294 return registry.worldImpact; | 287 return registry.worldImpact; |
295 }); | 288 }); |
296 } | 289 } |
297 | 290 |
298 WorldImpact resolveMethodElement(FunctionElementX element) { | 291 WorldImpact resolveMethodElement(FunctionElementX element) { |
299 assert(invariant(element, element.isDeclaration)); | 292 assert(invariant(element, element.isDeclaration)); |
300 return reporter.withCurrentElement(element, () { | 293 return reporter.withCurrentElement(element, () { |
301 if (compiler.enqueuer.resolution.hasBeenProcessed(element)) { | 294 if (enqueuer.hasBeenProcessed(element)) { |
302 // TODO(karlklose): Remove the check for [isConstructor]. [elememts] | 295 // TODO(karlklose): Remove the check for [isConstructor]. [elememts] |
303 // should never be non-null, not even for constructors. | 296 // should never be non-null, not even for constructors. |
304 assert(invariant(element, element.isConstructor, | 297 assert(invariant(element, element.isConstructor, |
305 message: 'Non-constructor element $element ' | 298 message: 'Non-constructor element $element ' |
306 'has already been analyzed.')); | 299 'has already been analyzed.')); |
307 return const ResolutionImpact(); | 300 return const ResolutionImpact(); |
308 } | 301 } |
309 if (element.isSynthesized) { | 302 if (element.isSynthesized) { |
310 if (element.isGenerativeConstructor) { | 303 if (element.isGenerativeConstructor) { |
311 ResolutionRegistry registry = | 304 ResolutionRegistry registry = |
312 new ResolutionRegistry(compiler, _ensureTreeElements(element)); | 305 new ResolutionRegistry(this.target, _ensureTreeElements(element)); |
313 ConstructorElement constructor = element.asFunctionElement(); | 306 ConstructorElement constructor = element.asFunctionElement(); |
314 ConstructorElement target = constructor.definingConstructor; | 307 ConstructorElement target = constructor.definingConstructor; |
315 // Ensure the signature of the synthesized element is | 308 // Ensure the signature of the synthesized element is |
316 // resolved. This is the only place where the resolver is | 309 // resolved. This is the only place where the resolver is |
317 // seeing this element. | 310 // seeing this element. |
318 element.computeType(resolution); | 311 element.computeType(resolution); |
319 if (!target.isMalformed) { | 312 if (!target.isMalformed) { |
320 registry.registerStaticUse(new StaticUse.superConstructorInvoke( | 313 registry.registerStaticUse(new StaticUse.superConstructorInvoke( |
321 target, CallStructure.NO_ARGS)); | 314 target, CallStructure.NO_ARGS)); |
322 } | 315 } |
323 return registry.worldImpact; | 316 return registry.worldImpact; |
324 } else { | 317 } else { |
325 assert(element.isDeferredLoaderGetter || element.isMalformed); | 318 assert(element.isDeferredLoaderGetter || element.isMalformed); |
326 _ensureTreeElements(element); | 319 _ensureTreeElements(element); |
327 return const ResolutionImpact(); | 320 return const ResolutionImpact(); |
328 } | 321 } |
329 } else { | 322 } else { |
330 element.parseNode(resolution.parsingContext); | 323 element.parseNode(resolution.parsingContext); |
331 element.computeType(resolution); | 324 element.computeType(resolution); |
332 FunctionElementX implementation = element; | 325 FunctionElementX implementation = element; |
333 if (element.isExternal) { | 326 if (element.isExternal) { |
334 implementation = compiler.backend.resolveExternalFunction(element); | 327 implementation = target.resolveExternalFunction(element); |
335 } | 328 } |
336 return resolveMethodElementImplementation( | 329 return resolveMethodElementImplementation( |
337 implementation, implementation.node); | 330 implementation, implementation.node); |
338 } | 331 } |
339 }); | 332 }); |
340 } | 333 } |
341 | 334 |
342 /// Creates a [ResolverVisitor] for resolving an AST in context of [element]. | 335 /// Creates a [ResolverVisitor] for resolving an AST in context of [element]. |
343 /// If [useEnclosingScope] is `true` then the initial scope of the visitor | 336 /// If [useEnclosingScope] is `true` then the initial scope of the visitor |
344 /// does not include inner scope of [element]. | 337 /// does not include inner scope of [element]. |
345 /// | 338 /// |
346 /// This method should only be used by this library (or tests of | 339 /// This method should only be used by this library (or tests of |
347 /// this library). | 340 /// this library). |
348 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) { | 341 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) { |
349 return new ResolverVisitor(compiler, element, | 342 return new ResolverVisitor(resolution, element, |
350 new ResolutionRegistry(compiler, _ensureTreeElements(element)), | 343 new ResolutionRegistry(target, _ensureTreeElements(element)), |
351 useEnclosingScope: useEnclosingScope); | 344 useEnclosingScope: useEnclosingScope); |
352 } | 345 } |
353 | 346 |
354 WorldImpact resolveField(FieldElementX element) { | 347 WorldImpact resolveField(FieldElementX element) { |
355 VariableDefinitions tree = element.parseNode(parsingContext); | 348 VariableDefinitions tree = element.parseNode(parsingContext); |
356 if (element.modifiers.isStatic && element.isTopLevel) { | 349 if (element.modifiers.isStatic && element.isTopLevel) { |
357 reporter.reportErrorMessage(element.modifiers.getStatic(), | 350 reporter.reportErrorMessage(element.modifiers.getStatic(), |
358 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); | 351 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); |
359 } | 352 } |
360 ResolverVisitor visitor = visitorFor(element); | 353 ResolverVisitor visitor = visitorFor(element); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
538 assert(invariant(from, cls.supertype != null, | 531 assert(invariant(from, cls.supertype != null, |
539 message: 'Missing supertype on cyclic class $cls.')); | 532 message: 'Missing supertype on cyclic class $cls.')); |
540 cls.interfaces = const Link<DartType>(); | 533 cls.interfaces = const Link<DartType>(); |
541 return; | 534 return; |
542 } | 535 } |
543 cls.supertypeLoadState = STATE_STARTED; | 536 cls.supertypeLoadState = STATE_STARTED; |
544 reporter.withCurrentElement(cls, () { | 537 reporter.withCurrentElement(cls, () { |
545 // TODO(ahe): Cache the node in cls. | 538 // TODO(ahe): Cache the node in cls. |
546 cls | 539 cls |
547 .parseNode(parsingContext) | 540 .parseNode(parsingContext) |
548 .accept(new ClassSupertypeResolver(compiler, cls)); | 541 .accept(new ClassSupertypeResolver(resolution, cls)); |
549 if (cls.supertypeLoadState != STATE_DONE) { | 542 if (cls.supertypeLoadState != STATE_DONE) { |
550 cls.supertypeLoadState = STATE_DONE; | 543 cls.supertypeLoadState = STATE_DONE; |
551 } | 544 } |
552 }); | 545 }); |
553 }); | 546 }); |
554 } | 547 } |
555 | 548 |
556 // TODO(johnniwinther): Remove this queue when resolution has been split into | 549 // TODO(johnniwinther): Remove this queue when resolution has been split into |
557 // syntax and semantic resolution. | 550 // syntax and semantic resolution. |
558 TypeDeclarationElement currentlyResolvedTypeDeclaration; | 551 TypeDeclarationElement currentlyResolvedTypeDeclaration; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
603 * scanner and most fields are null or empty. This method fills in | 596 * scanner and most fields are null or empty. This method fills in |
604 * these fields and also ensure that the supertypes of [element] are | 597 * these fields and also ensure that the supertypes of [element] are |
605 * resolved. | 598 * resolved. |
606 * | 599 * |
607 * Warning: Do not call this method directly. Instead use | 600 * Warning: Do not call this method directly. Instead use |
608 * [:element.ensureResolved(resolution):]. | 601 * [:element.ensureResolved(resolution):]. |
609 */ | 602 */ |
610 TreeElements resolveClass(BaseClassElementX element) { | 603 TreeElements resolveClass(BaseClassElementX element) { |
611 return _resolveTypeDeclaration(element, () { | 604 return _resolveTypeDeclaration(element, () { |
612 // TODO(johnniwinther): Store the mapping in the resolution enqueuer. | 605 // TODO(johnniwinther): Store the mapping in the resolution enqueuer. |
613 ResolutionRegistry registry = | 606 ResolutionRegistry registry = new ResolutionRegistry( |
614 new ResolutionRegistry(compiler, _ensureTreeElements(element)); | 607 resolution.target, _ensureTreeElements(element)); |
615 resolveClassInternal(element, registry); | 608 resolveClassInternal(element, registry); |
616 return element.treeElements; | 609 return element.treeElements; |
617 }); | 610 }); |
618 } | 611 } |
619 | 612 |
620 void ensureClassWillBeResolvedInternal(ClassElement element) { | 613 void ensureClassWillBeResolvedInternal(ClassElement element) { |
621 if (currentlyResolvedTypeDeclaration == null) { | 614 if (currentlyResolvedTypeDeclaration == null) { |
622 element.ensureResolved(resolution); | 615 element.ensureResolved(resolution); |
623 } else { | 616 } else { |
624 pendingClassesToBeResolved.add(element); | 617 pendingClassesToBeResolved.add(element); |
625 } | 618 } |
626 } | 619 } |
627 | 620 |
628 void resolveClassInternal( | 621 void resolveClassInternal( |
629 BaseClassElementX element, ResolutionRegistry registry) { | 622 BaseClassElementX element, ResolutionRegistry registry) { |
630 if (!element.isPatch) { | 623 if (!element.isPatch) { |
631 reporter.withCurrentElement( | 624 reporter.withCurrentElement( |
632 element, | 625 element, |
633 () => measure(() { | 626 () => measure(() { |
634 assert(element.resolutionState == STATE_NOT_STARTED); | 627 assert(element.resolutionState == STATE_NOT_STARTED); |
635 element.resolutionState = STATE_STARTED; | 628 element.resolutionState = STATE_STARTED; |
636 Node tree = element.parseNode(parsingContext); | 629 Node tree = element.parseNode(parsingContext); |
637 loadSupertypes(element, tree); | 630 loadSupertypes(element, tree); |
638 | 631 |
639 ClassResolverVisitor visitor = | 632 ClassResolverVisitor visitor = |
640 new ClassResolverVisitor(compiler, element, registry); | 633 new ClassResolverVisitor(resolution, element, registry); |
641 visitor.visit(tree); | 634 visitor.visit(tree); |
642 element.resolutionState = STATE_DONE; | 635 element.resolutionState = STATE_DONE; |
643 compiler.onClassResolved(element); | 636 resolution.onClassResolved(element); |
644 pendingClassesToBePostProcessed.add(element); | 637 pendingClassesToBePostProcessed.add(element); |
645 })); | 638 })); |
646 if (element.isPatched) { | 639 if (element.isPatched) { |
647 // Ensure handling patch after origin. | 640 // Ensure handling patch after origin. |
648 element.patch.ensureResolved(resolution); | 641 element.patch.ensureResolved(resolution); |
649 } | 642 } |
650 } else { | 643 } else { |
651 // Handle patch classes: | 644 // Handle patch classes: |
652 element.resolutionState = STATE_STARTED; | 645 element.resolutionState = STATE_STARTED; |
653 // Ensure handling origin before patch. | 646 // Ensure handling origin before patch. |
(...skipping 10 matching lines...) Expand all Loading... | |
664 element.resolutionState = STATE_DONE; | 657 element.resolutionState = STATE_DONE; |
665 // TODO(johnniwinther): Check matching type variables and | 658 // TODO(johnniwinther): Check matching type variables and |
666 // empty extends/implements clauses. | 659 // empty extends/implements clauses. |
667 } | 660 } |
668 } | 661 } |
669 | 662 |
670 void _postProcessClassElement(BaseClassElementX element) { | 663 void _postProcessClassElement(BaseClassElementX element) { |
671 for (MetadataAnnotation metadata in element.implementation.metadata) { | 664 for (MetadataAnnotation metadata in element.implementation.metadata) { |
672 metadata.ensureResolved(resolution); | 665 metadata.ensureResolved(resolution); |
673 ConstantValue value = | 666 ConstantValue value = |
674 compiler.constants.getConstantValue(metadata.constant); | 667 resolution.constants.getConstantValue(metadata.constant); |
675 if (!element.isProxy && compiler.isProxyConstant(value)) { | 668 if (!element.isProxy && resolution.isProxyConstant(value)) { |
676 element.isProxy = true; | 669 element.isProxy = true; |
677 } | 670 } |
678 } | 671 } |
679 | 672 |
680 // Force resolution of metadata on non-instance members since they may be | 673 // Force resolution of metadata on non-instance members since they may be |
681 // inspected by the backend while emitting. Metadata on instance members is | 674 // inspected by the backend while emitting. Metadata on instance members is |
682 // handled as a result of processing instantiated class members in the | 675 // handled as a result of processing instantiated class members in the |
683 // enqueuer. | 676 // enqueuer. |
684 // TODO(ahe): Avoid this eager resolution. | 677 // TODO(ahe): Avoid this eager resolution. |
685 element.forEachMember((_, Element member) { | 678 element.forEachMember((_, Element member) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
753 if (member.isGenerativeConstructor && !member.isSynthesized) { | 746 if (member.isGenerativeConstructor && !member.isSynthesized) { |
754 reporter.reportErrorMessage( | 747 reporter.reportErrorMessage( |
755 member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR); | 748 member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR); |
756 } else { | 749 } else { |
757 // Get the resolution tree and check that the resolved member | 750 // Get the resolution tree and check that the resolved member |
758 // doesn't use 'super'. This is the part of the 'super' mixin | 751 // doesn't use 'super'. This is the part of the 'super' mixin |
759 // check that happens when a function is resolved before the | 752 // check that happens when a function is resolved before the |
760 // mixin application has been performed. | 753 // mixin application has been performed. |
761 // TODO(johnniwinther): Obtain the [TreeElements] for [member] | 754 // TODO(johnniwinther): Obtain the [TreeElements] for [member] |
762 // differently. | 755 // differently. |
763 if (compiler.enqueuer.resolution.hasBeenProcessed(member)) { | 756 if (resolution.enqueuer.hasBeenProcessed(member)) { |
764 if (member.resolvedAst.kind == ResolvedAstKind.PARSED) { | 757 if (member.resolvedAst.kind == ResolvedAstKind.PARSED) { |
765 checkMixinSuperUses( | 758 checkMixinSuperUses( |
766 member.resolvedAst.elements, mixinApplication, mixin); | 759 member.resolvedAst.elements, mixinApplication, mixin); |
767 } | 760 } |
768 } | 761 } |
769 } | 762 } |
770 }); | 763 }); |
771 } | 764 } |
772 | 765 |
773 void checkMixinSuperUses(TreeElements elements, | 766 void checkMixinSuperUses(TreeElements elements, |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1002 MessageKind defaultValuesError = null; | 995 MessageKind defaultValuesError = null; |
1003 if (element.isFactoryConstructor) { | 996 if (element.isFactoryConstructor) { |
1004 FunctionExpression body = element.parseNode(parsingContext); | 997 FunctionExpression body = element.parseNode(parsingContext); |
1005 if (body.isRedirectingFactory) { | 998 if (body.isRedirectingFactory) { |
1006 defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT; | 999 defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT; |
1007 } | 1000 } |
1008 } | 1001 } |
1009 return reporter.withCurrentElement(element, () { | 1002 return reporter.withCurrentElement(element, () { |
1010 FunctionExpression node = element.parseNode(parsingContext); | 1003 FunctionExpression node = element.parseNode(parsingContext); |
1011 return measure(() => SignatureResolver.analyze( | 1004 return measure(() => SignatureResolver.analyze( |
1012 compiler, | 1005 resolution, |
1013 element.enclosingElement.buildScope(), | 1006 element.enclosingElement.buildScope(), |
1014 node.typeVariables, | 1007 node.typeVariables, |
1015 node.parameters, | 1008 node.parameters, |
1016 node.returnType, | 1009 node.returnType, |
1017 element, | 1010 element, |
1018 new ResolutionRegistry(compiler, _ensureTreeElements(element)), | 1011 new ResolutionRegistry( |
1012 resolution.target, _ensureTreeElements(element)), | |
1019 defaultValuesError: defaultValuesError, | 1013 defaultValuesError: defaultValuesError, |
1020 createRealParameters: true)); | 1014 createRealParameters: true)); |
1021 }); | 1015 }); |
1022 } | 1016 } |
1023 | 1017 |
1024 WorldImpact resolveTypedef(TypedefElementX element) { | 1018 WorldImpact resolveTypedef(TypedefElementX element) { |
1025 if (element.isResolved) return const ResolutionImpact(); | 1019 if (element.isResolved) return const ResolutionImpact(); |
1026 compiler.world.allTypedefs.add(element); | 1020 world.allTypedefs.add(element); |
1027 return _resolveTypeDeclaration(element, () { | 1021 return _resolveTypeDeclaration(element, () { |
1028 ResolutionRegistry registry = | 1022 ResolutionRegistry registry = new ResolutionRegistry( |
1029 new ResolutionRegistry(compiler, _ensureTreeElements(element)); | 1023 resolution.target, _ensureTreeElements(element)); |
1030 return reporter.withCurrentElement(element, () { | 1024 return reporter.withCurrentElement(element, () { |
1031 return measure(() { | 1025 return measure(() { |
1032 assert(element.resolutionState == STATE_NOT_STARTED); | 1026 assert(element.resolutionState == STATE_NOT_STARTED); |
1033 element.resolutionState = STATE_STARTED; | 1027 element.resolutionState = STATE_STARTED; |
1034 Typedef node = element.parseNode(parsingContext); | 1028 Typedef node = element.parseNode(parsingContext); |
1035 TypedefResolverVisitor visitor = | 1029 TypedefResolverVisitor visitor = |
1036 new TypedefResolverVisitor(compiler, element, registry); | 1030 new TypedefResolverVisitor(resolution, element, registry); |
1037 visitor.visit(node); | 1031 visitor.visit(node); |
1038 element.resolutionState = STATE_DONE; | 1032 element.resolutionState = STATE_DONE; |
1039 return registry.worldImpact; | 1033 return registry.worldImpact; |
1040 }); | 1034 }); |
1041 }); | 1035 }); |
1042 }); | 1036 }); |
1043 } | 1037 } |
1044 | 1038 |
1045 void resolveMetadataAnnotation(MetadataAnnotationX annotation) { | 1039 void resolveMetadataAnnotation(MetadataAnnotationX annotation) { |
1046 reporter.withCurrentElement( | 1040 reporter.withCurrentElement( |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1127 TreeElements get treeElements { | 1121 TreeElements get treeElements { |
1128 assert(invariant(this, _treeElements != null, | 1122 assert(invariant(this, _treeElements != null, |
1129 message: "TreeElements have not been computed for $this.")); | 1123 message: "TreeElements have not been computed for $this.")); |
1130 return _treeElements; | 1124 return _treeElements; |
1131 } | 1125 } |
1132 | 1126 |
1133 void reuseElement() { | 1127 void reuseElement() { |
1134 _treeElements = null; | 1128 _treeElements = null; |
1135 } | 1129 } |
1136 } | 1130 } |
OLD | NEW |