Skip to content

Commit 793d8cc

Browse files
scheglovCommit Queue
authored andcommitted
DeCo. Add FieldFormalParameterElement.isDeclaring, ConstructorElement.isDeclaring/isPrimary, FieldElement.declaringFormalParameter
This change introduces new experimental properties to the analyzer element model to identify elements related to declaring constructors. The new properties are: - `ConstructorElement.isDeclaring`: True for a declaring constructor. - `ConstructorElement.isPrimary`: True if the constructor is primary (which implies it is also `isDeclaring`). - `FieldFormalParameterElement.isDeclaring`: True for a formal parameter in a declaring constructor. - `FieldElement.declaringFormalParameter`: A link from a field back to the formal parameter that declared it, if it came from a declaring constructor. This allows other parts of the analyzer and analyzer clients to understand the origin of these implicitly declared elements. The change also updates the necessary serialization logic (manifest, data version) and member proxies to support these new properties. Bug: #61701 Change-Id: Iedefd6b5584d28a47aea0e90d6aedafaf8aecdef Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/459580 Reviewed-by: Paul Berry <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent 159bbb6 commit 793d8cc

File tree

15 files changed

+432
-166
lines changed

15 files changed

+432
-166
lines changed

pkg/analyzer/api.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3376,9 +3376,11 @@ package:analyzer/dart/element/element.dart:
33763376
firstFragment (getter: ConstructorFragment)
33773377
fragments (getter: List<ConstructorFragment>)
33783378
isConst (getter: bool)
3379+
isDeclaring (getter: bool, experimental)
33793380
isDefaultConstructor (getter: bool)
33803381
isFactory (getter: bool)
33813382
isGenerative (getter: bool)
3383+
isPrimary (getter: bool, experimental)
33823384
name (getter: String?)
33833385
redirectedConstructor (getter: ConstructorElement?)
33843386
returnType (getter: InterfaceType)
@@ -3611,6 +3613,7 @@ package:analyzer/dart/element/element.dart:
36113613
FieldElement (class extends Object implements PropertyInducingElement):
36123614
new (constructor: FieldElement Function())
36133615
baseElement (getter: FieldElement)
3616+
declaringFormalParameter (getter: FieldFormalParameterElement?, experimental)
36143617
enclosingElement (getter: InstanceElement)
36153618
firstFragment (getter: FieldFragment)
36163619
fragments (getter: List<FieldFragment>)
@@ -3624,6 +3627,7 @@ package:analyzer/dart/element/element.dart:
36243627
field (getter: FieldElement?)
36253628
firstFragment (getter: FieldFormalParameterFragment)
36263629
fragments (getter: List<FieldFormalParameterFragment>)
3630+
isDeclaring (getter: bool, experimental)
36273631
FieldFormalParameterFragment (class extends Object implements FormalParameterFragment):
36283632
new (constructor: FieldFormalParameterFragment Function())
36293633
element (getter: FieldFormalParameterElement)

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ import 'package:analyzer/source/line_info.dart';
5959
import 'package:analyzer/source/source.dart';
6060
import 'package:analyzer/src/dart/element/inheritance_manager3.dart' show Name;
6161
import 'package:analyzer/src/dart/resolver/scope.dart';
62+
import 'package:meta/meta.dart';
6263
import 'package:pub_semver/pub_semver.dart';
6364

6465
export 'package:analyzer/src/dart/element/inheritance_manager3.dart' show Name;
@@ -228,6 +229,10 @@ abstract class ConstructorElement implements ExecutableElement {
228229
/// Whether the constructor is a const constructor.
229230
bool get isConst;
230231

232+
/// Whether this is a declaring constructor.
233+
@experimental
234+
bool get isDeclaring;
235+
231236
/// Whether the constructor can be used as a default constructor - unnamed,
232237
/// and has no required parameters.
233238
bool get isDefaultConstructor;
@@ -238,6 +243,11 @@ abstract class ConstructorElement implements ExecutableElement {
238243
/// Whether the constructor represents a generative constructor.
239244
bool get isGenerative;
240245

246+
/// Whether this is a primary constructor.
247+
/// When `true`, [isDeclaring] is also `true`.
248+
@experimental
249+
bool get isPrimary;
250+
241251
/// The name of this constructor.
242252
///
243253
/// The name of the unnamed constructor is `new`.
@@ -1193,6 +1203,10 @@ abstract class FieldElement implements PropertyInducingElement {
11931203
@override
11941204
FieldElement get baseElement;
11951205

1206+
/// The declaring formal parameter, if created from one.
1207+
@experimental
1208+
FieldFormalParameterElement? get declaringFormalParameter;
1209+
11961210
@override
11971211
InstanceElement get enclosingElement;
11981212

@@ -1235,6 +1249,10 @@ abstract class FieldFormalParameterElement implements FormalParameterElement {
12351249

12361250
@override
12371251
List<FieldFormalParameterFragment> get fragments;
1252+
1253+
/// Whether this is a declaring formal parameter.
1254+
@experimental
1255+
bool get isDeclaring;
12381256
}
12391257

12401258
/// The portion of a [FieldFormalParameterElement] contributed by a single

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

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

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

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

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,10 @@ class ConstructorElementImpl extends ExecutableElementImpl
701701
@trackedIncludedInId
702702
bool get isConst => _firstFragment.isConst;
703703

704+
@override
705+
@trackedIncludedInId
706+
bool get isDeclaring => _firstFragment.isDeclaring;
707+
704708
@override
705709
@trackedIndirectly
706710
bool get isDefaultConstructor => _firstFragment.isDefaultConstructor;
@@ -713,6 +717,10 @@ class ConstructorElementImpl extends ExecutableElementImpl
713717
@trackedIndirectly
714718
bool get isGenerative => !isFactory;
715719

720+
@override
721+
@trackedIncludedInId
722+
bool get isPrimary => _firstFragment.isPrimary;
723+
716724
@override
717725
@trackedIncludedInId
718726
ElementKind get kind => ElementKind.CONSTRUCTOR;
@@ -2627,6 +2635,22 @@ class FieldElementImpl extends PropertyInducingElementImpl
26272635
@trackedIncludedInId
26282636
FieldElementImpl get baseElement => this;
26292637

2638+
@override
2639+
@trackedIndirectly
2640+
FieldFormalParameterElementImpl? get declaringFormalParameter {
2641+
if (enclosingElement case InterfaceElementImpl enclosingElement) {
2642+
var declaringConstructor = enclosingElement.constructors.firstWhereOrNull(
2643+
(constructor) => constructor.isDeclaring,
2644+
);
2645+
return declaringConstructor?.formalParameters
2646+
.whereType<FieldFormalParameterElementImpl>()
2647+
.firstWhereOrNull((f) {
2648+
return f.isDeclaring && f.field == this;
2649+
});
2650+
}
2651+
return null;
2652+
}
2653+
26302654
@override
26312655
@trackedIncludedInId
26322656
InstanceElementImpl get enclosingElement {
@@ -2828,12 +2852,17 @@ class FieldFormalParameterElementImpl extends FormalParameterElementImpl
28282852
];
28292853
}
28302854

2855+
@override
2856+
bool get isDeclaring => _firstFragment.isDeclaring;
2857+
28312858
@override
28322859
FieldFormalParameterFragmentImpl get _firstFragment =>
28332860
super._firstFragment as FieldFormalParameterFragmentImpl;
28342861
}
28352862

2863+
@GenerateFragmentImpl(modifiers: _FieldFormalParameterFragmentModifiers.values)
28362864
class FieldFormalParameterFragmentImpl extends FormalParameterFragmentImpl
2865+
with _FieldFormalParameterFragmentImplMixin
28372866
implements FieldFormalParameterFragment {
28382867
/// Initialize a newly created parameter element to have the given [name] and
28392868
/// [nameOffset].
@@ -7754,7 +7783,12 @@ enum Modifier {
77547783
/// Indicates that the class is `Object` from `dart:core`.
77557784
DART_CORE_OBJECT,
77567785

7757-
/// Indicates that the import element represents a deferred library.
7786+
/// Indicates that the element is either:
7787+
/// 1. Declaring formal parameters.
7788+
/// 2. Declaring constructor.
7789+
DECLARING,
7790+
7791+
/// Indicates that the element is a declaring formal parameter.
77587792
DEFERRED,
77597793

77607794
/// Indicates that a class element was defined by an enum declaration.
@@ -7822,6 +7856,10 @@ enum Modifier {
78227856
/// enclosing element. This includes not only explicitly specified type
78237857
/// annotations, but also inferred types.
78247858
NO_ENCLOSING_TYPE_PARAMETER_REFERENCE,
7859+
7860+
/// Whether the constructor is primary.
7861+
PRIMARY,
7862+
78257863
PROMOTABLE,
78267864

78277865
/// Indicates whether the type of a [PropertyInducingFragmentImpl] should be
@@ -10053,7 +10091,12 @@ enum _ClassFragmentImplModifiers {
1005310091
isSealed,
1005410092
}
1005510093

10056-
enum _ConstructorFragmentImplModifiers { isConst, isFactory }
10094+
enum _ConstructorFragmentImplModifiers {
10095+
isConst,
10096+
isDeclaring,
10097+
isFactory,
10098+
isPrimary,
10099+
}
1005710100

1005810101
enum _ExecutableFragmentImplModifiers {
1005910102
hasImplicitReturnType,
@@ -10073,6 +10116,8 @@ enum _ExecutableFragmentImplModifiers {
1007310116
isStatic,
1007410117
}
1007510118

10119+
enum _FieldFormalParameterFragmentModifiers { isDeclaring }
10120+
1007610121
enum _FieldFragmentImplModifiers {
1007710122
/// Whether the field was explicitly marked as being covariant.
1007810123
isExplicitlyCovariant,

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ mixin _ConstructorFragmentImplMixin {
9191
setModifier(Modifier.CONST, value);
9292
}
9393

94+
bool get isDeclaring {
95+
return hasModifier(Modifier.DECLARING);
96+
}
97+
98+
set isDeclaring(bool value) {
99+
setModifier(Modifier.DECLARING, value);
100+
}
101+
94102
bool get isFactory {
95103
return hasModifier(Modifier.FACTORY);
96104
}
@@ -99,6 +107,14 @@ mixin _ConstructorFragmentImplMixin {
99107
setModifier(Modifier.FACTORY, value);
100108
}
101109

110+
bool get isPrimary {
111+
return hasModifier(Modifier.PRIMARY);
112+
}
113+
114+
set isPrimary(bool value) {
115+
setModifier(Modifier.PRIMARY, value);
116+
}
117+
102118
bool hasModifier(Modifier modifier);
103119

104120
void setModifier(Modifier modifier, bool value);
@@ -172,6 +188,20 @@ mixin _ExecutableFragmentImplMixin {
172188
void setModifier(Modifier modifier, bool value);
173189
}
174190

191+
mixin _FieldFormalParameterFragmentImplMixin {
192+
bool get isDeclaring {
193+
return hasModifier(Modifier.DECLARING);
194+
}
195+
196+
set isDeclaring(bool value) {
197+
setModifier(Modifier.DECLARING, value);
198+
}
199+
200+
bool hasModifier(Modifier modifier);
201+
202+
void setModifier(Modifier modifier, bool value);
203+
}
204+
175205
mixin _FieldFragmentImplMixin {
176206
bool get isEnumConstant {
177207
return hasModifier(Modifier.ENUM_CONSTANT);

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ class SubstitutedConstructorElementImpl extends SubstitutedExecutableElementImpl
4949
@override
5050
bool get isConst => baseElement.isConst;
5151

52+
@override
53+
bool get isDeclaring => baseElement.isDeclaring;
54+
5255
@override
5356
bool get isDefaultConstructor => baseElement.isDefaultConstructor;
5457

@@ -58,6 +61,9 @@ class SubstitutedConstructorElementImpl extends SubstitutedExecutableElementImpl
5861
@override
5962
bool get isGenerative => baseElement.isGenerative;
6063

64+
@override
65+
bool get isPrimary => baseElement.isPrimary;
66+
6167
@override
6268
LibraryElementImpl get library => baseElement.library;
6369

@@ -399,6 +405,11 @@ class SubstitutedFieldElementImpl extends SubstitutedVariableElementImpl
399405
@override
400406
List<Element> get children => const [];
401407

408+
@override
409+
FieldFormalParameterElementImpl? get declaringFormalParameter {
410+
return baseElement.declaringFormalParameter;
411+
}
412+
402413
@override
403414
String? get documentationComment => baseElement.documentationComment;
404415

@@ -541,6 +552,9 @@ class SubstitutedFieldFormalParameterElementImpl
541552

542553
@override
543554
bool get isCovariant => baseElement.isCovariant;
555+
556+
@override
557+
bool get isDeclaring => baseElement.isDeclaring;
544558
}
545559

546560
/// A parameter element defined in a parameterized type where the values of the

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,9 @@ class ConstructorItem extends ExecutableItem<ConstructorElementImpl> {
183183
return context.withFormalParameters(element.formalParameters, () {
184184
return super.match(context, element) &&
185185
flags.isConst == element.isConst &&
186+
flags.isDeclaring == element.isDeclaring &&
186187
flags.isFactory == element.isFactory &&
188+
flags.isPrimary == element.isPrimary &&
187189
constantInitializers.match(context, element.constantInitializers) &&
188190
redirectedConstructor.match(context, element.redirectedConstructor) &&
189191
superConstructor.match(context, element.superConstructor);
@@ -1584,7 +1586,7 @@ enum _ClassItemFlag {
15841586
isSealed,
15851587
}
15861588

1587-
enum _ConstructorItemFlag { isConst, isFactory }
1589+
enum _ConstructorItemFlag { isConst, isDeclaring, isFactory, isPrimary }
15881590

15891591
enum _ExecutableItemFlag {
15901592
hasEnclosingTypeParameterReference,
@@ -1720,9 +1722,15 @@ extension type _ConstructorItemFlags._(int _bits)
17201722
if (element.isConst) {
17211723
bits |= _maskFor(_ConstructorItemFlag.isConst);
17221724
}
1725+
if (element.isDeclaring) {
1726+
bits |= _maskFor(_ConstructorItemFlag.isDeclaring);
1727+
}
17231728
if (element.isFactory) {
17241729
bits |= _maskFor(_ConstructorItemFlag.isFactory);
17251730
}
1731+
if (element.isPrimary) {
1732+
bits |= _maskFor(_ConstructorItemFlag.isPrimary);
1733+
}
17261734
return _ConstructorItemFlags._(bits);
17271735
}
17281736

@@ -1734,10 +1742,18 @@ extension type _ConstructorItemFlags._(int _bits)
17341742
return _has(_ConstructorItemFlag.isConst);
17351743
}
17361744

1745+
bool get isDeclaring {
1746+
return _has(_ConstructorItemFlag.isDeclaring);
1747+
}
1748+
17371749
bool get isFactory {
17381750
return _has(_ConstructorItemFlag.isFactory);
17391751
}
17401752

1753+
bool get isPrimary {
1754+
return _has(_ConstructorItemFlag.isPrimary);
1755+
}
1756+
17411757
void write(BinaryWriter writer) {
17421758
writer.writeUint30(_bits);
17431759
}

0 commit comments

Comments
 (0)