private void parseMandatory(String value) { StringTokenizer tokenizer = new StringTokenizer(value, Constants.MANDATORY_DELIMITER); while (tokenizer.hasMoreTokens()) { String token = (String) tokenizer.nextElement(); token = token.trim(); if (token.length() > 0) mandatory.add(token); } }
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); } }
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); // 解释函数域 }