Skip to content

Commit 45033c6

Browse files
johnniwinthercommit-bot@chromium.org
authored andcommitted
[cfe] Use StaticTypeContext for getStaticType
Change Expression.getStaticType to take a StaticTypeContext instead of a TypeEnvironment. The StaticTypeContext provides access to the TypeEnvironment and the current 'this type' as well as determining the nullability state of the enclosing library. This change is needed to support nnbd types for getStaticType and also serves as a step towards supporting caching during static type computations to avoid repeated computations of the same (complex) expressions. Change-Id: Ied974dff7f6f7c3c8f262aa80c8dea5c674662f7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/124683 Commit-Queue: Johnni Winther <[email protected]> Reviewed-by: Alexander Markov <[email protected]> Reviewed-by: Sigmund Cherem <[email protected]> Reviewed-by: Dmitry Stefantsov <[email protected]>
1 parent efbfda2 commit 45033c6

43 files changed

Lines changed: 1243 additions & 495 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

pkg/compiler/lib/src/ir/annotations.dart

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:kernel/ast.dart' as ir;
6+
import 'package:kernel/type_environment.dart' as ir;
67
import '../common/names.dart';
78
import 'modular.dart';
89

@@ -125,13 +126,15 @@ IrAnnotationData processAnnotations(ModularCore modularCore) {
125126
IrAnnotationData data = new IrAnnotationData();
126127

127128
void processMember(ir.Member member) {
129+
ir.StaticTypeContext staticTypeContext = new ir.StaticTypeContext(
130+
member, modularCore.constantEvaluator.typeEnvironment);
128131
List<PragmaAnnotationData> pragmaAnnotations;
129132
List<String> createsAnnotations;
130133
List<String> returnsAnnotations;
131134
for (ir.Expression annotation in member.annotations) {
132135
if (annotation is ir.ConstantExpression) {
133-
ir.Constant constant =
134-
modularCore.constantEvaluator.evaluate(annotation);
136+
ir.Constant constant = modularCore.constantEvaluator
137+
.evaluate(staticTypeContext, annotation);
135138

136139
String jsName = _getJsInteropName(constant);
137140
if (jsName != null) {
@@ -176,10 +179,13 @@ IrAnnotationData processAnnotations(ModularCore modularCore) {
176179
}
177180

178181
for (ir.Library library in component.libraries) {
182+
ir.StaticTypeContext staticTypeContext =
183+
new ir.StaticTypeContext.forAnnotations(
184+
library, modularCore.constantEvaluator.typeEnvironment);
179185
for (ir.Expression annotation in library.annotations) {
180186
if (annotation is ir.ConstantExpression) {
181-
ir.Constant constant =
182-
modularCore.constantEvaluator.evaluate(annotation);
187+
ir.Constant constant = modularCore.constantEvaluator
188+
.evaluate(staticTypeContext, annotation);
183189

184190
String jsName = _getJsInteropName(constant);
185191
if (jsName != null) {
@@ -190,8 +196,8 @@ IrAnnotationData processAnnotations(ModularCore modularCore) {
190196
for (ir.Class cls in library.classes) {
191197
for (ir.Expression annotation in cls.annotations) {
192198
if (annotation is ir.ConstantExpression) {
193-
ir.Constant constant =
194-
modularCore.constantEvaluator.evaluate(annotation);
199+
ir.Constant constant = modularCore.constantEvaluator
200+
.evaluate(staticTypeContext, annotation);
195201

196202
String nativeClassName = _getNativeClassName(constant);
197203
if (nativeClassName != null) {

pkg/compiler/lib/src/ir/cached_static_type.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ import 'static_type_provider.dart';
1616
class CachedStaticType extends StaticTypeBase implements StaticTypeProvider {
1717
final StaticTypeCache _cache;
1818

19+
@override
20+
final ir.StaticTypeContext staticTypeContext;
21+
1922
@override
2023
final ThisInterfaceType thisType;
2124

22-
CachedStaticType(
23-
ir.TypeEnvironment typeEnvironment, this._cache, this.thisType)
24-
: super(typeEnvironment);
25+
CachedStaticType(this.staticTypeContext, this._cache, this.thisType)
26+
: super(staticTypeContext.typeEnvironment);
2527

2628
@override
2729
ir.DartType getStaticType(ir.Expression node) {

pkg/compiler/lib/src/ir/constants.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,15 @@ class Dart2jsConstantEvaluator extends ir.ConstantEvaluator {
3434
ErrorReporter get errorReporter => super.errorReporter;
3535

3636
@override
37-
ir.Constant evaluate(ir.Expression node, {bool requireConstant: true}) {
37+
ir.Constant evaluate(
38+
ir.StaticTypeContext staticTypeContext, ir.Expression node,
39+
{bool requireConstant: true}) {
3840
errorReporter.requiresConstant = requireConstant;
3941
if (node is ir.ConstantExpression) {
4042
ir.Constant constant = node.constant;
4143
if (constant is ir.UnevaluatedConstant) {
42-
ir.Constant result = super.evaluate(constant.expression);
44+
ir.Constant result =
45+
super.evaluate(staticTypeContext, constant.expression);
4346
assert(
4447
result is ir.UnevaluatedConstant ||
4548
!result.accept(const UnevaluatedConstantFinder()),
@@ -54,10 +57,10 @@ class Dart2jsConstantEvaluator extends ir.ConstantEvaluator {
5457
if (requireConstant) {
5558
// TODO(johnniwinther): Handle reporting of compile-time constant
5659
// evaluation errors.
57-
return super.evaluate(node);
60+
return super.evaluate(staticTypeContext, node);
5861
} else {
5962
try {
60-
return super.evaluate(node);
63+
return super.evaluate(staticTypeContext, node);
6164
} catch (e) {
6265
return null;
6366
}

pkg/compiler/lib/src/ir/impact.dart

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,12 @@ abstract class ImpactBuilderBase extends StaticTypeVisitor
198198
@override
199199
final VariableScopeModel variableScopeModel;
200200

201-
ImpactBuilderBase(ir.TypeEnvironment typeEnvironment,
202-
ir.ClassHierarchy classHierarchy, this.variableScopeModel)
203-
: super(typeEnvironment, classHierarchy);
201+
@override
202+
final ir.StaticTypeContext staticTypeContext;
203+
204+
ImpactBuilderBase(this.staticTypeContext, ir.ClassHierarchy classHierarchy,
205+
this.variableScopeModel)
206+
: super(staticTypeContext.typeEnvironment, classHierarchy);
204207

205208
@override
206209
void handleIntLiteral(ir.IntLiteral node) {
@@ -668,10 +671,10 @@ class ImpactBuilder extends ImpactBuilderBase with ImpactRegistryMixin {
668671
@override
669672
final inferEffectivelyFinalVariableTypes;
670673

671-
ImpactBuilder(ir.TypeEnvironment typeEnvironment,
674+
ImpactBuilder(ir.StaticTypeContext staticTypeContext,
672675
ir.ClassHierarchy classHierarchy, VariableScopeModel variableScopeModel,
673676
{this.useAsserts: false, this.inferEffectivelyFinalVariableTypes: true})
674-
: super(typeEnvironment, classHierarchy, variableScopeModel);
677+
: super(staticTypeContext, classHierarchy, variableScopeModel);
675678

676679
ImpactBuilderData computeImpact(ir.Member node) {
677680
if (retainDataForTesting) {

pkg/compiler/lib/src/ir/scope_visitor.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:kernel/ast.dart' as ir;
6+
import 'package:kernel/type_environment.dart' as ir;
67
import 'package:front_end/src/api_prototype/constant_evaluator.dart' as ir;
78

89
import 'closure.dart';
@@ -15,6 +16,7 @@ import 'scope.dart';
1516
class ScopeModelBuilder extends ir.Visitor<InitializerComplexity>
1617
with VariableCollectorMixin {
1718
final ir.ConstantEvaluator _constantEvaluator;
19+
ir.StaticTypeContext _staticTypeContext;
1820

1921
final ClosureScopeModel _model = new ClosureScopeModel();
2022

@@ -85,6 +87,8 @@ class ScopeModelBuilder extends ir.Visitor<InitializerComplexity>
8587
initializerComplexity: const InitializerComplexity.lazy());
8688
}
8789

90+
_staticTypeContext =
91+
new ir.StaticTypeContext(node, _constantEvaluator.typeEnvironment);
8892
if (node is ir.Constructor) {
8993
_hasThisLocal = true;
9094
} else if (node is ir.Procedure && node.kind == ir.ProcedureKind.Factory) {
@@ -1074,7 +1078,7 @@ class ScopeModelBuilder extends ir.Visitor<InitializerComplexity>
10741078
@override
10751079
InitializerComplexity visitConstantExpression(ir.ConstantExpression node) {
10761080
if (node.constant is ir.UnevaluatedConstant) {
1077-
node.constant = _constantEvaluator.evaluate(node);
1081+
node.constant = _constantEvaluator.evaluate(_staticTypeContext, node);
10781082
}
10791083
return const InitializerComplexity.constant();
10801084
}

pkg/compiler/lib/src/ir/static_type_base.dart

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ abstract class StaticTypeBase extends ir.Visitor<ir.DartType> {
6565

6666
ir.TypeEnvironment get typeEnvironment => _typeEnvironment;
6767

68+
ir.StaticTypeContext get staticTypeContext;
69+
6870
ThisInterfaceType get thisType;
6971

7072
@override
@@ -131,17 +133,20 @@ abstract class StaticTypeBase extends ir.Visitor<ir.DartType> {
131133

132134
@override
133135
ir.DartType visitListLiteral(ir.ListLiteral node) {
134-
return typeEnvironment.literalListType(node.typeArgument);
136+
return typeEnvironment.literalListType(
137+
node.typeArgument, ir.Nullability.legacy);
135138
}
136139

137140
@override
138141
ir.DartType visitSetLiteral(ir.SetLiteral node) {
139-
return typeEnvironment.literalSetType(node.typeArgument);
142+
return typeEnvironment.literalSetType(
143+
node.typeArgument, ir.Nullability.legacy);
140144
}
141145

142146
@override
143147
ir.DartType visitMapLiteral(ir.MapLiteral node) {
144-
return typeEnvironment.literalMapType(node.keyType, node.valueType);
148+
return typeEnvironment.literalMapType(
149+
node.keyType, node.valueType, ir.Nullability.legacy);
145150
}
146151

147152
@override
@@ -225,12 +230,13 @@ abstract class StaticTypeBase extends ir.Visitor<ir.DartType> {
225230

226231
@override
227232
ir.DartType visitLoadLibrary(ir.LoadLibrary node) {
228-
return typeEnvironment.futureType(const ir.DynamicType());
233+
return typeEnvironment.futureType(
234+
const ir.DynamicType(), ir.Nullability.legacy);
229235
}
230236

231237
@override
232238
ir.DartType visitConstantExpression(ir.ConstantExpression node) {
233239
// TODO(johnniwinther): Include interface exactness where applicable.
234-
return node.getStaticType(typeEnvironment);
240+
return node.getStaticType(staticTypeContext);
235241
}
236242
}

pkg/compiler/lib/src/js_backend/field_analysis.dart

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:kernel/ast.dart' as ir;
6+
import 'package:kernel/type_environment.dart' as ir;
67

78
import '../common.dart';
89
import '../constants/values.dart';
@@ -56,7 +57,8 @@ class KFieldAnalysis {
5657

5758
FieldEntity fieldElement = _elementMap.getField(field);
5859
ir.Expression expression = field.initializer;
59-
ConstantValue value = _elementMap.getConstantValue(expression,
60+
ConstantValue value = _elementMap.getConstantValue(
61+
_elementMap.getStaticTypeContext(fieldElement), expression,
6062
requireConstant: false, implicitNull: true);
6163
if (value != null && value.isConstant) {
6264
fieldData[fieldElement] = new AllocatorData(value);
@@ -65,6 +67,8 @@ class KFieldAnalysis {
6567

6668
for (ir.Constructor constructor in classNode.constructors) {
6769
KConstructor constructorElement = _elementMap.getConstructor(constructor);
70+
ir.StaticTypeContext staticTypeContext =
71+
_elementMap.getStaticTypeContext(constructorElement);
6872
constructors.add(constructorElement);
6973
for (ir.Initializer initializer in constructor.initializers) {
7074
if (initializer is ir.FieldInitializer) {
@@ -79,7 +83,8 @@ class KFieldAnalysis {
7983

8084
Initializer initializerValue = const Initializer.complex();
8185
ir.Expression value = initializer.value;
82-
ConstantValue constantValue = _elementMap.getConstantValue(value,
86+
ConstantValue constantValue = _elementMap.getConstantValue(
87+
staticTypeContext, value,
8388
requireConstant: false, implicitNull: true);
8489
if (constantValue != null && constantValue.isConstant) {
8590
initializerValue = new Initializer.direct(constantValue);
@@ -90,9 +95,8 @@ class KFieldAnalysis {
9095
if (position != -1) {
9196
if (position >= constructor.function.requiredParameterCount) {
9297
constantValue = _elementMap.getConstantValue(
93-
parameter.initializer,
94-
requireConstant: false,
95-
implicitNull: true);
98+
staticTypeContext, parameter.initializer,
99+
requireConstant: false, implicitNull: true);
96100
if (constantValue != null && constantValue.isConstant) {
97101
initializerValue =
98102
new Initializer.positional(position, constantValue);
@@ -103,9 +107,8 @@ class KFieldAnalysis {
103107
constructor.function.namedParameters.indexOf(parameter);
104108
if (position != -1) {
105109
constantValue = _elementMap.getConstantValue(
106-
parameter.initializer,
107-
requireConstant: false,
108-
implicitNull: true);
110+
staticTypeContext, parameter.initializer,
111+
requireConstant: false, implicitNull: true);
109112
if (constantValue != null && constantValue.isConstant) {
110113
initializerValue =
111114
new Initializer.named(parameter.name, constantValue);
@@ -123,7 +126,8 @@ class KFieldAnalysis {
123126
void registerStaticField(KField field, InitializerComplexity complexity) {
124127
ir.Field node = _elementMap.getMemberNode(field);
125128
ir.Expression expression = node.initializer;
126-
ConstantValue value = _elementMap.getConstantValue(expression,
129+
ConstantValue value = _elementMap.getConstantValue(
130+
_elementMap.getStaticTypeContext(field), expression,
127131
requireConstant: node.isConst, implicitNull: true);
128132
if (value != null && !value.isConstant) {
129133
value = null;

pkg/compiler/lib/src/js_model/element_map_impl.dart

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,25 +1211,30 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
12111211
ir.ClassHierarchy get classHierarchy =>
12121212
_classHierarchy ??= ir.ClassHierarchy(programEnv.mainComponent);
12131213

1214+
ir.StaticTypeContext getStaticTypeContext(ir.Member node) {
1215+
// TODO(johnniwinther): Cache the static type context.
1216+
return new ir.StaticTypeContext(node, typeEnvironment);
1217+
}
1218+
12141219
@override
12151220
StaticTypeProvider getStaticTypeProvider(MemberEntity member) {
12161221
MemberDefinition memberDefinition = members.getData(member).definition;
12171222
StaticTypeCache cachedStaticTypes;
1218-
ir.InterfaceType thisType;
1223+
ir.StaticTypeContext staticTypeContext;
12191224
switch (memberDefinition.kind) {
12201225
case MemberKind.regular:
12211226
case MemberKind.constructor:
12221227
case MemberKind.constructorBody:
12231228
ir.Member node = memberDefinition.node;
1224-
thisType = node.enclosingClass?.thisType;
1229+
staticTypeContext = getStaticTypeContext(node);
12251230
cachedStaticTypes = members.getData(member).staticTypes;
12261231
break;
12271232
case MemberKind.closureCall:
12281233
ir.TreeNode node = memberDefinition.node;
12291234
while (node != null) {
12301235
if (node is ir.Member) {
12311236
ir.Member member = node;
1232-
thisType = member.enclosingClass?.thisType;
1237+
staticTypeContext = getStaticTypeContext(member);
12331238
cachedStaticTypes = members.getData(getMember(member)).staticTypes;
12341239
break;
12351240
}
@@ -1240,12 +1245,26 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
12401245
case MemberKind.signature:
12411246
case MemberKind.generatorBody:
12421247
cachedStaticTypes = const StaticTypeCache();
1248+
ir.TreeNode node = memberDefinition.node;
1249+
while (node != null) {
1250+
if (node is ir.Member) {
1251+
ir.Member member = node;
1252+
staticTypeContext = getStaticTypeContext(member);
1253+
break;
1254+
} else if (node is ir.Library) {
1255+
// Closure field may use class nodes or type parameter nodes as
1256+
// the definition node.
1257+
staticTypeContext =
1258+
new ir.StaticTypeContext.forAnnotations(node, typeEnvironment);
1259+
}
1260+
node = node.parent;
1261+
}
12431262
break;
12441263
}
1245-
12461264
assert(cachedStaticTypes != null, "No static types cached for $member.");
1247-
return new CachedStaticType(typeEnvironment, cachedStaticTypes,
1248-
new ThisInterfaceType.from(thisType));
1265+
assert(staticTypeContext != null, "No static types context for $member.");
1266+
return new CachedStaticType(staticTypeContext, cachedStaticTypes,
1267+
new ThisInterfaceType.from(staticTypeContext.thisType));
12491268
}
12501269

12511270
@override

pkg/compiler/lib/src/kernel/deferred_load.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
library kernel.deferred_load_data;
66

77
import 'package:kernel/ast.dart' as ir;
8+
import 'package:kernel/type_environment.dart' as ir;
89

910
import '../common_elements.dart';
1011
import '../compiler.dart' show Compiler;
@@ -83,7 +84,8 @@ class KernelDeferredLoadTask extends DeferredLoadTask {
8384
// Fetch the internal node in order to skip annotations on the member.
8485
// TODO(sigmund): replace this pattern when the kernel-ast provides a better
8586
// way to skip annotations (issue 31565).
86-
var visitor = new ConstantCollector(_elementMap, dependencies);
87+
var visitor = new ConstantCollector(
88+
_elementMap, _elementMap.getStaticTypeContext(element), dependencies);
8789
if (node is ir.Field) {
8890
node.initializer?.accept(visitor);
8991
return;
@@ -119,14 +121,15 @@ bool _isVisible(List<ir.Combinator> combinators, String name) {
119121
class ConstantCollector extends ir.RecursiveVisitor {
120122
final KernelToElementMap elementMap;
121123
final Dependencies dependencies;
124+
final ir.StaticTypeContext staticTypeContext;
122125

123-
ConstantCollector(this.elementMap, this.dependencies);
126+
ConstantCollector(this.elementMap, this.staticTypeContext, this.dependencies);
124127

125128
CommonElements get commonElements => elementMap.commonElements;
126129

127130
void add(ir.Expression node, {bool required: true}) {
128-
ConstantValue constant =
129-
elementMap.getConstantValue(node, requireConstant: required);
131+
ConstantValue constant = elementMap
132+
.getConstantValue(staticTypeContext, node, requireConstant: required);
130133
if (constant != null) {
131134
dependencies.addConstant(
132135
constant, elementMap.getImport(getDeferredImport(node)));

0 commit comments

Comments
 (0)