Chromium Code Reviews| 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) { |
|
Harry Terkelsen
2016/07/06 22:44:45
this diff looks a lot crazier than it actually is.
| |
| 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 |