| Index: pkg/compiler/lib/src/constants/values.dart
|
| diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
|
| index 24b6370024005d7d1c2dc8fe968f434a150321e3..5404d7042249a05251b33261b67cd6f985a812e8 100644
|
| --- a/pkg/compiler/lib/src/constants/values.dart
|
| +++ b/pkg/compiler/lib/src/constants/values.dart
|
| @@ -7,14 +7,17 @@ library dart2js.constants.values;
|
| import '../common.dart';
|
| import '../core_types.dart';
|
| import '../dart_types.dart';
|
| -import '../elements/elements.dart'
|
| - show ClassElement,
|
| - Element,
|
| - FieldElement,
|
| - FunctionElement,
|
| - PrefixElement;
|
| +import '../diagnostics/invariant.dart' show
|
| + DEBUG_MODE;
|
| +import '../elements/elements.dart' show
|
| + ClassElement,
|
| + Element,
|
| + FieldElement,
|
| + FunctionElement,
|
| + PrefixElement;
|
| import '../tree/tree.dart' hide unparse;
|
| -import '../util/util.dart' show Hashing;
|
| +import '../util/util.dart' show
|
| + Hashing;
|
|
|
| abstract class ConstantValueVisitor<R, A> {
|
| const ConstantValueVisitor();
|
| @@ -32,6 +35,7 @@ abstract class ConstantValueVisitor<R, A> {
|
| R visitInterceptor(InterceptorConstantValue constant, A arg);
|
| R visitSynthetic(SyntheticConstantValue constant, A arg);
|
| R visitDeferred(DeferredConstantValue constant, A arg);
|
| + R visitNonConstant(NonConstantValue constant, A arg);
|
| }
|
|
|
| abstract class ConstantValue {
|
| @@ -633,13 +637,40 @@ class ConstructedConstantValue extends ObjectConstantValue {
|
| final Map<FieldElement, ConstantValue> fields;
|
| final int hashCode;
|
|
|
| - ConstructedConstantValue(InterfaceType type,
|
| - Map<FieldElement, ConstantValue> fields)
|
| - : this.fields = fields,
|
| - hashCode = Hashing.mapHash(fields, Hashing.objectHash(type)),
|
| - super(type) {
|
| + factory ConstructedConstantValue(
|
| + InterfaceType type,
|
| + Map<FieldElement, ConstantValue> fields) {
|
| + fields = normalizeFields(type, fields);
|
| + int hashCode = Hashing.mapHash(fields, Hashing.objectHash(type));
|
| + return new ConstructedConstantValue._(type, fields, hashCode);
|
| + }
|
| +
|
| + ConstructedConstantValue._(InterfaceType type, this.fields, this.hashCode)
|
| + : super(type) {
|
| assert(type != null);
|
| - assert(!fields.containsValue(null));
|
| + assert(invariant(NO_LOCATION_SPANNABLE, !fields.containsValue(null),
|
| + message: () {
|
| + DEBUG_MODE = true;
|
| + return "Null field value for constructed constant of type '$type' "
|
| + "with fields ${fields}.";
|
| + }));
|
| + }
|
| +
|
| + static Map<FieldElement, ConstantValue> normalizeFields(
|
| + InterfaceType type, Map<FieldElement, ConstantValue> fields) {
|
| + Map<FieldElement, ConstantValue> normalizedFields =
|
| + <FieldElement, ConstantValue>{};
|
| + type.element.implementation.forEachInstanceField(
|
| + (ClassElement enclosingClass, FieldElement field) {
|
| + assert(invariant(NO_LOCATION_SPANNABLE, fields.containsKey(field),
|
| + message: () {
|
| + DEBUG_MODE = true;
|
| + return "No field value provided for $field in constructed constant "
|
| + "of type '$type' with fields ${fields}.";
|
| + }));
|
| + normalizedFields[field] = fields[field];
|
| + }, includeSuperAndInjectedMembers: true);
|
| + return normalizedFields;
|
| }
|
|
|
| bool get isConstructedObject => true;
|
| @@ -734,7 +765,7 @@ class NonConstantValue extends ConstantValue {
|
|
|
| @override
|
| accept(ConstantValueVisitor visitor, arg) {
|
| - // TODO(johnniwinther): Should this be part of the visiting?
|
| + return visitor.visitNonConstant(this, arg);
|
| }
|
|
|
| @override
|
| @@ -748,4 +779,4 @@ class NonConstantValue extends ConstantValue {
|
|
|
| @override
|
| String unparse() => '>>non-constant<<';
|
| -}
|
| +}
|
|
|