Skip to content

Commit 4177d28

Browse files
johnniwintherCommit Queue
authored and
Commit Queue
committed
[_fe_analyzer_shared] Support deferencing of StaticGet
This adds support for replacement a [StaticGet] with the constant initializer of the referenced constant during evaluation of macro metadata. Currently constants defined in the same library or compilation is supported. For full support the constant initializers need to be included in the outlines/summaries. Change-Id: I219f85dded63342d4e3f957f0b7321badbe376a4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/392907 Commit-Queue: Johnni Winther <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]> Reviewed-by: Jens Johansen <[email protected]>
1 parent 48d8741 commit 4177d28

19 files changed

+343
-99
lines changed

pkg/_fe_analyzer_shared/lib/src/metadata/evaluate.dart

+37-3
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,55 @@
44

55
import 'ast.dart';
66

7+
typedef GetFieldInitializer = Expression? Function(
8+
FieldReference fieldReference);
9+
710
/// Evaluates an [expression] based on the semantics that can be deduced from
811
/// the syntax.
9-
Expression evaluateExpression(Expression expression) {
10-
return new Evaluator().evaluate(expression);
12+
///
13+
/// If [getFieldInitializer] is provided, it is used to get constant initializer
14+
/// expressions of const [StaticGet]s in [expression]. The evaluated constant
15+
/// initializer expressions are used as the evaluation result of the
16+
/// [StaticGet]s.
17+
///
18+
/// If [dereferences] is provided, the field references of [StaticGet]s, for
19+
/// which [getFieldInitializer] has provided a constant initializer
20+
/// [Expression], are mapped to there corresponding in constant initializer
21+
/// [Expression]s in [dereferences].
22+
Expression evaluateExpression(Expression expression,
23+
{GetFieldInitializer? getFieldInitializer,
24+
Map<FieldReference, Expression>? dereferences}) {
25+
return new Evaluator(
26+
getFieldInitializer: getFieldInitializer, dereferences: dereferences)
27+
.evaluate(expression);
1128
}
1229

1330
class Evaluator {
31+
final GetFieldInitializer? _getFieldInitializer;
32+
final Map<FieldReference, Expression>? _dereferences;
33+
34+
Evaluator(
35+
{required GetFieldInitializer? getFieldInitializer,
36+
required Map<FieldReference, Expression>? dereferences})
37+
: _getFieldInitializer = getFieldInitializer,
38+
_dereferences = dereferences;
39+
1440
Expression evaluate(Expression expression) {
1541
return _visitExpression(expression);
1642
}
1743

1844
Expression _visitExpression(Expression expression) {
1945
switch (expression) {
2046
case StaticGet():
21-
// TODO(johnniwinther): Support inlining constant values.
47+
if (_getFieldInitializer != null) {
48+
Expression? result = _getFieldInitializer(expression.reference);
49+
if (result != null) {
50+
if (_dereferences != null) {
51+
_dereferences[expression.reference] = result;
52+
}
53+
return _visitExpression(result);
54+
}
55+
}
2256
return expression;
2357
case InvalidExpression():
2458
case FunctionTearOff():

pkg/_fe_analyzer_shared/lib/src/metadata/parser.dart

+12
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,18 @@ Expression parseAnnotation(
10531053
return listener.pop() as Expression;
10541054
}
10551055

1056+
/// Parses the expression beginning at [initializerToken].
1057+
Expression parseExpression(
1058+
Token initializerToken, Uri fileUri, Scope scope, References references,
1059+
{required bool isDartLibrary, bool delayLookupForTesting = false}) {
1060+
AnnotationsListener listener = new AnnotationsListener(
1061+
fileUri, scope, references,
1062+
delayLookup: delayLookupForTesting, isDartLibrary: isDartLibrary);
1063+
Parser parser = new Parser(listener, useImplicitCreationExpression: false);
1064+
parser.parseExpression(parser.syntheticPreviousToken(initializerToken));
1065+
return listener._popExpression();
1066+
}
1067+
10561068
/// A [Scope] extended to include function type parameters.
10571069
class FunctionTypeParameterScope implements Scope {
10581070
final Scope parentScope;

pkg/_fe_analyzer_shared/lib/src/testing/metadata_helper.dart

+13-3
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,23 @@ Expression unwrap(Expression expression) {
2727

2828
/// Creates a list containing structured and readable textual representation of
2929
/// the [resolved] expression and the result of evaluating [resolved].
30-
List<String> evaluationToText(Expression resolved) {
30+
///
31+
/// If [getFieldInitializer] is provided, it is used to dereference constant
32+
/// field references during evaluation.
33+
List<String> evaluationToText(Expression resolved,
34+
{GetFieldInitializer? getFieldInitializer}) {
3135
List<String> list = [];
3236

3337
Expression unwrappedResolved = unwrap(resolved);
3438
list.add('resolved=${expressionToText(unwrappedResolved)}');
35-
list.add(
36-
'evaluate=${expressionToText(evaluateExpression(unwrappedResolved))}');
39+
40+
Map<FieldReference, Expression> dereferences = {};
41+
Expression evaluated = evaluateExpression(unwrappedResolved,
42+
getFieldInitializer: getFieldInitializer, dereferences: dereferences);
43+
list.add('evaluate=${expressionToText(evaluated)}');
44+
for (MapEntry<FieldReference, Expression> entry in dereferences.entries) {
45+
list.add('${entry.key.name}=${expressionToText(entry.value)}');
46+
}
3747

3848
return list;
3949
}

pkg/_fe_analyzer_shared/test/metadata/evaluate_data/binary.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -125,5 +125,6 @@ void binary19() {}
125125
@Helper(1 + constInt)
126126
/*member: binary20:
127127
resolved=BinaryExpression(IntegerLiteral(1) + StaticGet(constInt))
128-
evaluate=BinaryExpression(IntegerLiteral(1) + StaticGet(constInt))*/
128+
evaluate=IntegerLiteral(value=43)
129+
constInt=IntegerLiteral(42)*/
129130
void binary20() {}

pkg/_fe_analyzer_shared/test/metadata/evaluate_data/equality.dart

+4-2
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,14 @@ void equalityExpression6() {}
4747
@Helper(constInt == 1)
4848
/*member: equalityExpression7:
4949
resolved=EqualityExpression(StaticGet(constInt) == IntegerLiteral(1))
50-
evaluate=EqualityExpression(StaticGet(constInt) == IntegerLiteral(1))*/
50+
evaluate=BooleanLiteral(false)
51+
constInt=IntegerLiteral(42)*/
5152
void equalityExpression7() {}
5253

5354
@Helper(constInt != 1)
5455
/*member: equalityExpression8:
5556
resolved=EqualityExpression(StaticGet(constInt) != IntegerLiteral(1))
56-
evaluate=EqualityExpression(StaticGet(constInt) != IntegerLiteral(1))*/
57+
evaluate=BooleanLiteral(true)
58+
constInt=IntegerLiteral(42)*/
5759
void equalityExpression8() {}
5860

pkg/_fe_analyzer_shared/test/metadata/evaluate_data/if_null.dart

+2-5
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,6 @@ resolved=IfNull(
5555
??
5656
IntegerLiteral(0)
5757
)
58-
evaluate=IfNull(
59-
StaticGet(constNullableInt)
60-
??
61-
IntegerLiteral(0)
62-
)*/
58+
evaluate=IntegerLiteral(42)
59+
constNullableInt=IntegerLiteral(42)*/
6360
void ifNull5() {}

pkg/_fe_analyzer_shared/test/metadata/evaluate_data/list_literal.dart

+39-24
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ void listLiteral3() {}
3333
@Helper([?constInt])
3434
/*member: listLiteral4:
3535
resolved=ListLiteral([ExpressionElement(?StaticGet(constInt))])
36-
evaluate=ListLiteral([ExpressionElement(?StaticGet(constInt))])*/
36+
evaluate=ListLiteral([ExpressionElement(IntegerLiteral(42))])
37+
constInt=IntegerLiteral(42)*/
3738
void listLiteral4() {}
3839

3940
@Helper([if (true) 1])
@@ -57,9 +58,8 @@ void listLiteral6() {}
5758
resolved=ListLiteral([IfElement(
5859
StaticGet(constBool),
5960
ExpressionElement(IntegerLiteral(1)))])
60-
evaluate=ListLiteral([IfElement(
61-
StaticGet(constBool),
62-
ExpressionElement(IntegerLiteral(1)))])*/
61+
evaluate=ListLiteral([ExpressionElement(IntegerLiteral(1))])
62+
constBool=BooleanLiteral(true)*/
6363
void listLiteral7() {}
6464

6565
@Helper([if (true) 1 else 2])
@@ -86,10 +86,8 @@ resolved=ListLiteral([IfElement(
8686
StaticGet(constBool),
8787
ExpressionElement(IntegerLiteral(1)),
8888
ExpressionElement(IntegerLiteral(2)))])
89-
evaluate=ListLiteral([IfElement(
90-
StaticGet(constBool),
91-
ExpressionElement(IntegerLiteral(1)),
92-
ExpressionElement(IntegerLiteral(2)))])*/
89+
evaluate=ListLiteral([ExpressionElement(IntegerLiteral(1))])
90+
constBool=BooleanLiteral(true)*/
9391
void listLiteral10() {}
9492

9593
@Helper([...[0, 1]])
@@ -105,7 +103,12 @@ void listLiteral11() {}
105103
@Helper([...constList])
106104
/*member: listLiteral12:
107105
resolved=ListLiteral([SpreadElement(...StaticGet(constList))])
108-
evaluate=ListLiteral([SpreadElement(...StaticGet(constList))])*/
106+
evaluate=ListLiteral([
107+
ExpressionElement(IntegerLiteral(2)),
108+
ExpressionElement(IntegerLiteral(3))])
109+
constList=ListLiteral([
110+
ExpressionElement(IntegerLiteral(2)),
111+
ExpressionElement(IntegerLiteral(3))])*/
109112
void listLiteral12() {}
110113

111114
@Helper([...?[0, 1]])
@@ -121,7 +124,12 @@ void listLiteral13() {}
121124
@Helper([...?constList])
122125
/*member: listLiteral14:
123126
resolved=ListLiteral([SpreadElement(?...StaticGet(constList))])
124-
evaluate=ListLiteral([SpreadElement(?...StaticGet(constList))])*/
127+
evaluate=ListLiteral([
128+
ExpressionElement(IntegerLiteral(2)),
129+
ExpressionElement(IntegerLiteral(3))])
130+
constList=ListLiteral([
131+
ExpressionElement(IntegerLiteral(2)),
132+
ExpressionElement(IntegerLiteral(3))])*/
125133
void listLiteral14() {}
126134

127135
@Helper([...?null])
@@ -135,7 +143,8 @@ void listLiteral15() {}
135143
resolved=ListLiteral([IfElement(
136144
StaticGet(constBool),
137145
ExpressionElement(?NullLiteral()))])
138-
evaluate=ListLiteral([])*/
146+
evaluate=ListLiteral([])
147+
constBool=BooleanLiteral(true)*/
139148
void listLiteral16() {}
140149

141150
@Helper([if (constBool) ?null else 2])
@@ -144,9 +153,8 @@ resolved=ListLiteral([IfElement(
144153
StaticGet(constBool),
145154
ExpressionElement(?NullLiteral()),
146155
ExpressionElement(IntegerLiteral(2)))])
147-
evaluate=ListLiteral([IfElement(
148-
UnaryExpression(!StaticGet(constBool)),
149-
ExpressionElement(IntegerLiteral(2)))])*/
156+
evaluate=ListLiteral([])
157+
constBool=BooleanLiteral(true)*/
150158
void listLiteral17() {}
151159

152160
@Helper([if (constBool) 1 else ?null])
@@ -155,9 +163,8 @@ resolved=ListLiteral([IfElement(
155163
StaticGet(constBool),
156164
ExpressionElement(IntegerLiteral(1)),
157165
ExpressionElement(?NullLiteral()))])
158-
evaluate=ListLiteral([IfElement(
159-
StaticGet(constBool),
160-
ExpressionElement(IntegerLiteral(1)))])*/
166+
evaluate=ListLiteral([ExpressionElement(IntegerLiteral(1))])
167+
constBool=BooleanLiteral(true)*/
161168
void listLiteral18() {}
162169

163170
@Helper([if (constBool) ?null else ?null])
@@ -166,47 +173,53 @@ resolved=ListLiteral([IfElement(
166173
StaticGet(constBool),
167174
ExpressionElement(?NullLiteral()),
168175
ExpressionElement(?NullLiteral()))])
169-
evaluate=ListLiteral([])*/
176+
evaluate=ListLiteral([])
177+
constBool=BooleanLiteral(true)*/
170178
void listLiteral19() {}
171179

172180
@Helper([if (constBool) ...[]])
173181
/*member: listLiteral20:
174182
resolved=ListLiteral([IfElement(
175183
StaticGet(constBool),
176184
SpreadElement(...ListLiteral([])))])
177-
evaluate=ListLiteral([])*/
185+
evaluate=ListLiteral([])
186+
constBool=BooleanLiteral(true)*/
178187
void listLiteral20() {}
179188

180189
@Helper([if (constBool) ...{}])
181190
/*member: listLiteral21:
182191
resolved=ListLiteral([IfElement(
183192
StaticGet(constBool),
184193
SpreadElement(...SetOrMapLiteral({})))])
185-
evaluate=ListLiteral([])*/
194+
evaluate=ListLiteral([])
195+
constBool=BooleanLiteral(true)*/
186196
void listLiteral21() {}
187197

188198
@Helper([if (constBool) ...?[]])
189199
/*member: listLiteral22:
190200
resolved=ListLiteral([IfElement(
191201
StaticGet(constBool),
192202
SpreadElement(?...ListLiteral([])))])
193-
evaluate=ListLiteral([])*/
203+
evaluate=ListLiteral([])
204+
constBool=BooleanLiteral(true)*/
194205
void listLiteral22() {}
195206

196207
@Helper([if (constBool) ...?{}])
197208
/*member: listLiteral23:
198209
resolved=ListLiteral([IfElement(
199210
StaticGet(constBool),
200211
SpreadElement(?...SetOrMapLiteral({})))])
201-
evaluate=ListLiteral([])*/
212+
evaluate=ListLiteral([])
213+
constBool=BooleanLiteral(true)*/
202214
void listLiteral23() {}
203215

204216
@Helper([if (constBool) ...?null])
205217
/*member: listLiteral24:
206218
resolved=ListLiteral([IfElement(
207219
StaticGet(constBool),
208220
SpreadElement(?...NullLiteral()))])
209-
evaluate=ListLiteral([])*/
221+
evaluate=ListLiteral([])
222+
constBool=BooleanLiteral(true)*/
210223
void listLiteral24() {}
211224

212225
@Helper([if (constBool) if (constBool) ?null else ?null])
@@ -217,5 +230,7 @@ resolved=ListLiteral([IfElement(
217230
StaticGet(constBool),
218231
ExpressionElement(?NullLiteral()),
219232
ExpressionElement(?NullLiteral())))])
220-
evaluate=ListLiteral([])*/
233+
evaluate=ListLiteral([])
234+
constBool=BooleanLiteral(true)
235+
constBool=BooleanLiteral(true)*/
221236
void listLiteral25() {}

pkg/_fe_analyzer_shared/test/metadata/evaluate_data/logical.dart

+8-4
Original file line numberDiff line numberDiff line change
@@ -59,23 +59,27 @@ void logicalExpression8() {}
5959
@Helper(constBool && true)
6060
/*member: logicalExpression9:
6161
resolved=LogicalExpression(StaticGet(constBool) && BooleanLiteral(true))
62-
evaluate=LogicalExpression(StaticGet(constBool) && BooleanLiteral(true))*/
62+
evaluate=BooleanLiteral(true)
63+
constBool=BooleanLiteral(true)*/
6364
void logicalExpression9() {}
6465

6566
@Helper(constBool && false)
6667
/*member: logicalExpression10:
6768
resolved=LogicalExpression(StaticGet(constBool) && BooleanLiteral(false))
68-
evaluate=LogicalExpression(StaticGet(constBool) && BooleanLiteral(false))*/
69+
evaluate=BooleanLiteral(false)
70+
constBool=BooleanLiteral(true)*/
6971
void logicalExpression10() {}
7072

7173
@Helper(constBool || true)
7274
/*member: logicalExpression11:
7375
resolved=LogicalExpression(StaticGet(constBool) || BooleanLiteral(true))
74-
evaluate=LogicalExpression(StaticGet(constBool) || BooleanLiteral(true))*/
76+
evaluate=BooleanLiteral(true)
77+
constBool=BooleanLiteral(true)*/
7578
void logicalExpression11() {}
7679

7780
@Helper(constBool || false)
7881
/*member: logicalExpression12:
7982
resolved=LogicalExpression(StaticGet(constBool) || BooleanLiteral(false))
80-
evaluate=LogicalExpression(StaticGet(constBool) || BooleanLiteral(false))*/
83+
evaluate=BooleanLiteral(true)
84+
constBool=BooleanLiteral(true)*/
8185
void logicalExpression12() {}

pkg/_fe_analyzer_shared/test/metadata/evaluate_data/null_check.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@ void nullCheck2() {}
2323
@Helper(constInt!)
2424
/*member: nullCheck3:
2525
resolved=NullCheck(StaticGet(constInt))
26-
evaluate=NullCheck(StaticGet(constInt))*/
26+
evaluate=IntegerLiteral(42)
27+
constInt=IntegerLiteral(42)*/
2728
void nullCheck3() {}

0 commit comments

Comments
 (0)