diff options
Diffstat (limited to 'js/compiler.ts')
-rw-r--r-- | js/compiler.ts | 94 |
1 files changed, 25 insertions, 69 deletions
diff --git a/js/compiler.ts b/js/compiler.ts index 72deb360b..842ee77b3 100644 --- a/js/compiler.ts +++ b/js/compiler.ts @@ -5,9 +5,6 @@ import { assetSourceCode } from "./assets"; import * as os from "./os"; import { assert, log, notImplemented } from "./util"; -// tslint:disable-next-line:no-circular-imports -// import * as deno from "./deno"; - const EOL = "\n"; const ASSETS = "$asset$"; const LIB_RUNTIME = "lib.deno_runtime.d.ts"; @@ -38,7 +35,6 @@ type SourceMap = string; /** Abstraction of the APIs required from the `os` module so they can be * easily mocked. - * @internal */ export interface Os { codeCache: typeof os.codeCache; @@ -48,7 +44,6 @@ export interface Os { /** Abstraction of the APIs required from the `typescript` module so they can * be easily mocked. - * @internal */ export interface Ts { createLanguageService: typeof ts.createLanguageService; @@ -62,10 +57,6 @@ export interface Ts { * the module, not the actual module instance. */ export class ModuleMetaData implements ts.IScriptSnapshot { - public deps?: ModuleFileName[]; - public exports = {}; - public gatheringDeps = false; - public hasRun = false; public scriptVersion = ""; constructor( @@ -113,19 +104,19 @@ function getExtension( } /** Generate output code for a provided JSON string along with its source. */ -export function jsonAmdTemplate( +export function jsonEsmTemplate( jsonString: string, sourceFileName: string ): OutputCode { // tslint:disable-next-line:max-line-length - return `define([], function() { return JSON.parse(\`${jsonString}\`); });\n//# sourceURL=${sourceFileName}`; + return `const _json = JSON.parse(\`${jsonString}\`)\nexport default _json;\n//# sourceURL=${sourceFileName}`; } /** A singleton class that combines the TypeScript Language Service host API * with Deno specific APIs to provide an interface for compiling and running * TypeScript and JavaScript modules. */ -export class DenoCompiler +export class Compiler implements ts.LanguageServiceHost, ts.FormatDiagnosticsHost { // Modules are usually referenced by their ModuleSpecifier and ContainingFile, // and keeping a map of the resolved module file name allows more efficient @@ -164,6 +155,7 @@ export class DenoCompiler // A reference to `typescript` module so it can be monkey patched during // testing private _ts: Ts = ts; + // Flags forcing recompilation of TS code public recompile = false; @@ -175,7 +167,9 @@ export class DenoCompiler * TypeScript compiler, but the TypeScript compiler shouldn't be asking about * external modules that we haven't told it about yet. */ - getModuleMetaData(fileName: ModuleFileName): ModuleMetaData | undefined { + private _getModuleMetaData( + fileName: ModuleFileName + ): ModuleMetaData | undefined { return this._moduleMetaDataMap.has(fileName) ? this._moduleMetaDataMap.get(fileName) : fileName.startsWith(ASSETS) @@ -218,7 +212,7 @@ export class DenoCompiler } private constructor() { - if (DenoCompiler._instance) { + if (Compiler._instance) { throw new TypeError("Attempt to create an additional compiler."); } this._service = this._ts.createLanguageService(this); @@ -229,17 +223,22 @@ export class DenoCompiler /** Retrieve the output of the TypeScript compiler for a given module and * cache the result. Re-compilation can be forced using '--recompile' flag. */ - compile(moduleMetaData: ModuleMetaData): OutputCode { + compile( + moduleSpecifier: ModuleSpecifier, + containingFile: ContainingFile + ): ModuleMetaData { + const moduleMetaData = this.resolveModule(moduleSpecifier, containingFile); + this._scriptFileNames = [moduleMetaData.fileName]; const recompile = !!this.recompile; if (!recompile && moduleMetaData.outputCode) { - return moduleMetaData.outputCode; + return moduleMetaData; } const { fileName, sourceCode, mediaType, moduleId } = moduleMetaData; console.warn("Compiling", moduleId); // Instead of using TypeScript to transpile JSON modules, we will just do // it directly. if (mediaType === MediaType.Json) { - moduleMetaData.outputCode = jsonAmdTemplate(sourceCode, fileName); + moduleMetaData.outputCode = jsonEsmTemplate(sourceCode, fileName); } else { const service = this._service; assert( @@ -302,20 +301,7 @@ export class DenoCompiler moduleMetaData.outputCode, moduleMetaData.sourceMap ); - return moduleMetaData.outputCode; - } - - /** Given a fileName, return what was generated by the compiler. */ - getGeneratedSourceMap(fileName: string): string { - const moduleMetaData = this._moduleMetaDataMap.get(fileName); - return moduleMetaData ? moduleMetaData.sourceMap : ""; - } - - getOutput(filename: ModuleFileName): OutputCode { - const moduleMetaData = this.getModuleMetaData(filename)!; - assert(moduleMetaData != null, `Module not loaded: "${filename}"`); - this._scriptFileNames = [moduleMetaData.fileName]; - return this.compile(moduleMetaData); + return moduleMetaData; } /** Given a `moduleSpecifier` and `containingFile`, resolve the module and @@ -365,7 +351,6 @@ export class DenoCompiler } assert(moduleId != null, "No module ID."); assert(fileName != null, "No file name."); - assert(sourceCode ? sourceCode.length > 0 : false, "No source code."); assert( mediaType !== MediaType.Unknown, `Unknown media type for: "${moduleSpecifier}" from "${containingFile}".` @@ -394,33 +379,6 @@ export class DenoCompiler return moduleMetaData; } - /** Load and run a module and all of its dependencies based on a module - * specifier and a containing file - */ - run( - moduleSpecifier: ModuleSpecifier, - containingFile: ContainingFile - ): ModuleMetaData { - this._log("compiler.run", { moduleSpecifier, containingFile }); - const moduleMetaData = this.resolveModule(moduleSpecifier, containingFile); - this._scriptFileNames = [moduleMetaData.fileName]; - return moduleMetaData; - } - - getSource(filename: ModuleFileName): SourceCode { - const moduleMetaData = this.getModuleMetaData(filename)!; - assert(moduleMetaData != null, `Module not loaded: "${filename}"`); - return moduleMetaData.sourceCode; - } - - getJavaScriptSource(filename: ModuleFileName): OutputCode { - let s = this.getOutput(filename); - if (!s) { - s = this.getSource(filename); - } - return s; - } - // TypeScript Language Service and Format Diagnostic Host API getCanonicalFileName(fileName: string): string { @@ -446,7 +404,7 @@ export class DenoCompiler getScriptKind(fileName: ModuleFileName): ts.ScriptKind { this._log("getScriptKind()", fileName); - const moduleMetaData = this.getModuleMetaData(fileName); + const moduleMetaData = this._getModuleMetaData(fileName); if (moduleMetaData) { switch (moduleMetaData.mediaType) { case MediaType.TypeScript: @@ -465,13 +423,13 @@ export class DenoCompiler getScriptVersion(fileName: ModuleFileName): string { this._log("getScriptVersion()", fileName); - const moduleMetaData = this.getModuleMetaData(fileName); + const moduleMetaData = this._getModuleMetaData(fileName); return (moduleMetaData && moduleMetaData.scriptVersion) || ""; } getScriptSnapshot(fileName: ModuleFileName): ts.IScriptSnapshot | undefined { this._log("getScriptSnapshot()", fileName); - return this.getModuleMetaData(fileName); + return this._getModuleMetaData(fileName); } getCurrentDirectory(): string { @@ -497,7 +455,7 @@ export class DenoCompiler } fileExists(fileName: string): boolean { - const moduleMetaData = this.getModuleMetaData(fileName); + const moduleMetaData = this._getModuleMetaData(fileName); const exists = moduleMetaData != null; this._log("fileExists()", fileName, exists); return exists; @@ -537,12 +495,10 @@ export class DenoCompiler }); } - private static _instance: DenoCompiler | undefined; + private static _instance: Compiler | undefined; - /** Returns the instance of `DenoCompiler` or creates a new instance. */ - static instance(): DenoCompiler { - return ( - DenoCompiler._instance || (DenoCompiler._instance = new DenoCompiler()) - ); + /** Returns the instance of `Compiler` or creates a new instance. */ + static instance(): Compiler { + return Compiler._instance || (Compiler._instance = new Compiler()); } } |