Java Code Examples for com.google.javascript.rhino.Node#cloneTree()

The following examples show how to use com.google.javascript.rhino.Node#cloneTree() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Closure_87_PeepholeSubstituteAlternateSyntax_t.java    From coming with MIT License 6 votes vote down vote up
/**
 * returns a string node that can safely be rendered inside /brackets/.
 */
private static Node makeForwardSlashBracketSafe(Node n) {
  String s = n.getString();
  // sb contains everything in s[0:pos]
  StringBuilder sb = null;
  int pos = 0;
  for (int i = 0; i < s.length(); ++i) {
    switch (s.charAt(i)) {
      case '\\':  // skip over the next char after a '\\'.
        ++i;
        break;
      case '/':  // escape it
        if (null == sb) { sb = new StringBuilder(s.length() + 16); }
        sb.append(s, pos, i).append('\\');
        pos = i;
        break;
    }
  }

  // don't discard useful line-number info if there were no changes
  if (null == sb) { return n.cloneTree(); }

  sb.append(s, pos, s.length());
  return Node.newString(sb.toString()).copyInformationFrom(n);
}
 
Example 2
Source File: FunctionType.java    From astor with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Get the return value of calling "bind" on this function
 * with the specified number of arguments.
 *
 * If -1 is passed, then we will return a result that accepts
 * any parameters.
 */
public FunctionType getBindReturnType(int argsToBind) {
  FunctionBuilder builder = new FunctionBuilder(registry)
      .withReturnType(getReturnType())
      .withTemplateKeys(getTemplateKeys());
  if (argsToBind >= 0) {
    Node origParams = getParametersNode();
    if (origParams != null) {
      Node params = origParams.cloneTree();
      for (int i = 1; i < argsToBind && params.getFirstChild() != null; i++) {
        if (params.getFirstChild().isVarArgs()) {
          break;
        }
        params.removeFirstChild();
      }
      builder.withParamsNode(params);
    }
  }
  return builder.build();
}
 
Example 3
Source File: Closure_105_FoldConstants_t.java    From coming with MIT License 6 votes vote down vote up
/**
 * returns a string node that can safely be rendered inside /brackets/.
 */
private static Node makeForwardSlashBracketSafe(Node n) {
  String s = n.getString();
  // sb contains everything in s[0:pos]
  StringBuilder sb = null;
  int pos = 0;
  for (int i = 0; i < s.length(); ++i) {
    switch (s.charAt(i)) {
      case '\\':  // skip over the next char after a '\\'.
        ++i;
        break;
      case '/':  // escape it
        if (null == sb) { sb = new StringBuilder(s.length() + 16); }
        sb.append(s, pos, i).append('\\');
        pos = i;
        break;
    }
  }

  // don't discard useful line-number info if there were no changes
  if (null == sb) { return n.cloneTree(); }

  sb.append(s, pos, s.length());
  return Node.newString(sb.toString());
}
 
Example 4
Source File: 1_FunctionInjector.java    From SimFix with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Inline a function that fulfills the requirements of
 * canInlineReferenceDirectly into the call site, replacing only the CALL
 * node.
 */
private Node inlineReturnValue(Node callNode, Node fnNode) {
  Node block = fnNode.getLastChild();
  Node callParentNode = callNode.getParent();

  // NOTE: As the normalize pass guarantees globals aren't being
  // shadowed and an expression can't introduce new names, there is
  // no need to check for conflicts.

  // Create an argName -> expression map, checking for side effects.
  Map<String, Node> argMap =
      FunctionArgumentInjector.getFunctionCallParameterMap(
          fnNode, callNode, this.safeNameIdSupplier);

  Node newExpression;
  if (!block.hasChildren()) {
    Node srcLocation = block;
    newExpression = NodeUtil.newUndefinedNode(srcLocation);
  } else {
    Node returnNode = block.getFirstChild();
    Preconditions.checkArgument(returnNode.isReturn());

    // Clone the return node first.
    Node safeReturnNode = returnNode.cloneTree();
    Node inlineResult = FunctionArgumentInjector.inject(
        null, safeReturnNode, null, argMap);
    Preconditions.checkArgument(safeReturnNode == inlineResult);
    newExpression = safeReturnNode.removeFirstChild();
  }

  callParentNode.replaceChild(callNode, newExpression);
  return newExpression;
}
 
Example 5
Source File: FunctionInjector.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Inline a function that fulfills the requirements of
 * canInlineReferenceDirectly into the call site, replacing only the CALL
 * node.
 */
private Node inlineReturnValue(Node callNode, Node fnNode) {
  Node block = fnNode.getLastChild();
  Node callParentNode = callNode.getParent();

  // NOTE: As the normalize pass guarantees globals aren't being
  // shadowed and an expression can't introduce new names, there is
  // no need to check for conflicts.

  // Create an argName -> expression map, checking for side effects.
  Map<String, Node> argMap =
      FunctionArgumentInjector.getFunctionCallParameterMap(
          fnNode, callNode, this.safeNameIdSupplier);

  Node newExpression;
  if (!block.hasChildren()) {
    Node srcLocation = block;
    newExpression = NodeUtil.newUndefinedNode(srcLocation);
  } else {
    Node returnNode = block.getFirstChild();
    Preconditions.checkArgument(returnNode.isReturn());

    // Clone the return node first.
    Node safeReturnNode = returnNode.cloneTree();
    Node inlineResult = FunctionArgumentInjector.inject(
        null, safeReturnNode, null, argMap);
    Preconditions.checkArgument(safeReturnNode == inlineResult);
    newExpression = safeReturnNode.removeFirstChild();
  }

  callParentNode.replaceChild(callNode, newExpression);
  return newExpression;
}
 
Example 6
Source File: SpecializeModule.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
public OriginalFunctionInformation(Node originalFunction) {
  name = NodeUtil.getFunctionName(originalFunction);

  originalFunctionCopy = originalFunction.cloneTree();
  originalFunctionCopy.copyInformationFromForTree(originalFunction);

  Node originalParent = originalFunction.getParent();

  isAssignFunction = originalParent.isAssign() ||
      originalParent.isName();

  assignHasVar =
      isAssignFunction && originalParent.getParent().isVar();
}
 
Example 7
Source File: VarCheckTest.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
public void checkSynthesizedExtern(
    String extern, String input, String expectedExtern) {
  Compiler compiler = new Compiler();
  CompilerOptions options = new CompilerOptions();
  options.setWarningLevel(
      DiagnosticGroup.forType(VarCheck.UNDEFINED_VAR_ERROR),
      CheckLevel.OFF);
  compiler.init(
      ImmutableList.of(SourceFile.fromCode("extern", extern)),
      ImmutableList.of(SourceFile.fromCode("input", input)),
      options);
  compiler.parseInputs();
  assertFalse(compiler.hasErrors());

  Node externsAndJs = compiler.getRoot();
  Node root = externsAndJs.getLastChild();

  Node rootOriginal = root.cloneTree();
  Node externs = externsAndJs.getFirstChild();

  Node expected = compiler.parseTestCode(expectedExtern);
  assertFalse(compiler.hasErrors());

  (new VarCheck(compiler, sanityCheck))
      .process(externs, root);
  if (!sanityCheck) {
    (new VariableTestCheck(compiler)).process(externs, root);
  }

  String externsCode = compiler.toSource(externs);
  String expectedCode = compiler.toSource(expected);

  assertEquals(expectedCode, externsCode);
}
 
Example 8
Source File: Closure_115_FunctionInjector_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Inline a function that fulfills the requirements of
 * canInlineReferenceDirectly into the call site, replacing only the CALL
 * node.
 */
private Node inlineReturnValue(Node callNode, Node fnNode) {
  Node block = fnNode.getLastChild();
  Node callParentNode = callNode.getParent();

  // NOTE: As the normalize pass guarantees globals aren't being
  // shadowed and an expression can't introduce new names, there is
  // no need to check for conflicts.

  // Create an argName -> expression map, checking for side effects.
  Map<String, Node> argMap =
      FunctionArgumentInjector.getFunctionCallParameterMap(
          fnNode, callNode, this.safeNameIdSupplier);

  Node newExpression;
  if (!block.hasChildren()) {
    Node srcLocation = block;
    newExpression = NodeUtil.newUndefinedNode(srcLocation);
  } else {
    Node returnNode = block.getFirstChild();
    Preconditions.checkArgument(returnNode.isReturn());

    // Clone the return node first.
    Node safeReturnNode = returnNode.cloneTree();
    Node inlineResult = FunctionArgumentInjector.inject(
        null, safeReturnNode, null, argMap);
    Preconditions.checkArgument(safeReturnNode == inlineResult);
    newExpression = safeReturnNode.removeFirstChild();
  }

  callParentNode.replaceChild(callNode, newExpression);
  return newExpression;
}
 
Example 9
Source File: Closure_115_FunctionInjector_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Inline a function that fulfills the requirements of
 * canInlineReferenceDirectly into the call site, replacing only the CALL
 * node.
 */
private Node inlineReturnValue(Node callNode, Node fnNode) {
  Node block = fnNode.getLastChild();
  Node callParentNode = callNode.getParent();

  // NOTE: As the normalize pass guarantees globals aren't being
  // shadowed and an expression can't introduce new names, there is
  // no need to check for conflicts.

  // Create an argName -> expression map, checking for side effects.
  Map<String, Node> argMap =
      FunctionArgumentInjector.getFunctionCallParameterMap(
          fnNode, callNode, this.safeNameIdSupplier);

  Node newExpression;
  if (!block.hasChildren()) {
    Node srcLocation = block;
    newExpression = NodeUtil.newUndefinedNode(srcLocation);
  } else {
    Node returnNode = block.getFirstChild();
    Preconditions.checkArgument(returnNode.isReturn());

    // Clone the return node first.
    Node safeReturnNode = returnNode.cloneTree();
    Node inlineResult = FunctionArgumentInjector.inject(
        null, safeReturnNode, null, argMap);
    Preconditions.checkArgument(safeReturnNode == inlineResult);
    newExpression = safeReturnNode.removeFirstChild();
  }

  callParentNode.replaceChild(callNode, newExpression);
  return newExpression;
}
 
Example 10
Source File: FunctionType.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Notice that "call" and "bind" have the same argument signature,
 * except that all the arguments of "bind" (except the first)
 * are optional.
 */
private FunctionType getCallOrBindSignature(boolean isCall) {
  boolean isBind = !isCall;
  FunctionBuilder builder = new FunctionBuilder(registry)
      .withReturnType(isCall ? getReturnType() : getBindReturnType(-1))
      .withTemplateKeys(getTemplateKeys());

  Node origParams = getParametersNode();
  if (origParams != null) {
    Node params = origParams.cloneTree();

    Node thisTypeNode = Node.newString(Token.NAME, "thisType");
    thisTypeNode.setJSType(
        registry.createOptionalNullableType(getTypeOfThis()));
    params.addChildToFront(thisTypeNode);

    if (isBind) {
      // The arguments of bind() are unique in that they are all
      // optional but not undefinable.
      for (Node current = thisTypeNode.getNext();
           current != null; current = current.getNext()) {
        current.setOptionalArg(true);
      }
    } else if (isCall) {
      // The first argument of call() is optional iff all the arguments
      // are optional. It's sufficient to check the first argument.
      Node firstArg = thisTypeNode.getNext();
      if (firstArg == null
          || firstArg.isOptionalArg()
          || firstArg.isVarArgs()) {
        thisTypeNode.setOptionalArg(true);
      }
    }

    builder.withParamsNode(params);
  }

  return builder.build();
}
 
Example 11
Source File: 1_FunctionInjector.java    From SimFix with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Inline a function that fulfills the requirements of
 * canInlineReferenceDirectly into the call site, replacing only the CALL
 * node.
 */
private Node inlineReturnValue(Node callNode, Node fnNode) {
  Node block = fnNode.getLastChild();
  Node callParentNode = callNode.getParent();

  // NOTE: As the normalize pass guarantees globals aren't being
  // shadowed and an expression can't introduce new names, there is
  // no need to check for conflicts.

  // Create an argName -> expression map, checking for side effects.
  Map<String, Node> argMap =
      FunctionArgumentInjector.getFunctionCallParameterMap(
          fnNode, callNode, this.safeNameIdSupplier);

  Node newExpression;
  if (!block.hasChildren()) {
    Node srcLocation = block;
    newExpression = NodeUtil.newUndefinedNode(srcLocation);
  } else {
    Node returnNode = block.getFirstChild();
    Preconditions.checkArgument(returnNode.isReturn());

    // Clone the return node first.
    Node safeReturnNode = returnNode.cloneTree();
    Node inlineResult = FunctionArgumentInjector.inject(
        null, safeReturnNode, null, argMap);
    Preconditions.checkArgument(safeReturnNode == inlineResult);
    newExpression = safeReturnNode.removeFirstChild();
  }

  callParentNode.replaceChild(callNode, newExpression);
  return newExpression;
}
 
Example 12
Source File: Closure_132_PeepholeSubstituteAlternateSyntax_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * returns a string node that can safely be rendered inside /brackets/.
 */
private static Node makeForwardSlashBracketSafe(Node n) {
  String s = n.getString();
  // sb contains everything in s[0:pos]
  StringBuilder sb = null;
  int pos = 0;
  boolean isEscaped = false, inCharset = false;
  for (int i = 0; i < s.length(); ++i) {
    char ch = s.charAt(i);
    switch (ch) {
      case '\\':
        isEscaped = !isEscaped;
        continue;
      case '/':
        // Escape a literal forward slash if it is not already escaped and is
        // not inside a character set.
        //     new RegExp('/') -> /\//
        // but the following do not need extra escaping
        //     new RegExp('\\/') -> /\//
        //     new RegExp('[/]') -> /[/]/
        if (!isEscaped && !inCharset) {
          if (null == sb) { sb = new StringBuilder(s.length() + 16); }
          sb.append(s, pos, i).append('\\');
          pos = i;
        }
        break;
      case '[':
        if (!isEscaped) {
          inCharset = true;
        }
        break;
      case ']':
        if (!isEscaped) {
          inCharset = false;
        }
        break;
      case '\r': case '\n': case '\u2028': case '\u2029':
        // LineTerminators cannot appear raw inside a regular
        // expression literal.
        // They can't appear legally in a quoted string, but when
        // the quoted string from
        //     new RegExp('\n')
        // reaches here, the quoting has been removed.
        // Requote just these code-points.
        if (null == sb) { sb = new StringBuilder(s.length() + 16); }
        if (isEscaped) {
          sb.append(s, pos, i - 1);
        } else {
          sb.append(s, pos, i);
        }
        switch (ch) {
          case '\r': sb.append("\\r"); break;
          case '\n': sb.append("\\n"); break;
          case '\u2028': sb.append("\\u2028"); break;
          case '\u2029': sb.append("\\u2029"); break;
        }
        pos = i + 1;
        break;
    }
    isEscaped = false;
  }

  if (null == sb) { return n.cloneTree(); }

  sb.append(s, pos, s.length());
  return IR.string(sb.toString()).srcref(n);
}
 
Example 13
Source File: Closure_20_PeepholeSubstituteAlternateSyntax_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * returns a string node that can safely be rendered inside /brackets/.
 */
private static Node makeForwardSlashBracketSafe(Node n) {
  String s = n.getString();
  // sb contains everything in s[0:pos]
  StringBuilder sb = null;
  int pos = 0;
  boolean isEscaped = false, inCharset = false;
  for (int i = 0; i < s.length(); ++i) {
    char ch = s.charAt(i);
    switch (ch) {
      case '\\':
        isEscaped = !isEscaped;
        continue;
      case '/':
        // Escape a literal forward slash if it is not already escaped and is
        // not inside a character set.
        //     new RegExp('/') -> /\//
        // but the following do not need extra escaping
        //     new RegExp('\\/') -> /\//
        //     new RegExp('[/]') -> /[/]/
        if (!isEscaped && !inCharset) {
          if (null == sb) { sb = new StringBuilder(s.length() + 16); }
          sb.append(s, pos, i).append('\\');
          pos = i;
        }
        break;
      case '[':
        if (!isEscaped) {
          inCharset = true;
        }
        break;
      case ']':
        if (!isEscaped) {
          inCharset = false;
        }
        break;
      case '\r': case '\n': case '\u2028': case '\u2029':
        // LineTerminators cannot appear raw inside a regular
        // expression literal.
        // They can't appear legally in a quoted string, but when
        // the quoted string from
        //     new RegExp('\n')
        // reaches here, the quoting has been removed.
        // Requote just these code-points.
        if (null == sb) { sb = new StringBuilder(s.length() + 16); }
        if (isEscaped) {
          sb.append(s, pos, i - 1);
        } else {
          sb.append(s, pos, i);
        }
        switch (ch) {
          case '\r': sb.append("\\r"); break;
          case '\n': sb.append("\\n"); break;
          case '\u2028': sb.append("\\u2028"); break;
          case '\u2029': sb.append("\\u2029"); break;
        }
        pos = i + 1;
        break;
    }
    isEscaped = false;
  }

  if (null == sb) { return n.cloneTree(); }

  sb.append(s, pos, s.length());
  return IR.string(sb.toString()).srcref(n);
}
 
Example 14
Source File: Closure_132_PeepholeSubstituteAlternateSyntax_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * returns a string node that can safely be rendered inside /brackets/.
 */
private static Node makeForwardSlashBracketSafe(Node n) {
  String s = n.getString();
  // sb contains everything in s[0:pos]
  StringBuilder sb = null;
  int pos = 0;
  boolean isEscaped = false, inCharset = false;
  for (int i = 0; i < s.length(); ++i) {
    char ch = s.charAt(i);
    switch (ch) {
      case '\\':
        isEscaped = !isEscaped;
        continue;
      case '/':
        // Escape a literal forward slash if it is not already escaped and is
        // not inside a character set.
        //     new RegExp('/') -> /\//
        // but the following do not need extra escaping
        //     new RegExp('\\/') -> /\//
        //     new RegExp('[/]') -> /[/]/
        if (!isEscaped && !inCharset) {
          if (null == sb) { sb = new StringBuilder(s.length() + 16); }
          sb.append(s, pos, i).append('\\');
          pos = i;
        }
        break;
      case '[':
        if (!isEscaped) {
          inCharset = true;
        }
        break;
      case ']':
        if (!isEscaped) {
          inCharset = false;
        }
        break;
      case '\r': case '\n': case '\u2028': case '\u2029':
        // LineTerminators cannot appear raw inside a regular
        // expression literal.
        // They can't appear legally in a quoted string, but when
        // the quoted string from
        //     new RegExp('\n')
        // reaches here, the quoting has been removed.
        // Requote just these code-points.
        if (null == sb) { sb = new StringBuilder(s.length() + 16); }
        if (isEscaped) {
          sb.append(s, pos, i - 1);
        } else {
          sb.append(s, pos, i);
        }
        switch (ch) {
          case '\r': sb.append("\\r"); break;
          case '\n': sb.append("\\n"); break;
          case '\u2028': sb.append("\\u2028"); break;
          case '\u2029': sb.append("\\u2029"); break;
        }
        pos = i + 1;
        break;
    }
    isEscaped = false;
  }

  if (null == sb) { return n.cloneTree(); }

  sb.append(s, pos, s.length());
  return IR.string(sb.toString()).srcref(n);
}
 
Example 15
Source File: FunctionToBlockMutator.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
/**
 * @param fnName The name to use when preparing human readable names.
 * @param fnNode The function to prepare.
 * @param callNode The call node that will be replaced.
 * @param resultName Function results should be assigned to this name.
 * @param needsDefaultResult Whether the result value must be set.
 * @param isCallInLoop Whether the function body must be prepared to be
 *   injected into the body of a loop.
 * @return A clone of the function body mutated to be suitable for injection
 *   as a statement into another code block.
 */
Node mutate(String fnName, Node fnNode, Node callNode,
    String resultName, boolean needsDefaultResult, boolean isCallInLoop) {
  Node newFnNode = fnNode.cloneTree();
  // Now that parameter names have been replaced, make sure all the local
  // names are unique, to allow functions to be inlined multiple times
  // without causing conflicts.
  makeLocalNamesUnique(newFnNode, isCallInLoop);

  // Function declarations must be rewritten as function expressions as
  // they will be within a block and normalization prevents function
  // declarations within block as browser implementations vary.
  rewriteFunctionDeclarations(newFnNode.getLastChild());

  // TODO(johnlenz): Mark NAME nodes constant for parameters that are not
  // modified.
  Set<String> namesToAlias =
      FunctionArgumentInjector.findModifiedParameters(newFnNode);
  LinkedHashMap<String, Node> args =
      FunctionArgumentInjector.getFunctionCallParameterMap(
          newFnNode, callNode, this.safeNameIdSupplier);
  boolean hasArgs = !args.isEmpty();
  if (hasArgs) {
    FunctionArgumentInjector.maybeAddTempsForCallArguments(
        newFnNode, args, namesToAlias, compiler.getCodingConvention());
  }

  Node newBlock = NodeUtil.getFunctionBody(newFnNode);
  // Make the newBlock insertable .
  newBlock.detachFromParent();

  if (hasArgs) {
    Node inlineResult = aliasAndInlineArguments(newBlock,
        args, namesToAlias);
    Preconditions.checkState(newBlock == inlineResult);
  }

  //
  // For calls inlined into loops, VAR declarations are not reinitialized to
  // undefined as they would have been if the function were called, so ensure
  // that they are properly initialized.
  //
  if (isCallInLoop) {
    fixUnitializedVarDeclarations(newBlock);
  }

  String labelName = getLabelNameForFunction(fnName);
  Node injectableBlock = replaceReturns(
      newBlock, resultName, labelName, needsDefaultResult);
  Preconditions.checkState(injectableBlock != null);

  return injectableBlock;
}
 
Example 16
Source File: ReplaceMessages.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Creates a parse tree corresponding to the remaining message parts in an
 * iteration. The result consists of one or more STRING nodes, placeholder
 * replacement value nodes (which can be arbitrary expressions), and ADD
 * nodes.
 *
 * @param parts  an iterator over message parts
 * @param objLitNode  an OBJLIT node mapping placeholder names to values
 * @return the root of the constructed parse tree
 *
 * @throws MalformedException if {@code parts} contains a placeholder
 *   reference that does not correspond to a valid placeholder name
 */
private Node constructStringExprNode(Iterator<CharSequence> parts,
    Node objLitNode) throws MalformedException {

  CharSequence part = parts.next();
  Node partNode = null;
  if (part instanceof JsMessage.PlaceholderReference) {
    JsMessage.PlaceholderReference phRef =
        (JsMessage.PlaceholderReference) part;

    // The translated message is null
    if (objLitNode == null) {
      throw new MalformedException("Empty placeholder value map " +
          "for a translated message with placeholders.", objLitNode);
    }

    for (Node key = objLitNode.getFirstChild(); key != null;
         key = key.getNext()) {
      if (key.getString().equals(phRef.getName())) {
        Node valueNode = key.getFirstChild();
        partNode = valueNode.cloneTree();
      }
    }

    if (partNode == null) {
      throw new MalformedException(
          "Unrecognized message placeholder referenced: " + phRef.getName(),
          objLitNode);
    }
  } else {
    // The part is just a string literal.
    partNode = IR.string(part.toString());
  }

  if (parts.hasNext()) {
    return IR.add(partNode,
        constructStringExprNode(parts, objLitNode));
  } else {
    return partNode;
  }
}
 
Example 17
Source File: Closure_54_FunctionType_t.java    From coming with MIT License 4 votes vote down vote up
@Override
public JSType getPropertyType(String name) {
  if (!hasOwnProperty(name)) {
    if ("call".equals(name)) {
      // Define the "call" function lazily.
      Node params = getParametersNode();
      if (params == null) {
        // If there's no params array, don't do any type-checking
        // in this CALL function.
        defineDeclaredProperty(name,
            new FunctionBuilder(registry)
            .withReturnType(getReturnType())
            .build(),
            source);
      } else {
        params = params.cloneTree();
        Node thisTypeNode = Node.newString(Token.NAME, "thisType");
        thisTypeNode.setJSType(
            registry.createOptionalNullableType(getTypeOfThis()));
        params.addChildToFront(thisTypeNode);
        thisTypeNode.setOptionalArg(true);

        defineDeclaredProperty(name,
            new FunctionBuilder(registry)
            .withParamsNode(params)
            .withReturnType(getReturnType())
            .build(),
            source);
      }
    } else if ("apply".equals(name)) {
      // Define the "apply" function lazily.
      FunctionParamBuilder builder = new FunctionParamBuilder(registry);

      // Ecma-262 says that apply's second argument must be an Array
      // or an arguments object. We don't model the arguments object,
      // so let's just be forgiving for now.
      // TODO(nicksantos): Model the Arguments object.
      builder.addOptionalParams(
          registry.createNullableType(getTypeOfThis()),
          registry.createNullableType(
              registry.getNativeType(JSTypeNative.OBJECT_TYPE)));

      defineDeclaredProperty(name,
          new FunctionBuilder(registry)
          .withParams(builder)
          .withReturnType(getReturnType())
          .build(),
          source);
    }
  }

  return super.getPropertyType(name);
}
 
Example 18
Source File: Closure_54_FunctionType_s.java    From coming with MIT License 4 votes vote down vote up
@Override
public JSType getPropertyType(String name) {
  if (!hasOwnProperty(name)) {
    if ("call".equals(name)) {
      // Define the "call" function lazily.
      Node params = getParametersNode();
      if (params == null) {
        // If there's no params array, don't do any type-checking
        // in this CALL function.
        defineDeclaredProperty(name,
            new FunctionBuilder(registry)
            .withReturnType(getReturnType())
            .build(),
            source);
      } else {
        params = params.cloneTree();
        Node thisTypeNode = Node.newString(Token.NAME, "thisType");
        thisTypeNode.setJSType(
            registry.createOptionalNullableType(getTypeOfThis()));
        params.addChildToFront(thisTypeNode);
        thisTypeNode.setOptionalArg(true);

        defineDeclaredProperty(name,
            new FunctionBuilder(registry)
            .withParamsNode(params)
            .withReturnType(getReturnType())
            .build(),
            source);
      }
    } else if ("apply".equals(name)) {
      // Define the "apply" function lazily.
      FunctionParamBuilder builder = new FunctionParamBuilder(registry);

      // Ecma-262 says that apply's second argument must be an Array
      // or an arguments object. We don't model the arguments object,
      // so let's just be forgiving for now.
      // TODO(nicksantos): Model the Arguments object.
      builder.addOptionalParams(
          registry.createNullableType(getTypeOfThis()),
          registry.createNullableType(
              registry.getNativeType(JSTypeNative.OBJECT_TYPE)));

      defineDeclaredProperty(name,
          new FunctionBuilder(registry)
          .withParams(builder)
          .withReturnType(getReturnType())
          .build(),
          source);
    }
  }

  return super.getPropertyType(name);
}
 
Example 19
Source File: Closure_90_FunctionType_t.java    From coming with MIT License 4 votes vote down vote up
@Override
public JSType getPropertyType(String name) {
  if ("prototype".equals(name)) {
    return getPrototype();
  } else {
    if (!hasOwnProperty(name)) {
      if ("call".equals(name)) {
        // Define the "call" function lazily.
        Node params = getParametersNode();
        if (params == null) {
          // If there's no params array, don't do any type-checking
          // in this CALL function.
          defineDeclaredProperty(name,
              new FunctionBuilder(registry)
                  .withReturnType(getReturnType())
                  .build(),
              false);
        } else {
          params = params.cloneTree();
          Node thisTypeNode = Node.newString(Token.NAME, "thisType");
          thisTypeNode.setJSType(
              registry.createOptionalNullableType(getTypeOfThis()));
          params.addChildToFront(thisTypeNode);
          thisTypeNode.setOptionalArg(true);

          defineDeclaredProperty(name,
              new FunctionBuilder(registry)
                  .withParamsNode(params)
                  .withReturnType(getReturnType())
                  .build(),
              false);
        }
      } else if ("apply".equals(name)) {
        // Define the "apply" function lazily.
        FunctionParamBuilder builder = new FunctionParamBuilder(registry);

        // Ecma-262 says that apply's second argument must be an Array
        // or an arguments object. We don't model the arguments object,
        // so let's just be forgiving for now.
        // TODO(nicksantos): Model the Arguments object.
        builder.addOptionalParams(
            registry.createNullableType(getTypeOfThis()),
            registry.createNullableType(
                registry.getNativeType(JSTypeNative.OBJECT_TYPE)));

        defineDeclaredProperty(name,
            new FunctionBuilder(registry)
                .withParams(builder)
                .withReturnType(getReturnType())
                .build(),
            false);
      }
    }

    return super.getPropertyType(name);
  }
}
 
Example 20
Source File: Closure_72_FunctionToBlockMutator_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * @param fnName The name to use when preparing human readable names.
 * @param fnNode The function to prepare.
 * @param callNode The call node that will be replaced.
 * @param resultName Function results should be assigned to this name.
 * @param needsDefaultResult Whether the result value must be set.
 * @param isCallInLoop Whether the function body must be prepared to be
 *   injected into the body of a loop.
 * @return A clone of the function body mutated to be suitable for injection
 *   as a statement into another code block.
 */
Node mutate(String fnName, Node fnNode, Node callNode,
    String resultName, boolean needsDefaultResult, boolean isCallInLoop) {
  Node newFnNode = fnNode.cloneTree();
  // Now that parameter names have been replaced, make sure all the local
  // names are unique, to allow functions to be inlined multiple times
  // without causing conflicts.
  makeLocalNamesUnique(newFnNode, isCallInLoop);

  // TODO(johnlenz): Mark NAME nodes constant for parameters that are not
  // modified.
  Set<String> namesToAlias =
      FunctionArgumentInjector.findModifiedParameters(newFnNode);
  LinkedHashMap<String, Node> args =
      FunctionArgumentInjector.getFunctionCallParameterMap(
          newFnNode, callNode, this.safeNameIdSupplier);
  boolean hasArgs = !args.isEmpty();
  if (hasArgs) {
    FunctionArgumentInjector.maybeAddTempsForCallArguments(
        newFnNode, args, namesToAlias, compiler.getCodingConvention());
  }

  Node newBlock = NodeUtil.getFunctionBody(newFnNode);
  // Make the newBlock insertable .
  newBlock.detachFromParent();

  if (hasArgs) {
    Node inlineResult = aliasAndInlineArguments(newBlock,
        args, namesToAlias);
    Preconditions.checkState(newBlock == inlineResult);
  }

  //
  // For calls inlined into loops, VAR declarations are not reinitialized to
  // undefined as they would have been if the function were called, so ensure
  // that they are properly initialized.
  //
  if (isCallInLoop) {
    fixUnitializedVarDeclarations(newBlock);
  }

  String labelName = getLabelNameForFunction(fnName);
  Node injectableBlock = replaceReturns(
      newBlock, resultName, labelName, needsDefaultResult);
  Preconditions.checkState(injectableBlock != null);

  return injectableBlock;
}