| 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
|
|
|