[vm/tfa] Stop accepting non-empty entry points json files

Entry points JSON files are deprecated (replaced with pragmas).
So TFA should not require them. As a sanity check, it will complain
if an entry points JSON file is not empty.

Change-Id: Ie64121ab4cdd0c330f81a8cb71a671e1df82f136
Reviewed-on: https://dart-review.googlesource.com/75423
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
diff --git a/pkg/vm/lib/transformations/type_flow/native_code.dart b/pkg/vm/lib/transformations/type_flow/native_code.dart
index 4ddf112..2c38d28 100644
--- a/pkg/vm/lib/transformations/type_flow/native_code.dart
+++ b/pkg/vm/lib/transformations/type_flow/native_code.dart
@@ -11,7 +11,6 @@
 
 import 'package:kernel/ast.dart';
 import 'package:kernel/core_types.dart' show CoreTypes;
-import 'package:kernel/external_name.dart' show getExternalName;
 import 'package:kernel/library_index.dart' show LibraryIndex;
 
 import 'calls.dart';
@@ -217,8 +216,6 @@
 
 /// Provides insights into the behavior of native code.
 class NativeCodeOracle {
-  final Map<String, List<Map<String, dynamic>>> _nativeMethods =
-      <String, List<Map<String, dynamic>>>{};
   final LibraryIndex _libraryIndex;
   final Set<Member> _membersReferencedFromNativeCode = new Set<Member>();
   final PragmaAnnotationParser _matcher;
@@ -238,11 +235,8 @@
   /// using [entryPointsListener]. Returns result type of the native method.
   Type handleNativeProcedure(
       Member member, EntryPointsListener entryPointsListener) {
-    final String nativeName = getExternalName(member);
     Type returnType = null;
 
-    final nativeActions = _nativeMethods[nativeName];
-
     for (var annotation in member.annotations) {
       ParsedPragma pragma = _matcher.parsePragma(annotation);
       if (pragma == null) continue;
@@ -282,178 +276,25 @@
     }
 
     if (returnType != null) {
-      assertx(nativeActions == null || nativeActions.length == 0);
-      return returnType;
-    }
-
-    if (nativeActions != null) {
-      for (var action in nativeActions) {
-        if (action['action'] == 'return') {
-          final c = _libraryIndex.getClass(action['library'], action['class']);
-
-          final concreteClass = entryPointsListener.addAllocatedClass(c);
-
-          final nullable = action['nullable'];
-          if (nullable == false) {
-            returnType = concreteClass;
-          } else if ((nullable == true) || (nullable == null)) {
-            returnType = new Type.nullable(concreteClass);
-          } else {
-            throw 'Bad entry point: unexpected nullable: "$nullable" in $action';
-          }
-        } else {
-          _addRoot(action, entryPointsListener);
-        }
-      }
-    }
-
-    if (returnType != null) {
       return returnType;
     } else {
       return new Type.fromStatic(member.function.returnType);
     }
   }
 
-  void _addRoot(
-      Map<String, String> rootDesc, EntryPointsListener entryPointsListener) {
-    final String library = rootDesc['library'];
-    final String class_ = rootDesc['class'];
-    final String name = rootDesc['name'];
-    final String action = rootDesc['action'];
-
-    final libraryIndex = _libraryIndex;
-
-    if ((action == 'create-instance') || ((action == null) && (name == null))) {
-      if (name != null) {
-        throw 'Bad entry point: unexpected "name" element in $rootDesc';
-      }
-
-      final Class cls = libraryIndex.getClass(library, class_);
-      if (cls.isAbstract) {
-        throw 'Bad entry point: abstract class listed in $rootDesc';
-      }
-
-      entryPointsListener.addAllocatedClass(cls);
-    } else if ((action == 'call') ||
-        (action == 'get') ||
-        (action == 'set') ||
-        ((action == null) && (name != null))) {
-      if (name == null) {
-        throw 'Bad entry point: expected "name" element in $rootDesc';
-      }
-
-      final String prefix = {
-            'get': LibraryIndex.getterPrefix,
-            'set': LibraryIndex.setterPrefix
-          }[action] ??
-          '';
-
-      Member member;
-
-      if (class_ != null) {
-        final classDotPrefix = class_ + '.';
-        if ((name == class_) || name.startsWith(classDotPrefix)) {
-          // constructor
-          if (action != 'call' && action != null) {
-            throw 'Bad entry point: action "$action" is not applicable to'
-                ' constructor in $rootDesc';
-          }
-
-          final constructorName =
-              (name == class_) ? '' : name.substring(classDotPrefix.length);
-
-          member = libraryIndex.getMember(library, class_, constructorName);
-        } else {
-          member = libraryIndex.tryGetMember(library, class_, prefix + name);
-          if (member == null) {
-            member = libraryIndex.getMember(library, class_, name);
-          }
-        }
-      } else {
-        member = libraryIndex.tryGetTopLevelMember(
-            library, /* unused */ null, prefix + name);
-        if (member == null) {
-          member = libraryIndex.getTopLevelMember(library, name);
-        }
-      }
-
-      assertx(member != null);
-
-      CallKind callKind;
-
-      if (action == null) {
-        if ((member is Field) || ((member is Procedure) && member.isGetter)) {
-          callKind = CallKind.PropertyGet;
-        } else if ((member is Procedure) && member.isSetter) {
-          callKind = CallKind.PropertySet;
-        } else {
-          callKind = CallKind.Method;
-        }
-      } else {
-        callKind = const {
-          'get': CallKind.PropertyGet,
-          'set': CallKind.PropertySet,
-          'call': CallKind.Method
-        }[action];
-      }
-
-      assertx(callKind != null);
-
-      final Selector selector = member.isInstanceMember
-          ? new InterfaceSelector(member, callKind: callKind)
-          : new DirectSelector(member, callKind: callKind);
-
-      entryPointsListener.addRawCall(selector);
-
-      if ((action == null) && (member is Field) && !member.isFinal) {
-        Selector selector = member.isInstanceMember
-            ? new InterfaceSelector(member, callKind: CallKind.PropertySet)
-            : new DirectSelector(member, callKind: CallKind.PropertySet);
-
-        entryPointsListener.addRawCall(selector);
-      }
-
-      _membersReferencedFromNativeCode.add(member);
-    } else {
-      throw 'Bad entry point: unrecognized action "$action" in $rootDesc';
-    }
-  }
-
-  /// Reads JSON describing entry points and native methods from [jsonString].
-  /// Adds all global entry points using [entryPointsListener].
-  ///
-  /// The format of the JSON descriptor is described in
-  /// 'runtime/vm/compiler/aot/entry_points_json.md'.
-  void processEntryPointsJSON(
-      String jsonString, EntryPointsListener entryPointsListener) {
-    final jsonObject = json.decode(jsonString);
-
-    final roots = jsonObject['roots'];
-    if (roots != null) {
-      for (var root in roots) {
-        _addRoot(new Map<String, String>.from(root), entryPointsListener);
-      }
-    }
-
-    final nativeMethods = jsonObject['native-methods'];
-    if (nativeMethods != null) {
-      nativeMethods.forEach((name, actions) {
-        _nativeMethods[name] = new List<Map<String, dynamic>>.from(
-            actions.map((action) => new Map<String, dynamic>.from(action)));
-      });
-    }
-  }
-
   /// Reads JSON files [jsonFiles] describing entry points and native methods.
-  /// Adds all global entry points using [entryPointsListener].
-  ///
-  /// The format of the JSON descriptor is described in
-  /// 'runtime/vm/compiler/aot/entry_points_json.md'.
+  /// Currently just checks that JSON file is empty as it is deprecated.
   void processEntryPointsJSONFiles(
       List<String> jsonFiles, EntryPointsListener entryPointsListener) {
     for (var file in jsonFiles) {
-      processEntryPointsJSON(
-          new File(file).readAsStringSync(), entryPointsListener);
+      String jsonString = new File(file).readAsStringSync();
+      final jsonObject = json.decode(jsonString);
+
+      final roots = jsonObject['roots'];
+      if (roots != null && roots.isNotEmpty) {
+        throw "Error: Found non-empty entry points JSON file $file."
+            " Use the @pragma('vm:entry-point') annotation instead.";
+      }
     }
   }
 }
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 849de1d..fcfd575 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -35,10 +35,6 @@
 Component transformComponent(Target target, CoreTypes coreTypes,
     Component component, List<String> entryPoints,
     [PragmaAnnotationParser matcher]) {
-  if ((entryPoints == null) || entryPoints.isEmpty) {
-    throw 'Error: unable to perform global type flow analysis without entry points.';
-  }
-
   void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
   final hierarchy = new ClassHierarchy(component,
       onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
diff --git a/pkg/vm/test/transformations/type_flow/transformer_test.dart b/pkg/vm/test/transformations/type_flow/transformer_test.dart
index 887c97a..3f8da8d 100644
--- a/pkg/vm/test/transformations/type_flow/transformer_test.dart
+++ b/pkg/vm/test/transformations/type_flow/transformer_test.dart
@@ -24,12 +24,7 @@
 
   final coreTypes = new CoreTypes(component);
 
-  final entryPoints = [
-    pkgVmDir + '/lib/transformations/type_flow/entry_points.json',
-    pkgVmDir + '/lib/transformations/type_flow/entry_points_extra.json',
-  ];
-
-  component = transformComponent(target, coreTypes, component, entryPoints,
+  component = transformComponent(target, coreTypes, component, [],
       new ExpressionPragmaAnnotationParser(coreTypes));
 
   final actual = kernelLibraryToString(component.mainMethod.enclosingLibrary);
diff --git a/runtime/vm/compiler/aot/entry_points_json.md b/runtime/vm/compiler/aot/entry_points_json.md
deleted file mode 100644
index 4ab2356..0000000
--- a/runtime/vm/compiler/aot/entry_points_json.md
+++ /dev/null
@@ -1,110 +0,0 @@
-
-# Entry points file format
-
-Dart VM precompiler (AOT compiler) performs whole-program optimizations such as
-tree shaking in order to decrease size of the resulting compiled apps and
-improve their performance. Such optimizations assume that compiler can see
-the whole Dart program, and is able to discover and analyze all Dart functions
-and members which can be potentially executed at run time. While the Dart code
-is fully available for precompiler, native code of the embedder and native
-methods are out of reach of the compiler. Such native code can call back to
-Dart via native Dart API.
-
-In order to aid precompiler, programmer can explicitly list entry
-points (roots) - Dart classes and members which are accessed from native code.
-Note that listing entry points is not optional: as long as program defines
-native methods which call into Dart, the entry points are required for the
-correctness of compilation.
-
-This memo describes _new_ format of entry points file, which is intended to
-replace old comma-separated lists of entry points. At the time of writing,
-new format is not fully adopted yet. 
-
-The native entry points are described in a JSON text file. The descriptor has the form
-
-```json
-{
- "roots": [
-    <root1>,
-    ...
-    <rootN>
-  ],
-
-  “native-methods”: {
-    “<native1_name>” : [
-      <native1_root1>,
-      ...
-      <native1_rootM1>,
-    ],
-
-    ...
-
-    “<nativeK_name>” : [
-      <nativeK_root1>,
-      ...
-      <nativeK_rootMK>,
-    ]
-  }
-```
-
-## "roots" element
-
-The “roots” element describes entry points which can be accessed by arbitrary native code.
-Each root has the following elements:
-
-```json
-{
- "library": "<library URI>",
- "class": "<class name>",
- "name": "<member name>",
- "action": "<action>"
-}
-```
-
-| Element | Meaning                                   | Can be omitted                     |
-| ------- | ----------------------------------------- | ---------------------------------- |
-| library | Library URI of the entry point.           | No.                                |
-| class   | Dart class name.                          | Omitted for top-level functions.   |
-| name    | Dart function name or member name.        | Omitted for class-related actions. |
-| action  | Specifies kind of the entry point access. | Depends on the entry point.        |
-
-
-The following actions are supported:
-* _"create-instance"_ - native code creates an instance of given Dart class.
-* _"call"_ - native code calls given Dart function or member.
-* _"get"_ - native code calls given getter or retrieves value of a given field.
-* _“set”_ - native code calls given setter or sets value to a given field.
-
-If action element is omitted, the following actions are assumed by default:
-* For classes - “create-instance”.
-* For fields - both “get” and “set” (only “get” if a field is final).
-* For others - “call”.
-
-If needed, the description of an entry point can be extended by supporting
-more elements or actions.
-
-## “native-methods” element
-
-The “native-methods” section contains description of entry points accessed from
-specific native methods. It can be used to declare behavior of a native method
-more accurately.
-Each element in “native-methods” section is identified by the native name - the
-name specified after the native clause in the Dart method or function declaration.
-
-Native method descriptor may contain arbitrary number of entry points.
-In addition to the declaration of entry points described above, native methods
-may contain the root with the action “return”, which describes the specific
-concrete type of a Dart instance returned from the native method:
-
-```json
-{
- "action": "return",
- "library": "<library URI>",
- "class": "<class name>",
- "nullable": "false|true"
-}
-```
-
-“nullable” attribute may be omitted defaulting to “true”.
-If “nullable” is “true” (or omitted), then native method can return an instance
-of the given class or null.