code: private Node tryFoldStringSubstr(Node n, Node stringNode, Node arg1) {
      checkArgument(n.isCall());
      checkArgument(stringNode.isString());
      checkArgument(arg1 != null);
  
      int start;
      int length;
      String stringAsString = stringNode.getString();
  
      Double maybeStart = NodeUtil.getNumberValue(arg1);
      if (maybeStart != null) {
        start = maybeStart.intValue();
      } else {
        return n;
      }
  
      Node arg2 = arg1.getNext();
      if (arg2 != null) {
        Double maybeLength = NodeUtil.getNumberValue(arg2);
        if (maybeLength != null) {
          length = maybeLength.intValue();
        } else {
          return n;
        }
  
        if (arg2.getNext() != null) {
          // If we got more args than we expected, bail out.
          return n;
        }
      } else {
        // parameter 2 not passed
        length = stringAsString.length() - start;
      }
  
      // Don't handle these cases. The specification actually does
      // specify the behavior in some of these cases, but we haven't
      // done a thorough investigation that it is correctly implemented
      // in all browsers.
      if ((start + length) > stringAsString.length() ||
          (length < 0) ||
          (start < 0)) {
        return n;
      }
  
      String result = stringAsString.substring(start, start + length);
      Node resultNode = IR.string(result);
  
      Node parent = n.getParent();
      parent.replaceChild(n, resultNode);
      reportChangeToEnclosingScope(parent);
      return resultNode;
    }
docs: Try to fold .substr() calls on strings