| 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, Parsing, Resolution, ResolutionImpact; | 12 show Feature, ParsingContext, Resolution, ResolutionImpact; |
| 13 import '../common/tasks.dart' show CompilerTask; | 13 import '../common/tasks.dart' show CompilerTask; |
| 14 import '../compile_time_constants.dart' show ConstantCompiler; | 14 import '../compile_time_constants.dart' show ConstantCompiler; |
| 15 import '../compiler.dart' show Compiler; | 15 import '../compiler.dart' show Compiler; |
| 16 import '../constants/expressions.dart' | 16 import '../constants/expressions.dart' |
| 17 show | 17 show |
| 18 ConstantExpression, | 18 ConstantExpression, |
| 19 ConstantExpressionKind, | 19 ConstantExpressionKind, |
| 20 ConstructedConstantExpression, | 20 ConstructedConstantExpression, |
| 21 ErroneousConstantExpression; | 21 ErroneousConstantExpression; |
| 22 import '../constants/values.dart' show ConstantValue; | 22 import '../constants/values.dart' show ConstantValue; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 | 59 |
| 60 class ResolverTask extends CompilerTask { | 60 class ResolverTask extends CompilerTask { |
| 61 final ConstantCompiler constantCompiler; | 61 final ConstantCompiler constantCompiler; |
| 62 | 62 |
| 63 ResolverTask(Compiler compiler, this.constantCompiler) : super(compiler); | 63 ResolverTask(Compiler compiler, this.constantCompiler) : super(compiler); |
| 64 | 64 |
| 65 String get name => 'Resolver'; | 65 String get name => 'Resolver'; |
| 66 | 66 |
| 67 Resolution get resolution => compiler.resolution; | 67 Resolution get resolution => compiler.resolution; |
| 68 | 68 |
| 69 Parsing get parsing => compiler.parsing; | 69 ParsingContext get parsingContext => compiler.parsingContext; |
| 70 | 70 |
| 71 CoreClasses get coreClasses => compiler.coreClasses; | 71 CoreClasses get coreClasses => compiler.coreClasses; |
| 72 | 72 |
| 73 CoreTypes get coreTypes => compiler.coreTypes; | 73 CoreTypes get coreTypes => compiler.coreTypes; |
| 74 | 74 |
| 75 ResolutionImpact resolve(Element element) { | 75 ResolutionImpact resolve(Element element) { |
| 76 return measure(() { | 76 return measure(() { |
| 77 if (Elements.isMalformed(element)) { | 77 if (Elements.isMalformed(element)) { |
| 78 // TODO(johnniwinther): Add a predicate for this. | 78 // TODO(johnniwinther): Add a predicate for this. |
| 79 assert(invariant(element, element is! ErroneousElement, | 79 assert(invariant(element, element is! ErroneousElement, |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 registry.registerStaticUse(new StaticUse.superConstructorInvoke( | 304 registry.registerStaticUse(new StaticUse.superConstructorInvoke( |
| 305 target, CallStructure.NO_ARGS)); | 305 target, CallStructure.NO_ARGS)); |
| 306 } | 306 } |
| 307 return registry.worldImpact; | 307 return registry.worldImpact; |
| 308 } else { | 308 } else { |
| 309 assert(element.isDeferredLoaderGetter || element.isMalformed); | 309 assert(element.isDeferredLoaderGetter || element.isMalformed); |
| 310 _ensureTreeElements(element); | 310 _ensureTreeElements(element); |
| 311 return const ResolutionImpact(); | 311 return const ResolutionImpact(); |
| 312 } | 312 } |
| 313 } else { | 313 } else { |
| 314 element.parseNode(resolution.parsing); | 314 element.parseNode(resolution.parsingContext); |
| 315 element.computeType(resolution); | 315 element.computeType(resolution); |
| 316 FunctionElementX implementation = element; | 316 FunctionElementX implementation = element; |
| 317 if (element.isExternal) { | 317 if (element.isExternal) { |
| 318 implementation = compiler.backend.resolveExternalFunction(element); | 318 implementation = compiler.backend.resolveExternalFunction(element); |
| 319 } | 319 } |
| 320 return resolveMethodElementImplementation( | 320 return resolveMethodElementImplementation( |
| 321 implementation, implementation.node); | 321 implementation, implementation.node); |
| 322 } | 322 } |
| 323 }); | 323 }); |
| 324 } | 324 } |
| 325 | 325 |
| 326 /// Creates a [ResolverVisitor] for resolving an AST in context of [element]. | 326 /// Creates a [ResolverVisitor] for resolving an AST in context of [element]. |
| 327 /// If [useEnclosingScope] is `true` then the initial scope of the visitor | 327 /// If [useEnclosingScope] is `true` then the initial scope of the visitor |
| 328 /// does not include inner scope of [element]. | 328 /// does not include inner scope of [element]. |
| 329 /// | 329 /// |
| 330 /// This method should only be used by this library (or tests of | 330 /// This method should only be used by this library (or tests of |
| 331 /// this library). | 331 /// this library). |
| 332 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) { | 332 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) { |
| 333 return new ResolverVisitor(compiler, element, | 333 return new ResolverVisitor(compiler, element, |
| 334 new ResolutionRegistry(compiler, _ensureTreeElements(element)), | 334 new ResolutionRegistry(compiler, _ensureTreeElements(element)), |
| 335 useEnclosingScope: useEnclosingScope); | 335 useEnclosingScope: useEnclosingScope); |
| 336 } | 336 } |
| 337 | 337 |
| 338 WorldImpact resolveField(FieldElementX element) { | 338 WorldImpact resolveField(FieldElementX element) { |
| 339 VariableDefinitions tree = element.parseNode(parsing); | 339 VariableDefinitions tree = element.parseNode(parsingContext); |
| 340 if (element.modifiers.isStatic && element.isTopLevel) { | 340 if (element.modifiers.isStatic && element.isTopLevel) { |
| 341 reporter.reportErrorMessage(element.modifiers.getStatic(), | 341 reporter.reportErrorMessage(element.modifiers.getStatic(), |
| 342 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); | 342 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); |
| 343 } | 343 } |
| 344 ResolverVisitor visitor = visitorFor(element); | 344 ResolverVisitor visitor = visitorFor(element); |
| 345 ResolutionRegistry registry = visitor.registry; | 345 ResolutionRegistry registry = visitor.registry; |
| 346 // TODO(johnniwinther): Maybe remove this when placeholderCollector migrates | 346 // TODO(johnniwinther): Maybe remove this when placeholderCollector migrates |
| 347 // to the backend ast. | 347 // to the backend ast. |
| 348 registry.defineElement(tree.definitions.nodes.head, element); | 348 registry.defineElement(tree.definitions.nodes.head, element); |
| 349 // TODO(johnniwinther): Share the resolved type between all variables | 349 // TODO(johnniwinther): Share the resolved type between all variables |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 cls.supertype = cls.allSupertypes.head; | 501 cls.supertype = cls.allSupertypes.head; |
| 502 assert(invariant(from, cls.supertype != null, | 502 assert(invariant(from, cls.supertype != null, |
| 503 message: 'Missing supertype on cyclic class $cls.')); | 503 message: 'Missing supertype on cyclic class $cls.')); |
| 504 cls.interfaces = const Link<DartType>(); | 504 cls.interfaces = const Link<DartType>(); |
| 505 return; | 505 return; |
| 506 } | 506 } |
| 507 cls.supertypeLoadState = STATE_STARTED; | 507 cls.supertypeLoadState = STATE_STARTED; |
| 508 reporter.withCurrentElement(cls, () { | 508 reporter.withCurrentElement(cls, () { |
| 509 // TODO(ahe): Cache the node in cls. | 509 // TODO(ahe): Cache the node in cls. |
| 510 cls | 510 cls |
| 511 .parseNode(parsing) | 511 .parseNode(parsingContext) |
| 512 .accept(new ClassSupertypeResolver(compiler, cls)); | 512 .accept(new ClassSupertypeResolver(compiler, cls)); |
| 513 if (cls.supertypeLoadState != STATE_DONE) { | 513 if (cls.supertypeLoadState != STATE_DONE) { |
| 514 cls.supertypeLoadState = STATE_DONE; | 514 cls.supertypeLoadState = STATE_DONE; |
| 515 } | 515 } |
| 516 }); | 516 }); |
| 517 }); | 517 }); |
| 518 } | 518 } |
| 519 | 519 |
| 520 // TODO(johnniwinther): Remove this queue when resolution has been split into | 520 // TODO(johnniwinther): Remove this queue when resolution has been split into |
| 521 // syntax and semantic resolution. | 521 // syntax and semantic resolution. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 } | 590 } |
| 591 | 591 |
| 592 void resolveClassInternal( | 592 void resolveClassInternal( |
| 593 BaseClassElementX element, ResolutionRegistry registry) { | 593 BaseClassElementX element, ResolutionRegistry registry) { |
| 594 if (!element.isPatch) { | 594 if (!element.isPatch) { |
| 595 reporter.withCurrentElement( | 595 reporter.withCurrentElement( |
| 596 element, | 596 element, |
| 597 () => measure(() { | 597 () => measure(() { |
| 598 assert(element.resolutionState == STATE_NOT_STARTED); | 598 assert(element.resolutionState == STATE_NOT_STARTED); |
| 599 element.resolutionState = STATE_STARTED; | 599 element.resolutionState = STATE_STARTED; |
| 600 Node tree = element.parseNode(parsing); | 600 Node tree = element.parseNode(parsingContext); |
| 601 loadSupertypes(element, tree); | 601 loadSupertypes(element, tree); |
| 602 | 602 |
| 603 ClassResolverVisitor visitor = | 603 ClassResolverVisitor visitor = |
| 604 new ClassResolverVisitor(compiler, element, registry); | 604 new ClassResolverVisitor(compiler, element, registry); |
| 605 visitor.visit(tree); | 605 visitor.visit(tree); |
| 606 element.resolutionState = STATE_DONE; | 606 element.resolutionState = STATE_DONE; |
| 607 compiler.onClassResolved(element); | 607 compiler.onClassResolved(element); |
| 608 pendingClassesToBePostProcessed.add(element); | 608 pendingClassesToBePostProcessed.add(element); |
| 609 })); | 609 })); |
| 610 if (element.isPatched) { | 610 if (element.isPatched) { |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 958 'className': contextElement.enclosingClass.name | 958 'className': contextElement.enclosingClass.name |
| 959 }), | 959 }), |
| 960 <DiagnosticMessage>[ | 960 <DiagnosticMessage>[ |
| 961 reporter.createMessage(contextElement, contextMessage), | 961 reporter.createMessage(contextElement, contextMessage), |
| 962 ]); | 962 ]); |
| 963 } | 963 } |
| 964 | 964 |
| 965 FunctionSignature resolveSignature(FunctionElementX element) { | 965 FunctionSignature resolveSignature(FunctionElementX element) { |
| 966 MessageKind defaultValuesError = null; | 966 MessageKind defaultValuesError = null; |
| 967 if (element.isFactoryConstructor) { | 967 if (element.isFactoryConstructor) { |
| 968 FunctionExpression body = element.parseNode(parsing); | 968 FunctionExpression body = element.parseNode(parsingContext); |
| 969 if (body.isRedirectingFactory) { | 969 if (body.isRedirectingFactory) { |
| 970 defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT; | 970 defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT; |
| 971 } | 971 } |
| 972 } | 972 } |
| 973 return reporter.withCurrentElement(element, () { | 973 return reporter.withCurrentElement(element, () { |
| 974 FunctionExpression node = element.parseNode(parsing); | 974 FunctionExpression node = element.parseNode(parsingContext); |
| 975 return measure(() => SignatureResolver.analyze( | 975 return measure(() => SignatureResolver.analyze( |
| 976 compiler, | 976 compiler, |
| 977 node.parameters, | 977 node.parameters, |
| 978 node.returnType, | 978 node.returnType, |
| 979 element, | 979 element, |
| 980 new ResolutionRegistry(compiler, _ensureTreeElements(element)), | 980 new ResolutionRegistry(compiler, _ensureTreeElements(element)), |
| 981 defaultValuesError: defaultValuesError, | 981 defaultValuesError: defaultValuesError, |
| 982 createRealParameters: true)); | 982 createRealParameters: true)); |
| 983 }); | 983 }); |
| 984 } | 984 } |
| 985 | 985 |
| 986 WorldImpact resolveTypedef(TypedefElementX element) { | 986 WorldImpact resolveTypedef(TypedefElementX element) { |
| 987 if (element.isResolved) return const ResolutionImpact(); | 987 if (element.isResolved) return const ResolutionImpact(); |
| 988 compiler.world.allTypedefs.add(element); | 988 compiler.world.allTypedefs.add(element); |
| 989 return _resolveTypeDeclaration(element, () { | 989 return _resolveTypeDeclaration(element, () { |
| 990 ResolutionRegistry registry = | 990 ResolutionRegistry registry = |
| 991 new ResolutionRegistry(compiler, _ensureTreeElements(element)); | 991 new ResolutionRegistry(compiler, _ensureTreeElements(element)); |
| 992 return reporter.withCurrentElement(element, () { | 992 return reporter.withCurrentElement(element, () { |
| 993 return measure(() { | 993 return measure(() { |
| 994 assert(element.resolutionState == STATE_NOT_STARTED); | 994 assert(element.resolutionState == STATE_NOT_STARTED); |
| 995 element.resolutionState = STATE_STARTED; | 995 element.resolutionState = STATE_STARTED; |
| 996 Typedef node = element.parseNode(parsing); | 996 Typedef node = element.parseNode(parsingContext); |
| 997 TypedefResolverVisitor visitor = | 997 TypedefResolverVisitor visitor = |
| 998 new TypedefResolverVisitor(compiler, element, registry); | 998 new TypedefResolverVisitor(compiler, element, registry); |
| 999 visitor.visit(node); | 999 visitor.visit(node); |
| 1000 element.resolutionState = STATE_DONE; | 1000 element.resolutionState = STATE_DONE; |
| 1001 return registry.worldImpact; | 1001 return registry.worldImpact; |
| 1002 }); | 1002 }); |
| 1003 }); | 1003 }); |
| 1004 }); | 1004 }); |
| 1005 } | 1005 } |
| 1006 | 1006 |
| 1007 void resolveMetadataAnnotation(MetadataAnnotationX annotation) { | 1007 void resolveMetadataAnnotation(MetadataAnnotationX annotation) { |
| 1008 reporter.withCurrentElement( | 1008 reporter.withCurrentElement( |
| 1009 annotation.annotatedElement, | 1009 annotation.annotatedElement, |
| 1010 () => measure(() { | 1010 () => measure(() { |
| 1011 assert(annotation.resolutionState == STATE_NOT_STARTED); | 1011 assert(annotation.resolutionState == STATE_NOT_STARTED); |
| 1012 annotation.resolutionState = STATE_STARTED; | 1012 annotation.resolutionState = STATE_STARTED; |
| 1013 | 1013 |
| 1014 Node node = annotation.parseNode(parsing); | 1014 Node node = annotation.parseNode(parsingContext); |
| 1015 Element annotatedElement = annotation.annotatedElement; | 1015 Element annotatedElement = annotation.annotatedElement; |
| 1016 AnalyzableElement context = annotatedElement.analyzableElement; | 1016 AnalyzableElement context = annotatedElement.analyzableElement; |
| 1017 ClassElement classElement = annotatedElement.enclosingClass; | 1017 ClassElement classElement = annotatedElement.enclosingClass; |
| 1018 if (classElement != null) { | 1018 if (classElement != null) { |
| 1019 // The annotation is resolved in the scope of [classElement]. | 1019 // The annotation is resolved in the scope of [classElement]. |
| 1020 classElement.ensureResolved(resolution); | 1020 classElement.ensureResolved(resolution); |
| 1021 } | 1021 } |
| 1022 assert(invariant(node, context != null, | 1022 assert(invariant(node, context != null, |
| 1023 message: "No context found for metadata annotation " | 1023 message: "No context found for metadata annotation " |
| 1024 "on $annotatedElement.")); | 1024 "on $annotatedElement.")); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1090 TreeElements get treeElements { | 1090 TreeElements get treeElements { |
| 1091 assert(invariant(this, _treeElements != null, | 1091 assert(invariant(this, _treeElements != null, |
| 1092 message: "TreeElements have not been computed for $this.")); | 1092 message: "TreeElements have not been computed for $this.")); |
| 1093 return _treeElements; | 1093 return _treeElements; |
| 1094 } | 1094 } |
| 1095 | 1095 |
| 1096 void reuseElement() { | 1096 void reuseElement() { |
| 1097 _treeElements = null; | 1097 _treeElements = null; |
| 1098 } | 1098 } |
| 1099 } | 1099 } |
| OLD | NEW |