From 786b53873603395a6fb0c39b5bc6ce0badcd721c Mon Sep 17 00:00:00 2001 From: Ivo Gabe de Wolff Date: Fri, 30 Nov 2018 16:41:29 +0100 Subject: [PATCH] Update release --- release/compiler.d.ts | 11 ++++---- release/compiler.js | 64 ++++++++++++++++++++++++++++--------------- release/host.d.ts | 2 +- release/host.js | 1 + release/input.d.ts | 3 +- release/main.d.ts | 3 +- release/main.js | 24 ++++++++++++++-- release/output.d.ts | 1 - release/project.d.ts | 5 ++-- release/project.js | 4 +-- release/reporter.d.ts | 3 +- release/reporter.js | 3 +- release/types.d.ts | 16 ++++++++++- release/utils.d.ts | 1 - 14 files changed, 96 insertions(+), 45 deletions(-) diff --git a/release/compiler.d.ts b/release/compiler.d.ts index 63f6bff7..266f7216 100644 --- a/release/compiler.d.ts +++ b/release/compiler.d.ts @@ -2,8 +2,9 @@ import * as ts from 'typescript'; import { File } from './input'; import { Host } from './host'; import { ProjectInfo } from './project'; +import { FinalTransformers } from './types'; export interface ICompiler { - prepare(project: ProjectInfo): void; + prepare(project: ProjectInfo, finalTransformers?: FinalTransformers): void; inputFile(file: File): void; inputDone(): void; } @@ -11,28 +12,28 @@ export interface ICompiler { * Compiles a whole project, with full type checking */ export declare class ProjectCompiler implements ICompiler { + finalTransformers: FinalTransformers; host: Host; project: ProjectInfo; program: ts.Program; private hasSourceMap; - prepare(project: ProjectInfo): void; + prepare(project: ProjectInfo, finalTransformers?: FinalTransformers): void; inputFile(file: File): void; inputDone(): void; private attachContentToFile; private emit; private emitFile; - private reportDiagnostics; private removeSourceMapComment; } export declare class FileCompiler implements ICompiler { + finalTransformers: FinalTransformers; host: Host; project: ProjectInfo; private output; private previousOutput; private compilationResult; - prepare(project: ProjectInfo): void; + prepare(project: ProjectInfo, finalTransformers: FinalTransformers): void; private write; inputFile(file: File): void; inputDone(): void; } -//# sourceMappingURL=compiler.d.ts.map \ No newline at end of file diff --git a/release/compiler.js b/release/compiler.js index 5e3c3762..5b3f1c4c 100644 --- a/release/compiler.js +++ b/release/compiler.js @@ -1,5 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +const ts = require("typescript"); const path = require("path"); const input_1 = require("./input"); const host_1 = require("./host"); @@ -9,7 +10,8 @@ const utils = require("./utils"); * Compiles a whole project, with full type checking */ class ProjectCompiler { - prepare(project) { + prepare(project, finalTransformers) { + this.finalTransformers = finalTransformers; this.project = project; this.hasSourceMap = false; } @@ -44,18 +46,25 @@ class ProjectCompiler { }) : this.project.typescript.createProgram(rootFilenames, this.project.options, this.host, this.program); const result = reporter_1.emptyCompilationResult(this.project.options.noEmit); - result.optionsErrors = this.reportDiagnostics(this.program.getOptionsDiagnostics()); - result.syntaxErrors = this.reportDiagnostics(this.program.getSyntacticDiagnostics()); - result.globalErrors = this.reportDiagnostics(this.program.getGlobalDiagnostics()); - result.semanticErrors = this.reportDiagnostics(this.program.getSemanticDiagnostics()); + const optionErrors = this.program.getOptionsDiagnostics(); + const syntaxErrors = this.program.getSyntacticDiagnostics(); + const globalErrors = this.program.getGlobalDiagnostics(); + const semanticErrors = this.program.getSemanticDiagnostics(); + result.optionsErrors = optionErrors.length; + result.syntaxErrors = syntaxErrors.length; + result.globalErrors = globalErrors.length; + result.semanticErrors = semanticErrors.length; + let declarationErrors = []; if (this.project.options.declaration) { - result.declarationErrors = this.program.getDeclarationDiagnostics().length; + declarationErrors = this.program.getDeclarationDiagnostics(); + result.declarationErrors = declarationErrors.length; } + const preEmitDiagnostics = [...optionErrors, ...syntaxErrors, ...globalErrors, ...semanticErrors, ...declarationErrors]; if (this.project.singleOutput) { const output = { file: undefined }; - this.emit(result, (fileName, content) => { + this.emit(result, preEmitDiagnostics, (fileName, content) => { this.attachContentToFile(output, fileName, content); }); this.emitFile(output, currentDirectory); @@ -68,7 +77,7 @@ class ProjectCompiler { const file = this.project.input.getFile(fileName); output[fileName] = { file }; } - this.emit(result, (fileName, content, writeByteOrderMark, onError, sourceFiles) => { + this.emit(result, preEmitDiagnostics, (fileName, content, writeByteOrderMark, onError, sourceFiles) => { if (sourceFiles.length !== 1) { throw new Error("Failure: sourceFiles in WriteFileCallback should have length 1, got " + sourceFiles.length); } @@ -106,11 +115,19 @@ class ProjectCompiler { break; } } - emit(result, callback) { - const emitOutput = this.program.emit(undefined, callback); - result.emitErrors += emitOutput.diagnostics.length; - this.reportDiagnostics(emitOutput.diagnostics); + emit(result, preEmitDiagnostics, callback) { + const emitOutput = this.program.emit(undefined, callback, undefined, false, this.finalTransformers ? this.finalTransformers(this.program) : undefined); result.emitSkipped = emitOutput.emitSkipped; + // `emitOutput.diagnostics` might contain diagnostics that were already part of `preEmitDiagnostics`. + // See https://github.com/Microsoft/TypeScript/issues/20876 + // We use sortAndDeduplicateDiagnostics to remove duplicate diagnostics. + // We then count the number of diagnostics in `diagnostics` that we not in `preEmitDiagnostics` + // to count the number of emit diagnostics. + const diagnostics = ts.sortAndDeduplicateDiagnostics([...preEmitDiagnostics, ...emitOutput.diagnostics]); + result.emitErrors += diagnostics.length - preEmitDiagnostics.length; + for (const error of diagnostics) { + this.project.output.diagnostic(error); + } } emitFile({ file, jsFileName, dtsFileName, dtsMapFileName, jsContent, dtsContent, dtsMapContent, jsMapContent }, currentDirectory) { if (!jsFileName) @@ -148,15 +165,12 @@ class ProjectCompiler { this.project.output.writeJs(base, jsFileName, jsContent, jsMapContent, file ? file.gulp.cwd : currentDirectory, file); } if (dtsContent !== undefined) { + if (dtsMapContent !== undefined) { + dtsContent = this.removeSourceMapComment(dtsContent); + } this.project.output.writeDts(baseDeclarations, dtsFileName, dtsContent, dtsMapContent, file ? file.gulp.cwd : currentDirectory, file); } } - reportDiagnostics(diagnostics) { - for (const error of diagnostics) { - this.project.output.diagnostic(error); - } - return diagnostics.length; - } removeSourceMapComment(content) { // By default the TypeScript automaticly inserts a source map comment. // This should be removed because gulp-sourcemaps takes care of that. @@ -173,7 +187,8 @@ class FileCompiler { this.previousOutput = {}; this.compilationResult = undefined; } - prepare(project) { + prepare(project, finalTransformers) { + this.finalTransformers = finalTransformers; this.project = project; this.project.input.noParse = true; this.compilationResult = reporter_1.emptyCompilationResult(this.project.options.noEmit); @@ -196,8 +211,13 @@ class FileCompiler { this.write(file, old.fileName, old.diagnostics, old.content, old.sourceMap); return; } - const diagnostics = []; - const outputString = this.project.typescript.transpile(file.content, this.project.options, file.fileNameOriginal, diagnostics); + const output = this.project.typescript.transpileModule(file.content, { + compilerOptions: this.project.options, + fileName: file.fileNameOriginal, + reportDiagnostics: true, + transformers: this.finalTransformers ? this.finalTransformers() : undefined, + }); + const outputString = output.outputText; let index = outputString.lastIndexOf('\n'); let mapString = outputString.substring(index + 1); if (mapString.substring(0, 1) === '\r') @@ -214,7 +234,7 @@ class FileCompiler { // map.sources[0] = path.relative(map.sourceRoot, file.gulp.path); const [fileNameExtensionless] = utils.splitExtension(file.fileNameOriginal); const [, extension] = utils.splitExtension(map.file); // js or jsx - this.write(file, fileNameExtensionless + '.' + extension, diagnostics, outputString.substring(0, index), JSON.stringify(map)); + this.write(file, fileNameExtensionless + '.' + extension, output.diagnostics, outputString.substring(0, index), JSON.stringify(map)); } inputDone() { this.project.output.finish(this.compilationResult); diff --git a/release/host.d.ts b/release/host.d.ts index e497ff04..85ccf367 100644 --- a/release/host.d.ts +++ b/release/host.d.ts @@ -19,5 +19,5 @@ export declare class Host implements ts.CompilerHost { realpath: (path: string) => string; getDirectories: (path: string) => string[]; directoryExists: (path: string) => boolean; + readDirectory: (rootDir: string, extensions: string[], excludes: string[], includes: string[], depth?: number) => string[]; } -//# sourceMappingURL=host.d.ts.map \ No newline at end of file diff --git a/release/host.js b/release/host.js index 51ca3e0d..e2d05870 100644 --- a/release/host.js +++ b/release/host.js @@ -29,6 +29,7 @@ class Host { this.realpath = (path) => this.fallback.realpath(path); this.getDirectories = (path) => this.fallback.getDirectories(path); this.directoryExists = (path) => this.fallback.directoryExists(path); + this.readDirectory = (rootDir, extensions, excludes, includes, depth) => this.fallback.readDirectory(rootDir, extensions, excludes, includes, depth); this.typescript = typescript; this.fallback = typescript.createCompilerHost(options); this.currentDirectory = currentDirectory; diff --git a/release/input.d.ts b/release/input.d.ts index 84c97428..805f34c2 100644 --- a/release/input.d.ts +++ b/release/input.d.ts @@ -1,6 +1,6 @@ import * as ts from 'typescript'; import * as utils from './utils'; -import * as VinylFile from 'vinyl'; +import { VinylFile } from './types'; export declare enum FileChangeState { New = 0, Equal = 1, @@ -67,4 +67,3 @@ export declare class FileCache { commonSourceDirectory: string; isChanged(onlyGulp?: boolean): boolean; } -//# sourceMappingURL=input.d.ts.map \ No newline at end of file diff --git a/release/main.d.ts b/release/main.d.ts index 6626469c..bf567735 100644 --- a/release/main.d.ts +++ b/release/main.d.ts @@ -1,6 +1,7 @@ import * as ts from 'typescript'; import * as _project from './project'; import * as _reporter from './reporter'; +import { GetCustomTransformers } from './types'; declare function compile(proj: _project.Project, theReporter?: _reporter.Reporter): compile.CompileStream; declare function compile(settings: compile.Settings, theReporter?: _reporter.Reporter): compile.CompileStream; declare function compile(): compile.CompileStream; @@ -30,6 +31,7 @@ declare module compile { declarationFiles?: boolean; noExternalResolve?: boolean; sortOutput?: boolean; + getCustomTransformers?: GetCustomTransformers; typescript?: typeof ts; isolatedModules?: boolean; rootDir?: string; @@ -47,4 +49,3 @@ declare module compile { function filter(...args: any[]): void; } export = compile; -//# sourceMappingURL=main.d.ts.map \ No newline at end of file diff --git a/release/main.js b/release/main.js index c080bb19..f25f76e2 100644 --- a/release/main.js +++ b/release/main.js @@ -31,6 +31,24 @@ function compile(param, theReporter) { } return proj(theReporter); } +function getFinalTransformers(getCustomTransformers) { + if (typeof getCustomTransformers === 'function') { + return getCustomTransformers; + } + if (typeof getCustomTransformers === 'string') { + try { + getCustomTransformers = require(getCustomTransformers); + } + catch (err) { + throw new Error(`Failed to load customTransformers from "${getCustomTransformers}": ${err.message}`); + } + if (typeof getCustomTransformers !== 'function') { + throw new Error(`Custom transformers in "${getCustomTransformers}" should export a function, got ${typeof getCustomTransformers}`); + } + return getCustomTransformers; + } + return null; +} function getTypeScript(typescript) { if (typescript) return typescript; @@ -43,7 +61,7 @@ function getTypeScript(typescript) { } } function checkAndNormalizeSettings(settings) { - const { declarationFiles, noExternalResolve, sortOutput, typescript } = settings, standardSettings = __rest(settings, ["declarationFiles", "noExternalResolve", "sortOutput", "typescript"]); + const { getCustomTransformers, declarationFiles, noExternalResolve, sortOutput, typescript } = settings, standardSettings = __rest(settings, ["getCustomTransformers", "declarationFiles", "noExternalResolve", "sortOutput", "typescript"]); if (settings.sourceRoot !== undefined) { console.warn('gulp-typescript: sourceRoot isn\'t supported any more. Use sourceRoot option of gulp-sourcemaps instead.'); } @@ -81,6 +99,7 @@ function reportErrors(errors, typescript, ignore = []) { (function (compile) { compile.reporter = _reporter; function createProject(fileNameOrSettings, settings) { + let finalTransformers; let tsConfigFileName = undefined; let tsConfigContent = undefined; let projectDirectory = process.cwd(); @@ -100,6 +119,7 @@ function reportErrors(errors, typescript, ignore = []) { else { settings = fileNameOrSettings || {}; } + finalTransformers = getFinalTransformers(settings.getCustomTransformers); typescript = getTypeScript(settings.typescript); settings = checkAndNormalizeSettings(settings); const settingsResult = typescript.convertCompilerOptionsFromJson(settings, projectDirectory); @@ -123,7 +143,7 @@ function reportErrors(errors, typescript, ignore = []) { } } normalizeCompilerOptions(compilerOptions, typescript); - const project = _project.setupProject(projectDirectory, tsConfigFileName, rawConfig, tsConfigContent, compilerOptions, projectReferences, typescript); + const project = _project.setupProject(projectDirectory, tsConfigFileName, rawConfig, tsConfigContent, compilerOptions, projectReferences, typescript, finalTransformers); return project; } compile.createProject = createProject; diff --git a/release/output.d.ts b/release/output.d.ts index 2d471bf8..55c93ede 100644 --- a/release/output.d.ts +++ b/release/output.d.ts @@ -24,4 +24,3 @@ export declare class Output { diagnostic(info: ts.Diagnostic): void; error(error: reporter.TypeScriptError): void; } -//# sourceMappingURL=output.d.ts.map \ No newline at end of file diff --git a/release/project.d.ts b/release/project.d.ts index f16bdc60..e5787d64 100644 --- a/release/project.d.ts +++ b/release/project.d.ts @@ -5,7 +5,7 @@ import { Reporter } from './reporter'; import { FileCache } from './input'; import { Output } from './output'; import { ICompiler } from './compiler'; -import { TsConfig } from './types'; +import { FinalTransformers, TsConfig } from './types'; export interface Project { (reporter?: Reporter): ICompileStream; src(this: Project): NodeJS.ReadWriteStream; @@ -28,9 +28,8 @@ export interface ProjectInfo { directory: string; reporter: Reporter; } -export declare function setupProject(projectDirectory: string, configFileName: string, rawConfig: any, config: TsConfig, options: ts.CompilerOptions, projectReferences: ReadonlyArray, typescript: typeof ts): Project; +export declare function setupProject(projectDirectory: string, configFileName: string, rawConfig: any, config: TsConfig, options: ts.CompilerOptions, projectReferences: ReadonlyArray, typescript: typeof ts, finalTransformers: FinalTransformers): Project; export interface ICompileStream extends NodeJS.ReadWriteStream { js: stream.Readable; dts: stream.Readable; } -//# sourceMappingURL=project.d.ts.map \ No newline at end of file diff --git a/release/project.js b/release/project.js index 642b90fb..96711505 100644 --- a/release/project.js +++ b/release/project.js @@ -18,7 +18,7 @@ const reporter_1 = require("./reporter"); const input_1 = require("./input"); const output_1 = require("./output"); const compiler_1 = require("./compiler"); -function setupProject(projectDirectory, configFileName, rawConfig, config, options, projectReferences, typescript) { +function setupProject(projectDirectory, configFileName, rawConfig, config, options, projectReferences, typescript, finalTransformers) { const input = new input_1.FileCache(typescript, options); const compiler = options.isolatedModules ? new compiler_1.FileCompiler() : new compiler_1.ProjectCompiler(); let running = false; @@ -34,7 +34,7 @@ function setupProject(projectDirectory, configFileName, rawConfig, config, optio } running = true; input.reset(); - compiler.prepare(projectInfo); + compiler.prepare(projectInfo, finalTransformers); const stream = new CompileStream(projectInfo); projectInfo.output = new output_1.Output(projectInfo, stream, stream.js, stream.dts); projectInfo.reporter = reporter || reporter_1.defaultReporter(); diff --git a/release/reporter.d.ts b/release/reporter.d.ts index 5de7a1ec..828c23db 100644 --- a/release/reporter.d.ts +++ b/release/reporter.d.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import * as VinylFile from 'vinyl'; +import { VinylFile } from './types'; export interface TypeScriptError extends Error { fullFilename?: string; relativeFilename?: string; @@ -41,4 +41,3 @@ export declare function nullReporter(): Reporter; export declare function defaultReporter(): Reporter; export declare function longReporter(): Reporter; export declare function fullReporter(fullFilename?: boolean): Reporter; -//# sourceMappingURL=reporter.d.ts.map \ No newline at end of file diff --git a/release/reporter.js b/release/reporter.js index f8af2e11..1e6db620 100644 --- a/release/reporter.js +++ b/release/reporter.js @@ -63,9 +63,8 @@ function defaultReporter() { } exports.defaultReporter = defaultReporter; function longReporter() { - const typescript = require('typescript'); return { - error: (error) => { + error: (error, typescript) => { if (error.tsFile) { console.log('[' + colors.gray('gulp-typescript') + '] ' + colors.red(error.fullFilename + '(' + error.startPosition.line + ',' + error.startPosition.character + '): ') diff --git a/release/types.d.ts b/release/types.d.ts index 11e88471..d845ebb6 100644 --- a/release/types.d.ts +++ b/release/types.d.ts @@ -1,7 +1,21 @@ +/// +import * as ts from 'typescript'; +export declare type FinalTransformers = undefined | ((program?: ts.Program) => ts.CustomTransformers); +export declare type GetCustomTransformers = string | ((program?: ts.Program) => ts.CustomTransformers | undefined); export interface TsConfig { files?: string[]; include?: string[]; exclude?: string[]; compilerOptions?: any; } -//# sourceMappingURL=types.d.ts.map \ No newline at end of file +export interface VinylFile { + contents: Buffer | NodeJS.ReadableStream | null; + cwd: string; + base: string; + path: string; + dirname: string; + basename: string; + stem: string; + extname: string; + sourceMap?: any; +} diff --git a/release/utils.d.ts b/release/utils.d.ts index 382785bd..263b102d 100644 --- a/release/utils.d.ts +++ b/release/utils.d.ts @@ -21,4 +21,3 @@ export declare function getCommonBasePathOfArray(paths: string[]): string; export declare function getError(info: ts.Diagnostic, typescript: typeof ts, file?: File): reporter.TypeScriptError; export declare function deprecate(title: string, alternative: string, description?: string): void; export declare function message(title: string, alternative: string, description?: string): void; -//# sourceMappingURL=utils.d.ts.map \ No newline at end of file