Skip to content

Commit 89e9afc

Browse files
scheglovCommit Queue
authored andcommitted
Fine. Support for enums.
Change-Id: I56d7a40e2d140c8e25e9050e54c0ecc36307ea73 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/425880 Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Paul Berry <[email protected]>
1 parent ea03016 commit 89e9afc

File tree

11 files changed

+8140
-6797
lines changed

11 files changed

+8140
-6797
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ testFineAfterLibraryAnalyzerHook;
110110
// TODO(scheglov): Clean up the list of implicitly analyzed files.
111111
class AnalysisDriver {
112112
/// The version of data format, should be incremented on every format change.
113-
static const int DATA_VERSION = 459;
113+
static const int DATA_VERSION = 460;
114114

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

pkg/analyzer/lib/src/dart/ast/ast.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,6 +1462,23 @@ sealed class AstNodeImpl implements AstNode {
14621462
// Handle the general case.
14631463
return offset <= rangeOffset && end >= rangeEnd;
14641464
}
1465+
1466+
static void linkNodeTokens(AstNode parent) {
1467+
Token? lastToken;
1468+
for (var entity in parent.childEntities) {
1469+
switch (entity) {
1470+
case Token token:
1471+
lastToken?.next = token;
1472+
token.previous = lastToken;
1473+
lastToken = token;
1474+
case AstNode node:
1475+
linkNodeTokens(node);
1476+
lastToken?.next = node.beginToken;
1477+
node.beginToken.previous = lastToken;
1478+
lastToken = node.endToken;
1479+
}
1480+
}
1481+
}
14651482
}
14661483

14671484
/// Mixin for any [AstNodeImpl] that can potentially introduce a new scope.

pkg/analyzer/lib/src/dart/element/element.dart

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -718,31 +718,14 @@ class ClassFragmentImpl extends ClassOrMixinFragmentImpl
718718
rightParenthesis: Tokens.closeParenthesis(),
719719
),
720720
);
721-
_linkTokens(superInvocation);
721+
AstNodeImpl.linkNodeTokens(superInvocation);
722722
superInvocation.element = superclassConstructor.asElement2;
723723
implicitConstructor.constantInitializers = [superInvocation];
724724

725725
return implicitConstructor;
726726
})
727727
.toList(growable: false);
728728
}
729-
730-
static void _linkTokens(AstNode parent) {
731-
Token? lastToken;
732-
for (var entity in parent.childEntities) {
733-
switch (entity) {
734-
case Token token:
735-
lastToken?.next = token;
736-
token.previous = lastToken;
737-
lastToken = token;
738-
case AstNode node:
739-
_linkTokens(node);
740-
lastToken?.next = node.beginToken;
741-
node.beginToken.previous = lastToken;
742-
lastToken = node.endToken;
743-
}
744-
}
745-
}
746729
}
747730

748731
abstract class ClassOrMixinFragmentImpl extends InterfaceFragmentImpl {

pkg/analyzer/lib/src/fine/library_manifest.dart

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class LibraryManifest {
2424
final Map<LookupName, ManifestItemId> reExportMap;
2525

2626
final Map<LookupName, ClassItem> declaredClasses;
27+
final Map<LookupName, EnumItem> declaredEnums;
2728
final Map<LookupName, MixinItem> declaredMixins;
2829
final Map<LookupName, TopLevelGetterItem> declaredGetters;
2930
final Map<LookupName, TopLevelSetterItem> declaredSetters;
@@ -33,6 +34,7 @@ class LibraryManifest {
3334
LibraryManifest({
3435
required this.reExportMap,
3536
required this.declaredClasses,
37+
required this.declaredEnums,
3638
required this.declaredMixins,
3739
required this.declaredGetters,
3840
required this.declaredSetters,
@@ -46,6 +48,9 @@ class LibraryManifest {
4648
declaredClasses: reader.readLookupNameMap(
4749
readValue: () => ClassItem.read(reader),
4850
),
51+
declaredEnums: reader.readLookupNameMap(
52+
readValue: () => EnumItem.read(reader),
53+
),
4954
declaredMixins: reader.readLookupNameMap(
5055
readValue: () => MixinItem.read(reader),
5156
),
@@ -68,6 +73,7 @@ class LibraryManifest {
6873
/// or `null` if there is no such element.
6974
ManifestItemId? getExportedId(LookupName name) {
7075
return declaredClasses[name]?.id ??
76+
declaredEnums[name]?.id ??
7177
declaredMixins[name]?.id ??
7278
declaredGetters[name]?.id ??
7379
declaredSetters[name]?.id ??
@@ -78,6 +84,7 @@ class LibraryManifest {
7884
void write(BufferedSink sink) {
7985
reExportMap.write(sink);
8086
declaredClasses.write(sink);
87+
declaredEnums.write(sink);
8188
declaredMixins.write(sink);
8289
declaredGetters.write(sink);
8390
declaredSetters.write(sink);
@@ -227,6 +234,33 @@ class LibraryManifestBuilder {
227234
}
228235
}
229236

237+
void _addEnum({
238+
required EncodeContext encodingContext,
239+
required Map<LookupName, TopLevelItem> newItems,
240+
required EnumElementImpl2 element,
241+
required LookupName lookupName,
242+
}) {
243+
var enumItem = _getOrBuildElementItem(element, () {
244+
return EnumItem.fromElement(
245+
id: ManifestItemId.generate(),
246+
context: encodingContext,
247+
element: element,
248+
);
249+
});
250+
newItems[lookupName] = enumItem;
251+
252+
encodingContext.withTypeParameters(element.typeParameters2, (
253+
typeParameters,
254+
) {
255+
enumItem.beforeUpdatingMembers();
256+
_addInterfaceElementMembers(
257+
encodingContext: encodingContext,
258+
instanceElement: element,
259+
interfaceItem: enumItem,
260+
);
261+
});
262+
}
263+
230264
void _addInstanceElementField({
231265
required EncodeContext encodingContext,
232266
required InstanceItem instanceItem,
@@ -564,6 +598,7 @@ class LibraryManifestBuilder {
564598
for (var libraryElement in libraryElements) {
565599
var libraryUri = libraryElement.uri;
566600
var newClassItems = <LookupName, ClassItem>{};
601+
var newEnumItems = <LookupName, EnumItem>{};
567602
var newMixinItems = <LookupName, MixinItem>{};
568603
var newTopLevelGetters = <LookupName, TopLevelGetterItem>{};
569604
var newTopLevelSetters = <LookupName, TopLevelSetterItem>{};
@@ -584,6 +619,13 @@ class LibraryManifestBuilder {
584619
element: element,
585620
lookupName: lookupName,
586621
);
622+
case EnumElementImpl2():
623+
_addEnum(
624+
encodingContext: encodingContext,
625+
newItems: newEnumItems,
626+
element: element,
627+
lookupName: lookupName,
628+
);
587629
case GetterElementImpl():
588630
_addTopLevelGetter(
589631
encodingContext: encodingContext,
@@ -627,6 +669,7 @@ class LibraryManifestBuilder {
627669
var newManifest = LibraryManifest(
628670
reExportMap: {},
629671
declaredClasses: newClassItems,
672+
declaredEnums: newEnumItems,
630673
declaredMixins: newMixinItems,
631674
declaredGetters: newTopLevelGetters,
632675
declaredSetters: newTopLevelSetters,
@@ -778,6 +821,7 @@ class LibraryManifestBuilder {
778821
LibraryManifest(
779822
reExportMap: {},
780823
declaredClasses: {},
824+
declaredEnums: {},
781825
declaredMixins: {},
782826
declaredGetters: {},
783827
declaredSetters: {},
@@ -893,6 +937,10 @@ class _LibraryMatch {
893937
if (!_matchClass(name: name, element: element)) {
894938
structureMismatched.add(element);
895939
}
940+
case EnumElementImpl2():
941+
if (!_matchEnum(name: name, element: element)) {
942+
structureMismatched.add(element);
943+
}
896944
case GetterElementImpl():
897945
if (!_matchTopGetter(name: name, element: element)) {
898946
structureMismatched.add(element);
@@ -961,6 +1009,37 @@ class _LibraryMatch {
9611009
return true;
9621010
}
9631011

1012+
bool _matchEnum({
1013+
required LookupName? name,
1014+
required EnumElementImpl2 element,
1015+
}) {
1016+
var item = manifest.declaredEnums[name];
1017+
if (item is! EnumItem) {
1018+
return false;
1019+
}
1020+
1021+
var matchContext = MatchContext(parent: null);
1022+
if (!item.match(matchContext, element)) {
1023+
return false;
1024+
}
1025+
1026+
_addMatchingElementItem(element, item, matchContext);
1027+
1028+
_matchInterfaceElementConstructors(
1029+
matchContext: matchContext,
1030+
interfaceElement: element,
1031+
item: item,
1032+
);
1033+
1034+
_matchInstanceElementExecutables(
1035+
matchContext: matchContext,
1036+
element: element,
1037+
item: item,
1038+
);
1039+
1040+
return true;
1041+
}
1042+
9641043
void _matchInstanceElementExecutables({
9651044
required InstanceElementImpl2 element,
9661045
required InstanceItem item,

pkg/analyzer/lib/src/fine/manifest_item.dart

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,71 @@ class ClassItem extends InterfaceItem<ClassElementImpl2> {
7979
}
8080
}
8181

82+
class EnumItem extends InterfaceItem<EnumElementImpl2> {
83+
EnumItem({
84+
required super.id,
85+
required super.metadata,
86+
required super.typeParameters,
87+
required super.declaredConflicts,
88+
required super.declaredFields,
89+
required super.declaredGetters,
90+
required super.declaredSetters,
91+
required super.declaredMethods,
92+
required super.declaredConstructors,
93+
required super.inheritedConstructors,
94+
required super.interface,
95+
required super.supertype,
96+
required super.mixins,
97+
required super.interfaces,
98+
});
99+
100+
factory EnumItem.fromElement({
101+
required ManifestItemId id,
102+
required EncodeContext context,
103+
required EnumElementImpl2 element,
104+
}) {
105+
return context.withTypeParameters(element.typeParameters2, (
106+
typeParameters,
107+
) {
108+
return EnumItem(
109+
id: id,
110+
metadata: ManifestMetadata.encode(context, element.metadata2),
111+
typeParameters: typeParameters,
112+
declaredConflicts: {},
113+
declaredFields: {},
114+
declaredGetters: {},
115+
declaredSetters: {},
116+
declaredMethods: {},
117+
declaredConstructors: {},
118+
inheritedConstructors: {},
119+
interface: ManifestInterface.empty(),
120+
supertype: element.supertype?.encode(context),
121+
mixins: element.mixins.encode(context),
122+
interfaces: element.interfaces.encode(context),
123+
);
124+
});
125+
}
126+
127+
factory EnumItem.read(SummaryDataReader reader) {
128+
return EnumItem(
129+
id: ManifestItemId.read(reader),
130+
metadata: ManifestMetadata.read(reader),
131+
typeParameters: ManifestTypeParameter.readList(reader),
132+
declaredConflicts: reader.readLookupNameToIdMap(),
133+
declaredFields: InstanceItemFieldItem.readMap(reader),
134+
declaredGetters: InstanceItemGetterItem.readMap(reader),
135+
declaredSetters: InstanceItemSetterItem.readMap(reader),
136+
declaredMethods: InstanceItemMethodItem.readMap(reader),
137+
declaredConstructors: InterfaceItemConstructorItem.readMap(reader),
138+
inheritedConstructors: reader.readLookupNameToIdMap(),
139+
supertype: ManifestType.readOptional(reader),
140+
mixins: ManifestType.readList(reader),
141+
interfaces: ManifestType.readList(reader),
142+
interface: ManifestInterface.read(reader),
143+
);
144+
}
145+
}
146+
82147
/// The item for [InstanceElementImpl2].
83148
sealed class InstanceItem<E extends InstanceElementImpl2>
84149
extends TopLevelItem<E> {

pkg/analyzer/lib/src/fine/requirements.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class ExportRequirement {
6464
var actualCount = 0;
6565
var declaredTopEntries = <MapEntry<LookupName, TopLevelItem>>[
6666
...libraryManifest.declaredClasses.entries,
67+
...libraryManifest.declaredEnums.entries,
6768
...libraryManifest.declaredMixins.entries,
6869
...libraryManifest.declaredGetters.entries,
6970
...libraryManifest.declaredSetters.entries,
@@ -380,6 +381,7 @@ class RequirementsManifest {
380381

381382
var instanceItem =
382383
libraryManifest.declaredClasses[instanceName] ??
384+
libraryManifest.declaredEnums[instanceName] ??
383385
libraryManifest.declaredMixins[instanceName];
384386
if (instanceItem is! InstanceItem) {
385387
return TopLevelNotInterface(
@@ -463,6 +465,7 @@ class RequirementsManifest {
463465
var interfaceName = interfaceEntry.key;
464466
var interfaceItem =
465467
libraryManifest.declaredClasses[interfaceName] ??
468+
libraryManifest.declaredEnums[interfaceName] ??
466469
libraryManifest.declaredMixins[interfaceName];
467470
if (interfaceItem is! InterfaceItem) {
468471
return TopLevelNotInterface(
@@ -817,6 +820,7 @@ class RequirementsManifest {
817820
var instancesMap = instances[libraryElement.uri] ??= {};
818821
var instanceItem =
819822
manifest.declaredClasses[instanceName] ??
823+
manifest.declaredEnums[instanceName] ??
820824
manifest.declaredMixins[instanceName];
821825

822826
// SAFETY: every instance element must be in the manifest.
@@ -848,6 +852,7 @@ class RequirementsManifest {
848852
var interfacesMap = interfaces[libraryElement.uri] ??= {};
849853
var interfaceItem =
850854
manifest.declaredClasses[interfaceName] ??
855+
manifest.declaredEnums[interfaceName] ??
851856
manifest.declaredMixins[interfaceName];
852857

853858
// SAFETY: every interface element must be in the manifest.

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

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,8 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
368368
constant.metadata,
369369
);
370370

371-
var constructorSelector = constant.arguments?.constructorSelector;
371+
var constantArguments = constant.arguments;
372+
var constructorSelector = constantArguments?.constructorSelector;
372373
var constructorName = constructorSelector?.name.name;
373374

374375
var initializer = InstanceCreationExpressionImpl(
@@ -377,7 +378,7 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
377378
type: NamedTypeImpl(
378379
importPrefix: null,
379380
name: StringToken(TokenType.STRING, fragment.name, -1),
380-
typeArguments: constant.arguments?.typeArguments,
381+
typeArguments: constantArguments?.typeArguments,
381382
question: null,
382383
),
383384
period: constructorName != null ? Tokens.period() : null,
@@ -388,11 +389,14 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
388389
)
389390
: null,
390391
),
391-
argumentList: ArgumentListImpl(
392-
leftParenthesis: Tokens.openParenthesis(),
393-
arguments: [...?constant.arguments?.argumentList.arguments],
394-
rightParenthesis: Tokens.closeParenthesis(),
395-
),
392+
argumentList:
393+
constantArguments != null
394+
? constantArguments.argumentList
395+
: ArgumentListImpl(
396+
leftParenthesis: Tokens.openParenthesis(),
397+
arguments: [],
398+
rightParenthesis: Tokens.closeParenthesis(),
399+
),
396400
typeArguments: null,
397401
);
398402

@@ -415,6 +419,7 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
415419
);
416420
_linker.elementNodes[field] = variableDeclaration;
417421

422+
AstNodeImpl.linkNodeTokens(initializer);
418423
field.constantInitializer = initializer;
419424

420425
var refName = field.name2 ?? '${_nextUnnamedId++}';
@@ -441,6 +446,7 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
441446
elements: valuesElements,
442447
rightBracket: Tokens.closeSquareBracket(),
443448
);
449+
AstNodeImpl.linkNodeTokens(initializer);
444450
valuesField.constantInitializer = initializer;
445451

446452
var variableDeclaration = VariableDeclarationImpl(

0 commit comments

Comments
 (0)