[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)+]