Skip to content

Commit

Permalink
feat(ApiIncrementalChecker): improve generation of diagnostics
Browse files Browse the repository at this point in the history
when the options `checkSyntacticErrors: false` and `useTypescriptIncrementalApi: true` both were active, no semantic errors were emitted as soon as the first syntactic error was encountered
this patches the `typescript` import to override that behavior
see discussion in TypeStrong#257
  • Loading branch information
phryneas committed Apr 22, 2019
1 parent 61f9c49 commit 2709397
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/patchTypescript.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// tslint:disable-next-line:no-implicit-dependencies
import * as ts from 'typescript'; // Imported for types alone

export interface TypeScriptPatchConfig {
/**
* Ususally, the compilerHost created with typescript.createWatchCompilerHost will bail out of diagnostics collection if there has been any syntactic error.
* (see /~https://github.com/Microsoft/TypeScript/blob/89386ddda7dafc63cb35560e05412487f47cc267/src/compiler/watch.ts#L141 )
* If this plugin is running with `checkSyntacticErrors: false`, this might lead to situations where no syntactic errors are reported within webpack
* (because the file causing a syntactic error might not get processed by ts-loader), but there are semantic errors that would be missed due to this behavior.
* This ensures that the compilerHost always assumes that there were no syntactic errors to be found and continues to check for semantic errors.
*/
skipGetSyntacticDiagnostics: boolean;
}

export function patchTypescript(
typescript: typeof ts,
config: TypeScriptPatchConfig
) {
const {
createEmitAndSemanticDiagnosticsBuilderProgram: originalCreateEmitAndSemanticDiagnosticsBuilderProgram
} = typescript;

const patchSkipGetSyntacticDiagnostics: Pick<
typeof ts,
'createEmitAndSemanticDiagnosticsBuilderProgram'
> = {
createEmitAndSemanticDiagnosticsBuilderProgram(...args: any[]) {
const program = originalCreateEmitAndSemanticDiagnosticsBuilderProgram.apply(
typescript,
args as any
);
program.getSyntacticDiagnostics = () => [];
return program;
}
};

// directly patch the typescript object
Object.assign(
typescript,
config.skipGetSyntacticDiagnostics ? patchSkipGetSyntacticDiagnostics : {}
);
}
8 changes: 8 additions & 0 deletions src/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from './NormalizedMessageFactories';
import { RpcProvider } from 'worker-rpc';
import { RunPayload, RunResult, RUN } from './RpcTypes';
import { TypeScriptPatchConfig, patchTypescript } from './patchTypescript';

const rpc = new RpcProvider(message => {
try {
Expand All @@ -25,6 +26,13 @@ const rpc = new RpcProvider(message => {
process.on('message', message => rpc.dispatch(message));

const typescript: typeof ts = require(process.env.TYPESCRIPT_PATH!);
const patchConfig: TypeScriptPatchConfig = {
skipGetSyntacticDiagnostics:
process.env.USE_INCREMENTAL_API === 'true' &&
process.env.CHECK_SYNTACTIC_ERRORS !== 'true'
};

patchTypescript(typescript, patchConfig);

// message factories
export const createNormalizedMessageFromDiagnostic = makeCreateNormalizedMessageFromDiagnostic(
Expand Down

0 comments on commit 2709397

Please sign in to comment.