Index: pkg/compiler/lib/src/resolution/resolution.dart |
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart |
index ef5c04f199decfe7d8488c1df9faff384e71f0ac..d9ae57438b9f470156a52331a4c43284dbf5f2f0 100644 |
--- a/pkg/compiler/lib/src/resolution/resolution.dart |
+++ b/pkg/compiler/lib/src/resolution/resolution.dart |
@@ -55,6 +55,7 @@ import 'class_members.dart' show MembersCreator; |
import 'constructors.dart'; |
import 'members.dart'; |
import 'registry.dart'; |
+import 'resolution_result.dart'; |
import 'signatures.dart'; |
import 'tree_elements.dart'; |
import 'typedefs.dart'; |
@@ -227,13 +228,21 @@ class ResolverTask extends CompilerTask { |
processAsyncMarker(compiler, element, registry); |
if (element.isGenerativeConstructor) { |
+ ConstructorElementX constructor = element; |
// Even if there is no initializer list we still have to do the |
// resolution in case there is an implicit super constructor call. |
InitializerResolver resolver = |
- new InitializerResolver(visitor, element, tree); |
+ new InitializerResolver(visitor, constructor, tree); |
FunctionElement redirection = resolver.resolveInitializers(); |
+ constructor.constantConstructor; |
+ /*if (constructor.isConst && !constructor.isFromEnvironmentConstructor) { |
+ assert(invariant(constructor, |
+ constructor.constantConstructorCache != null, |
+ message: "Constant constructor has")) |
+ }*/ |
if (redirection != null) { |
- resolveRedirectingConstructor(resolver, tree, element, redirection); |
+ resolveRedirectingConstructor( |
+ resolver, tree, constructor, redirection); |
} |
} else if (tree.initializers != null) { |
reporter.reportErrorMessage( |
@@ -339,6 +348,16 @@ class ResolverTask extends CompilerTask { |
element.modifiers.getStatic(), |
MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); |
} |
+ bool requireConstant = element.isConst; |
+ if (!requireConstant && element.isInstanceMember) { |
+ for (ConstructorElement constructor in |
+ element.enclosingClass.constructors) { |
+ if (constructor.isConst) { |
+ requireConstant = true; |
+ break; |
+ } |
+ } |
+ } |
ResolverVisitor visitor = visitorFor(element); |
ResolutionRegistry registry = visitor.registry; |
// TODO(johnniwinther): Maybe remove this when placeholderCollector migrates |
@@ -354,10 +373,18 @@ class ResolverTask extends CompilerTask { |
Expression initializer = element.initializer; |
Modifiers modifiers = element.modifiers; |
+ ResolutionResult result = const NoneResult(); |
if (initializer != null) { |
// TODO(johnniwinther): Avoid analyzing initializers if |
// [Compiler.analyzeSignaturesOnly] is set. |
- visitor.visit(initializer); |
+ //reportHere(reporter, element, 'resolveField:$element (${visitor.constantState}) (${initializer.runtimeType})'); |
+ if (requireConstant) { |
+ result = visitor.visitInConstantContext(initializer); |
+ visitor.checkConstantInvariant(initializer, result); |
+ } else { |
+ result = visitor.visit(initializer); |
+ } |
+ registry.setConstant(initializer, result.constant); |
} else if (modifiers.isConst) { |
reporter.reportErrorMessage( |
element, MessageKind.CONST_WITHOUT_INITIALIZER); |
@@ -367,11 +394,13 @@ class ResolverTask extends CompilerTask { |
} else { |
registry.registerInstantiatedClass(compiler.nullClass); |
} |
+ element.constant = result.constant; |
if (Elements.isStaticOrTopLevelField(element)) { |
visitor.addDeferredAction(element, () { |
if (element.modifiers.isConst) { |
- element.constant = constantCompiler.compileConstant(element); |
+ // Ensure constant expression will be evaluated. |
+ constantCompiler.compileConstant(element); |
} else { |
constantCompiler.compileVariable(element); |
} |
@@ -1030,7 +1059,7 @@ class ResolverTask extends CompilerTask { |
// [compileMetadata]. |
annotation.constant = |
constantCompiler.compileMetadata(annotation, node, registry.mapping); |
- constantCompiler.evaluate(annotation.constant); |
+ constantCompiler.evaluate(node, annotation.constant); |
// TODO(johnniwinther): Register the relation between the annotation |
// and the annotated element instead. This will allow the backend to |
// retrieve the backend constant and only register metadata on the |