Chromium Code Reviews| Index: pkg/analyzer/lib/src/dart/element/element.dart |
| diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart |
| index b4d898e3da78a94b7b03e44d9fc90061f2c0974a..17c71e5897e82c3b435c959963272b8d387168bc 100644 |
| --- a/pkg/analyzer/lib/src/dart/element/element.dart |
| +++ b/pkg/analyzer/lib/src/dart/element/element.dart |
| @@ -14,6 +14,7 @@ import 'package:analyzer/dart/element/element.dart'; |
| import 'package:analyzer/dart/element/type.dart'; |
| import 'package:analyzer/dart/element/visitor.dart'; |
| import 'package:analyzer/src/dart/ast/utilities.dart'; |
| +import 'package:analyzer/src/dart/constant/value.dart'; |
| import 'package:analyzer/src/dart/element/handle.dart'; |
| import 'package:analyzer/src/dart/element/type.dart'; |
| import 'package:analyzer/src/generated/constant.dart' show EvaluationResultImpl; |
| @@ -1787,6 +1788,149 @@ class ConstFieldElementImpl extends FieldElementImpl with ConstVariableElement { |
| } |
| /** |
| + * A value field of an enum. |
|
Brian Wilkerson
2016/06/06 13:39:50
This wasn't clear to me; I had to read more code t
scheglov
2016/06/06 15:31:43
Done.
|
| + */ |
| +class ConstFieldElementImpl_EnumValue extends ConstFieldElementImpl_ofEnum { |
| + final UnlinkedEnumValue _unlinkedEnumValue; |
| + final int _index; |
| + |
| + ConstFieldElementImpl_EnumValue( |
| + EnumElementImpl enumElement, this._unlinkedEnumValue, this._index) |
| + : super(enumElement); |
| + |
| + @override |
| + SourceRange get docRange { |
| + if (_unlinkedEnumValue != null) { |
| + UnlinkedDocumentationComment comment = |
| + _unlinkedEnumValue.documentationComment; |
| + return comment != null |
| + ? new SourceRange(comment.offset, comment.length) |
| + : null; |
| + } |
| + return super.docRange; |
| + } |
| + |
| + @override |
| + String get documentationComment { |
| + if (_unlinkedEnumValue != null) { |
| + return _unlinkedEnumValue?.documentationComment?.text; |
| + } |
| + return super.documentationComment; |
| + } |
| + |
| + @override |
| + EvaluationResultImpl get evaluationResult { |
| + if (_evaluationResult == null) { |
| + Map<String, DartObjectImpl> fieldMap = <String, DartObjectImpl>{ |
| + name: new DartObjectImpl( |
| + context.typeProvider.intType, new IntState(_index)) |
| + }; |
| + DartObjectImpl value = |
| + new DartObjectImpl(type, new GenericState(fieldMap)); |
| + _evaluationResult = new EvaluationResultImpl(value); |
| + } |
| + return _evaluationResult; |
| + } |
| + |
| + @override |
| + String get name { |
| + if (_unlinkedEnumValue != null) { |
| + return _unlinkedEnumValue.name; |
| + } |
| + return super.name; |
| + } |
| + |
| + @override |
| + int get nameOffset { |
| + if (_unlinkedEnumValue != null) { |
| + return _unlinkedEnumValue.nameOffset; |
| + } |
| + return super.nameOffset; |
| + } |
| + |
| + @override |
| + InterfaceType get type => _enum.type; |
| +} |
| + |
| +/** |
| + * The synthetic `values` field of an enum. |
| + */ |
| +class ConstFieldElementImpl_EnumValues extends ConstFieldElementImpl_ofEnum { |
| + ConstFieldElementImpl_EnumValues(EnumElementImpl enumElement) |
| + : super(enumElement) { |
| + synthetic = true; |
| + } |
| + |
| + @override |
| + EvaluationResultImpl get evaluationResult { |
| + if (_evaluationResult == null) { |
| + List<DartObjectImpl> constantValues = <DartObjectImpl>[]; |
| + for (FieldElement field in _enum.fields) { |
| + if (field is ConstFieldElementImpl_EnumValue) { |
| + constantValues.add(field.evaluationResult.value); |
| + } |
| + } |
| + _evaluationResult = new EvaluationResultImpl( |
| + new DartObjectImpl(type, new ListState(constantValues))); |
| + } |
| + return _evaluationResult; |
| + } |
| + |
| + @override |
| + String get name => 'values'; |
| + |
| + @override |
| + InterfaceType get type { |
| + if (_type == null) { |
| + InterfaceType listType = context.typeProvider.listType; |
| + return _type = listType.instantiate(<DartType>[_enum.type]); |
| + } |
| + return _type; |
| + } |
| +} |
| + |
| +/** |
| + * An abstract constant field of an enum. |
| + */ |
| +abstract class ConstFieldElementImpl_ofEnum extends ConstFieldElementImpl { |
| + final EnumElementImpl _enum; |
| + |
| + ConstFieldElementImpl_ofEnum(this._enum) : super(null, -1) { |
| + enclosingElement = _enum; |
| + } |
| + |
| + @override |
| + void set const3(bool isConst) { |
| + assert(false); |
| + } |
| + |
| + @override |
| + void set evaluationResult(_) { |
| + assert(false); |
| + } |
| + |
| + @override |
| + void set final2(bool isFinal) { |
| + assert(false); |
| + } |
| + |
| + @override |
| + bool get isConst => true; |
| + |
| + @override |
| + bool get isStatic => true; |
| + |
| + @override |
| + void set static(bool isStatic) { |
| + assert(false); |
| + } |
| + |
| + void set type(DartType type) { |
| + assert(false); |
| + } |
| +} |
| + |
| +/** |
| * A [LocalVariableElement] for a local 'const' variable that has an |
| * initializer. |
| */ |
| @@ -2166,8 +2310,7 @@ abstract class ConstVariableElement |
| */ |
| Expression _constantInitializer; |
| - @override |
| - EvaluationResultImpl evaluationResult; |
| + EvaluationResultImpl _evaluationResult; |
| Expression get constantInitializer { |
| if (_constantInitializer == null && _unlinkedConst != null) { |
| @@ -2182,6 +2325,12 @@ abstract class ConstVariableElement |
| _constantInitializer = constantInitializer; |
| } |
| + EvaluationResultImpl get evaluationResult => _evaluationResult; |
| + |
| + void set evaluationResult(EvaluationResultImpl evaluationResult) { |
| + _evaluationResult = evaluationResult; |
| + } |
| + |
| /** |
| * If this element is resynthesized from the summary, return the unlinked |
| * initializer, otherwise return `null`. |
| @@ -3191,6 +3340,20 @@ class EnumElementImpl extends AbstractClassElementImpl { |
| } |
| @override |
| + List<PropertyAccessorElement> get accessors { |
| + if (_unlinkedEnum != null && _accessors == null) { |
| + _resynthesizeFieldsAndPropertyAccessors(); |
| + } |
| + return _accessors ?? const <PropertyAccessorElement>[]; |
| + } |
| + |
| + @override |
| + void set accessors(List<PropertyAccessorElement> accessors) { |
| + assert(_unlinkedEnum == null); |
| + super.accessors = accessors; |
| + } |
| + |
| + @override |
| List<InterfaceType> get allSupertypes => <InterfaceType>[supertype]; |
| @override |
| @@ -3238,6 +3401,20 @@ class EnumElementImpl extends AbstractClassElementImpl { |
| } |
| @override |
| + List<FieldElement> get fields { |
| + if (_unlinkedEnum != null && _fields == null) { |
| + _resynthesizeFieldsAndPropertyAccessors(); |
| + } |
| + return _fields ?? const <FieldElement>[]; |
| + } |
| + |
| + @override |
| + void set fields(List<FieldElement> fields) { |
| + assert(_unlinkedEnum == null); |
| + super.fields = fields; |
| + } |
| + |
| + @override |
| bool get hasNonFinalField => false; |
| @override |
| @@ -3337,6 +3514,32 @@ class EnumElementImpl extends AbstractClassElementImpl { |
| @override |
| bool isSuperConstructorAccessible(ConstructorElement constructor) => false; |
| + |
| + void _resynthesizeFieldsAndPropertyAccessors() { |
| + List<FieldElementImpl> fields = <FieldElementImpl>[]; |
| + // Build the 'index' field. |
| + fields.add(new FieldElementImpl('index', -1) |
| + ..enclosingElement = this |
| + ..synthetic = true |
| + ..final2 = true |
| + ..type = context.typeProvider.intType); |
| + // Build the 'values' field. |
| + fields.add(new ConstFieldElementImpl_EnumValues(this)); |
| + // Build fields for all enum constants. |
| + for (int i = 0; i < _unlinkedEnum.values.length; i++) { |
| + UnlinkedEnumValue unlinkedValue = _unlinkedEnum.values[i]; |
| + ConstFieldElementImpl_EnumValue field = |
| + new ConstFieldElementImpl_EnumValue(this, unlinkedValue, i); |
| + fields.add(field); |
| + } |
| + // done |
| + _fields = fields; |
| + _accessors = fields |
| + .map((FieldElementImpl field) => |
| + new PropertyAccessorElementImpl_ImplicitGetter(field) |
| + ..enclosingElement = this) |
| + .toList(growable: false); |
| + } |
| } |
| /** |
| @@ -7427,6 +7630,7 @@ class PropertyAccessorElementImpl_ImplicitGetter |
| PropertyInducingElementImpl property) |
| : super.forVariable(property) { |
| property.getter = this; |
| + enclosingElement = property.enclosingElement; |
| } |
| @override |