From 900dc8c6ac8b20c9eb9a3294a4adeebe6e43b7b1 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 19 Dec 2018 13:44:47 -0800 Subject: [PATCH] Revert BuilderProgram to be redirected object to Program in preparation to set Program in state to undefined for storing. --- src/compiler/builder.ts | 72 +++++++++++++++---- src/compiler/tsbuild.ts | 2 +- src/compiler/watch.ts | 17 ++++- src/tsc/tsc.ts | 2 +- .../reference/api/tsserverlibrary.d.ts | 38 +++++++++- tests/baselines/reference/api/typescript.d.ts | 38 +++++++++- 6 files changed, 150 insertions(+), 19 deletions(-) diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 9c0cc92fb36..c2acd8e1b04 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -427,11 +427,9 @@ namespace ts { oldProgram = undefined; oldState = undefined; - const result = createRedirectObject(state.program) as BuilderProgram; + const result = createRedirectedBuilderProgram(state, configFileParsingDiagnostics); result.getState = () => state; - result.getProgram = () => state.program; result.getAllDependencies = sourceFile => BuilderState.getAllDependencies(state, state.program, sourceFile); - result.getConfigFileParsingDiagnostics = () => configFileParsingDiagnostics; result.getSemanticDiagnostics = getSemanticDiagnostics; result.emit = emit; @@ -579,6 +577,25 @@ namespace ts { return diagnostics || emptyArray; } } + + export function createRedirectedBuilderProgram(state: { program: Program; }, configFileParsingDiagnostics: ReadonlyArray): BuilderProgram { + return { + getState: notImplemented, + getProgram: () => state.program, + getCompilerOptions: () => state.program.getCompilerOptions(), + getSourceFile: fileName => state.program.getSourceFile(fileName), + getSourceFiles: () => state.program.getSourceFiles(), + getOptionsDiagnostics: cancellationToken => state.program.getOptionsDiagnostics(cancellationToken), + getGlobalDiagnostics: cancellationToken => state.program.getGlobalDiagnostics(cancellationToken), + getConfigFileParsingDiagnostics: () => configFileParsingDiagnostics, + getSyntacticDiagnostics: (sourceFile, cancellationToken) => state.program.getSyntacticDiagnostics(sourceFile, cancellationToken), + getDeclarationDiagnostics: (sourceFile, cancellationToken) => state.program.getDeclarationDiagnostics(sourceFile, cancellationToken), + getSemanticDiagnostics: (sourceFile, cancellationToken) => state.program.getSemanticDiagnostics(sourceFile, cancellationToken), + emit: (sourceFile, writeFile, cancellationToken, emitOnlyDts, customTransformers) => state.program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDts, customTransformers), + getAllDependencies: notImplemented, + getCurrentDirectory: () => state.program.getCurrentDirectory() + }; + } } namespace ts { @@ -603,20 +620,50 @@ namespace ts { /** * Builder to manage the program state changes */ - export interface BuilderProgram extends Program { + export interface BuilderProgram { /*@internal*/ getState(): BuilderProgramState; /** * Returns current program */ getProgram(): Program; + /** + * Get compiler options of the program + */ + getCompilerOptions(): CompilerOptions; + /** + * Get the source file in the program with file name + */ + getSourceFile(fileName: string): SourceFile | undefined; + /** + * Get a list of files in the program + */ + getSourceFiles(): ReadonlyArray; + /** + * Get the diagnostics for compiler options + */ + getOptionsDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray; + /** + * Get the diagnostics that dont belong to any file + */ + getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray; + /** + * Get the diagnostics from config file parsing + */ + getConfigFileParsingDiagnostics(): ReadonlyArray; + /** + * Get the syntax diagnostics, for all source files if source file is not supplied + */ + getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; + /** + * Get the declaration diagnostics, for all source files if source file is not supplied + */ + getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; /** * Get all the dependencies of the file */ getAllDependencies(sourceFile: SourceFile): ReadonlyArray; - // These two are same signatures but because the doc comments are useful they are retained - /** * Gets the semantic diagnostics from the program corresponding to this state of file (if provided) or whole program * The semantic diagnostics are cached and managed here @@ -638,6 +685,10 @@ namespace ts { * in that order would be used to write the files */ emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult; + /** + * Get the current directory of the program + */ + getCurrentDirectory(): string; } /** @@ -690,13 +741,6 @@ namespace ts { export function createAbstractBuilder(rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray, projectReferences?: ReadonlyArray): BuilderProgram; export function createAbstractBuilder(newProgramOrRootNames: Program | ReadonlyArray | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: CompilerHost | BuilderProgram, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray | BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray, projectReferences?: ReadonlyArray): BuilderProgram { const { newProgram, configFileParsingDiagnostics: newConfigFileParsingDiagnostics } = getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences); - const builderProgram = createRedirectObject(newProgram) as BuilderProgram; - builderProgram.getState = notImplemented; - builderProgram.getProgram = () => newProgram; - builderProgram.getAllDependencies = notImplemented; - - // Always return latest config file diagnostics - builderProgram.getConfigFileParsingDiagnostics = () => newConfigFileParsingDiagnostics; - return builderProgram; + return createRedirectedBuilderProgram({ program: newProgram }, newConfigFileParsingDiagnostics); } } diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index bc0a2f87680..ca3108616a6 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -331,7 +331,7 @@ namespace ts { // TODO: To do better with watch mode and normal build mode api that creates program and emits files // This currently helps enable --diagnostics and --extendedDiagnostics - afterProgramEmitAndDiagnostics?(program: Program): void; + afterProgramEmitAndDiagnostics?(program: T): void; } export interface SolutionBuilderHost extends SolutionBuilderHostBase { diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index a29d54ac981..cc6d1236fed 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -106,10 +106,25 @@ namespace ts { return `${newLine}${flattenDiagnosticMessageText(d.messageText, newLine)}${newLine}${newLine}`; } + /** + * Program structure needed to emit the files and report diagnostics + */ + export interface ProgramToEmitFilesAndReportErrors { + getCurrentDirectory(): string; + getCompilerOptions(): CompilerOptions; + getSourceFiles(): ReadonlyArray; + getSyntacticDiagnostics(): ReadonlyArray; + getOptionsDiagnostics(): ReadonlyArray; + getGlobalDiagnostics(): ReadonlyArray; + getSemanticDiagnostics(): ReadonlyArray; + getConfigFileParsingDiagnostics(): ReadonlyArray; + emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback): EmitResult; + } + /** * Helper that emit files, report diagnostics and lists emitted and/or source files depending on compiler options */ - export function emitFilesAndReportErrors(program: Program, reportDiagnostic: DiagnosticReporter, writeFileName?: (s: string) => void, reportSummary?: ReportEmitErrorSummary, writeFile?: WriteFileCallback) { + export function emitFilesAndReportErrors(program: ProgramToEmitFilesAndReportErrors, reportDiagnostic: DiagnosticReporter, writeFileName?: (s: string) => void, reportSummary?: ReportEmitErrorSummary, writeFile?: WriteFileCallback) { // First get and report any syntactic errors. const diagnostics = program.getConfigFileParsingDiagnostics().slice(); const configFileParsingDiagnosticsLength = diagnostics.length; diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index a9d961a14d6..cafd06ca417 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -209,7 +209,7 @@ namespace ts { createSolutionBuilderWithWatchHost(sys, createSemanticDiagnosticsBuilderProgram, reportDiagnostic, createBuilderStatusReporter(sys, shouldBePretty()), createWatchStatusReporter()) : createSolutionBuilderHost(sys, createAbstractBuilder, reportDiagnostic, createBuilderStatusReporter(sys, shouldBePretty()), createReportErrorSummary(buildOptions)); updateCreateProgram(buildHost); - buildHost.afterProgramEmitAndDiagnostics = reportStatistics; + buildHost.afterProgramEmitAndDiagnostics = (program: BuilderProgram) => reportStatistics(program.getProgram()); const builder = createSolutionBuilder(buildHost, projects, buildOptions); if (buildOptions.clean) { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index ea3916d5d1d..d7bddfa2746 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4246,11 +4246,43 @@ declare namespace ts { /** * Builder to manage the program state changes */ - interface BuilderProgram extends Program { + interface BuilderProgram { /** * Returns current program */ getProgram(): Program; + /** + * Get compiler options of the program + */ + getCompilerOptions(): CompilerOptions; + /** + * Get the source file in the program with file name + */ + getSourceFile(fileName: string): SourceFile | undefined; + /** + * Get a list of files in the program + */ + getSourceFiles(): ReadonlyArray; + /** + * Get the diagnostics for compiler options + */ + getOptionsDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray; + /** + * Get the diagnostics that dont belong to any file + */ + getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray; + /** + * Get the diagnostics from config file parsing + */ + getConfigFileParsingDiagnostics(): ReadonlyArray; + /** + * Get the syntax diagnostics, for all source files if source file is not supplied + */ + getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; + /** + * Get the declaration diagnostics, for all source files if source file is not supplied + */ + getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; /** * Get all the dependencies of the file */ @@ -4276,6 +4308,10 @@ declare namespace ts { * in that order would be used to write the files */ emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult; + /** + * Get the current directory of the program + */ + getCurrentDirectory(): string; } /** * The builder that caches the semantic diagnostics for the program and handles the changed files and affected files diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index b9e7149fe76..52a4f147a61 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4246,11 +4246,43 @@ declare namespace ts { /** * Builder to manage the program state changes */ - interface BuilderProgram extends Program { + interface BuilderProgram { /** * Returns current program */ getProgram(): Program; + /** + * Get compiler options of the program + */ + getCompilerOptions(): CompilerOptions; + /** + * Get the source file in the program with file name + */ + getSourceFile(fileName: string): SourceFile | undefined; + /** + * Get a list of files in the program + */ + getSourceFiles(): ReadonlyArray; + /** + * Get the diagnostics for compiler options + */ + getOptionsDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray; + /** + * Get the diagnostics that dont belong to any file + */ + getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray; + /** + * Get the diagnostics from config file parsing + */ + getConfigFileParsingDiagnostics(): ReadonlyArray; + /** + * Get the syntax diagnostics, for all source files if source file is not supplied + */ + getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; + /** + * Get the declaration diagnostics, for all source files if source file is not supplied + */ + getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; /** * Get all the dependencies of the file */ @@ -4276,6 +4308,10 @@ declare namespace ts { * in that order would be used to write the files */ emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult; + /** + * Get the current directory of the program + */ + getCurrentDirectory(): string; } /** * The builder that caches the semantic diagnostics for the program and handles the changed files and affected files