mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
Link augmented methods and augmentations, fill 'augmented.methods'
Change-Id: Ic7e979c46fc646e436bafa18b5c5b01622ab209b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313544 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
parent
7918525a6b
commit
d1a75901c4
|
@ -87,7 +87,7 @@ import 'package:analyzer/src/utilities/uri_cache.dart';
|
|||
/// 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 = 285;
|
||||
static const int DATA_VERSION = 288;
|
||||
|
||||
/// The number of exception contexts allowed to write. Once this field is
|
||||
/// zero, we stop writing any new exception contexts in this process.
|
||||
|
|
|
@ -1683,6 +1683,13 @@ class MethodElementLinkedData extends ElementLinkedData<MethodElementImpl> {
|
|||
_readTypeParameters(reader, element.typeParameters);
|
||||
_readFormalParameters(reader, element.parameters);
|
||||
element.returnType = reader.readRequiredType();
|
||||
element.augmentation = reader.readElement() as MethodElementImpl?;
|
||||
if (reader.readBool()) {
|
||||
final target = reader.readElement() as MethodElementImpl?;
|
||||
element.maybeAugmentation = AugmentationMethodElementImpl(
|
||||
augmentationTarget: target,
|
||||
);
|
||||
}
|
||||
applyConstantOffsets?.perform();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -432,6 +432,13 @@ class BundleWriter {
|
|||
_writeList(element.parameters, _writeParameterElement);
|
||||
_sink._writeTopLevelInferenceError(element.typeInferenceError);
|
||||
_resolutionSink.writeType(element.returnType2);
|
||||
_resolutionSink.writeElement(element.augmentation);
|
||||
_resolutionSink.writeIfType<AugmentationMethodElementImpl>(
|
||||
element.maybeAugmentation,
|
||||
(maybe) {
|
||||
_resolutionSink.writeElement(maybe.augmentationTarget);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -109,15 +109,8 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
|
|||
node.declaredElement = element;
|
||||
_linker.elementNodes[element] = node;
|
||||
|
||||
switch (_libraryBuilder.getAugmentationTarget(name)) {
|
||||
case ClassOrAugmentationElementMixin target:
|
||||
element.augmentationTarget = target;
|
||||
target.augmentation = element;
|
||||
}
|
||||
|
||||
final reference = _enclosingContext.addClassAugmentation(name, element);
|
||||
_libraryBuilder.declare(name, reference);
|
||||
_libraryBuilder.putAugmentationTarget(name, element);
|
||||
|
||||
final holder = _EnclosingContext(reference, element);
|
||||
_withEnclosing(holder, () {
|
||||
|
@ -140,6 +133,11 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
|
|||
element.fields = holder.fields;
|
||||
element.methods = holder.methods;
|
||||
|
||||
switch (_libraryBuilder.getAugmentedBuilder(name)) {
|
||||
case AugmentedClassDeclarationBuilder builder:
|
||||
builder.augment(element);
|
||||
}
|
||||
|
||||
// TODO(scheglov) We cannot do this anymore.
|
||||
// Not for class augmentations, not for classes.
|
||||
// At the time when we build, we don't know all fields yet.
|
||||
|
@ -172,7 +170,6 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
|
|||
|
||||
var reference = _enclosingContext.addClass(name, element);
|
||||
_libraryBuilder.declare(name, reference);
|
||||
_libraryBuilder.putAugmentationTarget(name, element);
|
||||
|
||||
var holder = _EnclosingContext(reference, element);
|
||||
_withEnclosing(holder, () {
|
||||
|
@ -187,6 +184,13 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
|
|||
node.withClause?.accept(this);
|
||||
node.implementsClause?.accept(this);
|
||||
_buildClass(node);
|
||||
|
||||
_libraryBuilder.putAugmentedBuilder(
|
||||
name,
|
||||
AugmentedClassDeclarationBuilder(
|
||||
declaration: element,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -936,15 +940,8 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
|
|||
node.declaredElement = element;
|
||||
_linker.elementNodes[element] = node;
|
||||
|
||||
switch (_libraryBuilder.getAugmentationTarget(name)) {
|
||||
case MixinOrAugmentationElementMixin target:
|
||||
element.augmentationTarget = target;
|
||||
target.augmentation = element;
|
||||
}
|
||||
|
||||
final reference = _enclosingContext.addMixinAugmentation(name, element);
|
||||
_libraryBuilder.declare(name, reference);
|
||||
_libraryBuilder.putAugmentationTarget(name, element);
|
||||
|
||||
final holder = _EnclosingContext(reference, element);
|
||||
_withEnclosing(holder, () {
|
||||
|
@ -965,6 +962,11 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
|
|||
element.accessors = holder.propertyAccessors;
|
||||
element.fields = holder.fields;
|
||||
element.methods = holder.methods;
|
||||
|
||||
switch (_libraryBuilder.getAugmentedBuilder(name)) {
|
||||
case AugmentedMixinDeclarationBuilder builder:
|
||||
builder.augment(element);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -983,7 +985,6 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
|
|||
|
||||
var reference = _enclosingContext.addMixin(name, element);
|
||||
_libraryBuilder.declare(name, reference);
|
||||
_libraryBuilder.putAugmentationTarget(name, element);
|
||||
|
||||
var holder = _EnclosingContext(reference, element);
|
||||
_withEnclosing(holder, () {
|
||||
|
@ -997,6 +998,13 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
|
|||
node.onClause?.accept(this);
|
||||
node.implementsClause?.accept(this);
|
||||
_buildMixin(node);
|
||||
|
||||
_libraryBuilder.putAugmentedBuilder(
|
||||
name,
|
||||
AugmentedMixinDeclarationBuilder(
|
||||
declaration: element,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -29,6 +29,62 @@ import 'package:analyzer/src/summary2/types_builder.dart';
|
|||
import 'package:analyzer/src/util/performance/operation_performance.dart';
|
||||
import 'package:analyzer/src/utilities/extensions/collection.dart';
|
||||
|
||||
class AugmentedClassDeclarationBuilder
|
||||
extends AugmentedInstanceDeclarationBuilder {
|
||||
final ClassElementImpl declaration;
|
||||
ClassOrAugmentationElementMixin target;
|
||||
|
||||
AugmentedClassDeclarationBuilder({
|
||||
required this.declaration,
|
||||
}) : target = declaration {
|
||||
addMethods(declaration.methods);
|
||||
}
|
||||
|
||||
void augment(ClassAugmentationElementImpl element) {
|
||||
element.augmentationTarget = target;
|
||||
target.augmentation = element;
|
||||
target = element;
|
||||
addMethods(element.methods);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AugmentedInstanceDeclarationBuilder {
|
||||
final Map<String, MethodElementImpl> methods = {};
|
||||
|
||||
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.maybeAugmentation = AugmentationMethodElementImpl(
|
||||
augmentationTarget: existing,
|
||||
);
|
||||
}
|
||||
methods[name] = element;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AugmentedMixinDeclarationBuilder
|
||||
extends AugmentedInstanceDeclarationBuilder {
|
||||
final MixinElementImpl declaration;
|
||||
MixinOrAugmentationElementMixin target;
|
||||
|
||||
AugmentedMixinDeclarationBuilder({
|
||||
required this.declaration,
|
||||
}) : target = declaration {
|
||||
addMethods(declaration.methods);
|
||||
}
|
||||
|
||||
void augment(MixinAugmentationElementImpl element) {
|
||||
element.augmentationTarget = target;
|
||||
target.augmentation = element;
|
||||
target = element;
|
||||
addMethods(element.methods);
|
||||
}
|
||||
}
|
||||
|
||||
class DefiningLinkingUnit extends LinkingUnit {
|
||||
DefiningLinkingUnit({
|
||||
required super.reference,
|
||||
|
@ -61,7 +117,8 @@ class LibraryBuilder {
|
|||
final List<ImplicitEnumNodes> implicitEnumNodes = [];
|
||||
|
||||
/// The top-level elements that can be augmented.
|
||||
final Map<String, ElementImpl> _augmentationTargets = {};
|
||||
final Map<String, AugmentedInstanceDeclarationBuilder> _augmentedBuilders =
|
||||
{};
|
||||
|
||||
/// Local declarations.
|
||||
final Map<String, Reference> _declaredReferences = {};
|
||||
|
@ -406,12 +463,15 @@ class LibraryBuilder {
|
|||
);
|
||||
}
|
||||
|
||||
ElementImpl? getAugmentationTarget(String name) {
|
||||
return _augmentationTargets[name];
|
||||
AugmentedInstanceDeclarationBuilder? getAugmentedBuilder(String name) {
|
||||
return _augmentedBuilders[name];
|
||||
}
|
||||
|
||||
void putAugmentationTarget(String name, ElementImpl element) {
|
||||
_augmentationTargets[name] = element;
|
||||
void putAugmentedBuilder(
|
||||
String name,
|
||||
AugmentedInstanceDeclarationBuilder element,
|
||||
) {
|
||||
_augmentedBuilders[name] = element;
|
||||
}
|
||||
|
||||
void resolveConstructors() {
|
||||
|
|
|
@ -162,7 +162,7 @@ class TypesBuilder {
|
|||
element.augmentedInternal = augmented;
|
||||
augmented.mixins.addAll(element.mixins);
|
||||
augmented.interfaces.addAll(element.interfaces);
|
||||
augmented.methods.addAll(element.methods);
|
||||
augmented.methods.addAll(element.methods.notAugmented);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -359,7 +359,7 @@ class TypesBuilder {
|
|||
element.augmentedInternal = augmented;
|
||||
augmented.superclassConstraints.addAll(element.superclassConstraints);
|
||||
augmented.interfaces.addAll(element.interfaces);
|
||||
augmented.methods.addAll(element.methods);
|
||||
augmented.methods.addAll(element.methods.notAugmented);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -453,7 +453,7 @@ class TypesBuilder {
|
|||
}
|
||||
|
||||
augmented.methods.addAll(
|
||||
element.methods.map(mapMethodElement),
|
||||
element.methods.notAugmented.map(mapMethodElement),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -705,3 +705,9 @@ class _MixinsInference {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension on List<MethodElement> {
|
||||
Iterable<MethodElement> get notAugmented {
|
||||
return where((e) => e.augmentation == null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -210,14 +210,8 @@ class _ElementWriter {
|
|||
final augmented = e.augmented;
|
||||
|
||||
void writeMethods() {
|
||||
_writeElements('methods', augmented.methods, (element) {
|
||||
if (element.enclosingElement2 == e) {
|
||||
_writeMethodElement(element);
|
||||
} else {
|
||||
_sink.writeIndent();
|
||||
_elementPrinter.writeElement(element);
|
||||
}
|
||||
});
|
||||
final sorted = augmented.methods.sortedBy((e) => e.name);
|
||||
_elementPrinter.writeElementList('methods', sorted);
|
||||
}
|
||||
|
||||
_sink.writelnWithIndent('augmented');
|
||||
|
@ -715,6 +709,22 @@ class _ElementWriter {
|
|||
_writeParameterElements(e.parameters);
|
||||
_writeType('returnType', e.returnType2);
|
||||
_writeNonSyntheticElement(e);
|
||||
|
||||
final maybeAugmentation = e.maybeAugmentation;
|
||||
if (maybeAugmentation != null) {
|
||||
_sink.writelnWithIndent('maybeAugmentation');
|
||||
_sink.withIndent(() {
|
||||
_elementPrinter.writeNamedElement(
|
||||
'augmentationTarget',
|
||||
maybeAugmentation.augmentationTarget,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
final augmentation = e.augmentation;
|
||||
if (augmentation != null) {
|
||||
_elementPrinter.writeNamedElement('augmentation', augmentation);
|
||||
}
|
||||
});
|
||||
|
||||
if (e.isSynthetic && e.enclosingElement2 is EnumElementImpl) {
|
||||
|
|
|
@ -19,11 +19,29 @@ import 'elements_base.dart';
|
|||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(ElementsKeepLinkingTest);
|
||||
defineReflectiveTests(ClassAugmentationElementsKeepLinkingTest);
|
||||
defineReflectiveTests(MixinAugmentationElementsKeepLinkingTest);
|
||||
defineReflectiveTests(ElementsFromBytesTest);
|
||||
defineReflectiveTests(ClassAugmentationElementsFromBytesTest);
|
||||
defineReflectiveTests(MixinAugmentationElementsFromBytesTest3);
|
||||
defineReflectiveTests(UpdateNodeTextExpectations);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ClassAugmentationElementsFromBytesTest extends ElementsBaseTest
|
||||
with ClassAugmentationElementsMixin {
|
||||
@override
|
||||
bool get keepLinkingLibraries => false;
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ClassAugmentationElementsKeepLinkingTest extends ElementsBaseTest
|
||||
with ClassAugmentationElementsMixin {
|
||||
@override
|
||||
bool get keepLinkingLibraries => true;
|
||||
}
|
||||
|
||||
mixin ClassAugmentationElementsMixin on ElementsBaseTest {
|
||||
test_augmentationTarget() async {
|
||||
newFile('$testPackageLibPath/a1.dart', r'''
|
||||
|
@ -375,9 +393,8 @@ library
|
|||
returnType: void
|
||||
augmented
|
||||
methods
|
||||
foo @42
|
||||
returnType: void
|
||||
self::@augmentation::package:test/a.dart::@classAugmentation::A::@method::bar
|
||||
self::@class::A::@method::foo
|
||||
augmentationImports
|
||||
package:test/a.dart
|
||||
definingUnit
|
||||
|
@ -391,6 +408,122 @@ library
|
|||
''');
|
||||
}
|
||||
|
||||
test_augmented_methods_augment() async {
|
||||
newFile('$testPackageLibPath/a.dart', r'''
|
||||
library augment 'test.dart';
|
||||
augment class A {
|
||||
augment void foo1() {}
|
||||
}
|
||||
''');
|
||||
|
||||
var library = await buildLibrary(r'''
|
||||
import augment 'a.dart';
|
||||
class A {
|
||||
void foo1() {}
|
||||
void foo2() {}
|
||||
}
|
||||
''');
|
||||
|
||||
checkElementText(library, r'''
|
||||
library
|
||||
definingUnit
|
||||
classes
|
||||
class A @31
|
||||
augmentation: self::@augmentation::package:test/a.dart::@classAugmentation::A
|
||||
constructors
|
||||
synthetic @-1
|
||||
methods
|
||||
foo1 @42
|
||||
returnType: void
|
||||
augmentation: self::@augmentation::package:test/a.dart::@classAugmentation::A::@method::foo1
|
||||
foo2 @59
|
||||
returnType: void
|
||||
augmented
|
||||
methods
|
||||
self::@augmentation::package:test/a.dart::@classAugmentation::A::@method::foo1
|
||||
self::@class::A::@method::foo2
|
||||
augmentationImports
|
||||
package:test/a.dart
|
||||
definingUnit
|
||||
classAugmentations
|
||||
augment class A @43
|
||||
augmentationTarget: self::@class::A
|
||||
augmentedDeclaration: self::@class::A
|
||||
methods
|
||||
foo1 @62
|
||||
returnType: void
|
||||
maybeAugmentation
|
||||
augmentationTarget: self::@class::A::@method::foo1
|
||||
''');
|
||||
}
|
||||
|
||||
test_augmented_methods_augment2() async {
|
||||
newFile('$testPackageLibPath/a.dart', r'''
|
||||
library augment 'test.dart';
|
||||
import augment 'b.dart';
|
||||
augment class A {
|
||||
augment void foo() {}
|
||||
}
|
||||
''');
|
||||
|
||||
newFile('$testPackageLibPath/b.dart', r'''
|
||||
library augment 'a.dart';
|
||||
augment class A {
|
||||
augment void foo() {}
|
||||
}
|
||||
''');
|
||||
|
||||
var library = await buildLibrary(r'''
|
||||
import augment 'a.dart';
|
||||
class A {
|
||||
void foo() {}
|
||||
}
|
||||
''');
|
||||
|
||||
checkElementText(library, r'''
|
||||
library
|
||||
definingUnit
|
||||
classes
|
||||
class A @31
|
||||
augmentation: self::@augmentation::package:test/a.dart::@classAugmentation::A
|
||||
constructors
|
||||
synthetic @-1
|
||||
methods
|
||||
foo @42
|
||||
returnType: void
|
||||
augmentation: self::@augmentation::package:test/a.dart::@classAugmentation::A::@method::foo
|
||||
augmented
|
||||
methods
|
||||
self::@augmentation::package:test/b.dart::@classAugmentation::A::@method::foo
|
||||
augmentationImports
|
||||
package:test/a.dart
|
||||
definingUnit
|
||||
classAugmentations
|
||||
augment class A @68
|
||||
augmentationTarget: self::@class::A
|
||||
augmentedDeclaration: self::@class::A
|
||||
augmentation: self::@augmentation::package:test/b.dart::@classAugmentation::A
|
||||
methods
|
||||
foo @87
|
||||
returnType: void
|
||||
maybeAugmentation
|
||||
augmentationTarget: self::@class::A::@method::foo
|
||||
augmentation: self::@augmentation::package:test/b.dart::@classAugmentation::A::@method::foo
|
||||
augmentationImports
|
||||
package:test/b.dart
|
||||
definingUnit
|
||||
classAugmentations
|
||||
augment class A @40
|
||||
augmentationTarget: self::@augmentation::package:test/a.dart::@classAugmentation::A
|
||||
augmentedDeclaration: self::@class::A
|
||||
methods
|
||||
foo @59
|
||||
returnType: void
|
||||
maybeAugmentation
|
||||
augmentationTarget: self::@augmentation::package:test/a.dart::@classAugmentation::A::@method::foo
|
||||
''');
|
||||
}
|
||||
|
||||
test_augmented_methods_generic() async {
|
||||
newFile('$testPackageLibPath/a.dart', r'''
|
||||
library augment 'test.dart';
|
||||
|
@ -422,11 +555,10 @@ library
|
|||
returnType: T
|
||||
augmented
|
||||
methods
|
||||
foo @42
|
||||
returnType: T
|
||||
MethodMember
|
||||
base: self::@augmentation::package:test/a.dart::@classAugmentation::A::@method::bar
|
||||
substitution: {T2: T}
|
||||
self::@class::A::@method::foo
|
||||
augmentationImports
|
||||
package:test/a.dart
|
||||
definingUnit
|
||||
|
@ -443,6 +575,59 @@ library
|
|||
''');
|
||||
}
|
||||
|
||||
test_augmented_methods_generic_augment() async {
|
||||
newFile('$testPackageLibPath/a.dart', r'''
|
||||
library augment 'test.dart';
|
||||
augment class A<T2> {
|
||||
augment T2 foo() => throw 0;
|
||||
}
|
||||
''');
|
||||
|
||||
var library = await buildLibrary(r'''
|
||||
import augment 'a.dart';
|
||||
class A<T> {
|
||||
T foo() => throw 0;
|
||||
}
|
||||
''');
|
||||
|
||||
checkElementText(library, r'''
|
||||
library
|
||||
definingUnit
|
||||
classes
|
||||
class A @31
|
||||
typeParameters
|
||||
covariant T @33
|
||||
defaultType: dynamic
|
||||
augmentation: self::@augmentation::package:test/a.dart::@classAugmentation::A
|
||||
constructors
|
||||
synthetic @-1
|
||||
methods
|
||||
foo @42
|
||||
returnType: T
|
||||
augmentation: self::@augmentation::package:test/a.dart::@classAugmentation::A::@method::foo
|
||||
augmented
|
||||
methods
|
||||
MethodMember
|
||||
base: self::@augmentation::package:test/a.dart::@classAugmentation::A::@method::foo
|
||||
substitution: {T2: T}
|
||||
augmentationImports
|
||||
package:test/a.dart
|
||||
definingUnit
|
||||
classAugmentations
|
||||
augment class A @43
|
||||
typeParameters
|
||||
covariant T2 @45
|
||||
defaultType: dynamic
|
||||
augmentationTarget: self::@class::A
|
||||
augmentedDeclaration: self::@class::A
|
||||
methods
|
||||
foo @64
|
||||
returnType: T2
|
||||
maybeAugmentation
|
||||
augmentationTarget: self::@class::A::@method::foo
|
||||
''');
|
||||
}
|
||||
|
||||
test_augmented_mixins() async {
|
||||
newFile('$testPackageLibPath/a.dart', r'''
|
||||
library augment 'test.dart';
|
||||
|
@ -838,15 +1023,13 @@ library
|
|||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ElementsFromBytesTest extends ElementsTest
|
||||
with ClassAugmentationElementsMixin, MixinAugmentationElementsMixin {
|
||||
class ElementsFromBytesTest extends ElementsTest {
|
||||
@override
|
||||
bool get keepLinkingLibraries => false;
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ElementsKeepLinkingTest extends ElementsTest
|
||||
with ClassAugmentationElementsMixin, MixinAugmentationElementsMixin {
|
||||
class ElementsKeepLinkingTest extends ElementsTest {
|
||||
@override
|
||||
bool get keepLinkingLibraries => true;
|
||||
}
|
||||
|
@ -45391,6 +45574,20 @@ library
|
|||
}
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class MixinAugmentationElementsFromBytesTest3 extends ElementsBaseTest
|
||||
with MixinAugmentationElementsMixin {
|
||||
@override
|
||||
bool get keepLinkingLibraries => false;
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class MixinAugmentationElementsKeepLinkingTest extends ElementsBaseTest
|
||||
with MixinAugmentationElementsMixin {
|
||||
@override
|
||||
bool get keepLinkingLibraries => true;
|
||||
}
|
||||
|
||||
mixin MixinAugmentationElementsMixin on ElementsBaseTest {
|
||||
test_augmentationTarget() async {
|
||||
newFile('$testPackageLibPath/a.dart', r'''
|
||||
|
@ -45588,9 +45785,8 @@ library
|
|||
superclassConstraints
|
||||
Object
|
||||
methods
|
||||
foo @42
|
||||
returnType: void
|
||||
self::@augmentation::package:test/a.dart::@mixinAugmentation::A::@method::bar
|
||||
self::@mixin::A::@method::foo
|
||||
augmentationImports
|
||||
package:test/a.dart
|
||||
definingUnit
|
||||
|
@ -45604,6 +45800,126 @@ library
|
|||
''');
|
||||
}
|
||||
|
||||
test_augmented_methods_augment() async {
|
||||
newFile('$testPackageLibPath/a.dart', r'''
|
||||
library augment 'test.dart';
|
||||
augment mixin A {
|
||||
augment void foo1() {}
|
||||
}
|
||||
''');
|
||||
|
||||
var library = await buildLibrary(r'''
|
||||
import augment 'a.dart';
|
||||
mixin A {
|
||||
void foo1() {}
|
||||
void foo2() {}
|
||||
}
|
||||
''');
|
||||
|
||||
checkElementText(library, r'''
|
||||
library
|
||||
definingUnit
|
||||
mixins
|
||||
mixin A @31
|
||||
augmentation: self::@augmentation::package:test/a.dart::@mixinAugmentation::A
|
||||
superclassConstraints
|
||||
Object
|
||||
methods
|
||||
foo1 @42
|
||||
returnType: void
|
||||
augmentation: self::@augmentation::package:test/a.dart::@mixinAugmentation::A::@method::foo1
|
||||
foo2 @59
|
||||
returnType: void
|
||||
augmented
|
||||
superclassConstraints
|
||||
Object
|
||||
methods
|
||||
self::@augmentation::package:test/a.dart::@mixinAugmentation::A::@method::foo1
|
||||
self::@mixin::A::@method::foo2
|
||||
augmentationImports
|
||||
package:test/a.dart
|
||||
definingUnit
|
||||
mixinAugmentations
|
||||
augment mixin A @43
|
||||
augmentationTarget: self::@mixin::A
|
||||
augmentedDeclaration: self::@mixin::A
|
||||
methods
|
||||
foo1 @62
|
||||
returnType: void
|
||||
maybeAugmentation
|
||||
augmentationTarget: self::@mixin::A::@method::foo1
|
||||
''');
|
||||
}
|
||||
|
||||
test_augmented_methods_augment2() async {
|
||||
newFile('$testPackageLibPath/a.dart', r'''
|
||||
library augment 'test.dart';
|
||||
import augment 'b.dart';
|
||||
augment mixin A {
|
||||
augment void foo() {}
|
||||
}
|
||||
''');
|
||||
|
||||
newFile('$testPackageLibPath/b.dart', r'''
|
||||
library augment 'a.dart';
|
||||
augment mixin A {
|
||||
augment void foo() {}
|
||||
}
|
||||
''');
|
||||
|
||||
var library = await buildLibrary(r'''
|
||||
import augment 'a.dart';
|
||||
mixin A {
|
||||
void foo() {}
|
||||
}
|
||||
''');
|
||||
|
||||
checkElementText(library, r'''
|
||||
library
|
||||
definingUnit
|
||||
mixins
|
||||
mixin A @31
|
||||
augmentation: self::@augmentation::package:test/a.dart::@mixinAugmentation::A
|
||||
superclassConstraints
|
||||
Object
|
||||
methods
|
||||
foo @42
|
||||
returnType: void
|
||||
augmentation: self::@augmentation::package:test/a.dart::@mixinAugmentation::A::@method::foo
|
||||
augmented
|
||||
superclassConstraints
|
||||
Object
|
||||
methods
|
||||
self::@augmentation::package:test/b.dart::@mixinAugmentation::A::@method::foo
|
||||
augmentationImports
|
||||
package:test/a.dart
|
||||
definingUnit
|
||||
mixinAugmentations
|
||||
augment mixin A @68
|
||||
augmentationTarget: self::@mixin::A
|
||||
augmentedDeclaration: self::@mixin::A
|
||||
augmentation: self::@augmentation::package:test/b.dart::@mixinAugmentation::A
|
||||
methods
|
||||
foo @87
|
||||
returnType: void
|
||||
maybeAugmentation
|
||||
augmentationTarget: self::@mixin::A::@method::foo
|
||||
augmentation: self::@augmentation::package:test/b.dart::@mixinAugmentation::A::@method::foo
|
||||
augmentationImports
|
||||
package:test/b.dart
|
||||
definingUnit
|
||||
mixinAugmentations
|
||||
augment mixin A @40
|
||||
augmentationTarget: self::@augmentation::package:test/a.dart::@mixinAugmentation::A
|
||||
augmentedDeclaration: self::@mixin::A
|
||||
methods
|
||||
foo @59
|
||||
returnType: void
|
||||
maybeAugmentation
|
||||
augmentationTarget: self::@augmentation::package:test/a.dart::@mixinAugmentation::A::@method::foo
|
||||
''');
|
||||
}
|
||||
|
||||
test_augmented_methods_generic() async {
|
||||
newFile('$testPackageLibPath/a.dart', r'''
|
||||
library augment 'test.dart';
|
||||
|
@ -45637,11 +45953,10 @@ library
|
|||
superclassConstraints
|
||||
Object
|
||||
methods
|
||||
foo @42
|
||||
returnType: T
|
||||
MethodMember
|
||||
base: self::@augmentation::package:test/a.dart::@mixinAugmentation::A::@method::bar
|
||||
substitution: {T2: T}
|
||||
self::@mixin::A::@method::foo
|
||||
augmentationImports
|
||||
package:test/a.dart
|
||||
definingUnit
|
||||
|
@ -45657,6 +45972,60 @@ library
|
|||
''');
|
||||
}
|
||||
|
||||
test_augmented_methods_generic_augment() async {
|
||||
newFile('$testPackageLibPath/a.dart', r'''
|
||||
library augment 'test.dart';
|
||||
augment mixin A<T2> {
|
||||
augment T2 foo() => throw 0;
|
||||
}
|
||||
''');
|
||||
|
||||
var library = await buildLibrary(r'''
|
||||
import augment 'a.dart';
|
||||
mixin A<T> {
|
||||
T foo() => throw 0;
|
||||
}
|
||||
''');
|
||||
|
||||
checkElementText(library, r'''
|
||||
library
|
||||
definingUnit
|
||||
mixins
|
||||
mixin A @31
|
||||
typeParameters
|
||||
covariant T @33
|
||||
defaultType: dynamic
|
||||
augmentation: self::@augmentation::package:test/a.dart::@mixinAugmentation::A
|
||||
superclassConstraints
|
||||
Object
|
||||
methods
|
||||
foo @42
|
||||
returnType: T
|
||||
augmentation: self::@augmentation::package:test/a.dart::@mixinAugmentation::A::@method::foo
|
||||
augmented
|
||||
superclassConstraints
|
||||
Object
|
||||
methods
|
||||
MethodMember
|
||||
base: self::@augmentation::package:test/a.dart::@mixinAugmentation::A::@method::foo
|
||||
substitution: {T2: T}
|
||||
augmentationImports
|
||||
package:test/a.dart
|
||||
definingUnit
|
||||
mixinAugmentations
|
||||
augment mixin A @43
|
||||
typeParameters
|
||||
covariant T2 @45
|
||||
augmentationTarget: self::@mixin::A
|
||||
augmentedDeclaration: self::@mixin::A
|
||||
methods
|
||||
foo @64
|
||||
returnType: T2
|
||||
maybeAugmentation
|
||||
augmentationTarget: self::@mixin::A::@method::foo
|
||||
''');
|
||||
}
|
||||
|
||||
test_augmented_superclassConstraints() async {
|
||||
newFile('$testPackageLibPath/a.dart', r'''
|
||||
library augment 'test.dart';
|
||||
|
|
|
@ -89,6 +89,13 @@ class ElementPrinter {
|
|||
}
|
||||
}
|
||||
|
||||
void writeElementList(String name, List<Element> elements) {
|
||||
_sink.writeElements(name, elements, (element) {
|
||||
_sink.writeIndent();
|
||||
writeElement(element);
|
||||
});
|
||||
}
|
||||
|
||||
void writeNamedElement(String name, Element? element) {
|
||||
_sink.writeWithIndent('$name: ');
|
||||
writeElement(element);
|
||||
|
|
|
@ -24,6 +24,21 @@ class TreeStringSink {
|
|||
_sink.write(object);
|
||||
}
|
||||
|
||||
void writeElements<T extends Object>(
|
||||
String name,
|
||||
List<T> elements,
|
||||
void Function(T) f,
|
||||
) {
|
||||
if (elements.isNotEmpty) {
|
||||
writelnWithIndent(name);
|
||||
withIndent(() {
|
||||
for (var element in elements) {
|
||||
f(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void writeIf(bool flag, Object object) {
|
||||
if (flag) {
|
||||
write(object);
|
||||
|
|
Loading…
Reference in a new issue