private void handleException(ParserExceptionWithSource exception) { ParserException e = exception.getCause(); String sourceCode = exception.getSourceCode(); int lineOffset = exception.getSource().getLine(); String sourceInfo = String.format("%s:%d:%d", e.getFile(), e.getLine(), e.getColumn()); int start = skipLines(sourceCode, e.getLine() - lineOffset); int end = nextLineTerminator(sourceCode, start); String offendingLine = sourceCode.substring(start, end); String marker = Strings.repeat('.', Math.max(e.getColumn() - 1, 0)) + '^'; console.printf("%s %s: %s%n", sourceInfo, e.getType(), e.getFormattedMessage()); console.printf("%s %s%n", sourceInfo, offendingLine); console.printf("%s %s%n", sourceInfo, marker); printStackTrace(e); }
/** * REPL: Read * * @param realm the realm instance * @param line the current line * @return the parsed script node or {@coden null} if the end of stream has been reached */ private com.github.anba.es6draft.ast.Script read(Realm realm, int[] line) { StringBuilder sourceBuffer = new StringBuilder(); for (String prompt = PROMPT; ; prompt = "") { String s = console.readLine(prompt); if (s == null) { return null; } sourceBuffer.append(s).append('\n'); String sourceCode = sourceBuffer.toString(); Source source = new Source(Paths.get(".").toAbsolutePath(), "typein", line[0]); try { com.github.anba.es6draft.ast.Script script = parse(realm, source, sourceCode); line[0] += script.getEndLine() - script.getBeginLine(); return script; } catch (ParserEOFException e) { continue; } catch (ParserException e) { throw new ParserExceptionWithSource(e, source, sourceCode); } } }
/** * REPL: Print * * @param realm the realm instance * @param result the object to be printed */ private void print(Realm realm, Object result) { if (result != UNDEFINED) { console.printf("%s%n", sourceBuilder.toSource(realm.defaultContext(), result)); } }
private void handleException(Realm realm, UnhandledRejectionException e) { String message = formatMessage("unhandled_rejection", e.getMessage(realm.defaultContext())); console.printf("%s%n", message); printStackTrace(e.getCauseIfPresent()); }
private void handleException(Realm realm, ScriptException e) { String message = formatMessage("uncaught_exception", e.getMessage(realm.defaultContext())); console.printf("%s%n", message); printScriptStackTrace(realm, e); printStackTrace(e); }
private void handleException(IOException e) { String message = Objects.toString(e.getMessage(), ""); console.printf("%s: %s%n", e.getClass().getSimpleName(), message); printStackTrace(e); }
private Repl(ShellConsole console, Options options) { this.console = console; this.options = options; this.sourceBuilder = new SourceBuilder(console.isAnsiSupported() && !options.noColor, 10, 30, 80); }
private Realm newRealm() { ObjectAllocator<? extends ShellGlobalObject> allocator; if (options.shellMode == ShellMode.Mozilla) { allocator = MozShellGlobalObject::new; } else if (options.shellMode == ShellMode.V8) { allocator = V8ShellGlobalObject::new; } else { allocator = SimpleShellGlobalObject::new; } BiFunction<RuntimeContext, ScriptLoader, ModuleLoader> moduleLoader; switch (options.moduleLoaderMode) { case Default: moduleLoader = FileModuleLoader::new; break; case Node: moduleLoader = NodeModuleLoader::new; break; case NodeStandard: moduleLoader = NodeStandardModuleLoader::new; break; default: throw new AssertionError(); } /* @formatter:off */ RuntimeContext context = new RuntimeContext.Builder() .setBaseDirectory(Paths.get("").toAbsolutePath()) .setGlobalAllocator(allocator) .setModuleLoader(moduleLoader) .setConsole(console) .setWorkerErrorReporter(this::errorReporter) .setOptions(compatibilityOptions(options)) .setParserOptions(parserOptions(options)) .setCompilerOptions(compilerOptions(options)) .build(); /* @formatter:on */ World world = new World(context); Realm realm = world.newRealm(); ExecutionContext cx = realm.defaultContext(); // Add completion to console console.addCompleter(new ShellCompleter(realm)); // Execute global specific initialization enqueueScriptTask( realm, () -> { InitializeHostDefinedRealm(realm); // Add global "arguments" property ScriptObject arguments = CreateArrayFromList(cx, options.arguments); CreateMethodProperty(cx, realm.getGlobalObject(), "arguments", arguments); }); if (options.console) { enqueueScriptTask( realm, () -> { ScriptObject console = ConsoleObject.createConsole(realm); CreateMethodProperty(cx, realm.getGlobalObject(), "console", console); }); } if (options.moduleLoaderMode == ModuleLoaderMode.Node) { // TODO: Add default initialize(Realm) method to ModuleLoader interface? enqueueScriptTask( realm, () -> { NodeModuleLoader nodeLoader = (NodeModuleLoader) world.getModuleLoader(); nodeLoader.initialize(realm); }); } // Run eval expressions and files for (EvalScript evalScript : options.evalScripts) { if (options.module) { enqueueScriptTask( realm, () -> { ModuleSource moduleSource = evalScript.getModuleSource(); SourceIdentifier moduleName = evalScript.getModuleName(); try { ModuleEvaluationJob(realm, moduleName, moduleSource); } catch (ParserException e) { Source source = moduleSource.toSource(); String file = e.getFile(); if (file.equals(source.getFileString())) { throw new ParserExceptionWithSource(e, source, moduleSource.sourceCode()); } Path filePath = Paths.get(file).toAbsolutePath(); Source errorSource = new Source(filePath, file, 1); String code = new String(Files.readAllBytes(filePath), StandardCharsets.UTF_8); throw new ParserExceptionWithSource(e, errorSource, code); } }); } else { enqueueScriptTask( realm, () -> { Source source = evalScript.getSource(); String sourceCode = evalScript.getSourceCode(); try { eval(realm, parse(realm, source, sourceCode)); } catch (ParserException e) { throw new ParserExceptionWithSource(e, source, sourceCode); } }); } } return realm; }