Support for property accessors in augmentations. Change-Id: I06e68030f3f1c0b9cb86df2abd7ba9b90d93f5e5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/314585 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart index 7cdcc68..9ef4ff2 100644 --- a/pkg/analyzer/lib/src/dart/analysis/driver.dart +++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -87,7 +87,7 @@ /// TODO(scheglov) Clean up the list of implicitly analyzed files. class AnalysisDriver implements AnalysisDriverGeneric { /// The version of data format, should be incremented on every format change. - static const int DATA_VERSION = 289; + static const int DATA_VERSION = 290; /// The number of exception contexts allowed to write. Once this field is /// zero, we stop writing any new exception contexts in this process.
diff --git a/pkg/analyzer/lib/src/dart/element/display_string_builder.dart b/pkg/analyzer/lib/src/dart/element/display_string_builder.dart index bec2d7f..6de14f0 100644 --- a/pkg/analyzer/lib/src/dart/element/display_string_builder.dart +++ b/pkg/analyzer/lib/src/dart/element/display_string_builder.dart
@@ -95,6 +95,10 @@ } void writeExecutableElement(ExecutableElement element, String name) { + if (element.isAugmentation) { + _write('augment '); + } + _writeType(element.returnType2); _write(' ');
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart index dafbab3..eb3bbb1 100644 --- a/pkg/analyzer/lib/src/dart/element/element.dart +++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -117,21 +117,19 @@ abstract class AugmentedInstanceElementImpl implements AugmentedInstanceElement { @override - List<MethodElement> methods = []; + List<FieldElement> fields = []; @override - // TODO: implement accessors - List<PropertyAccessorElement> get accessors => throw UnimplementedError(); + List<PropertyAccessorElement> accessors = []; + + @override + List<MethodElement> methods = []; @override // TODO: implement declaration InstanceElement get declaration => throw UnimplementedError(); @override - // TODO: implement fields - List<FieldElement> get fields => throw UnimplementedError(); - - @override // TODO: implement metadata List<ElementAnnotation> get metadata => throw UnimplementedError(); @@ -6063,17 +6061,16 @@ /// A concrete implementation of a [PropertyAccessorElement]. class PropertyAccessorElementImpl extends ExecutableElementImpl implements PropertyAccessorElement { - /// The variable associated with this accessor. - @override - late PropertyInducingElementImpl variable; + late PropertyInducingElementImpl _variable; /// If this method is a synthetic element which is based on another method /// with some modifications (such as making some parameters covariant), /// this field contains the base method. PropertyAccessorElement? prototype; - @override - PropertyAccessorElementImpl? augmentationTarget; + PropertyAccessorElementImpl? _augmentation; + + PropertyAccessorElementImpl? _augmentationTarget; /// Initialize a newly created property accessor element to have the given /// [name] and [offset]. @@ -6081,8 +6078,9 @@ /// Initialize a newly created synthetic property accessor element to be /// associated with the given [variable]. - PropertyAccessorElementImpl.forVariable(this.variable, {Reference? reference}) - : super(variable.name, -1, reference: reference) { + PropertyAccessorElementImpl.forVariable(this._variable, + {Reference? reference}) + : super(_variable.name, -1, reference: reference) { isAbstract = variable is FieldElementImpl && (variable as FieldElementImpl).isAbstract; isStatic = variable.isStatic; @@ -6090,9 +6088,23 @@ } @override - PropertyAccessorElement? get augmentation { - // TODO(scheglov) implement - throw UnimplementedError(); + PropertyAccessorElementImpl? get augmentation { + linkedData?.read(this); + return _augmentation; + } + + set augmentation(PropertyAccessorElementImpl? value) { + _augmentation = value; + } + + @override + PropertyAccessorElementImpl? get augmentationTarget { + linkedData?.read(this); + return _augmentationTarget; + } + + set augmentationTarget(PropertyAccessorElementImpl? value) { + _augmentationTarget = value; } @override @@ -6169,6 +6181,16 @@ } @override + PropertyInducingElementImpl get variable { + linkedData?.read(this); + return _variable; + } + + set variable(PropertyInducingElementImpl value) { + _variable = value; + } + + @override T? accept<T>(ElementVisitor<T> visitor) => visitor.visitPropertyAccessorElement(this);
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart index 92eb7cb..1014a25 100644 --- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart +++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -132,6 +132,8 @@ element.augmentedInternal = augmented; augmented.mixins = reader._readInterfaceTypeList(); augmented.interfaces = reader._readInterfaceTypeList(); + augmented.fields = reader.readElementList(); + augmented.accessors = reader.readElementList(); augmented.methods = reader.readElementList(); } } @@ -554,6 +556,8 @@ _reader.readUInt30List(), ); + final accessorAugmentationsOffset = _reader.readUInt30(); + libraryElement.linkedData = LibraryElementLinkedData( reference: _reference, libraryReader: this, @@ -566,6 +570,8 @@ InformativeDataApplier(_elementFactory, _unitsInformativeBytes) .applyTo(libraryElement); + _readPropertyAccessorAugmentations(accessorAugmentationsOffset); + return libraryElement; } @@ -1276,6 +1282,20 @@ ); } + /// Read resolution information for property accessor augmentations, + /// during which we update `getter` and `setter` of augmented variables. + void _readPropertyAccessorAugmentations(int offset) { + final reader = ResolutionReader( + _elementFactory, + _referenceReader, + _reader.fork(_baseResolutionOffset + offset), + ); + final elements = reader.readElementList<PropertyAccessorElementImpl>(); + for (final element in elements) { + element.variable; + } + } + PropertyAccessorElementImpl _readPropertyAccessorElement( CompilationUnitElementImpl unitElement, ElementImpl classElement, @@ -1322,6 +1342,10 @@ ); accessors.add(accessor); + if (accessor.isAugmentation) { + continue; + } + var name = accessor.displayName; var isGetter = accessor.isGetter; @@ -1340,6 +1364,7 @@ } else { property = TopLevelVariableElementImpl(name, -1) ..enclosingElement = enclosingElement + ..reference = reference ..isSynthetic = true; reference.element ??= property; properties.add(property); @@ -1350,6 +1375,7 @@ } else { property = FieldElementImpl(name, -1) ..enclosingElement = enclosingElement + ..reference = reference ..isStatic = accessor.isStatic ..isSynthetic = true; reference.element ??= property; @@ -1604,6 +1630,8 @@ element.augmentedInternal = augmented; augmented.superclassConstraints = reader._readInterfaceTypeList(); augmented.interfaces = reader._readInterfaceTypeList(); + augmented.fields = reader.readElementList(); + augmented.accessors = reader.readElementList(); augmented.methods = reader.readElementList(); } } @@ -1634,6 +1662,21 @@ element.returnType = reader.readRequiredType(); _readFormalParameters(reader, element.parameters); + // If augmentation... + if (reader.readBool()) { + element.augmentationTarget = + reader.readElement() as PropertyAccessorElementImpl?; + final variable = reader.readElement() as PropertyInducingElementImpl; + element.variable = variable; + if (element.isGetter) { + variable.getter?.augmentation = element; + variable.getter = element; + } else { + variable.setter?.augmentation = element; + variable.setter = element; + } + } + applyConstantOffsets?.perform(); } } @@ -1687,12 +1730,16 @@ if (memberFlags == Tag.MemberLegacyWithTypeArguments || memberFlags == Tag.MemberWithTypeArguments) { - element as ExecutableElement; var enclosing = element.enclosingElement2 as TypeParameterizedElement; var typeParameters = enclosing.typeParameters; var typeArguments = _readTypeList(); var substitution = Substitution.fromPairs(typeParameters, typeArguments); - element = ExecutableMember.from2(element, substitution); + if (element is ExecutableElement) { + element = ExecutableMember.from2(element, substitution); + } else { + element as FieldElement; + element = FieldMember.from2(element, substitution); + } } if (memberFlags == Tag.MemberLegacyWithoutTypeArguments ||
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart index 63e643b..8d838a4 100644 --- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart +++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -56,6 +56,11 @@ /// and read them later on demand. List<int> _classMembersLengths = []; + /// [_writePropertyAccessorElement] adds augmentations here, so that after + /// reading the library we can read them, and while doing this, update + /// `getter` and `setter` of augmented variables. + List<PropertyAccessorElementImpl> _accessorAugmentations = []; + final StringIndexer _stringIndexer = StringIndexer(); final List<_Library> _libraries = []; @@ -96,7 +101,8 @@ void writeLibraryElement(LibraryElementImpl libraryElement) { var libraryOffset = _sink.offset; - _classMembersLengths = <int>[]; + _classMembersLengths = []; + _accessorAugmentations = []; _sink.writeUInt30(_resolutionSink.offset); _sink._writeStringReference(libraryElement.name); @@ -115,6 +121,8 @@ _sink.writeUint30List(libraryElement.nameUnion.mask); + _writePropertyAccessorAugmentations(); + _libraries.add( _Library( uriStr: '${libraryElement.source.uri}', @@ -163,6 +171,8 @@ (augmented) { _resolutionSink._writeTypeList(augmented.mixins); _resolutionSink._writeTypeList(augmented.interfaces); + _resolutionSink._writeElementList(augmented.fields); + _resolutionSink._writeElementList(augmented.accessors); _resolutionSink._writeElementList(augmented.methods); }, ); @@ -433,6 +443,8 @@ (augmented) { _resolutionSink._writeTypeList(augmented.superclassConstraints); _resolutionSink._writeTypeList(augmented.interfaces); + _resolutionSink._writeElementList(augmented.fields); + _resolutionSink._writeElementList(augmented.accessors); _resolutionSink._writeElementList(augmented.methods); }, ); @@ -498,6 +510,14 @@ _writeDirectiveUri(element.uri); } + /// Write information to update `getter` and `setter` properties of + /// augmented variables to use the corresponding augmentations. + void _writePropertyAccessorAugmentations() { + final offset = _resolutionSink.offset; + _resolutionSink._writeElementList(_accessorAugmentations); + _sink.writeUInt30(offset); + } + void _writePropertyAccessorElement(PropertyAccessorElementImpl element) { _sink.writeUInt30(_resolutionSink.offset); _sink._writeStringReference(element.displayName); @@ -506,6 +526,12 @@ _resolutionSink._writeAnnotationList(element.metadata); _resolutionSink.writeType(element.returnType2); _writeList(element.parameters, _writeParameterElement); + + _resolutionSink.writeIf(element.isAugmentation, () { + _accessorAugmentations.add(element); + _resolutionSink.writeElement(element.augmentationTarget); + _resolutionSink.writeElement(element.variable); + }); } void _writeTopLevelVariableElement(TopLevelVariableElementImpl element) {
diff --git a/pkg/analyzer/lib/src/summary2/data_writer.dart b/pkg/analyzer/lib/src/summary2/data_writer.dart index c39868a..afb0ae6 100644 --- a/pkg/analyzer/lib/src/summary2/data_writer.dart +++ b/pkg/analyzer/lib/src/summary2/data_writer.dart
@@ -121,6 +121,18 @@ addByte(byte); } + void writeIf<T extends Object>( + bool condition, + void Function() ifTrue, + ) { + if (condition) { + writeBool(true); + ifTrue(); + } else { + writeBool(false); + } + } + void writeIfType<T extends Object>( Object? object, void Function(T t) ifTrue,
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart index 471239b..87a7422 100644 --- a/pkg/analyzer/lib/src/summary2/element_builder.dart +++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -814,6 +814,7 @@ if (node.isGetter) { var element = PropertyAccessorElementImpl(name, nameOffset); element.isAbstract = node.isAbstract; + element.isAugmentation = node.augmentKeyword != null; element.isGetter = true; element.isStatic = node.isStatic; @@ -832,6 +833,7 @@ } else if (node.isSetter) { var element = PropertyAccessorElementImpl(name, nameOffset); element.isAbstract = node.isAbstract; + element.isAugmentation = node.augmentKeyword != null; element.isSetter = true; element.isStatic = node.isStatic; @@ -1244,6 +1246,10 @@ required String name, required PropertyAccessorElementImpl accessorElement, }) { + if (accessorElement.isAugmentation) { + return; + } + var enclosingRef = _enclosingContext.reference; var enclosingElement = _enclosingContext.element;
diff --git a/pkg/analyzer/lib/src/summary2/element_flags.dart b/pkg/analyzer/lib/src/summary2/element_flags.dart index d113509..7600efd 100644 --- a/pkg/analyzer/lib/src/summary2/element_flags.dart +++ b/pkg/analyzer/lib/src/summary2/element_flags.dart
@@ -308,15 +308,16 @@ class PropertyAccessorElementFlags { static const int _invokesSuperSelf = 1 << 0; - static const int _isGetter = 1 << 1; - static const int _isSetter = 1 << 2; - static const int _hasImplicitReturnType = 1 << 3; - static const int _isAbstract = 1 << 4; - static const int _isAsynchronous = 1 << 5; - static const int _isExternal = 1 << 6; - static const int _isGenerator = 1 << 7; - static const int _isStatic = 1 << 8; - static const int _isTempAugmentation = 1 << 9; + static const int _isAugmentation = 1 << 1; + static const int _isGetter = 1 << 2; + static const int _isSetter = 1 << 3; + static const int _hasImplicitReturnType = 1 << 4; + static const int _isAbstract = 1 << 5; + static const int _isAsynchronous = 1 << 6; + static const int _isExternal = 1 << 7; + static const int _isGenerator = 1 << 8; + static const int _isStatic = 1 << 9; + static const int _isTempAugmentation = 1 << 10; static void read( SummaryDataReader reader, @@ -324,6 +325,7 @@ ) { var byte = reader.readUInt30(); element.invokesSuperSelf = (byte & _invokesSuperSelf) != 0; + element.isAugmentation = (byte & _isAugmentation) != 0; element.isGetter = (byte & _isGetter) != 0; element.isSetter = (byte & _isSetter) != 0; element.hasImplicitReturnType = (byte & _hasImplicitReturnType) != 0; @@ -338,6 +340,7 @@ static void write(BufferedSink sink, PropertyAccessorElementImpl element) { var result = 0; result |= element.invokesSuperSelf ? _invokesSuperSelf : 0; + result |= element.isAugmentation ? _isAugmentation : 0; result |= element.isGetter ? _isGetter : 0; result |= element.isSetter ? _isSetter : 0; result |= element.hasImplicitReturnType ? _hasImplicitReturnType : 0;
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart index 835a374..9a6e8a9 100644 --- a/pkg/analyzer/lib/src/summary2/library_builder.dart +++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -36,24 +36,51 @@ AugmentedClassDeclarationBuilder({ required this.declaration, }) { + addAccessors(declaration.accessors); addMethods(declaration.methods); } void augment(ClassElementImpl element) { + addAccessors(element.accessors); addMethods(element.methods); } } abstract class AugmentedInstanceDeclarationBuilder { + final Map<String, PropertyAccessorElementImpl> accessors = {}; final Map<String, MethodElementImpl> methods = {}; + void addAccessors(List<PropertyAccessorElementImpl> elements) { + for (final element in elements) { + final name = element.name; + if (element.isAugmentation) { + final existing = accessors[name]; + if (existing != null) { + existing.augmentation = element; + element.augmentationTarget = existing; + // Link the accessor to the variable. + final variable = existing.variable; + element.variable = variable; + if (element.isGetter) { + variable.getter = element; + } else { + variable.setter = element; + } + } + } + accessors[name] = element; + } + } + void addMethods(List<MethodElementImpl> elements) { for (final element in elements) { final name = element.name; - final existing = methods[name]; - if (existing != null) { - existing.augmentation = element; - element.augmentationTarget = existing; + if (element.isAugmentation) { + final existing = methods[name]; + if (existing != null) { + existing.augmentation = element; + element.augmentationTarget = existing; + } } methods[name] = element; } @@ -67,10 +94,12 @@ AugmentedMixinDeclarationBuilder({ required this.declaration, }) { + addAccessors(declaration.accessors); addMethods(declaration.methods); } void augment(MixinElementImpl element) { + addAccessors(element.accessors); addMethods(element.methods); } }
diff --git a/pkg/analyzer/lib/src/summary2/types_builder.dart b/pkg/analyzer/lib/src/summary2/types_builder.dart index f2fdbad..9963a6e 100644 --- a/pkg/analyzer/lib/src/summary2/types_builder.dart +++ b/pkg/analyzer/lib/src/summary2/types_builder.dart
@@ -148,6 +148,8 @@ element.augmentedInternal = augmented; augmented.mixins.addAll(element.mixins); augmented.interfaces.addAll(element.interfaces); + augmented.fields.addAll(element.fields); + augmented.accessors.addAll(element.accessors.notAugmented); augmented.methods.addAll(element.methods.notAugmented); } _toInferMixins[element] = _ToInferMixins(element, node.withClause); @@ -336,6 +338,8 @@ element.augmentedInternal = augmented; augmented.superclassConstraints.addAll(element.superclassConstraints); augmented.interfaces.addAll(element.interfaces); + augmented.fields.addAll(element.fields); + augmented.accessors.addAll(element.accessors.notAugmented); augmented.methods.addAll(element.methods.notAugmented); } } @@ -433,15 +437,32 @@ } if (augmented is AugmentedInstanceElementImpl) { - MethodElement mapMethodElement(MethodElement element) { - if (toDeclaration.map.isEmpty) { - return element; - } - return MethodMember(typeProvider, element, toDeclaration, false); - } + augmented.fields.addAll( + element.fields.map((element) { + if (toDeclaration.map.isEmpty) { + return element; + } + return FieldMember(typeProvider, element, toDeclaration, false); + }), + ); + + augmented.accessors.addAll( + element.accessors.notAugmented.map((element) { + if (toDeclaration.map.isEmpty) { + return element; + } + return PropertyAccessorMember( + typeProvider, element, toDeclaration, false); + }), + ); augmented.methods.addAll( - element.methods.notAugmented.map(mapMethodElement), + element.methods.notAugmented.map((element) { + if (toDeclaration.map.isEmpty) { + return element; + } + return MethodMember(typeProvider, element, toDeclaration, false); + }), ); } } @@ -729,8 +750,8 @@ } } -extension on List<MethodElement> { - Iterable<MethodElement> get notAugmented { +extension<T extends ExecutableElement> on List<T> { + Iterable<T> get notAugmented { return where((e) => e.augmentation == null); } }
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart index cb61aa5..cb3db06 100644 --- a/pkg/analyzer/test/src/summary/element_text.dart +++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -113,33 +113,6 @@ expect(element.nonSynthetic, same(element)); } - /// Assert that the [accessor] of the [property] is correctly linked to - /// the same enclosing element as the [property]. - void _assertSyntheticAccessorEnclosing( - PropertyInducingElement property, PropertyAccessorElement accessor) { - if (accessor.isSynthetic) { - // Usually we have a non-synthetic property, and a synthetic accessor. - } else { - // But it is possible to have a non-synthetic setter. - // class A { - // final int foo; - // set foo(int newValue) {} - // } - expect(accessor.isSetter, isTrue); - } - - expect(accessor.variable, same(property)); - - var propertyEnclosing = property.enclosingElement2; - expect(accessor.enclosingElement2, same(propertyEnclosing)); - - if (propertyEnclosing is CompilationUnitElement) { - expect(propertyEnclosing.accessors, contains(accessor)); - } else if (propertyEnclosing is InterfaceElement) { - expect(propertyEnclosing.accessors, contains(accessor)); - } - } - ResolvedAstPrinter _createAstPrinter() { return ResolvedAstPrinter( sink: _sink, @@ -172,7 +145,7 @@ expect(augmented, same(endOfAugmentations.augmented)); } - void _writeAugmentation(InterfaceElementImpl e) { + void _writeAugmentation(ElementImpl e) { switch (e) { case ClassElementImpl e: final augmentation = e.augmentation; @@ -184,6 +157,11 @@ if (augmentation != null) { _elementPrinter.writeNamedElement('augmentation', augmentation); } + case PropertyAccessorElementImpl e: + final augmentation = e.augmentation; + if (augmentation != null) { + _elementPrinter.writeNamedElement('augmentation', augmentation); + } } } @@ -205,12 +183,22 @@ }); } - void _writeAugmentationTarget(InterfaceElementImpl e) { - if (e.isAugmentation) { - _elementPrinter.writeNamedElement( - 'augmentationTarget', - e.augmentationTarget, - ); + void _writeAugmentationTarget(ElementImpl e) { + switch (e) { + case InterfaceElementImpl e: + if (e.isAugmentation) { + _elementPrinter.writeNamedElement( + 'augmentationTarget', + e.augmentationTarget, + ); + } + case PropertyAccessorElementImpl e: + if (e.isAugmentation) { + _elementPrinter.writeNamedElement( + 'augmentationTarget', + e.augmentationTarget, + ); + } } } @@ -237,6 +225,16 @@ return; } + void writeFields() { + final sorted = augmented.fields.sortedBy((e) => e.name); + _elementPrinter.writeElementList('fields', sorted); + } + + void writeAccessors() { + final sorted = augmented.accessors.sortedBy((e) => e.name); + _elementPrinter.writeElementList('accessors', sorted); + } + void writeMethods() { final sorted = augmented.methods.sortedBy((e) => e.name); _elementPrinter.writeElementList('methods', sorted); @@ -248,6 +246,8 @@ case AugmentedClassElement(): _elementPrinter.writeTypeList('mixins', augmented.mixins); _elementPrinter.writeTypeList('interfaces', augmented.interfaces); + writeFields(); + writeAccessors(); writeMethods(); case AugmentedMixinElement(): _elementPrinter.writeTypeList( @@ -255,6 +255,8 @@ augmented.superclassConstraints, ); _elementPrinter.writeTypeList('interfaces', augmented.interfaces); + writeFields(); + writeAccessors(); writeMethods(); } // TODO(scheglov) Add other types and properties @@ -697,6 +699,7 @@ void _writeMethodElement(MethodElement e) { _sink.writeIndentedLine(() { + _sink.writeIf(e.isAugmentation, 'augment '); _sink.writeIf(e.isSynthetic, 'synthetic '); _sink.writeIf(e.isStatic, 'static '); _sink.writeIf(e.isAbstract, 'abstract '); @@ -864,18 +867,6 @@ expect(variableEnclosing.fields, contains(variable)); } - if (e.isGetter) { - expect(variable.getter, same(e)); - if (variable.setter != null) { - expect(variable.setter!.variable, same(variable)); - } - } else { - expect(variable.setter, same(e)); - if (variable.getter != null) { - expect(variable.getter!.variable, same(variable)); - } - } - if (e.isSynthetic) { expect(e.nameOffset, -1); } else { @@ -886,6 +877,7 @@ } _sink.writeIndentedLine(() { + _sink.writeIf(e.isAugmentation, 'augment '); _sink.writeIf(e.isSynthetic, 'synthetic '); _sink.writeIf(e.isStatic, 'static '); _sink.writeIf(e.isAbstract, 'abstract '); @@ -919,6 +911,8 @@ _writeType('returnType', e.returnType2); _writeNonSyntheticElement(e); writeLinking(); + _writeAugmentationTarget(e); + _writeAugmentation(e); }); } @@ -932,11 +926,6 @@ expect(e.nameOffset, -1); } else { expect(e.getter, isNotNull); - _assertSyntheticAccessorEnclosing(e, e.getter!); - - if (e.setter != null) { - _assertSyntheticAccessorEnclosing(e, e.setter!); - } if (!e.isTempAugmentation) { expect(e.nameOffset, isPositive); @@ -988,6 +977,8 @@ _writeConstantInitializer(e); _writeNonSyntheticElement(e); writeLinking(); + _writeAugmentationTarget(e); + _writeAugmentation(e); }); }
diff --git a/pkg/analyzer/test/src/summary/elements_test.dart b/pkg/analyzer/test/src/summary/elements_test.dart index 95476ff..7cc374b 100644 --- a/pkg/analyzer/test/src/summary/elements_test.dart +++ b/pkg/analyzer/test/src/summary/elements_test.dart
@@ -174,6 +174,601 @@ '''); } + test_augmented_fields_add() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment class A { + int foo2 = 0; +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +class A { + int foo1 = 0; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + classes + class A @31 + augmentation: self::@augmentation::package:test/a.dart::@class::A + fields + foo1 @41 + type: int + shouldUseTypeForInitializerInference: true + id: field_0 + getter: getter_0 + setter: setter_0 + constructors + synthetic @-1 + accessors + synthetic get foo1 @-1 + returnType: int + id: getter_0 + variable: field_0 + synthetic set foo1= @-1 + parameters + requiredPositional _foo1 @-1 + type: int + returnType: void + id: setter_0 + variable: field_0 + augmented + fields + self::@class::A::@field::foo1 + self::@augmentation::package:test/a.dart::@class::A::@field::foo2 + accessors + self::@class::A::@getter::foo1 + self::@class::A::@setter::foo1 + self::@augmentation::package:test/a.dart::@class::A::@getter::foo2 + self::@augmentation::package:test/a.dart::@class::A::@setter::foo2 + augmentationImports + package:test/a.dart + definingUnit + classes + augment class A @43 + augmentationTarget: self::@class::A + fields + foo2 @53 + type: int + shouldUseTypeForInitializerInference: true + id: field_1 + getter: getter_1 + setter: setter_1 + accessors + synthetic get foo2 @-1 + returnType: int + id: getter_1 + variable: field_1 + synthetic set foo2= @-1 + parameters + requiredPositional _foo2 @-1 + type: int + returnType: void + id: setter_1 + variable: field_1 +'''); + } + + test_augmented_fields_add_generic() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment class A<T2> { + T2 foo2; +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +class A<T1> { + T1 foo1; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + classes + class A @31 + typeParameters + covariant T1 @33 + defaultType: dynamic + augmentation: self::@augmentation::package:test/a.dart::@class::A + fields + foo1 @44 + type: T1 + shouldUseTypeForInitializerInference: true + id: field_0 + getter: getter_0 + setter: setter_0 + constructors + synthetic @-1 + accessors + synthetic get foo1 @-1 + returnType: T1 + id: getter_0 + variable: field_0 + synthetic set foo1= @-1 + parameters + requiredPositional _foo1 @-1 + type: T1 + returnType: void + id: setter_0 + variable: field_0 + augmented + fields + self::@class::A::@field::foo1 + FieldMember + base: self::@augmentation::package:test/a.dart::@class::A::@field::foo2 + substitution: {T2: T1} + accessors + self::@class::A::@getter::foo1 + self::@class::A::@setter::foo1 + PropertyAccessorMember + base: self::@augmentation::package:test/a.dart::@class::A::@getter::foo2 + substitution: {T2: T1} + PropertyAccessorMember + base: self::@augmentation::package:test/a.dart::@class::A::@setter::foo2 + substitution: {T2: T1} + augmentationImports + package:test/a.dart + definingUnit + classes + augment class A @43 + typeParameters + covariant T2 @45 + defaultType: dynamic + augmentationTarget: self::@class::A + fields + foo2 @56 + type: T2 + shouldUseTypeForInitializerInference: true + id: field_1 + getter: getter_1 + setter: setter_1 + accessors + synthetic get foo2 @-1 + returnType: T2 + id: getter_1 + variable: field_1 + synthetic set foo2= @-1 + parameters + requiredPositional _foo2 @-1 + type: T2 + returnType: void + id: setter_1 + variable: field_1 +'''); + } + + test_augmented_getters_add() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment class A { + int get foo2 => 0; +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +class A { + int get foo1 => 0; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + classes + class A @31 + augmentation: self::@augmentation::package:test/a.dart::@class::A + fields + synthetic foo1 @-1 + type: int + id: field_0 + getter: getter_0 + constructors + synthetic @-1 + accessors + get foo1 @45 + returnType: int + id: getter_0 + variable: field_0 + augmented + fields + self::@class::A::@field::foo1 + self::@augmentation::package:test/a.dart::@class::A::@field::foo2 + accessors + self::@class::A::@getter::foo1 + self::@augmentation::package:test/a.dart::@class::A::@getter::foo2 + augmentationImports + package:test/a.dart + definingUnit + classes + augment class A @43 + augmentationTarget: self::@class::A + fields + synthetic foo2 @-1 + type: int + id: field_1 + getter: getter_1 + accessors + get foo2 @57 + returnType: int + id: getter_1 + variable: field_1 +'''); + } + + test_augmented_getters_add_generic() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment class A<T2> { + T2 get foo2; +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +class A<T1> { + T1 get foo1; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + classes + class A @31 + typeParameters + covariant T1 @33 + defaultType: dynamic + augmentation: self::@augmentation::package:test/a.dart::@class::A + fields + synthetic foo1 @-1 + type: T1 + id: field_0 + getter: getter_0 + constructors + synthetic @-1 + accessors + abstract get foo1 @48 + returnType: T1 + id: getter_0 + variable: field_0 + augmented + fields + self::@class::A::@field::foo1 + FieldMember + base: self::@augmentation::package:test/a.dart::@class::A::@field::foo2 + substitution: {T2: T1} + accessors + self::@class::A::@getter::foo1 + PropertyAccessorMember + base: self::@augmentation::package:test/a.dart::@class::A::@getter::foo2 + substitution: {T2: T1} + augmentationImports + package:test/a.dart + definingUnit + classes + augment class A @43 + typeParameters + covariant T2 @45 + defaultType: dynamic + augmentationTarget: self::@class::A + fields + synthetic foo2 @-1 + type: T2 + id: field_1 + getter: getter_1 + accessors + abstract get foo2 @60 + returnType: T2 + id: getter_1 + variable: field_1 +'''); + } + + test_augmented_getters_augment_field() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment class A { + augment int get foo => 0; +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +class A { + int foo = 0; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + classes + class A @31 + augmentation: self::@augmentation::package:test/a.dart::@class::A + fields + foo @41 + type: int + shouldUseTypeForInitializerInference: true + id: field_0 + getter: getter_0 + setter: setter_0 + constructors + synthetic @-1 + accessors + synthetic get foo @-1 + returnType: int + id: getter_1 + variable: field_0 + augmentation: self::@augmentation::package:test/a.dart::@class::A::@getter::foo + synthetic set foo= @-1 + parameters + requiredPositional _foo @-1 + type: int + returnType: void + id: setter_0 + variable: field_0 + augmented + fields + self::@class::A::@field::foo + accessors + self::@augmentation::package:test/a.dart::@class::A::@getter::foo + self::@class::A::@setter::foo + augmentationImports + package:test/a.dart + definingUnit + classes + augment class A @43 + augmentationTarget: self::@class::A + accessors + augment get foo @65 + returnType: int + id: getter_0 + variable: field_0 + augmentationTarget: self::@class::A::@getter::foo +'''); + } + + test_augmented_getters_augment_field2() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment class A { + augment int get foo => 0; +} +'''); + + newFile('$testPackageLibPath/b.dart', r''' +library augment 'test.dart'; +augment class A { + augment int get foo => 0; +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +import augment 'b.dart'; +class A { + int foo = 0; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + classes + class A @56 + augmentation: self::@augmentation::package:test/a.dart::@class::A + fields + foo @66 + type: int + shouldUseTypeForInitializerInference: true + id: field_0 + getter: getter_0 + setter: setter_0 + constructors + synthetic @-1 + accessors + synthetic get foo @-1 + returnType: int + id: getter_1 + variable: field_0 + augmentation: self::@augmentation::package:test/a.dart::@class::A::@getter::foo + synthetic set foo= @-1 + parameters + requiredPositional _foo @-1 + type: int + returnType: void + id: setter_0 + variable: field_0 + augmented + fields + self::@class::A::@field::foo + accessors + self::@augmentation::package:test/b.dart::@class::A::@getter::foo + self::@class::A::@setter::foo + augmentationImports + package:test/a.dart + definingUnit + classes + augment class A @43 + augmentationTarget: self::@class::A + augmentation: self::@augmentation::package:test/b.dart::@class::A + accessors + augment get foo @65 + returnType: int + id: getter_2 + variable: field_0 + augmentationTarget: self::@class::A::@getter::foo + augmentation: self::@augmentation::package:test/b.dart::@class::A::@getter::foo + package:test/b.dart + definingUnit + classes + augment class A @43 + augmentationTarget: self::@augmentation::package:test/a.dart::@class::A + accessors + augment get foo @65 + returnType: int + id: getter_0 + variable: field_0 + augmentationTarget: self::@augmentation::package:test/a.dart::@class::A::@getter::foo +'''); + } + + test_augmented_getters_augment_getter() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment class A { + augment int get foo1 => 0; +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +class A { + int get foo1 => 0; + int get foo2 => 0; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + classes + class A @31 + augmentation: self::@augmentation::package:test/a.dart::@class::A + fields + synthetic foo1 @-1 + type: int + id: field_0 + getter: getter_0 + synthetic foo2 @-1 + type: int + id: field_1 + getter: getter_1 + constructors + synthetic @-1 + accessors + get foo1 @45 + returnType: int + id: getter_2 + variable: field_0 + augmentation: self::@augmentation::package:test/a.dart::@class::A::@getter::foo1 + get foo2 @66 + returnType: int + id: getter_1 + variable: field_1 + augmented + fields + self::@class::A::@field::foo1 + self::@class::A::@field::foo2 + accessors + self::@augmentation::package:test/a.dart::@class::A::@getter::foo1 + self::@class::A::@getter::foo2 + augmentationImports + package:test/a.dart + definingUnit + classes + augment class A @43 + augmentationTarget: self::@class::A + accessors + augment get foo1 @65 + returnType: int + id: getter_0 + variable: field_0 + augmentationTarget: self::@class::A::@getter::foo1 +'''); + } + + test_augmented_getters_augment_getter2() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment class A { + augment int get foo => 0; +} +'''); + + newFile('$testPackageLibPath/b.dart', r''' +library augment 'test.dart'; +augment class A { + augment int get foo => 0; +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +import augment 'b.dart'; +class A { + int get foo => 0; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + classes + class A @56 + augmentation: self::@augmentation::package:test/a.dart::@class::A + fields + synthetic foo @-1 + type: int + id: field_0 + getter: getter_0 + constructors + synthetic @-1 + accessors + get foo @70 + returnType: int + id: getter_1 + variable: field_0 + augmentation: self::@augmentation::package:test/a.dart::@class::A::@getter::foo + augmented + fields + self::@class::A::@field::foo + accessors + self::@augmentation::package:test/b.dart::@class::A::@getter::foo + augmentationImports + package:test/a.dart + definingUnit + classes + augment class A @43 + augmentationTarget: self::@class::A + augmentation: self::@augmentation::package:test/b.dart::@class::A + accessors + augment get foo @65 + returnType: int + id: getter_2 + variable: field_0 + augmentationTarget: self::@class::A::@getter::foo + augmentation: self::@augmentation::package:test/b.dart::@class::A::@getter::foo + package:test/b.dart + definingUnit + classes + augment class A @43 + augmentationTarget: self::@augmentation::package:test/a.dart::@class::A + accessors + augment get foo @65 + returnType: int + id: getter_0 + variable: field_0 + augmentationTarget: self::@augmentation::package:test/a.dart::@class::A::@getter::foo +'''); + } + test_augmented_interfaces() async { newFile('$testPackageLibPath/a.dart', r''' library augment 'test.dart'; @@ -472,7 +1067,7 @@ augment class A @43 augmentationTarget: self::@class::A methods - foo1 @62 + augment foo1 @62 returnType: void augmentationTarget: self::@class::A::@method::foo1 '''); @@ -524,7 +1119,7 @@ augmentationTarget: self::@class::A augmentation: self::@augmentation::package:test/b.dart::@class::A methods - foo @87 + augment foo @87 returnType: void augmentationTarget: self::@class::A::@method::foo augmentation: self::@augmentation::package:test/b.dart::@class::A::@method::foo @@ -535,7 +1130,7 @@ augment class A @40 augmentationTarget: self::@augmentation::package:test/a.dart::@class::A methods - foo @59 + augment foo @59 returnType: void augmentationTarget: self::@augmentation::package:test/a.dart::@class::A::@method::foo '''); @@ -636,7 +1231,7 @@ defaultType: dynamic augmentationTarget: self::@class::A methods - foo @64 + augment foo @64 returnType: T2 augmentationTarget: self::@class::A::@method::foo '''); @@ -784,6 +1379,215 @@ '''); } + test_augmented_setters_add() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment class A { + set foo2(int _) {} +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +class A { + set foo1(int _) {} +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + classes + class A @31 + augmentation: self::@augmentation::package:test/a.dart::@class::A + fields + synthetic foo1 @-1 + type: int + id: field_0 + setter: setter_0 + constructors + synthetic @-1 + accessors + set foo1= @41 + parameters + requiredPositional _ @50 + type: int + returnType: void + id: setter_0 + variable: field_0 + augmented + fields + self::@class::A::@field::foo1 + self::@augmentation::package:test/a.dart::@class::A::@field::foo2 + accessors + self::@class::A::@setter::foo1 + self::@augmentation::package:test/a.dart::@class::A::@setter::foo2 + augmentationImports + package:test/a.dart + definingUnit + classes + augment class A @43 + augmentationTarget: self::@class::A + fields + synthetic foo2 @-1 + type: int + id: field_1 + setter: setter_1 + accessors + set foo2= @53 + parameters + requiredPositional _ @62 + type: int + returnType: void + id: setter_1 + variable: field_1 +'''); + } + + test_augmented_setters_augment_field() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment class A { + augment set foo(int _) {} +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +class A { + int foo = 0; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + classes + class A @31 + augmentation: self::@augmentation::package:test/a.dart::@class::A + fields + foo @41 + type: int + shouldUseTypeForInitializerInference: true + id: field_0 + getter: getter_0 + setter: setter_0 + constructors + synthetic @-1 + accessors + synthetic get foo @-1 + returnType: int + id: getter_0 + variable: field_0 + synthetic set foo= @-1 + parameters + requiredPositional _foo @-1 + type: int + returnType: void + id: setter_1 + variable: field_0 + augmentation: self::@augmentation::package:test/a.dart::@class::A::@setter::foo + augmented + fields + self::@class::A::@field::foo + accessors + self::@class::A::@getter::foo + self::@augmentation::package:test/a.dart::@class::A::@setter::foo + augmentationImports + package:test/a.dart + definingUnit + classes + augment class A @43 + augmentationTarget: self::@class::A + accessors + augment set foo= @61 + parameters + requiredPositional _ @69 + type: int + returnType: void + id: setter_0 + variable: field_0 + augmentationTarget: self::@class::A::@setter::foo +'''); + } + + test_augmented_setters_augment_setter() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment class A { + augment set foo1(int _) {} +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +class A { + set foo1(int _) {} + set foo2(int _) {} +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + classes + class A @31 + augmentation: self::@augmentation::package:test/a.dart::@class::A + fields + synthetic foo1 @-1 + type: int + id: field_0 + setter: setter_0 + synthetic foo2 @-1 + type: int + id: field_1 + setter: setter_1 + constructors + synthetic @-1 + accessors + set foo1= @41 + parameters + requiredPositional _ @50 + type: int + returnType: void + id: setter_2 + variable: field_0 + augmentation: self::@augmentation::package:test/a.dart::@class::A::@setter::foo1 + set foo2= @62 + parameters + requiredPositional _ @71 + type: int + returnType: void + id: setter_1 + variable: field_1 + augmented + fields + self::@class::A::@field::foo1 + self::@class::A::@field::foo2 + accessors + self::@augmentation::package:test/a.dart::@class::A::@setter::foo1 + self::@class::A::@setter::foo2 + augmentationImports + package:test/a.dart + definingUnit + classes + augment class A @43 + augmentationTarget: self::@class::A + accessors + augment set foo1= @61 + parameters + requiredPositional _ @70 + type: int + returnType: void + id: setter_0 + variable: field_0 + augmentationTarget: self::@class::A::@setter::foo1 +'''); + } + test_inferTypes_method_ofAugment() async { newFile('$testPackageLibPath/a.dart', r''' class A { @@ -951,7 +1755,7 @@ newFile('$testPackageLibPath/b.dart', r''' library augment 'test.dart'; augment class B { - foo(a) => 0; + augment foo(a) => 0; } '''); @@ -993,11 +1797,12 @@ augment class B @43 augmentationTarget: self::@class::B methods - foo @49 + augment foo @57 parameters - requiredPositional a @53 + requiredPositional a @61 type: String returnType: int + augmentationTarget: self::@class::B::@method::foo '''); } @@ -45989,6 +46794,617 @@ '''); } + test_augmented_fields_add() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment mixin A { + int foo2 = 0; +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +mixin A { + int foo1 = 0; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + mixins + mixin A @31 + augmentation: self::@augmentation::package:test/a.dart::@mixin::A + superclassConstraints + Object + fields + foo1 @41 + type: int + shouldUseTypeForInitializerInference: true + id: field_0 + getter: getter_0 + setter: setter_0 + accessors + synthetic get foo1 @-1 + returnType: int + id: getter_0 + variable: field_0 + synthetic set foo1= @-1 + parameters + requiredPositional _foo1 @-1 + type: int + returnType: void + id: setter_0 + variable: field_0 + augmented + superclassConstraints + Object + fields + self::@mixin::A::@field::foo1 + self::@augmentation::package:test/a.dart::@mixin::A::@field::foo2 + accessors + self::@mixin::A::@getter::foo1 + self::@mixin::A::@setter::foo1 + self::@augmentation::package:test/a.dart::@mixin::A::@getter::foo2 + self::@augmentation::package:test/a.dart::@mixin::A::@setter::foo2 + augmentationImports + package:test/a.dart + definingUnit + mixins + augment mixin A @43 + augmentationTarget: self::@mixin::A + fields + foo2 @53 + type: int + shouldUseTypeForInitializerInference: true + id: field_1 + getter: getter_1 + setter: setter_1 + accessors + synthetic get foo2 @-1 + returnType: int + id: getter_1 + variable: field_1 + synthetic set foo2= @-1 + parameters + requiredPositional _foo2 @-1 + type: int + returnType: void + id: setter_1 + variable: field_1 +'''); + } + + test_augmented_fields_add_generic() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment mixin A<T2> { + T2 foo2; +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +mixin A<T1> { + T1 foo1; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + mixins + mixin A @31 + typeParameters + covariant T1 @33 + defaultType: dynamic + augmentation: self::@augmentation::package:test/a.dart::@mixin::A + superclassConstraints + Object + fields + foo1 @44 + type: T1 + shouldUseTypeForInitializerInference: true + id: field_0 + getter: getter_0 + setter: setter_0 + accessors + synthetic get foo1 @-1 + returnType: T1 + id: getter_0 + variable: field_0 + synthetic set foo1= @-1 + parameters + requiredPositional _foo1 @-1 + type: T1 + returnType: void + id: setter_0 + variable: field_0 + augmented + superclassConstraints + Object + fields + self::@mixin::A::@field::foo1 + FieldMember + base: self::@augmentation::package:test/a.dart::@mixin::A::@field::foo2 + substitution: {T2: T1} + accessors + self::@mixin::A::@getter::foo1 + self::@mixin::A::@setter::foo1 + PropertyAccessorMember + base: self::@augmentation::package:test/a.dart::@mixin::A::@getter::foo2 + substitution: {T2: T1} + PropertyAccessorMember + base: self::@augmentation::package:test/a.dart::@mixin::A::@setter::foo2 + substitution: {T2: T1} + augmentationImports + package:test/a.dart + definingUnit + mixins + augment mixin A @43 + typeParameters + covariant T2 @45 + defaultType: dynamic + augmentationTarget: self::@mixin::A + fields + foo2 @56 + type: T2 + shouldUseTypeForInitializerInference: true + id: field_1 + getter: getter_1 + setter: setter_1 + accessors + synthetic get foo2 @-1 + returnType: T2 + id: getter_1 + variable: field_1 + synthetic set foo2= @-1 + parameters + requiredPositional _foo2 @-1 + type: T2 + returnType: void + id: setter_1 + variable: field_1 +'''); + } + + test_augmented_getters_add() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment mixin A { + int get foo2 => 0; +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +mixin A { + int get foo1 => 0; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + mixins + mixin A @31 + augmentation: self::@augmentation::package:test/a.dart::@mixin::A + superclassConstraints + Object + fields + synthetic foo1 @-1 + type: int + id: field_0 + getter: getter_0 + accessors + get foo1 @45 + returnType: int + id: getter_0 + variable: field_0 + augmented + superclassConstraints + Object + fields + self::@mixin::A::@field::foo1 + self::@augmentation::package:test/a.dart::@mixin::A::@field::foo2 + accessors + self::@mixin::A::@getter::foo1 + self::@augmentation::package:test/a.dart::@mixin::A::@getter::foo2 + augmentationImports + package:test/a.dart + definingUnit + mixins + augment mixin A @43 + augmentationTarget: self::@mixin::A + fields + synthetic foo2 @-1 + type: int + id: field_1 + getter: getter_1 + accessors + get foo2 @57 + returnType: int + id: getter_1 + variable: field_1 +'''); + } + + test_augmented_getters_add_generic() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment mixin A<T2> { + T2 get foo2; +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +mixin A<T1> { + T1 get foo1; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + mixins + mixin A @31 + typeParameters + covariant T1 @33 + defaultType: dynamic + augmentation: self::@augmentation::package:test/a.dart::@mixin::A + superclassConstraints + Object + fields + synthetic foo1 @-1 + type: T1 + id: field_0 + getter: getter_0 + accessors + abstract get foo1 @48 + returnType: T1 + id: getter_0 + variable: field_0 + augmented + superclassConstraints + Object + fields + self::@mixin::A::@field::foo1 + FieldMember + base: self::@augmentation::package:test/a.dart::@mixin::A::@field::foo2 + substitution: {T2: T1} + accessors + self::@mixin::A::@getter::foo1 + PropertyAccessorMember + base: self::@augmentation::package:test/a.dart::@mixin::A::@getter::foo2 + substitution: {T2: T1} + augmentationImports + package:test/a.dart + definingUnit + mixins + augment mixin A @43 + typeParameters + covariant T2 @45 + defaultType: dynamic + augmentationTarget: self::@mixin::A + fields + synthetic foo2 @-1 + type: T2 + id: field_1 + getter: getter_1 + accessors + abstract get foo2 @60 + returnType: T2 + id: getter_1 + variable: field_1 +'''); + } + + test_augmented_getters_augment_field() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment mixin A { + augment int get foo => 0; +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +mixin A { + int foo = 0; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + mixins + mixin A @31 + augmentation: self::@augmentation::package:test/a.dart::@mixin::A + superclassConstraints + Object + fields + foo @41 + type: int + shouldUseTypeForInitializerInference: true + id: field_0 + getter: getter_0 + setter: setter_0 + accessors + synthetic get foo @-1 + returnType: int + id: getter_1 + variable: field_0 + augmentation: self::@augmentation::package:test/a.dart::@mixin::A::@getter::foo + synthetic set foo= @-1 + parameters + requiredPositional _foo @-1 + type: int + returnType: void + id: setter_0 + variable: field_0 + augmented + superclassConstraints + Object + fields + self::@mixin::A::@field::foo + accessors + self::@augmentation::package:test/a.dart::@mixin::A::@getter::foo + self::@mixin::A::@setter::foo + augmentationImports + package:test/a.dart + definingUnit + mixins + augment mixin A @43 + augmentationTarget: self::@mixin::A + accessors + augment get foo @65 + returnType: int + id: getter_0 + variable: field_0 + augmentationTarget: self::@mixin::A::@getter::foo +'''); + } + + test_augmented_getters_augment_field2() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment mixin A { + augment int get foo => 0; +} +'''); + + newFile('$testPackageLibPath/b.dart', r''' +library augment 'test.dart'; +augment mixin A { + augment int get foo => 0; +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +import augment 'b.dart'; +mixin A { + int foo = 0; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + mixins + mixin A @56 + augmentation: self::@augmentation::package:test/a.dart::@mixin::A + superclassConstraints + Object + fields + foo @66 + type: int + shouldUseTypeForInitializerInference: true + id: field_0 + getter: getter_0 + setter: setter_0 + accessors + synthetic get foo @-1 + returnType: int + id: getter_1 + variable: field_0 + augmentation: self::@augmentation::package:test/a.dart::@mixin::A::@getter::foo + synthetic set foo= @-1 + parameters + requiredPositional _foo @-1 + type: int + returnType: void + id: setter_0 + variable: field_0 + augmented + superclassConstraints + Object + fields + self::@mixin::A::@field::foo + accessors + self::@augmentation::package:test/b.dart::@mixin::A::@getter::foo + self::@mixin::A::@setter::foo + augmentationImports + package:test/a.dart + definingUnit + mixins + augment mixin A @43 + augmentationTarget: self::@mixin::A + augmentation: self::@augmentation::package:test/b.dart::@mixin::A + accessors + augment get foo @65 + returnType: int + id: getter_2 + variable: field_0 + augmentationTarget: self::@mixin::A::@getter::foo + augmentation: self::@augmentation::package:test/b.dart::@mixin::A::@getter::foo + package:test/b.dart + definingUnit + mixins + augment mixin A @43 + augmentationTarget: self::@augmentation::package:test/a.dart::@mixin::A + accessors + augment get foo @65 + returnType: int + id: getter_0 + variable: field_0 + augmentationTarget: self::@augmentation::package:test/a.dart::@mixin::A::@getter::foo +'''); + } + + test_augmented_getters_augment_getter() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment mixin A { + augment int get foo1 => 0; +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +mixin A { + int get foo1 => 0; + int get foo2 => 0; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + mixins + mixin A @31 + augmentation: self::@augmentation::package:test/a.dart::@mixin::A + superclassConstraints + Object + fields + synthetic foo1 @-1 + type: int + id: field_0 + getter: getter_0 + synthetic foo2 @-1 + type: int + id: field_1 + getter: getter_1 + accessors + get foo1 @45 + returnType: int + id: getter_2 + variable: field_0 + augmentation: self::@augmentation::package:test/a.dart::@mixin::A::@getter::foo1 + get foo2 @66 + returnType: int + id: getter_1 + variable: field_1 + augmented + superclassConstraints + Object + fields + self::@mixin::A::@field::foo1 + self::@mixin::A::@field::foo2 + accessors + self::@augmentation::package:test/a.dart::@mixin::A::@getter::foo1 + self::@mixin::A::@getter::foo2 + augmentationImports + package:test/a.dart + definingUnit + mixins + augment mixin A @43 + augmentationTarget: self::@mixin::A + accessors + augment get foo1 @65 + returnType: int + id: getter_0 + variable: field_0 + augmentationTarget: self::@mixin::A::@getter::foo1 +'''); + } + + test_augmented_getters_augment_getter2() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment mixin A { + augment int get foo => 0; +} +'''); + + newFile('$testPackageLibPath/b.dart', r''' +library augment 'test.dart'; +augment mixin A { + augment int get foo => 0; +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +import augment 'b.dart'; +mixin A { + int get foo => 0; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + mixins + mixin A @56 + augmentation: self::@augmentation::package:test/a.dart::@mixin::A + superclassConstraints + Object + fields + synthetic foo @-1 + type: int + id: field_0 + getter: getter_0 + accessors + get foo @70 + returnType: int + id: getter_1 + variable: field_0 + augmentation: self::@augmentation::package:test/a.dart::@mixin::A::@getter::foo + augmented + superclassConstraints + Object + fields + self::@mixin::A::@field::foo + accessors + self::@augmentation::package:test/b.dart::@mixin::A::@getter::foo + augmentationImports + package:test/a.dart + definingUnit + mixins + augment mixin A @43 + augmentationTarget: self::@mixin::A + augmentation: self::@augmentation::package:test/b.dart::@mixin::A + accessors + augment get foo @65 + returnType: int + id: getter_2 + variable: field_0 + augmentationTarget: self::@mixin::A::@getter::foo + augmentation: self::@augmentation::package:test/b.dart::@mixin::A::@getter::foo + package:test/b.dart + definingUnit + mixins + augment mixin A @43 + augmentationTarget: self::@augmentation::package:test/a.dart::@mixin::A + accessors + augment get foo @65 + returnType: int + id: getter_0 + variable: field_0 + augmentationTarget: self::@augmentation::package:test/a.dart::@mixin::A::@getter::foo +'''); + } + test_augmented_interfaces() async { newFile('$testPackageLibPath/a.dart', r''' library augment 'test.dart'; @@ -46193,7 +47609,7 @@ augment mixin A @43 augmentationTarget: self::@mixin::A methods - foo1 @62 + augment foo1 @62 returnType: void augmentationTarget: self::@mixin::A::@method::foo1 '''); @@ -46247,7 +47663,7 @@ augmentationTarget: self::@mixin::A augmentation: self::@augmentation::package:test/b.dart::@mixin::A methods - foo @87 + augment foo @87 returnType: void augmentationTarget: self::@mixin::A::@method::foo augmentation: self::@augmentation::package:test/b.dart::@mixin::A::@method::foo @@ -46258,7 +47674,7 @@ augment mixin A @40 augmentationTarget: self::@augmentation::package:test/a.dart::@mixin::A methods - foo @59 + augment foo @59 returnType: void augmentationTarget: self::@augmentation::package:test/a.dart::@mixin::A::@method::foo '''); @@ -46363,12 +47779,227 @@ defaultType: dynamic augmentationTarget: self::@mixin::A methods - foo @64 + augment foo @64 returnType: T2 augmentationTarget: self::@mixin::A::@method::foo '''); } + test_augmented_setters_add() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment mixin A { + set foo2(int _) {} +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +mixin A { + set foo1(int _) {} +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + mixins + mixin A @31 + augmentation: self::@augmentation::package:test/a.dart::@mixin::A + superclassConstraints + Object + fields + synthetic foo1 @-1 + type: int + id: field_0 + setter: setter_0 + accessors + set foo1= @41 + parameters + requiredPositional _ @50 + type: int + returnType: void + id: setter_0 + variable: field_0 + augmented + superclassConstraints + Object + fields + self::@mixin::A::@field::foo1 + self::@augmentation::package:test/a.dart::@mixin::A::@field::foo2 + accessors + self::@mixin::A::@setter::foo1 + self::@augmentation::package:test/a.dart::@mixin::A::@setter::foo2 + augmentationImports + package:test/a.dart + definingUnit + mixins + augment mixin A @43 + augmentationTarget: self::@mixin::A + fields + synthetic foo2 @-1 + type: int + id: field_1 + setter: setter_1 + accessors + set foo2= @53 + parameters + requiredPositional _ @62 + type: int + returnType: void + id: setter_1 + variable: field_1 +'''); + } + + test_augmented_setters_augment_field() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment mixin A { + augment set foo(int _) {} +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +mixin A { + int foo = 0; +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + mixins + mixin A @31 + augmentation: self::@augmentation::package:test/a.dart::@mixin::A + superclassConstraints + Object + fields + foo @41 + type: int + shouldUseTypeForInitializerInference: true + id: field_0 + getter: getter_0 + setter: setter_0 + accessors + synthetic get foo @-1 + returnType: int + id: getter_0 + variable: field_0 + synthetic set foo= @-1 + parameters + requiredPositional _foo @-1 + type: int + returnType: void + id: setter_1 + variable: field_0 + augmentation: self::@augmentation::package:test/a.dart::@mixin::A::@setter::foo + augmented + superclassConstraints + Object + fields + self::@mixin::A::@field::foo + accessors + self::@mixin::A::@getter::foo + self::@augmentation::package:test/a.dart::@mixin::A::@setter::foo + augmentationImports + package:test/a.dart + definingUnit + mixins + augment mixin A @43 + augmentationTarget: self::@mixin::A + accessors + augment set foo= @61 + parameters + requiredPositional _ @69 + type: int + returnType: void + id: setter_0 + variable: field_0 + augmentationTarget: self::@mixin::A::@setter::foo +'''); + } + + test_augmented_setters_augment_setter() async { + newFile('$testPackageLibPath/a.dart', r''' +library augment 'test.dart'; +augment mixin A { + augment set foo1(int _) {} +} +'''); + + var library = await buildLibrary(r''' +import augment 'a.dart'; +mixin A { + set foo1(int _) {} + set foo2(int _) {} +} +'''); + + configuration.withPropertyLinking = true; + checkElementText(library, r''' +library + definingUnit + mixins + mixin A @31 + augmentation: self::@augmentation::package:test/a.dart::@mixin::A + superclassConstraints + Object + fields + synthetic foo1 @-1 + type: int + id: field_0 + setter: setter_0 + synthetic foo2 @-1 + type: int + id: field_1 + setter: setter_1 + accessors + set foo1= @41 + parameters + requiredPositional _ @50 + type: int + returnType: void + id: setter_2 + variable: field_0 + augmentation: self::@augmentation::package:test/a.dart::@mixin::A::@setter::foo1 + set foo2= @62 + parameters + requiredPositional _ @71 + type: int + returnType: void + id: setter_1 + variable: field_1 + augmented + superclassConstraints + Object + fields + self::@mixin::A::@field::foo1 + self::@mixin::A::@field::foo2 + accessors + self::@augmentation::package:test/a.dart::@mixin::A::@setter::foo1 + self::@mixin::A::@setter::foo2 + augmentationImports + package:test/a.dart + definingUnit + mixins + augment mixin A @43 + augmentationTarget: self::@mixin::A + accessors + augment set foo1= @61 + parameters + requiredPositional _ @70 + type: int + returnType: void + id: setter_0 + variable: field_0 + augmentationTarget: self::@mixin::A::@setter::foo1 +'''); + } + test_augmented_superclassConstraints() async { newFile('$testPackageLibPath/a.dart', r''' library augment 'test.dart'; @@ -46701,7 +48332,7 @@ newFile('$testPackageLibPath/b.dart', r''' library augment 'test.dart'; augment mixin B { - foo(a) => 0; + augment foo(a) => 0; } '''); @@ -46743,11 +48374,12 @@ augment mixin B @43 augmentationTarget: self::@mixin::B methods - foo @49 + augment foo @57 parameters - requiredPositional a @53 + requiredPositional a @61 type: String returnType: int + augmentationTarget: self::@mixin::B::@method::foo '''); }