Skip to content

Commit 7ff66f4

Browse files
scheglovCommit Queue
authored andcommitted
Elements. Implement returning ConstantInitializer.
Change-Id: Ib0f3d569b28396cee2633630d8fc968c4fd822e4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/410900 Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Phil Quitslund <[email protected]>
1 parent 2f2c079 commit 7ff66f4

27 files changed

+11022
-161
lines changed

pkg/analyzer/api.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3635,6 +3635,7 @@ package:analyzer/dart/element/element2.dart:
36353635
ConstantInitializer (class extends Object):
36363636
new (constructor: ConstantInitializer Function())
36373637
expression (getter: Expression)
3638+
fragment (getter: VariableFragment)
36383639
evaluate (method: DartObject? Function())
36393640
ConstructorElement2 (class extends Object implements ExecutableElement2, HasSinceSdkVersion):
36403641
new (constructor: ConstructorElement2 Function())
@@ -4297,7 +4298,7 @@ package:analyzer/dart/element/element2.dart:
42974298
computeConstantValue (method: DartObject? Function())
42984299
VariableFragment (class extends Object implements Fragment):
42994300
new (constructor: VariableFragment Function())
4300-
constantInitializer2 (getter: ConstantInitializer?)
4301+
constantInitializer2 (getter: Expression?)
43014302
element (getter: VariableElement2)
43024303
nextFragment (getter: VariableFragment?)
43034304
previousFragment (getter: VariableFragment?)

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,11 @@ abstract class ConstantInitializer {
264264
/// have the default value.
265265
Expression get expression;
266266

267+
/// The [VariableFragment] that has [expression].
268+
///
269+
/// The offsets are inside the [LibraryFragment] that contains [fragment].
270+
VariableFragment get fragment;
271+
267272
/// Returns the result of evaluating [expression], computes it if necessary.
268273
///
269274
/// Returns `null` if the value could not be computed because of errors.
@@ -2890,7 +2895,7 @@ abstract class VariableFragment implements Fragment {
28902895
///
28912896
/// Is `null` if this variable fragment is not a constant, or does not have
28922897
/// the initializer or the default value specified.
2893-
ConstantInitializer? get constantInitializer2;
2898+
Expression? get constantInitializer2;
28942899

28952900
@override
28962901
VariableElement2 get element;

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

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,6 +1337,31 @@ class CompilationUnitElementImpl extends UriReferencedElementImpl
13371337
}
13381338
}
13391339

1340+
class ConstantInitializerImpl implements ConstantInitializer {
1341+
@override
1342+
final VariableElementImpl fragment;
1343+
1344+
@override
1345+
final ExpressionImpl expression;
1346+
1347+
/// The cached result of [evaluate].
1348+
Constant? _evaluationResult;
1349+
1350+
ConstantInitializerImpl({
1351+
required this.fragment,
1352+
required this.expression,
1353+
});
1354+
1355+
@override
1356+
DartObject? evaluate() {
1357+
if (_evaluationResult case DartObjectImpl result) {
1358+
return result;
1359+
}
1360+
// TODO(scheglov): implement it
1361+
throw UnimplementedError();
1362+
}
1363+
}
1364+
13401365
/// A [FieldElement] for a 'const' or 'final' field that has an initializer.
13411366
///
13421367
// TODO(paulberry): we should rename this class to reflect the fact that it's
@@ -4285,6 +4310,11 @@ class ExtensionTypeElementImpl2 extends InterfaceElementImpl2
42854310
}
42864311
}
42874312

4313+
/// Common base class for all analyzer-internal classes that implement
4314+
/// `FieldElement2`.
4315+
abstract class FieldElement2OrMember
4316+
implements PropertyInducingElement2OrMember, FieldElement2 {}
4317+
42884318
/// A concrete implementation of a [FieldElement].
42894319
class FieldElementImpl extends PropertyInducingElementImpl
42904320
with AugmentableElement<FieldElementImpl>
@@ -4403,7 +4433,7 @@ class FieldElementImpl2 extends PropertyInducingElementImpl2
44034433
FragmentedAnnotatableElementMixin<FieldElementImpl>,
44044434
FragmentedElementMixin<FieldElementImpl>,
44054435
_HasSinceSdkVersionMixin
4406-
implements FieldElement2 {
4436+
implements FieldElement2OrMember {
44074437
@override
44084438
final FieldElementImpl firstFragment;
44094439

@@ -4493,7 +4523,8 @@ class FieldElementImpl2 extends PropertyInducingElementImpl2
44934523

44944524
/// Common base class for all analyzer-internal classes that implement
44954525
/// `FieldElement`.
4496-
abstract class FieldElementOrMember implements FieldElement {
4526+
abstract class FieldElementOrMember
4527+
implements PropertyInducingElementOrMember, FieldElement {
44974528
@override
44984529
TypeImpl get type;
44994530
}
@@ -11791,12 +11822,11 @@ abstract class VariableElementImpl extends ElementImpl
1179111822
/// initializers. However, analyzer also needs to handle incorrect Dart code,
1179211823
/// in which case there might be some constant variables that lack
1179311824
/// initializers.
11794-
Expression? get constantInitializer => null;
11825+
ExpressionImpl? get constantInitializer => null;
1179511826

1179611827
@override
11797-
ConstantInitializer? get constantInitializer2 {
11798-
// TODO(scheglov): implement it
11799-
throw UnimplementedError();
11828+
ExpressionImpl? get constantInitializer2 {
11829+
return constantInitializer;
1180011830
}
1180111831

1180211832
@override
@@ -11896,10 +11926,24 @@ abstract class VariableElementImpl extends ElementImpl
1189611926

1189711927
abstract class VariableElementImpl2 extends ElementImpl2
1189811928
implements VariableElement2OrMember {
11929+
ConstantInitializerImpl? _constantInitializer;
11930+
1189911931
@override
1190011932
ConstantInitializer? get constantInitializer2 {
11901-
// TODO(scheglov): implement it
11902-
throw UnimplementedError();
11933+
if (_constantInitializer case var result?) {
11934+
return result;
11935+
}
11936+
11937+
for (var fragment in fragments.reversed) {
11938+
if (fragment.constantInitializer2 case ExpressionImpl expression) {
11939+
return _constantInitializer = ConstantInitializerImpl(
11940+
fragment: fragment as VariableElementImpl,
11941+
expression: expression,
11942+
);
11943+
}
11944+
}
11945+
11946+
return null;
1190311947
}
1190411948

1190511949
@override

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

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -530,12 +530,7 @@ class FieldFormalParameterMember extends ParameterMember
530530
/// A field element defined in a parameterized type where the values of the type
531531
/// parameters are known.
532532
class FieldMember extends VariableMember
533-
implements
534-
FieldElementOrMember,
535-
FieldElement2,
536-
VariableElement2OrMember,
537-
PropertyInducingElementOrMember,
538-
PropertyInducingElement2OrMember {
533+
implements FieldElementOrMember, FieldElement2OrMember {
539534
/// Initialize a newly created element to represent a field, based on the
540535
/// [declaration], with applied [substitution].
541536
FieldMember(
@@ -563,8 +558,7 @@ class FieldMember extends VariableMember
563558

564559
@override
565560
ConstantInitializer? get constantInitializer2 {
566-
// TODO(scheglov): implement it
567-
throw UnimplementedError();
561+
return baseElement.constantInitializer2;
568562
}
569563

570564
@override
@@ -1229,8 +1223,7 @@ class ParameterMember extends VariableMember
12291223

12301224
@override
12311225
ConstantInitializer? get constantInitializer2 {
1232-
// TODO(scheglov): implement it
1233-
throw UnimplementedError();
1226+
return baseElement.constantInitializer2;
12341227
}
12351228

12361229
@override

pkg/analyzer/lib/src/generated/resolver.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2510,7 +2510,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
25102510

25112511
var element = node.declaredElement!;
25122512
var initializer = element.constantInitializer;
2513-
if (initializer is InstanceCreationExpression) {
2513+
if (initializer is InstanceCreationExpressionImpl) {
25142514
var constructorName = initializer.constructorName;
25152515
var constructorElement = constructorName.staticElement;
25162516
if (constructorElement != null) {

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

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,18 @@ class _Element2Writer extends _AbstractElementWriter {
288288
expect(element.nonSynthetic2, same(element));
289289
}
290290

291+
void _writeConstantInitializerExpression(String name, Expression expression) {
292+
if (_idMap.existingExpressionId(expression) case var id?) {
293+
_sink.writelnWithIndent('$name: $id');
294+
} else {
295+
var id = _idMap[expression];
296+
_sink.writelnWithIndent('$name: $id');
297+
_sink.withIndent(() {
298+
_writeNode(expression);
299+
});
300+
}
301+
}
302+
291303
void _writeConstructorElement(ConstructorElement2 e) {
292304
// Check that the reference exists, and filled with the element.
293305
// var reference = e.reference;
@@ -510,6 +522,7 @@ class _Element2Writer extends _AbstractElementWriter {
510522
}
511523

512524
void _writeFieldElement(FieldElement2 e) {
525+
e as FieldElement2OrMember;
513526
DartType type = e.type;
514527
expect(type, isNotNull);
515528

@@ -565,7 +578,7 @@ class _Element2Writer extends _AbstractElementWriter {
565578
// _writeTypeInferenceError(e);
566579
_writeType('type', e.type);
567580
// _writeShouldUseTypeForInitializerInference(e);
568-
// _writeConstantInitializer(e);
581+
_writeVariableElementConstantInitializer(e);
569582
// _writeNonSyntheticElement(e);
570583
// writeLinking();
571584
_writeElementReference('getter', e.getter2);
@@ -623,7 +636,7 @@ class _Element2Writer extends _AbstractElementWriter {
623636
// _writeTypeInferenceError(f);
624637
// _writeType('type', f.type);
625638
// _writeShouldUseTypeForInitializerInference(f);
626-
// _writeConstantInitializer(f);
639+
_writeVariableFragmentConstantInitializer(f);
627640
// _writeNonSyntheticElement(f);
628641
// writeLinking();
629642
_writeFragmentReference('previousFragment', f.previousFragment);
@@ -634,6 +647,7 @@ class _Element2Writer extends _AbstractElementWriter {
634647
}
635648

636649
void _writeFormalParameterElement(FormalParameterElement e) {
650+
e as FormalParameterElementMixin;
637651
// if (e.isNamed && e.enclosingElement2 is ExecutableElement) {
638652
// expect(e.reference, isNotNull);
639653
// } else {
@@ -688,7 +702,7 @@ class _Element2Writer extends _AbstractElementWriter {
688702
e.formalParameters,
689703
_writeFormalParameterElement,
690704
);
691-
// _writeConstantInitializer(e);
705+
_writeVariableElementConstantInitializer(e);
692706
// _writeNonSyntheticElement(e);
693707
// _writeFieldFormalParameterField(e);
694708
// _writeSuperConstructorParameter(e);
@@ -739,7 +753,7 @@ class _Element2Writer extends _AbstractElementWriter {
739753
// _writeCodeRange(f);
740754
// _writeTypeParameterElements(e.typeParameters);
741755
// _writeFragmentList('parameters', f, f.parameters2, _writeFormalParameterFragments);
742-
// _writeConstantInitializer(e);
756+
_writeVariableFragmentConstantInitializer(f);
743757
// _writeNonSyntheticElement(e);
744758
// _writeFieldFormalParameterField(e);
745759
// _writeSuperConstructorParameter(e);
@@ -1626,7 +1640,7 @@ class _Element2Writer extends _AbstractElementWriter {
16261640
// _writeTypeInferenceError(e);
16271641
_writeType('type', e.type);
16281642
// _writeShouldUseTypeForInitializerInference(e);
1629-
// _writeConstantInitializer(e);
1643+
_writeVariableElementConstantInitializer(e);
16301644
// _writeNonSyntheticElement(e);
16311645
// writeLinking();
16321646
_writeElementReference('getter', e.getter2);
@@ -1682,7 +1696,7 @@ class _Element2Writer extends _AbstractElementWriter {
16821696
// _writeTypeInferenceError(f);
16831697
// _writeType('type', f.type);
16841698
// _writeShouldUseTypeForInitializerInference(f);
1685-
// _writeConstantInitializer(f);
1699+
_writeVariableFragmentConstantInitializer(f);
16861700
// _writeNonSyntheticElement(f);
16871701
// writeLinking();
16881702
_writeFragmentReference('previousFragment', f.previousFragment);
@@ -1828,6 +1842,25 @@ class _Element2Writer extends _AbstractElementWriter {
18281842

18291843
// _assertNonSyntheticElementSelf(f);
18301844
}
1845+
1846+
void _writeVariableElementConstantInitializer(VariableElement2OrMember e) {
1847+
if (e.constantInitializer2 case var initializer?) {
1848+
_sink.writelnWithIndent('constantInitializer');
1849+
_sink.withIndent(() {
1850+
_writeFragmentReference('fragment', initializer.fragment);
1851+
_writeConstantInitializerExpression(
1852+
'expression',
1853+
initializer.expression,
1854+
);
1855+
});
1856+
}
1857+
}
1858+
1859+
void _writeVariableFragmentConstantInitializer(VariableFragment f) {
1860+
if (f.constantInitializer2 case var initializer?) {
1861+
_writeConstantInitializerExpression('constantInitializer', initializer);
1862+
}
1863+
}
18311864
}
18321865

18331866
/// Writes the canonical text presentation of elements.
@@ -2943,24 +2976,31 @@ class _ElementWriter extends _AbstractElementWriter {
29432976
}
29442977

29452978
class _IdMap {
2979+
final Map<Expression, String> expressionMap = Map.identity();
29462980
final Map<Element, String> fieldMap = Map.identity();
29472981
final Map<Element, String> getterMap = Map.identity();
29482982
final Map<Element, String> partMap = Map.identity();
29492983
final Map<Element, String> setterMap = Map.identity();
29502984

2951-
String operator [](Element element) {
2952-
if (element is FieldElement) {
2953-
return fieldMap[element] ??= 'field_${fieldMap.length}';
2954-
} else if (element is TopLevelVariableElement) {
2955-
return fieldMap[element] ??= 'variable_${fieldMap.length}';
2956-
} else if (element is PropertyAccessorElement && element.isGetter) {
2957-
return getterMap[element] ??= 'getter_${getterMap.length}';
2958-
} else if (element is PartElementImpl) {
2959-
return partMap[element] ??= 'part_${partMap.length}';
2960-
} else if (element is PropertyAccessorElement && element.isSetter) {
2961-
return setterMap[element] ??= 'setter_${setterMap.length}';
2985+
String operator [](Object object) {
2986+
if (object is Expression) {
2987+
return expressionMap[object] ??= 'expression_${expressionMap.length}';
2988+
} else if (object is FieldElement) {
2989+
return fieldMap[object] ??= 'field_${fieldMap.length}';
2990+
} else if (object is TopLevelVariableElement) {
2991+
return fieldMap[object] ??= 'variable_${fieldMap.length}';
2992+
} else if (object is PropertyAccessorElement && object.isGetter) {
2993+
return getterMap[object] ??= 'getter_${getterMap.length}';
2994+
} else if (object is PartElementImpl) {
2995+
return partMap[object] ??= 'part_${partMap.length}';
2996+
} else if (object is PropertyAccessorElement && object.isSetter) {
2997+
return setterMap[object] ??= 'setter_${setterMap.length}';
29622998
} else {
29632999
return '???';
29643000
}
29653001
}
3002+
3003+
String? existingExpressionId(Expression object) {
3004+
return expressionMap[object];
3005+
}
29663006
}

0 commit comments

Comments
 (0)