Skip to content

Commit 8eba93e

Browse files
scheglovCommit Queue
authored andcommitted
Fine. Support for constructor formal parameters in constants.
Change-Id: I0f8c3de68ca20d375a40f67d51d6bd2d0f358eb5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/422382 Reviewed-by: Paul Berry <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent a9dd011 commit 8eba93e

File tree

5 files changed

+215
-53
lines changed

5 files changed

+215
-53
lines changed

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

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,32 @@ import 'package:analyzer/src/summary2/data_reader.dart';
1414
import 'package:analyzer/src/summary2/data_writer.dart';
1515
import 'package:analyzer/src/utilities/extensions/collection.dart';
1616
import 'package:collection/collection.dart';
17+
import 'package:meta/meta.dart';
18+
19+
@visibleForTesting
20+
enum ManifestAstElementKind {
21+
null_,
22+
dynamic_,
23+
formalParameter,
24+
importPrefix,
25+
typeParameter,
26+
regular;
27+
28+
static final _bitCount = values.length.bitLength;
29+
static final _bitMask = (1 << _bitCount) - 1;
30+
31+
int encodeRawIndex(int rawIndex) {
32+
assert(rawIndex < (1 << 16));
33+
return (rawIndex << _bitCount) | index;
34+
}
35+
36+
static (ManifestAstElementKind, int) decode(int index) {
37+
var kindIndex = index & _bitMask;
38+
var kind = ManifestAstElementKind.values[kindIndex];
39+
var rawIndex = index >> _bitCount;
40+
return (kind, rawIndex);
41+
}
42+
}
1743

1844
/// Enough information to decide if the node is the same.
1945
///
@@ -33,10 +59,8 @@ class ManifestNode {
3359
final List<ManifestElement> elements;
3460

3561
/// For each property in the AST structure summarized by this manifest that
36-
/// might point to an element:
37-
/// - `0` if the element pointer is `null`;
38-
/// - `1` if the element is an import prefix;
39-
/// - otherwise `2 + ` the index of the element in [elements].
62+
/// might point to an element, [ManifestAstElementKind.encodeRawIndex]
63+
/// produces the corresponding value.
4064
///
4165
/// The order of this list reflects the AST structure, according to the
4266
/// behavior of [_ElementCollector].
@@ -56,7 +80,10 @@ class ManifestNode {
5680
token = token.next ?? (throw StateError('endToken not found'));
5781
}
5882

59-
var collector = _ElementCollector();
83+
var collector = _ElementCollector(
84+
indexOfTypeParameter: context.indexOfTypeParameter,
85+
indexOfFormalParameter: context.indexOfFormalParameter,
86+
);
6087
node.accept(collector);
6188

6289
return ManifestNode._(
@@ -106,7 +133,10 @@ class ManifestNode {
106133
token = token.next ?? (throw StateError('endToken not found'));
107134
}
108135

109-
var collector = _ElementCollector();
136+
var collector = _ElementCollector(
137+
indexOfTypeParameter: context.indexOfTypeParameter,
138+
indexOfFormalParameter: context.indexOfFormalParameter,
139+
);
110140
node.accept(collector);
111141

112142
// Must reference the same elements.
@@ -147,9 +177,16 @@ class ManifestNode {
147177
}
148178

149179
class _ElementCollector extends ThrowingAstVisitor<void> {
180+
final int Function(TypeParameterElementImpl2) indexOfTypeParameter;
181+
final int Function(FormalParameterElementImpl) indexOfFormalParameter;
150182
final Map<Element2, int> map = Map.identity();
151183
final List<int> elementIndexList = [];
152184

185+
_ElementCollector({
186+
required this.indexOfTypeParameter,
187+
required this.indexOfFormalParameter,
188+
});
189+
153190
@override
154191
void visitAdjacentStrings(AdjacentStrings node) {
155192
node.visitChildren(this);
@@ -331,26 +368,32 @@ class _ElementCollector extends ThrowingAstVisitor<void> {
331368
}
332369

333370
void _addElement(Element2? element) {
371+
ManifestAstElementKind kind;
372+
int rawIndex;
334373
switch (element) {
335374
case null:
336-
elementIndexList.add(_ElementKind.null_.index);
375+
kind = ManifestAstElementKind.null_;
376+
rawIndex = 0;
337377
case DynamicElementImpl2():
338-
elementIndexList.add(_ElementKind.dynamic_.index);
378+
kind = ManifestAstElementKind.dynamic_;
379+
rawIndex = 0;
380+
case FormalParameterElementImpl():
381+
kind = ManifestAstElementKind.formalParameter;
382+
rawIndex = indexOfFormalParameter(element);
383+
case TypeParameterElementImpl2():
384+
kind = ManifestAstElementKind.typeParameter;
385+
rawIndex = indexOfTypeParameter(element);
339386
case PrefixElement2():
340-
elementIndexList.add(_ElementKind.importPrefix.index);
387+
kind = ManifestAstElementKind.importPrefix;
388+
rawIndex = 0;
341389
default:
342-
var base = _ElementKind.firstRegular.index;
343-
var index = map[element] ??= base + map.length;
344-
elementIndexList.add(index);
390+
kind = ManifestAstElementKind.regular;
391+
rawIndex = map[element] ??= map.length;
345392
}
346-
}
347-
}
348393

349-
enum _ElementKind {
350-
null_,
351-
dynamic_,
352-
importPrefix,
353-
firstRegular,
394+
var index = kind.encodeRawIndex(rawIndex);
395+
elementIndexList.add(index);
396+
}
354397
}
355398

356399
extension ListOfManifestNodeExtension on List<ManifestNode> {

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

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import 'package:analyzer/src/summary2/linked_element_factory.dart';
1313

1414
class EncodeContext {
1515
final LinkedElementFactory elementFactory;
16-
final Map<TypeParameterElement2, int> _typeParameters = {};
16+
final Map<TypeParameterElement2, int> _typeParameters = Map.identity();
17+
final Map<FormalParameterElement, int> _formalParameters = Map.identity();
1718

1819
EncodeContext({
1920
required this.elementFactory,
@@ -24,6 +25,14 @@ class EncodeContext {
2425
return elementFactory.getElementId(element);
2526
}
2627

28+
int indexOfFormalParameter(FormalParameterElement element) {
29+
if (_formalParameters[element] case var result?) {
30+
return result;
31+
}
32+
33+
throw StateError('No formal parameter $element');
34+
}
35+
2736
int indexOfTypeParameter(TypeParameterElement2 element) {
2837
if (_typeParameters[element] case var bottomIndex?) {
2938
return _typeParameters.length - 1 - bottomIndex;
@@ -32,6 +41,22 @@ class EncodeContext {
3241
return throw StateError('No type parameter $element');
3342
}
3443

44+
T withFormalParameters<T>(
45+
List<FormalParameterElement> formalParameters,
46+
T Function() operation,
47+
) {
48+
for (var formalParameter in formalParameters) {
49+
_formalParameters[formalParameter] = _formalParameters.length;
50+
}
51+
try {
52+
return operation();
53+
} finally {
54+
for (var formalParameter in formalParameters) {
55+
_formalParameters.remove(formalParameter);
56+
}
57+
}
58+
}
59+
3560
T withTypeParameters<T>(
3661
List<TypeParameterElement2> typeParameters,
3762
T Function(List<ManifestTypeParameter> typeParameters) operation,
@@ -155,6 +180,7 @@ final class ManifestElement {
155180
topLevelElement = element;
156181
} else {
157182
topLevelElement = enclosingElement;
183+
assert(topLevelElement.enclosingElement2 is LibraryElement2);
158184
memberElement = element;
159185
}
160186

@@ -181,7 +207,8 @@ class MatchContext {
181207
/// bundle.
182208
final Map<Element2, ManifestItemId> externalIds = {};
183209

184-
final Map<TypeParameterElement2, int> _typeParameters = {};
210+
final Map<TypeParameterElement2, int> _typeParameters = Map.identity();
211+
final Map<FormalParameterElement, int> _formalParameters = Map.identity();
185212

186213
MatchContext({
187214
required this.parent,
@@ -196,6 +223,14 @@ class MatchContext {
196223
}
197224
}
198225

226+
int indexOfFormalParameter(FormalParameterElement element) {
227+
if (_formalParameters[element] case var result?) {
228+
return result;
229+
}
230+
231+
throw StateError('No formal parameter $element');
232+
}
233+
199234
int indexOfTypeParameter(TypeParameterElement2 element) {
200235
if (_typeParameters[element] case var result?) {
201236
return _typeParameters.length - 1 - result;
@@ -209,6 +244,22 @@ class MatchContext {
209244
throw StateError('No type parameter $element');
210245
}
211246

247+
T withFormalParameters<T>(
248+
List<FormalParameterElement> formalParameters,
249+
T Function() operation,
250+
) {
251+
for (var formalParameter in formalParameters) {
252+
_formalParameters[formalParameter] = _formalParameters.length;
253+
}
254+
try {
255+
return operation();
256+
} finally {
257+
for (var formalParameter in formalParameters) {
258+
_formalParameters.remove(formalParameter);
259+
}
260+
}
261+
}
262+
212263
T withTypeParameters<T>(
213264
List<TypeParameterElement2> typeParameters,
214265
T Function() operation,

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

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -380,17 +380,19 @@ class InterfaceItemConstructorItem
380380
required EncodeContext context,
381381
required ConstructorElementImpl2 element,
382382
}) {
383-
return InterfaceItemConstructorItem(
384-
id: id,
385-
metadata: ManifestMetadata.encode(context, element.metadata2),
386-
isStatic: false,
387-
isConst: element.isConst,
388-
isFactory: element.isFactory,
389-
functionType: element.type.encode(context),
390-
constantInitializers: element.constantInitializers
391-
.map((initializer) => ManifestNode.encode(context, initializer))
392-
.toFixedList(),
393-
);
383+
return context.withFormalParameters(element.formalParameters, () {
384+
return InterfaceItemConstructorItem(
385+
id: id,
386+
metadata: ManifestMetadata.encode(context, element.metadata2),
387+
isStatic: false,
388+
isConst: element.isConst,
389+
isFactory: element.isFactory,
390+
functionType: element.type.encode(context),
391+
constantInitializers: element.constantInitializers
392+
.map((initializer) => ManifestNode.encode(context, initializer))
393+
.toFixedList(),
394+
);
395+
});
394396
}
395397

396398
factory InterfaceItemConstructorItem.read(SummaryDataReader reader) {
@@ -407,11 +409,13 @@ class InterfaceItemConstructorItem
407409

408410
@override
409411
bool match(MatchContext context, ConstructorElementImpl2 element) {
410-
return super.match(context, element) &&
411-
isConst == element.isConst &&
412-
isFactory == element.isFactory &&
413-
functionType.match(context, element.type) &&
414-
constantInitializers.match(context, element.constantInitializers);
412+
return context.withFormalParameters(element.formalParameters, () {
413+
return super.match(context, element) &&
414+
isConst == element.isConst &&
415+
isFactory == element.isFactory &&
416+
functionType.match(context, element.type) &&
417+
constantInitializers.match(context, element.constantInitializers);
418+
});
415419
}
416420

417421
@override

0 commit comments

Comments
 (0)