Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/hooks/tapStartToConnectAndRunReporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ function tapStartToConnectAndRunReporter(
await previousReport.close();
}

const report = await reporter.getReport(change);
const report = await reporter.getReport(change, state.watching);
resolve(report);

report
Expand Down
6 changes: 3 additions & 3 deletions src/reporter/AggregatedReporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function createAggregatedReporter<TReporter extends Reporter>(reporter: TReporte

const aggregatedReporter: TReporter = {
...reporter,
getReport: async (change) => {
getReport: async (change, watching) => {
if (!pendingPromise) {
let resolvePending: () => void;
pendingPromise = new Promise((resolve) => {
Expand All @@ -23,7 +23,7 @@ function createAggregatedReporter<TReporter extends Reporter>(reporter: TReporte
});

return reporter
.getReport(change)
.getReport(change, watching)
.then((report) => ({
...report,
async close() {
Expand All @@ -45,7 +45,7 @@ function createAggregatedReporter<TReporter extends Reporter>(reporter: TReporte
const change = aggregateFilesChanges(queuedChanges);
queuedChanges = [];

return aggregatedReporter.getReport(change);
return aggregatedReporter.getReport(change, watching);
} else {
throw new OperationCanceledError('getReport canceled - new report requested.');
}
Expand Down
2 changes: 1 addition & 1 deletion src/reporter/Reporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { FilesChange } from './FilesChange';
import { Report } from './Report';

interface Reporter {
getReport(change: FilesChange): Promise<Report>;
getReport(change: FilesChange, watching: boolean): Promise<Report>;
}

export { Reporter };
8 changes: 4 additions & 4 deletions src/reporter/reporter-rpc/ReporterRpcClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ function createReporterRpcClient<TConfiguration extends object>(
await channel.close();
}
},
getReport: async (change) => {
const reportId = await rpcClient.dispatchCall(getReport, change);
getReport: async (change, watching) => {
const reportId = await rpcClient.dispatchCall(getReport, { change, watching });

return {
getDependencies() {
Expand All @@ -65,8 +65,8 @@ function composeReporterRpcClients(clients: ReporterRpcClient[]): ReporterRpcCli
connect: () => Promise.all(clients.map((client) => client.connect())).then(() => undefined),
disconnect: () =>
Promise.all(clients.map((client) => client.disconnect())).then(() => undefined),
getReport: (change: FilesChange) =>
Promise.all(clients.map((client) => client.getReport(change))).then((reports) => ({
getReport: (change: FilesChange, watching: boolean) =>
Promise.all(clients.map((client) => client.getReport(change, watching))).then((reports) => ({
getDependencies: () =>
Promise.all(reports.map((report) => report.getDependencies())).then((dependencies) =>
dependencies.reduce(
Expand Down
2 changes: 1 addition & 1 deletion src/reporter/reporter-rpc/ReporterRpcProcedure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Issue } from '../../issue';
import { Dependencies } from '../Dependencies';

const configure: RpcProcedure<object, void> = 'configure';
const getReport: RpcProcedure<FilesChange, void> = 'getReport';
const getReport: RpcProcedure<{ change: FilesChange; watching: boolean }, void> = 'getReport';
const getDependencies: RpcProcedure<void, Dependencies> = 'getDependencies';
const getIssues: RpcProcedure<void, Issue[]> = 'getIssues';
const closeReport: RpcProcedure<void, void> = 'closeReport';
Expand Down
4 changes: 2 additions & 2 deletions src/reporter/reporter-rpc/ReporterRpcService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ function registerReporterRpcService<TConfiguration extends object>(

const reporter = reporterFactory(configuration);

rpcService.addCallHandler(getReport, async (change) => {
rpcService.addCallHandler(getReport, async ({ change, watching }) => {
if (report) {
throw new Error(`Close previous report before opening the next one.`);
}

report = await reporter.getReport(change);
report = await reporter.getReport(change, watching);
});
rpcService.addCallHandler(getDependencies, () => {
if (!report) {
Expand Down
34 changes: 34 additions & 0 deletions src/typescript-reporter/reporter/ControlledCompilerHost.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as ts from 'typescript';
import { TypeScriptHostExtension } from '../extension/TypeScriptExtension';
import { ControlledTypeScriptSystem } from './ControlledTypeScriptSystem';

function createControlledCompilerHost(
typescript: typeof ts,
parsedCommandLine: ts.ParsedCommandLine,
system: ControlledTypeScriptSystem,
hostExtensions: TypeScriptHostExtension[] = []
): ts.CompilerHost {
const baseCompilerHost = typescript.createCompilerHost(parsedCommandLine.options);

let controlledCompilerHost: ts.CompilerHost = {
...baseCompilerHost,
fileExists: system.fileExists,
readFile: system.readFile,
directoryExists: system.directoryExists,
getDirectories: system.getDirectories,
realpath: system.realpath,
};

hostExtensions.forEach((hostExtension) => {
if (hostExtension.extendCompilerHost) {
controlledCompilerHost = hostExtension.extendCompilerHost(
controlledCompilerHost,
parsedCommandLine
);
}
});

return controlledCompilerHost;
}

export { createControlledCompilerHost };
45 changes: 36 additions & 9 deletions src/typescript-reporter/reporter/TypeScriptReporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
} from './TypeScriptConfigurationParser';
import { createPerformance } from '../../profile/Performance';
import { connectTypeScriptPerformance } from '../profile/TypeScriptPerformance';
import { createControlledCompilerHost } from './ControlledCompilerHost';

// write this type as it's available only in the newest TypeScript versions (^4.1.0)
interface Tracing {
Expand All @@ -30,12 +31,14 @@ function createTypeScriptReporter(configuration: TypeScriptReporterConfiguration
let parseConfigurationDiagnostics: ts.Diagnostic[] = [];
let dependencies: Dependencies | undefined;
let configurationChanged = false;
let compilerHost: ts.CompilerHost | undefined;
let watchCompilerHost:
| ts.WatchCompilerHostOfFilesAndCompilerOptions<ts.SemanticDiagnosticsBuilderProgram>
| undefined;
let watchSolutionBuilderHost:
| ts.SolutionBuilderWithWatchHost<ts.SemanticDiagnosticsBuilderProgram>
| undefined;
let program: ts.Program | undefined;
let watchProgram:
| ts.WatchOfFilesAndCompilerOptions<ts.SemanticDiagnosticsBuilderProgram>
| undefined;
Expand Down Expand Up @@ -69,27 +72,27 @@ function createTypeScriptReporter(configuration: TypeScriptReporterConfiguration
return (typescript as any).tracing;
}

function getDiagnosticsOfBuilderProgram(builderProgram: ts.BuilderProgram) {
function getDiagnosticsOfProgram(program: ts.Program | ts.BuilderProgram) {
const diagnostics: ts.Diagnostic[] = [];

if (configuration.diagnosticOptions.syntactic) {
performance.markStart('Syntactic Diagnostics');
diagnostics.push(...builderProgram.getSyntacticDiagnostics());
diagnostics.push(...program.getSyntacticDiagnostics());
performance.markEnd('Syntactic Diagnostics');
}
if (configuration.diagnosticOptions.global) {
performance.markStart('Global Diagnostics');
diagnostics.push(...builderProgram.getGlobalDiagnostics());
diagnostics.push(...program.getGlobalDiagnostics());
performance.markEnd('Global Diagnostics');
}
if (configuration.diagnosticOptions.semantic) {
performance.markStart('Semantic Diagnostics');
diagnostics.push(...builderProgram.getSemanticDiagnostics());
diagnostics.push(...program.getSemanticDiagnostics());
performance.markEnd('Semantic Diagnostics');
}
if (configuration.diagnosticOptions.declaration) {
performance.markStart('Declaration Diagnostics');
diagnostics.push(...builderProgram.getDeclarationDiagnostics());
diagnostics.push(...program.getDeclarationDiagnostics());
performance.markEnd('Declaration Diagnostics');
}

Expand Down Expand Up @@ -221,7 +224,7 @@ function createTypeScriptReporter(configuration: TypeScriptReporterConfiguration
}

return {
getReport: async ({ changedFiles = [], deletedFiles = [] }) => {
getReport: async ({ changedFiles = [], deletedFiles = [] }, watching) => {
// clear cache to be ready for next iteration and to free memory
system.clearCache();

Expand All @@ -233,8 +236,10 @@ function createTypeScriptReporter(configuration: TypeScriptReporterConfiguration
// we need to re-create programs
parsedConfiguration = undefined;
dependencies = undefined;
compilerHost = undefined;
watchCompilerHost = undefined;
watchSolutionBuilderHost = undefined;
program = undefined;
watchProgram = undefined;
solutionBuilder = undefined;

Expand Down Expand Up @@ -346,7 +351,7 @@ function createTypeScriptReporter(configuration: TypeScriptReporterConfiguration
undefined,
(builderProgram) => {
const projectName = getProjectNameOfBuilderProgram(builderProgram);
const diagnostics = getDiagnosticsOfBuilderProgram(builderProgram);
const diagnostics = getDiagnosticsOfProgram(builderProgram);

// update diagnostics
diagnosticsPerProject.set(projectName, diagnostics);
Expand Down Expand Up @@ -379,7 +384,7 @@ function createTypeScriptReporter(configuration: TypeScriptReporterConfiguration
solutionBuilder.build();
performance.markEnd('Build Solutions');
}
} else {
} else if (watching) {
// watch compiler case
// ensure watch compiler host exists
if (!watchCompilerHost) {
Expand Down Expand Up @@ -412,7 +417,7 @@ function createTypeScriptReporter(configuration: TypeScriptReporterConfiguration
undefined,
(builderProgram) => {
const projectName = getProjectNameOfBuilderProgram(builderProgram);
const diagnostics = getDiagnosticsOfBuilderProgram(builderProgram);
const diagnostics = getDiagnosticsOfProgram(builderProgram);

// update diagnostics
diagnosticsPerProject.set(projectName, diagnostics);
Expand Down Expand Up @@ -440,6 +445,28 @@ function createTypeScriptReporter(configuration: TypeScriptReporterConfiguration
watchProgram.updateRootFileNames(dependencies.files);
shouldUpdateRootFiles = false;
}
} else {
if (!compilerHost) {
compilerHost = createControlledCompilerHost(
typescript,
parsedConfiguration,
system,
extensions
);
}
if (!program) {
program = ts.createProgram({
rootNames: parsedConfiguration.fileNames,
options: parsedConfiguration.options,
projectReferences: parsedConfiguration.projectReferences,
host: compilerHost,
});
}
const diagnostics = getDiagnosticsOfProgram(program);
const projectName = getConfigFilePathFromCompilerOptions(program.getCompilerOptions());

// update diagnostics
diagnosticsPerProject.set(projectName, diagnostics);
}

changedFiles.forEach((changedFile) => {
Expand Down