@@ -4939,6 +4939,9 @@ class ExtensionElementImpl extends ElementImpl
49394939 /// this extension.
49404940 List <PropertyAccessorElement > _accessors;
49414941
4942+ /// A list containing all of the fields contained in this extension.
4943+ List <FieldElement > _fields;
4944+
49424945 /// A list containing all of the methods contained in this extension.
49434946 List <MethodElement > _methods;
49444947
@@ -4967,16 +4970,14 @@ class ExtensionElementImpl extends ElementImpl
49674970
49684971 if (linkedNode != null ) {
49694972 if (linkedNode is ExtensionDeclaration ) {
4970- // TODO(brianwilkerson) Implement this.
4971- // _createPropertiesAndAccessors();
4972- // assert(_accessors != null);
4973- // return _accessors;
4973+ _createPropertiesAndAccessors ();
4974+ assert (_accessors != null );
4975+ return _accessors;
49744976 } else {
49754977 return _accessors = const [];
49764978 }
49774979 } else if (_unlinkedExtension != null ) {
4978- // TODO(brianwilkerson) Implement this.
4979- // _resynthesizePropertyAccessors();
4980+ _resynthesizeFieldsAndPropertyAccessors ();
49804981 }
49814982
49824983 return _accessors ?? = const < PropertyAccessorElement > [];
@@ -5016,6 +5017,36 @@ class ExtensionElementImpl extends ElementImpl
50165017 _extendedType = extendedType;
50175018 }
50185019
5020+ @override
5021+ List <FieldElement > get fields {
5022+ if (_fields != null ) {
5023+ return _fields;
5024+ }
5025+
5026+ if (linkedNode != null ) {
5027+ if (linkedNode is ExtensionDeclaration ) {
5028+ _createPropertiesAndAccessors ();
5029+ assert (_fields != null );
5030+ return _fields;
5031+ } else {
5032+ return _fields = const [];
5033+ }
5034+ } else if (_unlinkedExtension != null ) {
5035+ _resynthesizeFieldsAndPropertyAccessors ();
5036+ }
5037+
5038+ return _fields ?? const < FieldElement > [];
5039+ }
5040+
5041+ @override
5042+ void set fields (List <FieldElement > fields) {
5043+ _assertNotResynthesized (_unlinkedExtension);
5044+ for (FieldElement field in fields) {
5045+ (field as FieldElementImpl ).enclosingElement = this ;
5046+ }
5047+ _fields = fields;
5048+ }
5049+
50195050 @override
50205051 bool get isSimplyBounded => true ;
50215052
@@ -5155,6 +5186,183 @@ class ExtensionElementImpl extends ElementImpl
51555186 return AbstractClassElementImpl .getSetterFromAccessors (
51565187 setterName, accessors);
51575188 }
5189+
5190+ /// Create the accessors and fields when [linkedNode] is not `null` .
5191+ void _createPropertiesAndAccessors () {
5192+ assert (_accessors == null );
5193+ assert (_fields == null );
5194+
5195+ var context = enclosingUnit.linkedContext;
5196+ var accessorList = < PropertyAccessorElement > [];
5197+ var fieldList = < FieldElement > [];
5198+
5199+ var fields = context.getFields (linkedNode);
5200+ for (var field in fields) {
5201+ var name = field.name.name;
5202+ var fieldElement = FieldElementImpl .forLinkedNodeFactory (
5203+ this ,
5204+ reference.getChild ('@field' ).getChild (name),
5205+ field,
5206+ );
5207+ fieldList.add (fieldElement);
5208+
5209+ accessorList.add (fieldElement.getter);
5210+ if (fieldElement.setter != null ) {
5211+ accessorList.add (fieldElement.setter);
5212+ }
5213+ }
5214+
5215+ var methods = context.getMethods (linkedNode);
5216+ for (var method in methods) {
5217+ var isGetter = method.isGetter;
5218+ var isSetter = method.isSetter;
5219+ if (! isGetter && ! isSetter) continue ;
5220+
5221+ var name = method.name.name;
5222+ var containerRef = isGetter
5223+ ? reference.getChild ('@getter' )
5224+ : reference.getChild ('@setter' );
5225+
5226+ var accessorElement = PropertyAccessorElementImpl .forLinkedNode (
5227+ this ,
5228+ containerRef.getChild (name),
5229+ method,
5230+ );
5231+ accessorList.add (accessorElement);
5232+
5233+ var fieldRef = reference.getChild ('@field' ).getChild (name);
5234+ FieldElementImpl field = fieldRef.element;
5235+ if (field == null ) {
5236+ field = new FieldElementImpl (name, - 1 );
5237+ fieldRef.element = field;
5238+ field.enclosingElement = this ;
5239+ field.isSynthetic = true ;
5240+ field.isFinal = isGetter;
5241+ field.isStatic = accessorElement.isStatic;
5242+ fieldList.add (field);
5243+ } else {
5244+ // TODO(brianwilkerson) Shouldn't this depend on whether there is a
5245+ // setter?
5246+ field.isFinal = false ;
5247+ }
5248+
5249+ accessorElement.variable = field;
5250+ if (isGetter) {
5251+ field.getter = accessorElement;
5252+ } else {
5253+ field.setter = accessorElement;
5254+ }
5255+ }
5256+
5257+ _accessors = accessorList;
5258+ _fields = fieldList;
5259+ }
5260+
5261+ /// Resynthesize explicit fields and property accessors and fill [_fields] and
5262+ /// [_accessors] with explicit and implicit elements.
5263+ void _resynthesizeFieldsAndPropertyAccessors () {
5264+ assert (_fields == null );
5265+ assert (_accessors == null );
5266+
5267+ var unlinkedFields = _unlinkedExtension.fields;
5268+ var unlinkedExecutables = _unlinkedExtension.executables;
5269+
5270+ // Build explicit fields and implicit property accessors.
5271+ List <FieldElement > explicitFields;
5272+ List <PropertyAccessorElement > implicitAccessors;
5273+ var unlinkedFieldsLength = unlinkedFields.length;
5274+ if (unlinkedFieldsLength != 0 ) {
5275+ explicitFields = new List <FieldElement >(unlinkedFieldsLength);
5276+ implicitAccessors = < PropertyAccessorElement > [];
5277+ for (var i = 0 ; i < unlinkedFieldsLength; i++ ) {
5278+ var v = unlinkedFields[i];
5279+ FieldElementImpl field =
5280+ new FieldElementImpl .forSerializedFactory (v, this );
5281+ explicitFields[i] = field;
5282+ implicitAccessors.add (
5283+ new PropertyAccessorElementImpl_ImplicitGetter (field)
5284+ ..enclosingElement = this );
5285+ if (! field.isConst && ! field.isFinal) {
5286+ implicitAccessors.add (
5287+ new PropertyAccessorElementImpl_ImplicitSetter (field)
5288+ ..enclosingElement = this );
5289+ }
5290+ }
5291+ } else {
5292+ explicitFields = const < FieldElement > [];
5293+ implicitAccessors = const < PropertyAccessorElement > [];
5294+ }
5295+
5296+ var unlinkedExecutablesLength = unlinkedExecutables.length;
5297+ var getterSetterCount = 0 ;
5298+ for (var i = 0 ; i < unlinkedExecutablesLength; i++ ) {
5299+ var e = unlinkedExecutables[i];
5300+ if (e.kind == UnlinkedExecutableKind .getter ||
5301+ e.kind == UnlinkedExecutableKind .setter) {
5302+ getterSetterCount++ ;
5303+ }
5304+ }
5305+
5306+ // Build explicit property accessors and implicit fields.
5307+ List <PropertyAccessorElement > explicitAccessors;
5308+ Map <String , FieldElementImpl > implicitFields;
5309+ if (getterSetterCount != 0 ) {
5310+ explicitAccessors = new List <PropertyAccessorElement >(getterSetterCount);
5311+ implicitFields = < String , FieldElementImpl > {};
5312+ var index = 0 ;
5313+ for (var i = 0 ; i < unlinkedExecutablesLength; i++ ) {
5314+ var e = unlinkedExecutables[i];
5315+ if (e.kind == UnlinkedExecutableKind .getter ||
5316+ e.kind == UnlinkedExecutableKind .setter) {
5317+ PropertyAccessorElementImpl accessor =
5318+ new PropertyAccessorElementImpl .forSerialized (e, this );
5319+ explicitAccessors[index++ ] = accessor;
5320+ // Create or update the implicit field.
5321+ String fieldName = accessor.displayName;
5322+ FieldElementImpl field = implicitFields[fieldName];
5323+ if (field == null ) {
5324+ field = new FieldElementImpl (fieldName, - 1 );
5325+ implicitFields[fieldName] = field;
5326+ field.enclosingElement = this ;
5327+ field.isSynthetic = true ;
5328+ field.isFinal = e.kind == UnlinkedExecutableKind .getter;
5329+ field.isStatic = e.isStatic;
5330+ } else {
5331+ field.isFinal = false ;
5332+ }
5333+ accessor.variable = field;
5334+ if (e.kind == UnlinkedExecutableKind .getter) {
5335+ field.getter = accessor;
5336+ } else {
5337+ field.setter = accessor;
5338+ }
5339+ }
5340+ }
5341+ } else {
5342+ explicitAccessors = const < PropertyAccessorElement > [];
5343+ implicitFields = const < String , FieldElementImpl > {};
5344+ }
5345+
5346+ // Combine explicit and implicit fields and property accessors.
5347+ if (implicitFields.isEmpty) {
5348+ _fields = explicitFields;
5349+ } else if (explicitFields.isEmpty) {
5350+ _fields = implicitFields.values.toList (growable: false );
5351+ } else {
5352+ _fields = < FieldElement > []
5353+ ..addAll (explicitFields)
5354+ ..addAll (implicitFields.values);
5355+ }
5356+ if (explicitAccessors.isEmpty) {
5357+ _accessors = implicitAccessors;
5358+ } else if (implicitAccessors.isEmpty) {
5359+ _accessors = explicitAccessors;
5360+ } else {
5361+ _accessors = < PropertyAccessorElement > []
5362+ ..addAll (explicitAccessors)
5363+ ..addAll (implicitAccessors);
5364+ }
5365+ }
51585366}
51595367
51605368/// A concrete implementation of a [FieldElement] .
@@ -5185,7 +5393,7 @@ class FieldElementImpl extends PropertyInducingElementImpl
51855393 }
51865394
51875395 factory FieldElementImpl .forLinkedNodeFactory (
5188- ClassElementImpl enclosing, Reference reference, AstNode linkedNode) {
5396+ ElementImpl enclosing, Reference reference, AstNode linkedNode) {
51895397 var context = enclosing.enclosingUnit.linkedContext;
51905398 if (context.shouldBeConstFieldElement (linkedNode)) {
51915399 return ConstFieldElementImpl .forLinkedNode (
@@ -5207,23 +5415,21 @@ class FieldElementImpl extends PropertyInducingElementImpl
52075415
52085416 /// Initialize using the given serialized information.
52095417 factory FieldElementImpl .forSerializedFactory (
5210- UnlinkedVariable unlinkedVariable, ClassElementImpl enclosingClass ) {
5418+ UnlinkedVariable unlinkedVariable, ElementImpl enclosingElement ) {
52115419 if (unlinkedVariable.initializer? .bodyExpr != null &&
52125420 (unlinkedVariable.isConst ||
52135421 unlinkedVariable.isFinal &&
52145422 ! unlinkedVariable.isStatic &&
5215- enclosingClass._hasConstConstructor)) {
5423+ enclosingElement is ClassElementImpl &&
5424+ enclosingElement._hasConstConstructor)) {
52165425 return new ConstFieldElementImpl .forSerialized (
5217- unlinkedVariable, enclosingClass );
5426+ unlinkedVariable, enclosingElement );
52185427 } else {
52195428 return new FieldElementImpl .forSerialized (
5220- unlinkedVariable, enclosingClass );
5429+ unlinkedVariable, enclosingElement );
52215430 }
52225431 }
52235432
5224- @override
5225- ClassElement get enclosingElement => super .enclosingElement as ClassElement ;
5226-
52275433 @override
52285434 bool get isCovariant {
52295435 if (linkedNode != null ) {
@@ -5245,7 +5451,9 @@ class FieldElementImpl extends PropertyInducingElementImpl
52455451
52465452 @override
52475453 bool get isEnumConstant =>
5248- enclosingElement != null && enclosingElement.isEnum && ! isSynthetic;
5454+ enclosingElement is ClassElement &&
5455+ (enclosingElement as ClassElement ).isEnum &&
5456+ ! isSynthetic;
52495457
52505458 @override
52515459 bool get isStatic {
0 commit comments