Skip to content

Commit 9a38563

Browse files
scheglovCommit Queue
authored andcommitted
Augment. Basic support for enum elements..
Change-Id: I42e7b58f7edaa979740a8e5b6787665c7a79c54d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/363500 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent 1b46b26 commit 9a38563

File tree

11 files changed

+4619
-43
lines changed

11 files changed

+4619
-43
lines changed

pkg/analysis_server/test/lsp/code_lens/augmentations_test.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,6 @@ augment class A {
198198
await expectNavigationCodeLens();
199199
}
200200

201-
@failingTest // "augment enum" is currently an error?
202201
test_available_enum() async {
203202
setLibraryContent(r'''
204203
enum [!A!] {

pkg/analyzer/lib/src/dart/analysis/driver.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ import 'package:meta/meta.dart';
9595
// TODO(scheglov): Clean up the list of implicitly analyzed files.
9696
class AnalysisDriver {
9797
/// The version of data format, should be incremented on every format change.
98-
static const int DATA_VERSION = 355;
98+
static const int DATA_VERSION = 356;
9999

100100
/// The number of exception contexts allowed to write. Once this field is
101101
/// zero, we stop writing any new exception contexts in this process.

pkg/analyzer/lib/src/summary2/bundle_reader.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,20 @@ class EnumElementLinkedData extends ElementLinkedData<EnumElementImpl> {
351351
element.supertype = reader._readOptionalInterfaceType();
352352
element.mixins = reader._readInterfaceTypeList();
353353
element.interfaces = reader._readInterfaceTypeList();
354+
element.augmentationTarget = reader.readElement() as EnumElementImpl?;
355+
element.augmentation = reader.readElement() as EnumElementImpl?;
356+
if (element.augmentationTarget == null) {
357+
if (reader.readBool()) {
358+
var augmented = AugmentedEnumElementImpl(element);
359+
element.augmentedInternal = augmented;
360+
augmented.mixins = reader._readInterfaceTypeList();
361+
augmented.interfaces = reader._readInterfaceTypeList();
362+
augmented.fields = reader.readElementList();
363+
augmented.constructors = reader.readElementList();
364+
augmented.accessors = reader.readElementList();
365+
augmented.methods = reader.readElementList();
366+
}
367+
}
354368
applyConstantOffsets?.perform();
355369
}
356370
}

pkg/analyzer/lib/src/summary2/bundle_writer.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,21 @@ class BundleWriter {
280280
_resolutionSink.writeType(element.supertype);
281281
_resolutionSink._writeTypeList(element.mixins);
282282
_resolutionSink._writeTypeList(element.interfaces);
283+
_resolutionSink.writeElement(element.augmentationTarget);
284+
_resolutionSink.writeElement(element.augmentation);
285+
if (element.augmentationTarget == null) {
286+
_resolutionSink.writeIfType<AugmentedEnumElementImpl>(
287+
element.augmented,
288+
(augmented) {
289+
_resolutionSink._writeTypeList(augmented.mixins);
290+
_resolutionSink._writeTypeList(augmented.interfaces);
291+
_resolutionSink._writeElementList(augmented.fields);
292+
_resolutionSink._writeElementList(augmented.constructors);
293+
_resolutionSink._writeElementList(augmented.accessors);
294+
_resolutionSink._writeElementList(augmented.methods);
295+
},
296+
);
297+
}
283298

284299
_writeList(
285300
element.fields.where((e) {

pkg/analyzer/lib/src/summary2/element_builder.dart

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
239239
var nameOffset = nameNode.offset;
240240

241241
var element = EnumElementImpl(name, nameOffset);
242+
element.isAugmentation = node.augmentKeyword != null;
242243
element.metadata = _buildAnnotations(node.metadata);
243244
_setCodeRange(element, node);
244245
_setDocumentation(element, node);
@@ -249,6 +250,13 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
249250
var reference = _enclosingContext.addEnum(name, element);
250251
_libraryBuilder.declare(name, reference);
251252

253+
_libraryBuilder.updateAugmentationTarget(name, element, (target) {
254+
if (element.isAugmentation) {
255+
target.augmentation = element;
256+
element.augmentationTarget = target;
257+
}
258+
});
259+
252260
var holder = _EnclosingContext(
253261
reference,
254262
element,
@@ -330,10 +338,8 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
330338
}
331339

332340
// Build the 'values' field.
333-
ConstFieldElementImpl valuesField;
334-
NamedTypeImpl valuesTypeNode;
335-
{
336-
valuesField = ConstFieldElementImpl('values', -1)
341+
if (element.augmentationTarget == null) {
342+
var valuesField = ConstFieldElementImpl('values', -1)
337343
..isConst = true
338344
..isStatic = true
339345
..isSynthetic = true;
@@ -351,7 +357,7 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
351357
equals: Tokens.eq(),
352358
initializer: initializer,
353359
);
354-
valuesTypeNode = NamedTypeImpl(
360+
var valuesTypeNode = NamedTypeImpl(
355361
importPrefix: null,
356362
name2: StringToken(TokenType.STRING, 'List', -1),
357363
typeArguments: TypeArgumentListImpl(
@@ -379,6 +385,14 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
379385
_linker.elementNodes[valuesField] = variableDeclaration;
380386

381387
holder.addNonSyntheticField(valuesField);
388+
389+
_libraryBuilder.implicitEnumNodes.add(
390+
ImplicitEnumNodes(
391+
element: element,
392+
valuesTypeNode: valuesTypeNode,
393+
valuesField: valuesField,
394+
),
395+
);
382396
}
383397

384398
node.withClause?.accept(this);
@@ -389,35 +403,25 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
389403
_visitPropertyFirst<FieldDeclaration>(node.members);
390404
});
391405

392-
var needsImplicitConstructor = !holder.constructors.any(
393-
(e) => e.name.isEmpty || e.isGenerative,
394-
);
395-
396-
if (needsImplicitConstructor) {
397-
holder.addConstructor(
398-
ConstructorElementImpl('', -1)
399-
..isConst = true
400-
..isSynthetic = true,
401-
);
402-
}
403-
404-
_libraryBuilder.implicitEnumNodes.add(
405-
ImplicitEnumNodes(
406-
element: element,
407-
valuesTypeNode: valuesTypeNode,
408-
valuesField: valuesField,
409-
),
410-
);
411-
412406
element.accessors = holder.propertyAccessors;
413407
element.constructors = holder.constructors;
414408
element.fields = holder.fields;
415409
element.methods = holder.methods;
416410
element.typeParameters = holder.typeParameters;
417411

418-
// TODO(scheglov): We cannot do this anymore.
419-
// Not for class augmentations, not for classes.
420-
_resolveConstructorFieldFormals(element);
412+
if (element.augmentationTarget != null) {
413+
var builder = _libraryBuilder.getAugmentedBuilder(name);
414+
if (builder is AugmentedEnumDeclarationBuilder) {
415+
builder.augment(element);
416+
}
417+
} else {
418+
_libraryBuilder.putAugmentedBuilder(
419+
name,
420+
AugmentedEnumDeclarationBuilder(
421+
declaration: element,
422+
),
423+
);
424+
}
421425
}
422426

423427
@override

pkg/analyzer/lib/src/summary2/element_flags.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,18 @@ class ConstructorElementFlags {
8383

8484
class EnumElementFlags {
8585
static const int _isSimplyBounded = 1 << 0;
86+
static const int _isAugmentation = 1 << 1;
8687

8788
static void read(SummaryDataReader reader, EnumElementImpl element) {
8889
var byte = reader.readByte();
8990
element.isSimplyBounded = (byte & _isSimplyBounded) != 0;
91+
element.isAugmentation = (byte & _isAugmentation) != 0;
9092
}
9193

9294
static void write(BufferedSink sink, EnumElementImpl element) {
9395
var result = 0;
9496
result |= element.isSimplyBounded ? _isSimplyBounded : 0;
97+
result |= element.isAugmentation ? _isAugmentation : 0;
9598
sink.writeByte(result);
9699
}
97100
}

pkg/analyzer/lib/src/summary2/library_builder.dart

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,27 @@ class AugmentedClassDeclarationBuilder
5858
}
5959
}
6060

61+
class AugmentedEnumDeclarationBuilder
62+
extends AugmentedInstanceDeclarationBuilder {
63+
final EnumElementImpl declaration;
64+
65+
AugmentedEnumDeclarationBuilder({
66+
required this.declaration,
67+
}) {
68+
addFields(declaration.fields);
69+
addConstructors(declaration.constructors);
70+
addAccessors(declaration.accessors);
71+
addMethods(declaration.methods);
72+
}
73+
74+
void augment(EnumElementImpl element) {
75+
addFields(element.fields);
76+
addConstructors(element.constructors);
77+
addAccessors(element.accessors);
78+
addMethods(element.methods);
79+
}
80+
}
81+
6182
class AugmentedExtensionDeclarationBuilder
6283
extends AugmentedInstanceDeclarationBuilder {
6384
final ExtensionElementImpl declaration;
@@ -392,6 +413,40 @@ class LibraryBuilder with MacroApplicationsContainer {
392413
}
393414
}
394415

416+
void buildEnumSyntheticConstructors() {
417+
bool hasConstructor(EnumElementImpl element) {
418+
for (var constructor in element.augmented.constructors) {
419+
if (constructor.isGenerative || constructor.name == '') {
420+
return true;
421+
}
422+
}
423+
return false;
424+
}
425+
426+
for (var enumElement in element.topLevelElements) {
427+
if (enumElement is! EnumElementImpl) continue;
428+
if (enumElement.augmentationTarget != null) continue;
429+
if (hasConstructor(enumElement)) continue;
430+
431+
var constructor = ConstructorElementImpl('', -1)
432+
..isConst = true
433+
..isSynthetic = true;
434+
var containerRef = enumElement.reference!.getChild('@constructor');
435+
var reference = containerRef.getChild('new');
436+
reference.element = constructor;
437+
constructor.reference = reference;
438+
439+
enumElement.constructors = [
440+
...enumElement.constructors,
441+
constructor,
442+
].toFixedList();
443+
444+
if (enumElement.augmented case AugmentedEnumElementImpl augmented) {
445+
augmented.constructors = enumElement.constructors;
446+
}
447+
}
448+
}
449+
395450
void buildInitialExportScope() {
396451
exportScope = ExportScope();
397452
_declaredReferences.forEach((name, reference) {
@@ -719,12 +774,17 @@ class LibraryBuilder with MacroApplicationsContainer {
719774
}
720775

721776
void resolveConstructorFieldFormals() {
722-
for (var class_ in element.topLevelElements) {
723-
if (class_ is! ClassElementImpl) continue;
724-
if (class_.isMixinApplication) continue;
725-
var augmented = class_.augmented;
777+
for (var interface in element.topLevelElements) {
778+
if (interface is! InterfaceElementImpl) {
779+
continue;
780+
}
781+
782+
if (interface is ClassElementImpl && interface.isMixinApplication) {
783+
continue;
784+
}
726785

727-
for (var constructor in class_.constructors) {
786+
var augmented = interface.augmented;
787+
for (var constructor in interface.constructors) {
728788
for (var parameter in constructor.parameters) {
729789
if (parameter is FieldFormalParameterElementImpl) {
730790
parameter.field = augmented.getField(parameter.name);

pkg/analyzer/lib/src/summary2/link.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ class Linker {
124124
}
125125
}
126126

127+
void _buildEnumSyntheticConstructors() {
128+
for (var library in builders.values) {
129+
library.buildEnumSyntheticConstructors();
130+
}
131+
}
132+
127133
void _buildExportScopes() {
128134
for (var library in builders.values) {
129135
library.buildInitialExportScope();
@@ -224,6 +230,7 @@ class Linker {
224230
);
225231

226232
_buildClassSyntheticConstructors();
233+
_buildEnumSyntheticConstructors();
227234
_replaceConstFieldsIfNoConstConstructor();
228235
_resolveConstructorFieldFormals();
229236
_buildEnumChildren();

pkg/analyzer/lib/src/summary2/types_builder.dart

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -268,15 +268,15 @@ class TypesBuilder {
268268
void _enumDeclaration(EnumDeclaration node) {
269269
var element = node.declaredElement as EnumElementImpl;
270270

271-
element.mixins = _toInterfaceTypeList(
272-
node.withClause?.mixinTypes,
273-
);
274-
275271
element.interfaces = _toInterfaceTypeList(
276272
node.implementsClause?.interfaces,
277273
);
278274

279-
_toInferMixins[element] = _ToInferMixins(element, node.withClause);
275+
if (element.augmentationTarget != null) {
276+
_updatedAugmented(element, withClause: node.withClause);
277+
} else {
278+
_toInferMixins[element] = _ToInferMixins(element, node.withClause);
279+
}
280280
}
281281

282282
void _extensionDeclaration(ExtensionDeclaration node) {
@@ -687,9 +687,7 @@ class _MixinsInference {
687687
void perform() {
688688
for (var declaration in _declarations.values) {
689689
var element = declaration.element;
690-
if (element is ClassElementImpl) {
691-
element.mixinInferenceCallback = _callbackWhenRecursion;
692-
}
690+
element.mixinInferenceCallback = _callbackWhenRecursion;
693691
}
694692

695693
for (var declaration in _declarations.values) {

pkg/analyzer/test/src/summary/element_text.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,13 @@ class _ElementWriter {
230230
writeConstructors();
231231
writeAccessors();
232232
writeMethods();
233+
case AugmentedEnumElement():
234+
_elementPrinter.writeTypeList('mixins', augmented.mixins);
235+
_elementPrinter.writeTypeList('interfaces', augmented.interfaces);
236+
writeFields();
237+
writeConstructors();
238+
writeAccessors();
239+
writeMethods();
233240
case AugmentedExtensionElement():
234241
writeFields();
235242
writeAccessors();

0 commit comments

Comments
 (0)