Exemple #1
0
 public String toString() {
   StringBuffer sb = new StringBuffer();
   sb.append(getClass().getName());
   sb.append('@');
   sb.append(Integer.toHexString(System.identityHashCode(this)));
   sb.append(" (context=");
   sb.append(_context);
   sb.append(", static_permitions=");
   sb.append(_statisPermissions);
   sb.append(')');
   return sb.toString();
 }
  // 得到的tokens包含源代码的由词法分析器分析出的所有单词,但不包含注释
  private static ArrayList<JavaScriptToken> parse(
      Reader in, ErrorReporter reporter) // 返回tokens(保存的是源文件中出现的javascript关键字和NAME,REGEXP,STRING等类型)
      throws IOException, EvaluatorException {

    CompilerEnvirons env = new CompilerEnvirons(); // 创建编译环境对象
    env.setLanguageVersion(Context.VERSION_1_7); // 设置语言版本
    Parser parser = new Parser(env, reporter); // 创建解释器对象
    parser.parse(in, null, 1); // 解释输入流
    String source = parser.getEncodedSource(); // 获得已编码的源码(词法分析阶段通常是把从源程序中识别出的各个单词的词文
    // 转换为某种内部表示
    int offset = 0;
    int length = source.length();
    ArrayList<JavaScriptToken> tokens = new ArrayList<JavaScriptToken>();
    StringBuffer sb = new StringBuffer();

    while (offset < length) {
      int tt = source.charAt(offset++); // 获取特定位置上的字符,并转化为ASCII编码
      switch (tt) {
        case Token.CONDCOMMENT: // 条件注释
        case Token.KEEPCOMMENT: // 注释
        case Token.NAME: //
        case Token.REGEXP: // 正则表达式类型
        case Token.STRING: // String类型,js程序中双引号或单引号括起来的字符串
          sb.setLength(0);
          offset = printSourceString(source, offset, sb);
          tokens.add(new JavaScriptToken(tt, sb.toString()));
          break;

        case Token.NUMBER: // Number类型
          sb.setLength(0);
          offset = printSourceNumber(source, offset, sb);
          tokens.add(new JavaScriptToken(tt, sb.toString()));
          break;

        default:
          String literal = literals.get(new Integer(tt));
          if (literal != null) { // 若不为空,说明哈希表literals中含有键new
            // Integer(tt)所对应的值
            tokens.add(new JavaScriptToken(tt, literal)); // 将此关键字保存到数组列表tokens中
          }
          break;
      }
    }

    /*
     * //begin Iterator<JavaScriptToken> iterator = tokens.iterator();
     * JavaScriptToken token; while(iterator.hasNext()) { token =
     * iterator.next();
     * System.out.println(token.getType()+"\t"+token.getValue()); } //end
     */
    return tokens;
  }
Exemple #3
0
  protected int[] resize(
      int thumbWidth,
      int thumbHeight,
      int imageWidth,
      int imageHeight,
      String srcPath,
      String dstPath,
      boolean scaleComputed) {
    if (!scaleComputed) {
      int[] dims = computeResizedDimensions(thumbWidth, thumbHeight, imageWidth, imageHeight);
      thumbWidth = dims[0];
      thumbHeight = dims[1];
    }

    String[] paths = escapePaths(srcPath, dstPath);
    srcPath = paths[0];
    dstPath = paths[1];

    String cmd = core.app.getProperty("imagemagick");
    boolean success = false;

    if (cmd == null) {
      RenderedOp resizedImage =
          this.resizeJAI(
              thumbWidth,
              thumbHeight,
              FileLoadDescriptor.create(srcPath, null, null, null),
              false); // Don't like the pre-calculated scaling. Recalculate it.
      String type = dstPath.substring(dstPath.lastIndexOf(".") + 1);
      success = writeImage(dstPath, type, resizedImage);
    } else {
      if (!cmd.endsWith("convert")) {
        if (!cmd.endsWith(File.separator)) {
          cmd += File.separator;
        }
        cmd += "convert";
      }

      StringBuffer command = new StringBuffer(cmd);
      command.append(" -geometry ");
      command.append(thumbWidth).append("x").append(thumbHeight);
      command.append(" ").append(srcPath);
      command.append(" ").append(dstPath);
      success = exec(command.toString());
    }

    if (success) {
      return new int[] {thumbWidth, thumbHeight};
    }

    return null;
  }
 /** Returns the source URL for the given script or function. */
 private String getNormalizedUrl(DebuggableScript fnOrScript) {
   String url = fnOrScript.getSourceName();
   if (url == null) {
     url = "<stdin>";
   } else {
     // Not to produce window for eval from different lines,
     // strip line numbers, i.e. replace all #[0-9]+\(eval\) by
     // (eval)
     // Option: similar teatment for Function?
     char evalSeparator = '#';
     StringBuffer sb = null;
     int urlLength = url.length();
     int cursor = 0;
     for (; ; ) {
       int searchStart = url.indexOf(evalSeparator, cursor);
       if (searchStart < 0) {
         break;
       }
       String replace = null;
       int i = searchStart + 1;
       while (i != urlLength) {
         int c = url.charAt(i);
         if (!('0' <= c && c <= '9')) {
           break;
         }
         ++i;
       }
       if (i != searchStart + 1) {
         // i points after #[0-9]+
         if ("(eval)".regionMatches(0, url, i, 6)) {
           cursor = i + 6;
           replace = "(eval)";
         }
       }
       if (replace == null) {
         break;
       }
       if (sb == null) {
         sb = new StringBuffer();
         sb.append(url.substring(0, searchStart));
       }
       sb.append(replace);
     }
     if (sb != null) {
       if (cursor != urlLength) {
         sb.append(url.substring(cursor));
       }
       url = sb.toString();
     }
   }
   return url;
 }
Exemple #5
0
  @Override
  String toXMLString() {
    //    See ECMA 10.2.1
    StringBuffer sb = new StringBuffer();

    for (int i = 0; i < length(); i++) {
      if (getProcessor().isPrettyPrinting() && i != 0) {
        sb.append('\n');
      }
      sb.append(getXmlFromAnnotation(i).toXMLString());
    }
    return sb.toString();
  }
Exemple #6
0
  protected int[] crop(
      int width, int height, int offsetx, int offsety, String srcPath, String dstPath) {
    String[] paths = escapePaths(srcPath, dstPath);
    srcPath = paths[0];
    dstPath = paths[1];
    boolean success = false;

    String cmd = core.app.getProperty("imagemagick");
    if (cmd == null) {
      ParameterBlock args = new ParameterBlock();
      args.addSource(FileLoadDescriptor.create(srcPath, null, null, null));
      args.add((float) offsetx);
      args.add((float) offsety);
      args.add((float) width);
      args.add((float) height);
      RenderedOp croppedImage = JAI.create("crop", args);
      String type = dstPath.substring(dstPath.lastIndexOf(".") + 1);
      success = writeImage(dstPath, type, croppedImage);
    } else {
      if (!cmd.endsWith("convert")) {
        if (!cmd.endsWith(File.separator)) {
          cmd += File.separator;
        }
        cmd += "convert";
      }

      StringBuffer command = new StringBuffer(cmd);
      command.append(" -crop ");
      command
          .append(width)
          .append("x")
          .append(height)
          .append("+")
          .append(offsetx)
          .append("+")
          .append(offsety)
          .append("!");
      command.append(" ").append(srcPath);
      command.append(" ").append(dstPath);
      success = exec(command.toString());
    }

    if (success) {
      return new int[] {width, height};
    }

    return null;
  }
 private static int printSourceNumber(String source, int offset, StringBuffer sb) {
   double number = 0.0;
   char type = source.charAt(offset);
   ++offset;
   if (type == 'S') {
     if (sb != null) {
       number = source.charAt(offset);
     }
     ++offset;
   } else if (type == 'J' || type == 'D') {
     if (sb != null) {
       long lbits;
       lbits = (long) source.charAt(offset) << 48;
       lbits |= (long) source.charAt(offset + 1) << 32;
       lbits |= (long) source.charAt(offset + 2) << 16;
       lbits |= (long) source.charAt(offset + 3);
       if (type == 'J') {
         number = lbits;
       } else {
         number = Double.longBitsToDouble(lbits);
       }
     }
     offset += 4;
   } else {
     // Bad source
     throw new RuntimeException();
   }
   if (sb != null) {
     sb.append(ScriptRuntime.numberToString(number, 10));
   }
   return offset;
 }
Exemple #8
0
  /**
   * Adds another Image object as a thumbnail (child) of this Image object, which can be retrieved
   * using <code> getThumbnail(accessname) </code>.
   *
   * @param {Image} child The Image object to add as a child of this Image object
   * @param {String} [accessname] The accessname by which the child Image object may be retrieved by
   *     calling getThumbnail(accessname). If this argument is left unspecified, defaults to a
   *     String "[width]x[height]". So if the width is 200 and the height is 100, the default
   *     accessname will be 200x100
   * @returns {Boolean} Whether the operation was a success or not. If there is already an Image
   *     object with the same name as accessname located as a child of this Image object, then it
   *     will fail and return <code> false </code>
   */
  public boolean jsFunction_addThumbnail(Object child, Object accessname) {
    if (child instanceof ImageObject) {
      ImageObject th = (ImageObject) child;

      StringBuffer sb = new StringBuffer();
      if (accessname != null && accessname != Scriptable.NOT_FOUND) {
        sb.append((String) accessname);
      } else {
        sb.append(th.getDimension(WIDTH)).append("x").append(th.getDimension(HEIGHT));
      }

      th.node.setString(FileObject.ACCESSNAME, sb.toString());
      return super.jsFunction_add(th);
    }
    return false;
  }
 private String getDebugString(int max) {
   assert max > 0;
   StringBuffer result = new StringBuffer();
   int start = Math.max(offset - max, 0);
   int end = Math.min(offset + max, tokens.size());
   for (int i = start; i < end; i++) {
     JavaScriptToken token = tokens.get(i);
     if (i == offset - 1) {
       result.append(" ---> ");
     }
     result.append(token.getValue());
     if (i == offset - 1) {
       result.append(" <--- ");
     }
   }
   return result.toString();
 }
Exemple #10
0
 protected String[] escapePaths(String srcPath, String dstPath) {
   srcPath = srcPath.trim();
   dstPath = dstPath.trim();
   String os = System.getProperty("os.name").toLowerCase();
   if (os != null && os.indexOf("windows") > -1) {
     srcPath = "\"" + srcPath + "\"";
     dstPath = "\"" + dstPath + "\"";
   } else {
     int lastidx = -1, curridx;
     StringBuffer buff = new StringBuffer(srcPath);
     while ((curridx = buff.indexOf(" ", lastidx)) > 0) {
       buff.insert(curridx, "\\");
       lastidx = curridx + 2;
     }
     srcPath = buff.toString();
     buff = new StringBuffer(dstPath);
     lastidx = -1;
     while ((curridx = buff.indexOf(" ", lastidx)) > 0) {
       buff.insert(curridx, "\\");
       lastidx = curridx + 2;
     }
     dstPath = buff.toString();
   }
   return new String[] {srcPath, dstPath};
 }
  // Add necessary escaping that was removed in Rhino's tokenizer(词法分析器).
  private static String escapeString(String s, char quotechar) {

    assert quotechar == '"'
        || quotechar == '\''; // 如果启用了断言,则表达式为假时,程序抛出AssertionError(这是一个错误,不是异常,所以不能被捕获)

    if (s == null) {
      return null;
    }

    StringBuffer sb = new StringBuffer();
    for (int i = 0, L = s.length(); i < L; i++) {
      int c = s.charAt(i);
      if (c == quotechar) {
        sb.append("\\");
      }
      sb.append((char) c);
    }

    return sb.toString();
  }
Exemple #12
0
  @Override
  public String toString() {
    //    ECMA357 10.1.2
    if (hasSimpleContent()) {
      StringBuffer sb = new StringBuffer();

      for (int i = 0; i < length(); i++) {
        XML next = getXmlFromAnnotation(i);
        if (next.isComment() || next.isProcessingInstruction()) {
          //    do nothing
        } else {
          sb.append(next.toString());
        }
      }

      return sb.toString();
    } else {
      return toXMLString();
    }
  }
 private static int printSourceString(String source, int offset, StringBuffer sb) {
   int length = source.charAt(offset);
   ++offset;
   if ((0x8000 & length) != 0) {
     length = ((0x7FFF & length) << 16) | source.charAt(offset);
     ++offset;
   }
   if (sb != null) {
     String str = source.substring(offset, offset + length);
     sb.append(str);
   }
   return offset + length;
 }
 public String printMungeMapping() {
   StringBuffer sb = new StringBuffer();
   globalScope.getFullMapping(sb, "");
   return sb.toString();
 }
  public StringBuffer printSymbolTree(int linebreakpos, boolean preserveAllSemiColons)
      throws IOException {

    offset = 0;
    braceNesting = 0;
    scopes.clear();

    String symbol;
    JavaScriptToken token;
    // begin
    if (tokens.size() == 0) {
      StringBuffer result = new StringBuffer();
      return result;
    }
    // end
    JavaScriptToken lastToken = getToken(0);
    ScriptOrFnScope currentScope;
    JavaScriptIdentifier identifier;

    int length = tokens.size(); // 文本的长度
    StringBuffer result = new StringBuffer();

    int linestartpos = 0;

    enterScope(globalScope); // 将globalScope压入栈scopes中

    while (offset < length) {

      token = consumeToken();
      symbol = token.getValue();
      currentScope = getCurrentScope();
      switch (token.getType()) {
        case Token.GET:
        case Token.SET:
          lastToken = token; // 注意没有break;

        case Token.NAME:
          if (offset >= 2 && getToken(-2).getType() == Token.DOT
              || getToken(0).getType() == Token.OBJECTLIT) {

            result.append(symbol);

          } else {
            identifier = getIdentifier(symbol, currentScope);
            if (identifier != null) {
              if (identifier.getMungedValue() != null) {
                result.append(identifier.getMungedValue());
              } else {
                result.append(symbol);
              }
              if (currentScope != globalScope // 全局域中的变量可能被HTML文档使用,不需要发出警告
                  && identifier.getRefcount() == 0) {
                warn("标识符" + symbol + "已经声明但未使用 ", true);
              }
            } else {
              result.append(symbol);
            }
          }
          break;

        case Token.REGEXP:
        case Token.STRING:
          result.append(symbol);
          break;

        case Token.NUMBER:
          if (getToken(0).getType() == Token.DOT) {
            // calling methods on int requires a leading dot so JS
            // doesn't
            // treat the method as the decimal component of a float
            result.append('(');
            result.append(symbol);
            result.append(')');
          } else {
            result.append(symbol);
          }
          break;

        case Token.ADD:
        case Token.SUB:
          result.append(literals.get(new Integer(token.getType())));
          if (offset < length) {
            token = getToken(0);
            if (token.getType() == Token.INC
                || token.getType() == Token.DEC
                || token.getType() == Token.ADD
                || token.getType() == Token.DEC) {
              // Handle the case x +/- ++/-- y
              // We must keep a white space here. Otherwise, x +++ y
              // would be
              // interpreted as x ++ + y by the compiler, which is a
              // bug (due
              // to the implicit(隐式的) assignment being done on the
              // wrong variable)
              result.append(' ');
            } else if (token.getType() == Token.POS && getToken(-1).getType() == Token.ADD
                || token.getType() == Token.NEG && getToken(-1).getType() == Token.SUB) {
              // Handle the case x + + y and x - - y
              result.append(' ');
            }
          }
          break;

        case Token.FUNCTION:
          if (lastToken.getType() != Token.GET && lastToken.getType() != Token.SET) {
            result.append("function");
          }
          lastToken = token;
          token = consumeToken();
          if (token.getType() == Token.NAME) {
            result.append(' ');
            symbol = token.getValue();
            identifier = getIdentifier(symbol, currentScope);
            assert identifier != null;
            if (identifier.getMungedValue() != null) {
              result.append(identifier.getMungedValue());
            } else {
              result.append(symbol);
            }
            if (currentScope != globalScope && identifier.getRefcount() == 0) {
              warn("标识符" + symbol + "已经声明但未使用", true);
            }
            token = consumeToken();
          }
          assert token.getType() == Token.LP;
          result.append('(');
          currentScope = indexedScopes.get(new Integer(offset)); // 根据左圆括号的下一个索引映射得到函数作用域
          enterScope(currentScope);
          while ((token = consumeToken()).getType() != Token.RP) {
            assert token.getType() == Token.NAME || token.getType() == Token.COMMA;
            if (token.getType() == Token.NAME) {
              symbol = token.getValue();
              identifier = getIdentifier(symbol, currentScope);
              assert identifier != null;
              if (identifier.getMungedValue() != null) {
                result.append(identifier.getMungedValue());
              } else {
                result.append(symbol);
              }
            } else if (token.getType() == Token.COMMA) {
              result.append(',');
            }
          }
          result.append(')');
          token = consumeToken(); // 得到左花括号
          assert token.getType() == Token.LC;
          result.append("{"); // nomodify
          braceNesting++;
          token = getToken(0);
          if (token.getType() == Token.STRING && getToken(1).getType() == Token.SEMI) {
            // This is a hint. Skip it!
            consumeToken();
            consumeToken();
          }
          break;

        case Token.RETURN:
        case Token.TYPEOF:
          result.append(literals.get(new Integer(token.getType())));
          // No space needed after 'return' and 'typeof' when followed
          // by '(', '[', '{', a string or a regexp.
          if (offset < length) {
            token = getToken(0);
            if (token.getType() != Token.LP
                && token.getType() != Token.LB
                && token.getType() != Token.LC
                && token.getType() != Token.STRING
                && token.getType() != Token.REGEXP
                && token.getType() != Token.SEMI) {
              result.append(' ');
            }
          }
          break;

        case Token.CASE:
        case Token.THROW:
          result.append(literals.get(new Integer(token.getType())));
          // White-space needed after 'case' and 'throw' when not followed
          // by a string.
          if (offset < length && getToken(0).getType() != Token.STRING) {
            result.append(' ');
          }
          break;

        case Token.BREAK:
        case Token.CONTINUE:
          result.append(literals.get(new Integer(token.getType())));
          if (offset < length && getToken(0).getType() != Token.SEMI) {
            // If 'break' or 'continue' is not followed by a
            // semi-colon(分号), it must
            // be followed by a label, hence(因此) the need for a white
            // space.
            result.append(' ');
          }
          break;

        case Token.LC:
          result.append("{"); // nomodify
          braceNesting++;
          break;

        case Token.RC:
          result.append('}');
          braceNesting--;
          assert braceNesting >= currentScope.getBraceNesting();
          if (braceNesting == currentScope.getBraceNesting()) {
            leaveCurrentScope();
          }
          break;

        case Token.SEMI:
          // No need to output a semi-colon if the next character is a
          // right-curly...
          if (preserveAllSemiColons || offset < length && getToken(0).getType() != Token.RC) {
            result.append(';');
          }

          if (linebreakpos >= 0 && result.length() - linestartpos > linebreakpos) {
            // Some source control tools don't like it when files
            // containing lines longer
            // than, say 8000 characters, are checked in. The linebreak
            // option is used in
            // that case to split long lines after a specific column.
            result.append('\n');
            linestartpos = result.length();
          }
          break;

        case Token.COMMA:
          // No need to output a comma if the next character is a
          // right-curly or a right-square bracket
          if (offset < length
              && getToken(0).getType() != Token.RC
              && getToken(0).getType() != Token.RB) {
            result.append(',');
          }
          break;

        case Token.CONDCOMMENT:
        case Token.KEEPCOMMENT:
          if (result.length() > 0 && result.charAt(result.length() - 1) != '\n') {
            result.append("\n");
          }
          result.append("/*");
          if (token.getType() == Token.KEEPCOMMENT) {
            result.append("!");
          }
          result.append(symbol);
          result.append("*/\n");
          break;

          // begin--这个分支用于实现压扁控制流
          // 此分支将if(expression){...}else if(expression){...}else{...}转化为
          // switch(expression){case true:原if块;break;case false:原else块;break;}
        case Token.IF:
          if (!EditOptionPanel.checkBoxFlatten.isSelected()) {
            result.append(symbol);
            break;
          }
          FlattenIF flattenIF = new FlattenIF(offset, length, tokens, currentScope);
          String switchBlock = flattenIF.flattenIF();
          result.append(switchBlock);
          offset = flattenIF.offset;
          break;
        case Token.WHILE:
          if (!EditOptionPanel.checkBoxOpacity.isSelected()) {
            result.append(symbol);
            break;
          }
          result.append(symbol);
          OpacityPredicate opacityPredicateWhile =
              new OpacityPredicate(offset, tokens, currentScope);
          String whileBlock = opacityPredicateWhile.opacityPredicateWhile();
          result.append(whileBlock);
          offset = opacityPredicateWhile.offset;
          break;
        case Token.DO:
          if (!EditOptionPanel.checkBoxOpacity.isSelected()) {
            result.append(symbol);
            break;
          }
          result.append(symbol);
          OpacityPredicate opacityPredicateDoWhile =
              new OpacityPredicate(offset, tokens, currentScope);
          String doWhileBlock = opacityPredicateDoWhile.opacityPredicateDoWhile();
          result.append(doWhileBlock);
          offset = opacityPredicateDoWhile.offset;
          break;
          // end
        default:
          String literal = literals.get(new Integer(token.getType()));
          if (literal != null) {
            result.append(literal);
          } else {
            warn("此标志符不能被打印出来:" + symbol, true);
          }
          break;
      }
    }

    // Append a semi-colon at the end, even if unnecessary semi-colons are
    // supposed to be removed. This is especially useful when concatenating
    // several minified files (the absence of an ending semi-colon at the
    // end of one file may very likely cause a syntax error)
    /*if (!preserveAllSemiColons && result.length() > 0
    		&& getToken(-1).getType() != Token.CONDCOMMENT
    		&& getToken(-1).getType() != Token.KEEPCOMMENT) {
    	if (result.charAt(result.length() - 1) == '\n') {
    		result.setCharAt(result.length() - 1, ';');
    	} else {
    		result.append(';');
    	}
    }*/
    // 暂时用不上,注释掉

    return result;
  }