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 |