[vm/tfa] Pass receiver type into field initializer summaries.
This is required for tracking type arguments, since field initializers can
reference type variables from the enclosing class.
Also a few drive-by spelling fixes.
Change-Id: I91e33f7d8c61e288ccb2d8e18b33f4e67ac22a1b
Cq-Include-Trybots: luci.dart.try:vm-kernel-win-release-x64-try, vm-kernel-optcounter-threshold-linux-release-x64-try, vm-kernel-precomp-linux-debug-x64-try, vm-kernel-precomp-linux-release-simarm-try, vm-kernel-precomp-linux-release-simarm64-try, vm-kernel-precomp-linux-release-x64-try, vm-kernel-precomp-win-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/74666
Commit-Queue: Samir Jindel <sjindel@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 9542ab0..b59c80c 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -163,7 +163,8 @@
case CallKind.PropertyGet:
assertx(args.values.length == firstParamIndex);
assertx(args.names.isEmpty);
- return fieldValue.getValue(typeFlowAnalysis);
+ return fieldValue.getValue(
+ typeFlowAnalysis, field.isStatic ? null : args.values[0]);
case CallKind.PropertySet:
assertx(args.values.length == firstParamIndex + 1);
@@ -176,7 +177,8 @@
// Call via field.
// TODO(alexmarkov): support function types and use inferred type
// to get more precise return type.
- final receiver = fieldValue.getValue(typeFlowAnalysis);
+ final receiver = fieldValue.getValue(
+ typeFlowAnalysis, field.isStatic ? null : args.values[0]);
if (receiver != const EmptyType()) {
typeFlowAnalysis.applyCall(/* callSite = */ null,
DynamicSelector.kCall, new Args.withReceiver(args, receiver),
@@ -185,7 +187,7 @@
return new Type.nullableAny();
case CallKind.FieldInitializer:
- assertx(args.values.isEmpty);
+ assertx(args.values.length == firstParamIndex);
assertx(args.names.isEmpty);
Type initializerResult = typeFlowAnalysis
.getSummary(field)
@@ -685,7 +687,6 @@
final Field field;
final Type staticType;
Type value;
- _DirectInvocation _initializerInvocation;
_FieldValue(this.field) : staticType = new Type.fromStatic(field.type) {
if (field.initializer == null && _isDefaultValueOfFieldObservable()) {
@@ -717,22 +718,22 @@
});
}
- void ensureInitialized(TypeFlowAnalysis typeFlowAnalysis) {
+ void ensureInitialized(TypeFlowAnalysis typeFlowAnalysis, Type receiverType) {
if (field.initializer != null) {
- if (_initializerInvocation == null) {
- _initializerInvocation = typeFlowAnalysis._invocationsCache
- .getInvocation(
- new DirectSelector(field, callKind: CallKind.FieldInitializer),
- new Args<Type>(const <Type>[]));
- }
+ assertx(field.isStatic == (receiverType == null));
+ final args = !field.isStatic ? <Type>[receiverType] : const <Type>[];
+ final initializerInvocation = typeFlowAnalysis._invocationsCache
+ .getInvocation(
+ new DirectSelector(field, callKind: CallKind.FieldInitializer),
+ new Args<Type>(args));
// It may update the field value.
- typeFlowAnalysis.workList.processInvocation(_initializerInvocation);
+ typeFlowAnalysis.workList.processInvocation(initializerInvocation);
}
}
- Type getValue(TypeFlowAnalysis typeFlowAnalysis) {
- ensureInitialized(typeFlowAnalysis);
+ Type getValue(TypeFlowAnalysis typeFlowAnalysis, Type receiverType) {
+ ensureInitialized(typeFlowAnalysis, receiverType);
addDependentInvocation(typeFlowAnalysis.currentInvocation);
return value;
}
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 1126784..57cbe89 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -268,15 +268,24 @@
_returnValue = null;
_receiver = null;
- if (member is Field) {
- _summary = new Summary();
+ final hasReceiver = hasReceiverArg(member);
+ if (member is Field) {
+ if (hasReceiver) {
+ _summary = new Summary(parameterCount: 1, positionalParameterCount: 1);
+ // TODO(alexmarkov): subclass cone
+ _receiver = _declareParameter(
+ "this", member.enclosingClass.rawType, null,
+ isReceiver: true);
+ _environment.thisType = member.enclosingClass?.thisType;
+ } else {
+ _summary = new Summary();
+ }
assertx(member.initializer != null);
_summary.result = _visit(member.initializer);
} else {
FunctionNode function = member.function;
- final hasReceiver = hasReceiverArg(member);
final firstParamIndex = hasReceiver ? 1 : 0;
_summary = new Summary(
@@ -366,8 +375,7 @@
final List<Type> args = <Type>[];
final List<String> names = <String>[];
- if (hasReceiverArg(member) &&
- (selector.callKind != CallKind.FieldInitializer)) {
+ if (hasReceiverArg(member)) {
assertx(member.enclosingClass != null);
Type receiver = new Type.cone(member.enclosingClass.rawType);
args.add(receiver);
diff --git a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
index 88a16e2..f605342 100644
--- a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
+++ b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
@@ -18,11 +18,11 @@
final String pkgVmDir = Platform.script.resolve('../../..').toFilePath();
class PrintSummaries extends RecursiveVisitor<Null> {
- final SummaryCollector _summaryColector;
+ final SummaryCollector _summaryCollector;
final StringBuffer _buf = new StringBuffer();
PrintSummaries(TypeEnvironment environment, CoreTypes coreTypes)
- : _summaryColector = new SummaryCollector(
+ : _summaryCollector = new SummaryCollector(
environment,
new EmptyEntryPointsListener(),
new NativeCodeOracle(
@@ -38,7 +38,7 @@
if (!member.isAbstract &&
!((member is Field) && (member.initializer == null))) {
_buf.writeln("------------ $member ------------");
- _buf.writeln(_summaryColector.createSummary(member));
+ _buf.writeln(_summaryCollector.createSummary(member));
}
}
}
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
index 4deba6d..deb849c 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
@@ -22,7 +22,7 @@
%y = _Parameter #1 [_T (dart.core::int)+?]
RESULT: _T {}?
------------ #lib::B::bar4 ------------
-
+%this = _Parameter #0 [_T (#lib::B)+]
RESULT: _T {}?
------------ #lib::C:: ------------
%this = _Parameter #0 [_T (#lib::C)+]
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/setter_result.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/setter_result.dart.expect
index 608ebfa..d2e41b1 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/setter_result.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/setter_result.dart.expect
@@ -7,7 +7,7 @@
t1 = _Call direct [dart.core::Object::] (%this)
RESULT: _T {}?
------------ #lib::A::foo ------------
-
+%this = _Parameter #0 [_T (#lib::A)+]
RESULT: _T {}?
------------ #lib::B:: ------------
%this = _Parameter #0 [_T (#lib::B)+]