示例#1
0
  /**
   * Find a split point as designated in the {@link #PROP_INITIAL_SEQUENCE} configuration property.
   */
  public static JRunAsync findRunAsync(String refString, JProgram program, TreeLogger branch)
      throws UnableToCompleteException {
    SpeedTracerLogger.Event codeSplitterEvent =
        SpeedTracerLogger.start(CompilerEventType.CODE_SPLITTER, "phase", "findRunAsync");
    Multimap<String, JRunAsync> splitPointsByRunAsyncName =
        computeRunAsyncsByName(program.getRunAsyncs(), false);

    if (refString.startsWith("@")) {
      JsniRef jsniRef = JsniRef.parse(refString);
      if (jsniRef == null) {
        branch.log(
            TreeLogger.ERROR,
            "Badly formatted JSNI reference in " + PROP_INITIAL_SEQUENCE + ": " + refString);
        throw new UnableToCompleteException();
      }
      final String lookupErrorHolder[] = new String[1];
      JNode referent =
          JsniRefLookup.findJsniRefTarget(
              jsniRef,
              program,
              new JsniRefLookup.ErrorReporter() {
                @Override
                public void reportError(String error) {
                  lookupErrorHolder[0] = error;
                }
              });
      if (referent == null) {
        TreeLogger resolveLogger =
            branch.branch(TreeLogger.ERROR, "Could not resolve JSNI reference: " + jsniRef);
        resolveLogger.log(TreeLogger.ERROR, lookupErrorHolder[0]);
        throw new UnableToCompleteException();
      }

      if (!(referent instanceof JMethod)) {
        branch.log(TreeLogger.ERROR, "Not a method: " + referent);
        throw new UnableToCompleteException();
      }

      JMethod method = (JMethod) referent;
      String canonicalName = ReplaceRunAsyncs.getImplicitName(method);
      Collection<JRunAsync> splitPoints = splitPointsByRunAsyncName.get(canonicalName);
      if (splitPoints == null) {
        branch.log(TreeLogger.ERROR, "Method does not enclose a runAsync call: " + jsniRef);
        throw new UnableToCompleteException();
      }
      if (splitPoints.size() > 1) {
        branch.log(
            TreeLogger.ERROR,
            "Method includes multiple runAsync calls, "
                + "so it's ambiguous which one is meant: "
                + jsniRef);
        throw new UnableToCompleteException();
      }

      assert splitPoints.size() == 1;
      return splitPoints.iterator().next();
    }

    // Assume it's a raw class name
    Collection<JRunAsync> splitPoints = splitPointsByRunAsyncName.get(refString);
    if (splitPoints == null || splitPoints.size() == 0) {
      branch.log(TreeLogger.ERROR, "No runAsync call is labelled with class " + refString);
      throw new UnableToCompleteException();
    }
    if (splitPoints.size() > 1) {
      branch.log(
          TreeLogger.ERROR, "More than one runAsync call is labelled with class " + refString);
      throw new UnableToCompleteException();
    }
    assert splitPoints.size() == 1;
    JRunAsync result = splitPoints.iterator().next();
    codeSplitterEvent.end();

    return result;
  }