summaryrefslogtreecommitdiff
path: root/runtime.ts
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2018-06-22 14:23:42 +0200
committerGitHub <noreply@github.com>2018-06-22 14:23:42 +0200
commit86354a29a40fb97e334f951428239ab8e171e2dd (patch)
tree2f0d8cc2680aa4ccbaf865b427976b3f810b6920 /runtime.ts
parentef9dc2464e10510bdcc4be9eae431e3dcf7f7999 (diff)
Delete go implementation (#276)
The go prototype will remain at https://github.com/ry/deno/tree/golang
Diffstat (limited to 'runtime.ts')
-rw-r--r--runtime.ts339
1 files changed, 0 insertions, 339 deletions
diff --git a/runtime.ts b/runtime.ts
deleted file mode 100644
index 46538c80f..000000000
--- a/runtime.ts
+++ /dev/null
@@ -1,339 +0,0 @@
-// Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
-// All rights reserved. MIT License.
-// Glossary
-// outputCode = generated javascript code
-// sourceCode = typescript code (or input javascript code)
-// moduleName = a resolved module name
-// fileName = an unresolved raw fileName.
-// for http modules , its the path to the locally downloaded
-// version.
-
-import * as ts from "typescript";
-import * as util from "./util";
-import { log } from "./util";
-import * as os from "./os";
-import * as sourceMaps from "./v8_source_maps";
-import { _global, globalEval } from "./globals";
-import * as deno from "./deno";
-
-const EOL = "\n";
-
-// tslint:disable-next-line:no-any
-export type AmdFactory = (...args: any[]) => undefined | object;
-export type AmdDefine = (deps: string[], factory: AmdFactory) => void;
-
-// Uncaught exceptions are sent to window.onerror by v8worker2.
-// https://git.io/vhOsf
-window.onerror = (message, source, lineno, colno, error) => {
- // TODO Currently there is a bug in v8_source_maps.ts that causes a segfault
- // if it is used within window.onerror. To workaround we uninstall the
- // Error.prepareStackTrace handler. Users will get unmapped stack traces on
- // uncaught exceptions until this issue is fixed.
- Error.prepareStackTrace = null;
- console.log(error.message, error.stack);
- os.exit(1);
-};
-
-export function setup(mainJs: string, mainMap: string): void {
- sourceMaps.install({
- installPrepareStackTrace: true,
- getGeneratedContents: (filename: string): string => {
- if (filename === "/main.js") {
- return mainJs;
- } else if (filename === "/main.map") {
- return mainMap;
- } else {
- const mod = FileModule.load(filename);
- if (!mod) {
- console.error("getGeneratedContents cannot find", filename);
- }
- return mod.outputCode;
- }
- }
- });
-}
-
-// This class represents a module. We call it FileModule to make it explicit
-// that each module represents a single file.
-// Access to FileModule instances should only be done thru the static method
-// FileModule.load(). FileModules are NOT executed upon first load, only when
-// compileAndRun is called.
-export class FileModule {
- scriptVersion: string;
- readonly exports = {};
-
- private static readonly map = new Map<string, FileModule>();
- constructor(
- readonly fileName: string,
- readonly sourceCode = "",
- public outputCode = ""
- ) {
- util.assert(
- !FileModule.map.has(fileName),
- `FileModule.map already has ${fileName}`
- );
- FileModule.map.set(fileName, this);
- if (outputCode !== "") {
- this.scriptVersion = "1";
- }
- }
-
- compileAndRun(): void {
- if (!this.outputCode) {
- // If there is no cached outputCode, then compile the code.
- util.assert(
- this.sourceCode != null && this.sourceCode.length > 0,
- `Have no source code from ${this.fileName}`
- );
- const compiler = Compiler.instance();
- this.outputCode = compiler.compile(this.fileName);
- os.codeCache(this.fileName, this.sourceCode, this.outputCode);
- }
- util.log("compileAndRun", this.sourceCode);
- execute(this.fileName, this.outputCode);
- }
-
- static load(fileName: string): FileModule {
- return this.map.get(fileName);
- }
-
- static getScriptsWithSourceCode(): string[] {
- const out = [];
- for (const fn of this.map.keys()) {
- const m = this.map.get(fn);
- if (m.sourceCode) {
- out.push(fn);
- }
- }
- return out;
- }
-}
-
-export function makeDefine(fileName: string): AmdDefine {
- const localDefine = (deps: string[], factory: AmdFactory): void => {
- const localRequire = (x: string) => {
- log("localRequire", x);
- };
- const currentModule = FileModule.load(fileName);
- const localExports = currentModule.exports;
- log("localDefine", fileName, deps, localExports);
- const args = deps.map(dep => {
- if (dep === "require") {
- return localRequire;
- } else if (dep === "exports") {
- return localExports;
- } else if (dep === "typescript") {
- return ts;
- } else if (dep === "deno") {
- return deno;
- } else {
- const resolved = resolveModuleName(dep, fileName);
- const depModule = FileModule.load(resolved);
- depModule.compileAndRun();
- return depModule.exports;
- }
- });
- factory(...args);
- };
- return localDefine;
-}
-
-export function resolveModule(
- moduleSpecifier: string,
- containingFile: string
-): null | FileModule {
- //util.log("resolveModule", { moduleSpecifier, containingFile });
- util.assert(moduleSpecifier != null && moduleSpecifier.length > 0);
- // We ask golang to sourceCodeFetch. It will load the sourceCode and if
- // there is any outputCode cached, it will return that as well.
- let fetchResponse;
- try {
- fetchResponse = os.codeFetch(moduleSpecifier, containingFile);
- } catch (e) {
- // TODO Only catch "no such file or directory" errors. Need error codes.
- return null;
- }
- const { filename, sourceCode, outputCode } = fetchResponse;
- if (sourceCode.length === 0) {
- return null;
- }
- util.log("resolveModule sourceCode length ", sourceCode.length);
- const m = FileModule.load(filename);
- if (m != null) {
- return m;
- } else {
- return new FileModule(filename, sourceCode, outputCode);
- }
-}
-
-function resolveModuleName(
- moduleSpecifier: string,
- containingFile: string
-): string | undefined {
- const mod = resolveModule(moduleSpecifier, containingFile);
- if (mod) {
- return mod.fileName;
- } else {
- return undefined;
- }
-}
-
-function execute(fileName: string, outputCode: string): void {
- util.assert(outputCode && outputCode.length > 0);
- _global["define"] = makeDefine(fileName);
- outputCode += `\n//# sourceURL=${fileName}`;
- globalEval(outputCode);
- _global["define"] = null;
-}
-
-// This is a singleton class. Use Compiler.instance() to access.
-class Compiler {
- options: ts.CompilerOptions = {
- allowJs: true,
- module: ts.ModuleKind.AMD,
- outDir: "$deno$",
- inlineSourceMap: true,
- lib: ["es2017"],
- inlineSources: true,
- target: ts.ScriptTarget.ES2017
- };
- /*
- allowJs: true,
- module: ts.ModuleKind.AMD,
- noEmit: false,
- outDir: '$deno$',
- */
- private service: ts.LanguageService;
-
- private constructor() {
- const host = new TypeScriptHost(this.options);
- this.service = ts.createLanguageService(host);
- }
-
- private static _instance: Compiler;
- static instance(): Compiler {
- return this._instance || (this._instance = new this());
- }
-
- compile(fileName: string): string {
- const output = this.service.getEmitOutput(fileName);
-
- // Get the relevant diagnostics - this is 3x faster than
- // `getPreEmitDiagnostics`.
- const diagnostics = this.service
- .getCompilerOptionsDiagnostics()
- .concat(this.service.getSyntacticDiagnostics(fileName))
- .concat(this.service.getSemanticDiagnostics(fileName));
- if (diagnostics.length > 0) {
- const errMsg = ts.formatDiagnosticsWithColorAndContext(
- diagnostics,
- formatDiagnosticsHost
- );
- console.log(errMsg);
- os.exit(1);
- }
-
- util.assert(!output.emitSkipped);
-
- const outputCode = output.outputFiles[0].text;
- // let sourceMapCode = output.outputFiles[0].text;
- return outputCode;
- }
-}
-
-// Create the compiler host for type checking.
-class TypeScriptHost implements ts.LanguageServiceHost {
- constructor(readonly options: ts.CompilerOptions) {}
-
- getScriptFileNames(): string[] {
- const keys = FileModule.getScriptsWithSourceCode();
- util.log("getScriptFileNames", keys);
- return keys;
- }
-
- getScriptVersion(fileName: string): string {
- util.log("getScriptVersion", fileName);
- const m = FileModule.load(fileName);
- return m.scriptVersion;
- }
-
- getScriptSnapshot(fileName: string): ts.IScriptSnapshot | undefined {
- util.log("getScriptSnapshot", fileName);
- const m = resolveModule(fileName, ".");
- if (m == null) {
- util.log("getScriptSnapshot", fileName, "NOT FOUND");
- return undefined;
- }
- //const m = resolveModule(fileName, ".");
- util.assert(m.sourceCode.length > 0);
- return ts.ScriptSnapshot.fromString(m.sourceCode);
- }
-
- fileExists(fileName: string): boolean {
- const m = resolveModule(fileName, ".");
- const exists = m != null;
- util.log("fileExist", fileName, exists);
- return exists;
- }
-
- readFile(path: string, encoding?: string): string | undefined {
- util.log("readFile", path);
- throw Error("not implemented");
- }
-
- getNewLine() {
- return EOL;
- }
-
- getCurrentDirectory() {
- util.log("getCurrentDirectory");
- return ".";
- }
-
- getCompilationSettings() {
- util.log("getCompilationSettings");
- return this.options;
- }
-
- getDefaultLibFileName(options: ts.CompilerOptions): string {
- const fn = ts.getDefaultLibFileName(options);
- util.log("getDefaultLibFileName", fn);
- const m = resolveModule(fn, "/$asset$/");
- return m.fileName;
- }
-
- resolveModuleNames(
- moduleNames: string[],
- containingFile: string,
- reusedNames?: string[]
- ): Array<ts.ResolvedModule | undefined> {
- //util.log("resolveModuleNames", { moduleNames, reusedNames });
- return moduleNames.map((name: string) => {
- let resolvedFileName;
- if (name === "deno") {
- resolvedFileName = resolveModuleName("deno.d.ts", "/$asset$/");
- } else if (name === "typescript") {
- resolvedFileName = resolveModuleName("typescript.d.ts", "/$asset$/");
- } else {
- resolvedFileName = resolveModuleName(name, containingFile);
- if (resolvedFileName == null) {
- return undefined;
- }
- }
- const isExternalLibraryImport = false;
- return { resolvedFileName, isExternalLibraryImport };
- });
- }
-}
-
-const formatDiagnosticsHost: ts.FormatDiagnosticsHost = {
- getCurrentDirectory(): string {
- return ".";
- },
- getCanonicalFileName(fileName: string): string {
- return fileName;
- },
- getNewLine(): string {
- return EOL;
- }
-};