Skip to content

Commit 8404255

Browse files
committed
Support covariant parameter overrides in the summary linker.
Fixes #27298. [email protected] Review URL: https://codereview.chromium.org/2393683002 .
1 parent db73915 commit 8404255

File tree

10 files changed

+324
-14
lines changed

10 files changed

+324
-14
lines changed

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

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6837,12 +6837,7 @@ class ParameterElementImpl extends VariableElementImpl
68376837
*/
68386838
int _visibleRangeLength = -1;
68396839

6840-
/**
6841-
* True if this parameter inherits from a covariant parameter. This happens
6842-
* when it overrides a method in a supertype that has a corresponding
6843-
* covariant parameter.
6844-
*/
6845-
bool inheritsCovariant = false;
6840+
bool _inheritsCovariant = false;
68466841

68476842
/**
68486843
* Initialize a newly created parameter element to have the given [name] and
@@ -6967,6 +6962,28 @@ class ParameterElementImpl extends VariableElementImpl
69676962
super.hasImplicitType = hasImplicitType;
69686963
}
69696964

6965+
/**
6966+
* True if this parameter inherits from a covariant parameter. This happens
6967+
* when it overrides a method in a supertype that has a corresponding
6968+
* covariant parameter.
6969+
*/
6970+
bool get inheritsCovariant {
6971+
if (_unlinkedParam != null) {
6972+
return enclosingUnit.resynthesizerContext
6973+
.inheritsCovariant(_unlinkedParam.inheritsCovariantSlot);
6974+
} else {
6975+
return _inheritsCovariant;
6976+
}
6977+
}
6978+
6979+
/**
6980+
* Record whether or not this parameter inherits from a covariant parameter.
6981+
*/
6982+
void set inheritsCovariant(bool value) {
6983+
assert(_unlinkedParam == null);
6984+
_inheritsCovariant = value;
6985+
}
6986+
69706987
@override
69716988
FunctionElement get initializer {
69726989
if (_unlinkedParam != null && _initializer == null) {
@@ -7737,6 +7754,11 @@ abstract class ResynthesizerContext {
77377754
*/
77387755
UnitExplicitTopLevelVariables buildTopLevelVariables();
77397756

7757+
/**
7758+
* Return `true` if the given parameter [slot] inherits `@covariant` behavior.
7759+
*/
7760+
bool inheritsCovariant(int slot);
7761+
77407762
/**
77417763
* Return `true` if the given const constructor [slot] is a part of a cycle.
77427764
*/

pkg/analyzer/lib/src/summary/format.dart

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,6 +1425,7 @@ abstract class _LinkedReferenceMixin implements idl.LinkedReference {
14251425

14261426
class LinkedUnitBuilder extends Object with _LinkedUnitMixin implements idl.LinkedUnit {
14271427
List<int> _constCycles;
1428+
List<int> _parametersInheritingCovariant;
14281429
List<LinkedReferenceBuilder> _references;
14291430
List<EntityRefBuilder> _types;
14301431

@@ -1440,6 +1441,19 @@ class LinkedUnitBuilder extends Object with _LinkedUnitMixin implements idl.Link
14401441
this._constCycles = value;
14411442
}
14421443

1444+
@override
1445+
List<int> get parametersInheritingCovariant => _parametersInheritingCovariant ??= <int>[];
1446+
1447+
/**
1448+
* List of slot ids (referring to [UnlinkedParam.inheritsCovariantSlot])
1449+
* corresponding to parameters that inherit `@covariant` behavior from a base
1450+
* class.
1451+
*/
1452+
void set parametersInheritingCovariant(List<int> value) {
1453+
assert(value == null || value.every((e) => e >= 0));
1454+
this._parametersInheritingCovariant = value;
1455+
}
1456+
14431457
@override
14441458
List<LinkedReferenceBuilder> get references => _references ??= <LinkedReferenceBuilder>[];
14451459

@@ -1466,8 +1480,9 @@ class LinkedUnitBuilder extends Object with _LinkedUnitMixin implements idl.Link
14661480
this._types = value;
14671481
}
14681482

1469-
LinkedUnitBuilder({List<int> constCycles, List<LinkedReferenceBuilder> references, List<EntityRefBuilder> types})
1483+
LinkedUnitBuilder({List<int> constCycles, List<int> parametersInheritingCovariant, List<LinkedReferenceBuilder> references, List<EntityRefBuilder> types})
14701484
: _constCycles = constCycles,
1485+
_parametersInheritingCovariant = parametersInheritingCovariant,
14711486
_references = references,
14721487
_types = types;
14731488

@@ -1507,15 +1522,27 @@ class LinkedUnitBuilder extends Object with _LinkedUnitMixin implements idl.Link
15071522
signature.addInt(x);
15081523
}
15091524
}
1525+
if (this._parametersInheritingCovariant == null) {
1526+
signature.addInt(0);
1527+
} else {
1528+
signature.addInt(this._parametersInheritingCovariant.length);
1529+
for (var x in this._parametersInheritingCovariant) {
1530+
signature.addInt(x);
1531+
}
1532+
}
15101533
}
15111534

15121535
fb.Offset finish(fb.Builder fbBuilder) {
15131536
fb.Offset offset_constCycles;
1537+
fb.Offset offset_parametersInheritingCovariant;
15141538
fb.Offset offset_references;
15151539
fb.Offset offset_types;
15161540
if (!(_constCycles == null || _constCycles.isEmpty)) {
15171541
offset_constCycles = fbBuilder.writeListUint32(_constCycles);
15181542
}
1543+
if (!(_parametersInheritingCovariant == null || _parametersInheritingCovariant.isEmpty)) {
1544+
offset_parametersInheritingCovariant = fbBuilder.writeListUint32(_parametersInheritingCovariant);
1545+
}
15191546
if (!(_references == null || _references.isEmpty)) {
15201547
offset_references = fbBuilder.writeList(_references.map((b) => b.finish(fbBuilder)).toList());
15211548
}
@@ -1526,6 +1553,9 @@ class LinkedUnitBuilder extends Object with _LinkedUnitMixin implements idl.Link
15261553
if (offset_constCycles != null) {
15271554
fbBuilder.addOffset(2, offset_constCycles);
15281555
}
1556+
if (offset_parametersInheritingCovariant != null) {
1557+
fbBuilder.addOffset(3, offset_parametersInheritingCovariant);
1558+
}
15291559
if (offset_references != null) {
15301560
fbBuilder.addOffset(0, offset_references);
15311561
}
@@ -1550,6 +1580,7 @@ class _LinkedUnitImpl extends Object with _LinkedUnitMixin implements idl.Linked
15501580
_LinkedUnitImpl(this._bc, this._bcOffset);
15511581

15521582
List<int> _constCycles;
1583+
List<int> _parametersInheritingCovariant;
15531584
List<idl.LinkedReference> _references;
15541585
List<idl.EntityRef> _types;
15551586

@@ -1559,6 +1590,12 @@ class _LinkedUnitImpl extends Object with _LinkedUnitMixin implements idl.Linked
15591590
return _constCycles;
15601591
}
15611592

1593+
@override
1594+
List<int> get parametersInheritingCovariant {
1595+
_parametersInheritingCovariant ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 3, const <int>[]);
1596+
return _parametersInheritingCovariant;
1597+
}
1598+
15621599
@override
15631600
List<idl.LinkedReference> get references {
15641601
_references ??= const fb.ListReader<idl.LinkedReference>(const _LinkedReferenceReader()).vTableGet(_bc, _bcOffset, 0, const <idl.LinkedReference>[]);
@@ -1577,6 +1614,7 @@ abstract class _LinkedUnitMixin implements idl.LinkedUnit {
15771614
Map<String, Object> toJson() {
15781615
Map<String, Object> _result = <String, Object>{};
15791616
if (constCycles.isNotEmpty) _result["constCycles"] = constCycles;
1617+
if (parametersInheritingCovariant.isNotEmpty) _result["parametersInheritingCovariant"] = parametersInheritingCovariant;
15801618
if (references.isNotEmpty) _result["references"] = references.map((_value) => _value.toJson()).toList();
15811619
if (types.isNotEmpty) _result["types"] = types.map((_value) => _value.toJson()).toList();
15821620
return _result;
@@ -1585,6 +1623,7 @@ abstract class _LinkedUnitMixin implements idl.LinkedUnit {
15851623
@override
15861624
Map<String, Object> toMap() => {
15871625
"constCycles": constCycles,
1626+
"parametersInheritingCovariant": parametersInheritingCovariant,
15881627
"references": references,
15891628
"types": types,
15901629
};
@@ -6718,6 +6757,7 @@ class UnlinkedParamBuilder extends Object with _UnlinkedParamMixin implements id
67186757
CodeRangeBuilder _codeRange;
67196758
String _defaultValueCode;
67206759
int _inferredTypeSlot;
6760+
int _inheritsCovariantSlot;
67216761
UnlinkedExecutableBuilder _initializer;
67226762
bool _isFunctionTyped;
67236763
bool _isInitializingFormal;
@@ -6779,6 +6819,22 @@ class UnlinkedParamBuilder extends Object with _UnlinkedParamMixin implements id
67796819
this._inferredTypeSlot = value;
67806820
}
67816821

6822+
@override
6823+
int get inheritsCovariantSlot => _inheritsCovariantSlot ??= 0;
6824+
6825+
/**
6826+
* If this is a parameter of an instance method, a nonzero slot id which is
6827+
* unique within this compilation unit. If this id is found in
6828+
* [LinkedUnit.parametersInheritingCovariant], then this parameter inherits
6829+
* `@covariant` behavior from a base class.
6830+
*
6831+
* Otherwise, zero.
6832+
*/
6833+
void set inheritsCovariantSlot(int value) {
6834+
assert(value == null || value >= 0);
6835+
this._inheritsCovariantSlot = value;
6836+
}
6837+
67826838
@override
67836839
UnlinkedExecutableBuilder get initializer => _initializer;
67846840

@@ -6886,11 +6942,12 @@ class UnlinkedParamBuilder extends Object with _UnlinkedParamMixin implements id
68866942
this._visibleOffset = value;
68876943
}
68886944

6889-
UnlinkedParamBuilder({List<UnlinkedConstBuilder> annotations, CodeRangeBuilder codeRange, String defaultValueCode, int inferredTypeSlot, UnlinkedExecutableBuilder initializer, bool isFunctionTyped, bool isInitializingFormal, idl.UnlinkedParamKind kind, String name, int nameOffset, List<UnlinkedParamBuilder> parameters, EntityRefBuilder type, int visibleLength, int visibleOffset})
6945+
UnlinkedParamBuilder({List<UnlinkedConstBuilder> annotations, CodeRangeBuilder codeRange, String defaultValueCode, int inferredTypeSlot, int inheritsCovariantSlot, UnlinkedExecutableBuilder initializer, bool isFunctionTyped, bool isInitializingFormal, idl.UnlinkedParamKind kind, String name, int nameOffset, List<UnlinkedParamBuilder> parameters, EntityRefBuilder type, int visibleLength, int visibleOffset})
68906946
: _annotations = annotations,
68916947
_codeRange = codeRange,
68926948
_defaultValueCode = defaultValueCode,
68936949
_inferredTypeSlot = inferredTypeSlot,
6950+
_inheritsCovariantSlot = inheritsCovariantSlot,
68946951
_initializer = initializer,
68956952
_isFunctionTyped = isFunctionTyped,
68966953
_isInitializingFormal = isInitializingFormal,
@@ -6946,6 +7003,7 @@ class UnlinkedParamBuilder extends Object with _UnlinkedParamMixin implements id
69467003
signature.addInt(this._visibleOffset ?? 0);
69477004
signature.addBool(this._initializer != null);
69487005
this._initializer?.collectApiSignature(signature);
7006+
signature.addInt(this._inheritsCovariantSlot ?? 0);
69497007
}
69507008

69517009
fb.Offset finish(fb.Builder fbBuilder) {
@@ -6990,6 +7048,9 @@ class UnlinkedParamBuilder extends Object with _UnlinkedParamMixin implements id
69907048
if (_inferredTypeSlot != null && _inferredTypeSlot != 0) {
69917049
fbBuilder.addUint32(2, _inferredTypeSlot);
69927050
}
7051+
if (_inheritsCovariantSlot != null && _inheritsCovariantSlot != 0) {
7052+
fbBuilder.addUint32(14, _inheritsCovariantSlot);
7053+
}
69937054
if (offset_initializer != null) {
69947055
fbBuilder.addOffset(12, offset_initializer);
69957056
}
@@ -7041,6 +7102,7 @@ class _UnlinkedParamImpl extends Object with _UnlinkedParamMixin implements idl.
70417102
idl.CodeRange _codeRange;
70427103
String _defaultValueCode;
70437104
int _inferredTypeSlot;
7105+
int _inheritsCovariantSlot;
70447106
idl.UnlinkedExecutable _initializer;
70457107
bool _isFunctionTyped;
70467108
bool _isInitializingFormal;
@@ -7076,6 +7138,12 @@ class _UnlinkedParamImpl extends Object with _UnlinkedParamMixin implements idl.
70767138
return _inferredTypeSlot;
70777139
}
70787140

7141+
@override
7142+
int get inheritsCovariantSlot {
7143+
_inheritsCovariantSlot ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 14, 0);
7144+
return _inheritsCovariantSlot;
7145+
}
7146+
70797147
@override
70807148
idl.UnlinkedExecutable get initializer {
70817149
_initializer ??= const _UnlinkedExecutableReader().vTableGet(_bc, _bcOffset, 12, null);
@@ -7145,6 +7213,7 @@ abstract class _UnlinkedParamMixin implements idl.UnlinkedParam {
71457213
if (codeRange != null) _result["codeRange"] = codeRange.toJson();
71467214
if (defaultValueCode != '') _result["defaultValueCode"] = defaultValueCode;
71477215
if (inferredTypeSlot != 0) _result["inferredTypeSlot"] = inferredTypeSlot;
7216+
if (inheritsCovariantSlot != 0) _result["inheritsCovariantSlot"] = inheritsCovariantSlot;
71487217
if (initializer != null) _result["initializer"] = initializer.toJson();
71497218
if (isFunctionTyped != false) _result["isFunctionTyped"] = isFunctionTyped;
71507219
if (isInitializingFormal != false) _result["isInitializingFormal"] = isInitializingFormal;
@@ -7164,6 +7233,7 @@ abstract class _UnlinkedParamMixin implements idl.UnlinkedParam {
71647233
"codeRange": codeRange,
71657234
"defaultValueCode": defaultValueCode,
71667235
"inferredTypeSlot": inferredTypeSlot,
7236+
"inheritsCovariantSlot": inheritsCovariantSlot,
71677237
"initializer": initializer,
71687238
"isFunctionTyped": isFunctionTyped,
71697239
"isInitializingFormal": isInitializingFormal,

pkg/analyzer/lib/src/summary/format.fbs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,13 @@ table LinkedUnit {
10781078
*/
10791079
constCycles:[uint] (id: 2);
10801080

1081+
/**
1082+
* List of slot ids (referring to [UnlinkedParam.inheritsCovariantSlot])
1083+
* corresponding to parameters that inherit `@covariant` behavior from a base
1084+
* class.
1085+
*/
1086+
parametersInheritingCovariant:[uint] (id: 3);
1087+
10811088
/**
10821089
* Information about the resolution of references within the compilation
10831090
* unit. Each element of [UnlinkedUnit.references] has a corresponding
@@ -2015,6 +2022,16 @@ table UnlinkedParam {
20152022
*/
20162023
inferredTypeSlot:uint (id: 2);
20172024

2025+
/**
2026+
* If this is a parameter of an instance method, a nonzero slot id which is
2027+
* unique within this compilation unit. If this id is found in
2028+
* [LinkedUnit.parametersInheritingCovariant], then this parameter inherits
2029+
* `@covariant` behavior from a base class.
2030+
*
2031+
* Otherwise, zero.
2032+
*/
2033+
inheritsCovariantSlot:uint (id: 14);
2034+
20182035
/**
20192036
* The synthetic initializer function of the parameter. Absent if the variable
20202037
* does not have an initializer.

pkg/analyzer/lib/src/summary/idl.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,14 @@ abstract class LinkedUnit extends base.SummaryClass {
528528
@Id(2)
529529
List<int> get constCycles;
530530

531+
/**
532+
* List of slot ids (referring to [UnlinkedParam.inheritsCovariantSlot])
533+
* corresponding to parameters that inherit `@covariant` behavior from a base
534+
* class.
535+
*/
536+
@Id(3)
537+
List<int> get parametersInheritingCovariant;
538+
531539
/**
532540
* Information about the resolution of references within the compilation
533541
* unit. Each element of [UnlinkedUnit.references] has a corresponding
@@ -2260,6 +2268,17 @@ abstract class UnlinkedParam extends base.SummaryClass {
22602268
@Id(2)
22612269
int get inferredTypeSlot;
22622270

2271+
/**
2272+
* If this is a parameter of an instance method, a nonzero slot id which is
2273+
* unique within this compilation unit. If this id is found in
2274+
* [LinkedUnit.parametersInheritingCovariant], then this parameter inherits
2275+
* `@covariant` behavior from a base class.
2276+
*
2277+
* Otherwise, zero.
2278+
*/
2279+
@Id(14)
2280+
int get inheritsCovariantSlot;
2281+
22632282
/**
22642283
* The synthetic initializer function of the parameter. Absent if the variable
22652284
* does not have an initializer.

0 commit comments

Comments
 (0)