/** Registers the given script as a top-level script in the debugger. */ private void registerTopScript(DebuggableScript topScript, String source) { if (!topScript.isTopLevel()) { throw new IllegalArgumentException(); } String url = getNormalizedUrl(topScript); DebuggableScript[] functions = getAllFunctions(topScript); final SourceInfo sourceInfo = new SourceInfo(source, functions, url); synchronized (urlToSourceInfo) { SourceInfo old = urlToSourceInfo.get(url); if (old != null) { sourceInfo.copyBreakpointsFrom(old); } urlToSourceInfo.put(url, sourceInfo); for (int i = 0; i != sourceInfo.functionSourcesTop(); ++i) { FunctionSource fsource = sourceInfo.functionSource(i); String name = fsource.name(); if (name.length() != 0) { functionNames.put(name, fsource); } } } synchronized (functionToSource) { for (int i = 0; i != functions.length; ++i) { FunctionSource fsource = sourceInfo.functionSource(i); functionToSource.put(functions[i], fsource); } } callback.updateSourceText(sourceInfo); }
public static ScriptableObject require( Context cx, Scriptable thisObj, Object[] args, Function funObj) throws ScriptException, IOException { String functionName = "require"; int argsCount = args.length; if (argsCount != 1) { HostObjectUtil.invalidNumberOfArgs( CommonManager.HOST_OBJECT_NAME, functionName, argsCount, false); } if (!(args[0] instanceof String)) { HostObjectUtil.invalidArgsError( CommonManager.HOST_OBJECT_NAME, functionName, "1", "string", args[0], false); } String moduleId = (String) args[0]; int dotIndex = moduleId.lastIndexOf("."); if (moduleId.length() == dotIndex + 1) { String msg = "Invalid file path for require method : " + moduleId; log.error(msg); throw new ScriptException(msg); } JaggeryContext jaggeryContext = CommonManager.getJaggeryContext(); Map<String, ScriptableObject> requiredModules = (Map<String, ScriptableObject>) jaggeryContext.getProperty(Constants.JAGGERY_REQUIRED_MODULES); ScriptableObject object = requiredModules.get(moduleId); if (object != null) { return object; } if (dotIndex == -1) { object = CommonManager.require(cx, thisObj, args, funObj); initModule(cx, jaggeryContext, moduleId, object); } else { object = (ScriptableObject) cx.newObject(thisObj); object.setPrototype(thisObj); object.setParentScope(null); String ext = moduleId.substring(dotIndex + 1); if (ext.equalsIgnoreCase("json")) { object = executeScript(jaggeryContext, object, moduleId, true, true, false); } else if (ext.equalsIgnoreCase("js")) { object = executeScript(jaggeryContext, object, moduleId, false, true, false); } else if (ext.equalsIgnoreCase("jag")) { object = executeScript(jaggeryContext, object, moduleId, false, false, false); } else { String msg = "Unsupported file type for require() method : ." + ext; log.error(msg); throw new ScriptException(msg); } } requiredModules.put(moduleId, object); return object; }
private void parseDirective(String token) { int index = token.indexOf(Constants.DIRECTIVE_EQUALS); String directiveName = token.substring(0, index).trim(); if (directiveName.length() == 0) return; String value = token.substring(index + Constants.DIRECTIVE_EQUALS.length()).trim(); if (directiveName.equals(Constants.MANDATORY_DIRECTIVE)) parseMandatory(value); directives.put(directiveName, value); }
private void parseAttribute(String token) { int index = token.indexOf(Constants.ATTRIBUTE_EQUALS); String attributeName = token.substring(0, index).trim(); if (attributeName.length() == 0) return; Object value = token.substring(index + Constants.ATTRIBUTE_EQUALS.length()).trim(); if (attributeName.equals(Constants.VERSION_ATTRIBUTE)) version = Version.parseVersion((String) value); attributes.put(attributeName, value); }
PageInfo getPageInfo(ScriptContext context, String path) throws IOException { PageInfo info = null; if (pageInfoCache != null) info = this.pageInfoCache.get(path); if (info == null) { String file = prefix + path + suffix; String actualPath = FileHelper.findRecursive(file); String source = FileHelper.read(actualPath); Object object = context.evaluate(source, path); info = new PageInfo((BaseFunction) object, actualPath); if (pageInfoCache != null) pageInfoCache.put(path, info); } return info; }
private static ScriptableObject executeScript( JaggeryContext jaggeryContext, ScriptableObject scope, String fileURL, final boolean isJSON, boolean isBuilt, boolean isIncludeOnce) throws ScriptException { Stack<String> includesCallstack = CommonManager.getCallstack(jaggeryContext); Map<String, Boolean> includedScripts = CommonManager.getIncludes(jaggeryContext); ServletContext context = (ServletContext) jaggeryContext.getProperty(Constants.SERVLET_CONTEXT); String parent = includesCallstack.lastElement(); String keys[] = WebAppManager.getKeys(context.getContextPath(), parent, fileURL); fileURL = getNormalizedScriptPath(keys); if (includesCallstack.search(fileURL) != -1) { return scope; } if (isIncludeOnce && includedScripts.get(fileURL) != null) { return scope; } ScriptReader source; RhinoEngine engine = jaggeryContext.getEngine(); if (isBuilt) { source = new ScriptReader(context.getResourceAsStream(fileURL)) { @Override protected void build() throws IOException { try { if (isJSON) { sourceReader = new StringReader("(" + HostObjectUtil.streamToString(sourceIn) + ")"); } else { sourceReader = new StringReader(HostObjectUtil.streamToString(sourceIn)); } } catch (ScriptException e) { throw new IOException(e); } } }; } else { source = new ScriptReader(context.getResourceAsStream(fileURL)); } ScriptCachingContext sctx = new ScriptCachingContext(jaggeryContext.getTenantId(), keys[0], keys[1], keys[2]); sctx.setSecurityDomain(new JaggerySecurityDomain(fileURL, context)); long lastModified = WebAppManager.getScriptLastModified(context, fileURL); sctx.setSourceModifiedTime(lastModified); includedScripts.put(fileURL, true); includesCallstack.push(fileURL); if (isJSON) { scope = (ScriptableObject) engine.eval(source, scope, sctx); } else { engine.exec(source, scope, sctx); } includesCallstack.pop(); return scope; }
static { // This list contains all the 3 characters or less built-in global // symbols available in a browser. Please add to this list if you // see anything missing. builtin.add("NaN"); builtin.add("top"); ones = new ArrayList<String>(); for (char c = 'a'; c <= 'z'; c++) ones.add(Character.toString(c)); for (char c = 'A'; c <= 'Z'; c++) ones.add(Character.toString(c)); twos = new ArrayList<String>(); for (int i = 0; i < ones.size(); i++) { String one = ones.get(i); for (char c = 'a'; c <= 'z'; c++) twos.add(one + Character.toString(c)); for (char c = 'A'; c <= 'Z'; c++) twos.add(one + Character.toString(c)); for (char c = '0'; c <= '9'; c++) twos.add(one + Character.toString(c)); } // Remove two-letter JavaScript reserved words and built-in globals... twos.remove("as"); twos.remove("is"); twos.remove("do"); twos.remove("if"); twos.remove("in"); twos.removeAll(builtin); threes = new ArrayList<String>(); for (int i = 0; i < twos.size(); i++) { String two = twos.get(i); for (char c = 'a'; c <= 'z'; c++) threes.add(two + Character.toString(c)); for (char c = 'A'; c <= 'Z'; c++) threes.add(two + Character.toString(c)); for (char c = '0'; c <= '9'; c++) threes.add(two + Character.toString(c)); } // Remove three-letter JavaScript reserved words and built-in globals... threes.remove("for"); threes.remove("int"); threes.remove("new"); threes.remove("try"); threes.remove("use"); threes.remove("var"); threes.removeAll(builtin); // That's up to ((26+26)*(1+(26+26+10)))*(1+(26+26+10))-8 // (206,380 symbols per scope) // The following list comes from // org/mozilla/javascript/Decompiler.java... // 注意:此处并为认为地设定键与值的acsii码相等,比如Token.ASSIGN是89,而'='为61 literals.put(new Integer(Token.GET), "get "); literals.put(new Integer(Token.SET), "set "); literals.put(new Integer(Token.TRUE), "true"); literals.put(new Integer(Token.FALSE), "false"); literals.put(new Integer(Token.NULL), "null"); literals.put(new Integer(Token.THIS), "this"); literals.put(new Integer(Token.FUNCTION), "function"); literals.put(new Integer(Token.COMMA), ","); literals.put(new Integer(Token.LC), "{"); literals.put(new Integer(Token.RC), "}"); literals.put(new Integer(Token.LP), "("); literals.put(new Integer(Token.RP), ")"); literals.put(new Integer(Token.LB), "["); literals.put(new Integer(Token.RB), "]"); literals.put(new Integer(Token.DOT), "."); literals.put(new Integer(Token.NEW), "new "); literals.put(new Integer(Token.DELPROP), "delete "); literals.put(new Integer(Token.IF), "if"); literals.put(new Integer(Token.ELSE), "else"); literals.put(new Integer(Token.FOR), "for"); literals.put(new Integer(Token.IN), " in "); literals.put(new Integer(Token.WITH), "with"); literals.put(new Integer(Token.WHILE), "while"); literals.put(new Integer(Token.DO), "do"); literals.put(new Integer(Token.TRY), "try"); literals.put(new Integer(Token.CATCH), "catch"); literals.put(new Integer(Token.FINALLY), "finally"); literals.put(new Integer(Token.THROW), "throw"); literals.put(new Integer(Token.SWITCH), "switch"); literals.put(new Integer(Token.BREAK), "break"); literals.put(new Integer(Token.CONTINUE), "continue"); literals.put(new Integer(Token.CASE), "case"); literals.put(new Integer(Token.DEFAULT), "default"); literals.put(new Integer(Token.RETURN), "return"); literals.put(new Integer(Token.VAR), "var "); literals.put(new Integer(Token.SEMI), ";"); literals.put(new Integer(Token.ASSIGN), "="); literals.put(new Integer(Token.ASSIGN_ADD), "+="); literals.put(new Integer(Token.ASSIGN_SUB), "-="); literals.put(new Integer(Token.ASSIGN_MUL), "*="); literals.put(new Integer(Token.ASSIGN_DIV), "/="); literals.put(new Integer(Token.ASSIGN_MOD), "%="); literals.put(new Integer(Token.ASSIGN_BITOR), "|="); literals.put(new Integer(Token.ASSIGN_BITXOR), "^="); literals.put(new Integer(Token.ASSIGN_BITAND), "&="); literals.put(new Integer(Token.ASSIGN_LSH), "<<="); literals.put(new Integer(Token.ASSIGN_RSH), ">>="); literals.put(new Integer(Token.ASSIGN_URSH), ">>>="); literals.put(new Integer(Token.HOOK), "?"); literals.put(new Integer(Token.OBJECTLIT), ":"); literals.put(new Integer(Token.COLON), ":"); literals.put(new Integer(Token.OR), "||"); literals.put(new Integer(Token.AND), "&&"); literals.put(new Integer(Token.BITOR), "|"); literals.put(new Integer(Token.BITXOR), "^"); literals.put(new Integer(Token.BITAND), "&"); literals.put(new Integer(Token.SHEQ), "==="); literals.put(new Integer(Token.SHNE), "!=="); literals.put(new Integer(Token.EQ), "=="); literals.put(new Integer(Token.NE), "!="); literals.put(new Integer(Token.LE), "<="); literals.put(new Integer(Token.LT), "<"); literals.put(new Integer(Token.GE), ">="); literals.put(new Integer(Token.GT), ">"); literals.put(new Integer(Token.INSTANCEOF), " instanceof "); literals.put(new Integer(Token.LSH), "<<"); literals.put(new Integer(Token.RSH), ">>"); literals.put(new Integer(Token.URSH), ">>>"); literals.put(new Integer(Token.TYPEOF), "typeof"); literals.put(new Integer(Token.VOID), "void "); literals.put(new Integer(Token.CONST), "const "); literals.put(new Integer(Token.NOT), "!"); literals.put(new Integer(Token.BITNOT), "~"); literals.put(new Integer(Token.POS), "+"); literals.put(new Integer(Token.NEG), "-"); literals.put(new Integer(Token.INC), "++"); literals.put(new Integer(Token.DEC), "--"); literals.put(new Integer(Token.ADD), "+"); literals.put(new Integer(Token.SUB), "-"); literals.put(new Integer(Token.MUL), "*"); literals.put(new Integer(Token.DIV), "/"); literals.put(new Integer(Token.MOD), "%"); literals.put(new Integer(Token.COLONCOLON), "::"); literals.put(new Integer(Token.DOTDOT), ".."); literals.put(new Integer(Token.DOTQUERY), ".("); literals.put(new Integer(Token.XMLATTR), "@"); literals.put(new Integer(Token.LET), "let "); literals.put(new Integer(Token.YIELD), "yield "); // See // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Reserved_Words // JavaScript 1.5 reserved words reserved.add("break"); reserved.add("case"); reserved.add("catch"); reserved.add("continue"); reserved.add("default"); reserved.add("delete"); reserved.add("do"); reserved.add("else"); reserved.add("finally"); reserved.add("for"); reserved.add("function"); reserved.add("if"); reserved.add("in"); reserved.add("instanceof"); reserved.add("new"); reserved.add("return"); reserved.add("switch"); reserved.add("this"); reserved.add("throw"); reserved.add("try"); reserved.add("typeof"); reserved.add("var"); reserved.add("void"); reserved.add("while"); reserved.add("with"); // Words reserved for future use reserved.add("abstract"); reserved.add("boolean"); reserved.add("byte"); reserved.add("char"); reserved.add("class"); reserved.add("const"); reserved.add("debugger"); reserved.add("double"); reserved.add("enum"); reserved.add("export"); reserved.add("extends"); reserved.add("final"); reserved.add("float"); reserved.add("goto"); reserved.add("implements"); reserved.add("import"); reserved.add("int"); reserved.add("interface"); reserved.add("long"); reserved.add("native"); reserved.add("package"); reserved.add("private"); reserved.add("protected"); reserved.add("public"); reserved.add("short"); reserved.add("static"); reserved.add("super"); reserved.add("synchronized"); reserved.add("throws"); reserved.add("transient"); reserved.add("volatile"); // These are not reserved, but should be taken into account // in isValidIdentifier (See jslint source code) reserved.add("arguments"); reserved.add("eval"); reserved.add("true"); reserved.add("false"); reserved.add("Infinity"); reserved.add("NaN"); reserved.add("null"); reserved.add("undefined"); }