Exemple #1
0
 private void parseExport(String header) {
   StringTokenizer tokenizer = new StringTokenizer(header, Constants.PARAMETER_DELIMITER);
   this.name = tokenizer.nextToken().trim();
   while (tokenizer.hasMoreTokens()) {
     String token = (String) tokenizer.nextElement();
     if (token.indexOf(Constants.DIRECTIVE_EQUALS) != -1) parseDirective(token);
     else if (token.indexOf(Constants.ATTRIBUTE_EQUALS) != -1) parseAttribute(token);
   }
 }
Exemple #2
0
 protected void addToScope(Scriptable scope) {
   Object value = exportingBundle.lookup(name);
   StringTokenizer tokenizer = new StringTokenizer(name, "."); // $NON-NLS-1$
   while (true) {
     String token = tokenizer.nextToken();
     Object current = scope.get(token, scope);
     if (!tokenizer.hasMoreTokens()) {
       if (current == Scriptable.NOT_FOUND) {
         if (value instanceof NativeObject) {
           Scriptable wrapped = Context.getCurrentContext().newObject(scope);
           wrapped.setPrototype((Scriptable) value);
           value = wrapped;
         }
         scope.put(token, scope, value);
         return;
       }
       throw new IllegalStateException(
           "Resolve error: "
               + name
               + " already exists for "
               + this.toString()); // $NON-NLS-1$//$NON-NLS-2$	
     }
     if (current == Scriptable.NOT_FOUND) {
       current = ScriptableObject.getProperty(scope, token);
       if (current == Scriptable.NOT_FOUND) current = Context.getCurrentContext().newObject(scope);
       else if (current instanceof NativeObject) {
         // we need to wrap this object from the prototype
         Scriptable wrapped = Context.getCurrentContext().newObject(scope);
         wrapped.setPrototype((Scriptable) current);
         current = wrapped;
       } else
         throw new IllegalStateException(
             "Resolve error: "
                 + name
                 + "-"
                 + token
                 + " already exists for "
                 + this.toString()); // $NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
       scope.put(token, scope, current);
     }
     scope = (Scriptable) current;
   }
 }
  private void parseFunctionDeclaration() {

    String symbol;
    JavaScriptToken token;
    ScriptOrFnScope currentScope, fnScope;
    JavaScriptIdentifier identifier;

    currentScope = getCurrentScope(); // 得到此函数声明所在的域

    token = consumeToken();

    // 如果是函数名(说明这种函数的声明方式是:function funName(){})
    // 否则是:var varName = function(){}
    if (token.getType() == Token.NAME) {
      if (mode == BUILDING_SYMBOL_TREE) {
        // Get the name of the function and declare it in the current
        // scope.
        symbol = token.getValue(); // 得到的是函数名
        if (currentScope.getIdentifier(symbol) != null) {
          warn("函数" + symbol + "已经在相同的作用域中声明。", true);
        }
        currentScope.declareIdentifier(symbol, false); // 在本作用域中声明标识符
      }
      token = consumeToken(); // 得到左圆括号
    }

    assert token.getType() == Token.LP;
    if (mode == BUILDING_SYMBOL_TREE) {
      fnScope = new ScriptOrFnScope(braceNesting, currentScope); // 新建一个作用域,并把当前域传递过去最为父作用域
      indexedScopes.put(new Integer(offset), fnScope); // 圆括号的下一个索引映射到函数作用域
    } else {
      fnScope = indexedScopes.get(new Integer(offset));
    }

    // Parse function arguments.解释函数参数
    int argpos = 0;
    while ((token = consumeToken()).getType() != Token.RP) {
      assert token.getType() == Token.NAME || token.getType() == Token.COMMA;
      if (token.getType() == Token.NAME && mode == BUILDING_SYMBOL_TREE) {
        symbol = token.getValue();
        identifier = fnScope.declareIdentifier(symbol, false);
        if (symbol.equals("$super") && argpos == 0) {
          // Exception for Prototype 1.6...
          identifier.preventMunging();
        }
        argpos++;
      }
    }

    token = consumeToken(); // 得到函数的左花括号
    assert token.getType() == Token.LC;
    braceNesting++;

    token = getToken(0);
    if (token.getType() == Token.STRING && getToken(1).getType() == Token.SEMI) {
      // This is a hint. Hints are empty statements that look like
      // "localvar1:nomunge, localvar2:nomunge"; They allow developers
      // to prevent specific symbols from getting obfuscated (some heretic
      // implementations, such as Prototype 1.6, require specific variable
      // names, such as $super for example, in order to work
      // appropriately.
      // Note: right now, only "nomunge" is supported in the right hand
      // side
      // of a hint. However, in the future, the right hand side(右边) may
      // contain
      // other values.
      consumeToken();
      String hints = token.getValue();
      // Remove the leading and trailing quotes...
      hints = hints.substring(1, hints.length() - 1).trim();
      StringTokenizer st1 = new StringTokenizer(hints, ","); // Tokenizer分词器,以','为分词界限
      while (st1.hasMoreTokens()) {
        String hint = st1.nextToken();
        int idx = hint.indexOf(':');
        if (idx <= 0 || idx >= hint.length() - 1) {
          if (mode == BUILDING_SYMBOL_TREE) {
            // No need to report the error twice, hence the test...
            warn("提示语句有语法错误:" + hint, true);
          }
          break;
        }
        String variableName = hint.substring(0, idx).trim();
        String variableType = hint.substring(idx + 1).trim();
        if (mode == BUILDING_SYMBOL_TREE) {
          fnScope.addHint(variableName, variableType);
        } else if (mode == CHECKING_SYMBOL_TREE) {
          identifier = fnScope.getIdentifier(variableName);
          if (identifier != null) {
            if (variableType.equals("nomunge")) {
              identifier.preventMunging();
            } else {
              warn("不支持的提示指令: " + hint, true);
            }
          } else {
            warn("提示指令指向未知的标识符: " + hint, true);
          }
        }
      }
    }

    parseScope(fnScope); // 解释函数域
  }