Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| index 19e4e7308fbf5ee4377feb1781e69ac8a9c7ea88..de24e223112db3d43cff829a11a995951543bc3b 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| @@ -25,6 +25,8 @@ abstract class TreeElements { |
| Selector setIteratorSelector(ForIn node, Selector selector); |
| Selector setMoveNextSelector(ForIn node, Selector selector); |
| Selector setCurrentSelector(ForIn node, Selector selector); |
| + void setConstant(Node node, Constant constant); |
| + Constant getConstant(Node node); |
| /** |
| * Returns [:true:] if [node] is a type literal. |
| @@ -46,6 +48,7 @@ class TreeElementMapping implements TreeElements { |
| final Map<Node, DartType> types = new LinkedHashMap<Node, DartType>(); |
| final Set<Node> superUses = new LinkedHashSet<Node>(); |
| final Set<Element> otherDependencies = new LinkedHashSet<Element>(); |
| + final Map<Node, Constant> constants = new Map<Node, Constant>(); |
| final int hashCode = ++hashCodeCounter; |
| static int hashCodeCounter = 0; |
| @@ -140,6 +143,15 @@ class TreeElementMapping implements TreeElements { |
| return selectors[node.inToken]; |
| } |
| + void setConstant(Node node, Constant constant) { |
| + constants[node] = constant; |
| + } |
| + |
| + Constant getConstant(Node node) { |
| + return constants[node]; |
| + } |
| + |
| + |
|
ahe
2013/09/30 11:05:26
Extra line.
Johnni Winther
2013/10/01 11:21:48
Done.
|
| bool isTypeLiteral(Send node) { |
| return getType(node) != null; |
| } |
| @@ -348,7 +360,10 @@ class ResolverTask extends CompilerTask { |
| TreeElements elements = |
| compiler.enqueuer.resolution.getCachedElements(element); |
| if (elements != null) { |
| - assert(isConstructor); |
| + // TODO(karlklose): This should never happen, not even for constructors. |
|
ngeoffray
2013/10/01 08:33:35
Please add: TODO(...): remove this check. elements
Johnni Winther
2013/10/01 11:21:48
Done.
|
| + assert(invariant(element, isConstructor, |
| + message: 'Non-constructor element $element ' |
| + 'has already been analyzed.')); |
| return elements; |
| } |
| if (element.isSynthesized) { |
| @@ -402,7 +417,10 @@ class ResolverTask extends CompilerTask { |
| } else if (tree.initializers != null) { |
| error(tree, MessageKind.FUNCTION_WITH_INITIALIZER); |
| } |
| - visitBody(visitor, tree.body); |
| + |
| + if (!compiler.analyzeSignaturesOnly || tree.isRedirectingFactory) { |
|
ngeoffray
2013/10/01 08:33:35
What's this redirecting factory check? Please add
Johnni Winther
2013/10/01 11:21:48
Added comment: We need to analyze the redirecting
|
| + visitor.visit(tree.body); |
| + } |
| // Get the resolution tree and check that the resolved |
| // function doesn't use 'super' if it is mixed into another |
| @@ -458,10 +476,14 @@ class ResolverTask extends CompilerTask { |
| } |
| if (Elements.isStaticOrTopLevelField(element)) { |
| + visitor.addPostProcessAction(element, () { |
| + compiler.constantHandler.compileVariable( |
| + element, isConst: element.modifiers.isConst()); |
| + }); |
| if (tree.asSendSet() != null) { |
| - // TODO(13429): We could do better here by using the |
| - // constant handler to figure out if it's a lazy field or not. |
| - compiler.backend.registerLazyField(visitor.mapping); |
| + if (!element.modifiers.isConst()) { |
|
ngeoffray
2013/10/01 08:33:35
Note that this is not fixing it: what we want to k
Johnni Winther
2013/10/01 11:21:48
Added a TODO.
|
| + compiler.backend.registerLazyField(visitor.mapping); |
| + } |
| } else { |
| compiler.enqueuer.resolution.registerInstantiatedClass( |
| compiler.nullClass, visitor.mapping); |
| @@ -1043,8 +1065,10 @@ class ResolverTask extends CompilerTask { |
| } |
| ResolverVisitor visitor = visitorFor(context); |
| node.accept(visitor); |
| - annotation.value = compiler.metadataHandler.compileNodeWithDefinitions( |
| + annotation.value = compiler.constantHandler.compileNodeWithDefinitions( |
| node, visitor.mapping, isConst: true); |
| + compiler.backend.registerMetadataConstant(annotation.value, |
| + visitor.mapping); |
| annotation.resolutionState = STATE_DONE; |
| })); |
| @@ -1395,6 +1419,10 @@ class CommonResolverVisitor<R> extends Visitor<R> { |
| void unimplemented(Node node, String message) { |
| compiler.unimplemented(message, node: node); |
| } |
| + |
| + void addPostProcessAction(Element element, PostProcessAction action) { |
| + compiler.enqueuer.resolution.addPostProcessAction(element, action); |
| + } |
| } |
| abstract class LabelScope { |
| @@ -1657,7 +1685,7 @@ class TypeResolver { |
| // Remove the guarded when this is fixed. |
| if (!compiler.enqueuer.resolution.queueIsClosed && |
| addTypeVariableBoundsCheck) { |
| - compiler.enqueuer.resolution.addPostProcessAction( |
| + visitor.addPostProcessAction( |
| visitor.enclosingElement, |
| () => checkTypeVariableBounds(node, type)); |
| } |
| @@ -2033,6 +2061,11 @@ class ResolverVisitor extends MappingVisitor<Element> { |
| } |
| parameterNodes = parameterNodes.tail; |
| }); |
| + addPostProcessAction(enclosingElement, () { |
| + functionParameters.forEachOptionalParameter((Element parameter) { |
| + compiler.constantHandler.compileConstant(parameter); |
| + }); |
| + }); |
| if (inCheckContext) { |
| functionParameters.forEachParameter((Element element) { |
| compiler.enqueuer.resolution.registerIsCheck( |
| @@ -2401,6 +2434,7 @@ class ResolverVisitor extends MappingVisitor<Element> { |
| // type literal. |
| mapping.setType(node, compiler.typeClass.computeType(compiler)); |
| world.registerTypeLiteral(target, mapping); |
| + analyzeConstant(node); |
| } |
| } |
| @@ -2624,6 +2658,7 @@ class ResolverVisitor extends MappingVisitor<Element> { |
| compiler.reportError(node, MessageKind.UNSUPPORTED_LITERAL_SYMBOL, |
| {'value': node.slowNameString}); |
| } |
| + analyzeConstant(node); |
| } |
| visitStringJuxtaposition(StringJuxtaposition node) { |
| @@ -2709,7 +2744,7 @@ class ResolverVisitor extends MappingVisitor<Element> { |
| // Register a post process to check for cycles in the redirection chain and |
| // set the actual generative constructor at the end of the chain. |
| - compiler.enqueuer.resolution.addPostProcessAction(constructor, () { |
| + addPostProcessAction(constructor, () { |
| compiler.resolver.resolveRedirectionChain(constructor, node); |
| }); |
| @@ -2812,7 +2847,7 @@ class ResolverVisitor extends MappingVisitor<Element> { |
| if (isSymbolConstructor) { |
| if (node.isConst()) { |
| Node argumentNode = node.send.arguments.head; |
| - Constant name = compiler.metadataHandler.compileNodeWithDefinitions( |
| + Constant name = compiler.constantHandler.compileNodeWithDefinitions( |
| argumentNode, mapping, isConst: true); |
| if (!name.isString()) { |
| DartType type = name.computeType(compiler); |
| @@ -2837,10 +2872,21 @@ class ResolverVisitor extends MappingVisitor<Element> { |
| } else if (isMirrorsUsedConstant) { |
| compiler.mirrorUsageAnalyzerTask.validate(node, mapping); |
| } |
| + if (node.isConst()) { |
| + analyzeConstant(node); |
| + } |
| return null; |
| } |
| + void analyzeConstant(Node node) { |
| + addPostProcessAction(enclosingElement, () { |
| + mapping.setConstant(node, |
| + compiler.constantHandler.compileNodeWithDefinitions( |
| + node, mapping, isConst: true)); |
| + }); |
| + } |
| + |
| bool validateSymbol(Node node, String name, {bool reportError: true}) { |
| if (name.isEmpty) return true; |
| if (name.startsWith('_')) { |
| @@ -2924,6 +2970,9 @@ class ResolverVisitor extends MappingVisitor<Element> { |
| world.registerInstantiatedType(listType, mapping); |
| compiler.backend.registerRequiredType(listType, enclosingElement); |
| visit(node.elements); |
| + if (node.isConst()) { |
| + analyzeConstant(node); |
| + } |
| } |
| visitConditional(Conditional node) { |
| @@ -3139,6 +3188,9 @@ class ResolverVisitor extends MappingVisitor<Element> { |
| } |
| compiler.backend.registerRequiredType(mapType, enclosingElement); |
| node.visitChildren(this); |
| + if (node.isConst()) { |
| + analyzeConstant(node); |
| + } |
| } |
| visitLiteralMapEntry(LiteralMapEntry node) { |
| @@ -3158,7 +3210,11 @@ class ResolverVisitor extends MappingVisitor<Element> { |
| while (!cases.isEmpty) { |
| SwitchCase switchCase = cases.head; |
| for (Node labelOrCase in switchCase.labelsAndCases) { |
| - if (labelOrCase is! Label) continue; |
| + CaseMatch caseMatch = labelOrCase.asCaseMatch(); |
| + if (caseMatch != null) { |
| + analyzeConstant(caseMatch.expression); |
| + continue; |
| + } |
| Label label = labelOrCase; |
| String labelName = label.slowToString(); |
| @@ -3364,8 +3420,7 @@ class TypeDefinitionVisitor extends MappingVisitor<DartType> { |
| bound = element.bound; |
| } |
| } |
| - compiler.enqueuer.resolution.addPostProcessAction( |
| - element, checkTypeVariableBound); |
| + addPostProcessAction(element, checkTypeVariableBound); |
| } else { |
| variableElement.bound = compiler.objectClass.computeType(compiler); |
| } |
| @@ -3405,8 +3460,7 @@ class TypedefResolverVisitor extends TypeDefinitionVisitor { |
| var visitor = new TypedefCyclicVisitor(compiler, element); |
| type.accept(visitor, null); |
| } |
| - compiler.enqueuer.resolution.addPostProcessAction(element, |
| - checkCyclicReference); |
| + addPostProcessAction(element, checkCyclicReference); |
| } |
| } |