Skip to content

Commit

Permalink
fix(typescript-estree): ensure --fix works with singleRun mode
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesHenry committed Jul 23, 2021
1 parent d358785 commit 86d0703
Showing 1 changed file with 39 additions and 6 deletions.
45 changes: 39 additions & 6 deletions packages/typescript-estree/src/parser.ts
Expand Up @@ -496,6 +496,8 @@ function parseWithNodeMaps<T extends TSESTreeOptions = TSESTreeOptions>(
return parseWithNodeMapsInternal(code, options, true);
}

const parseAndGenerateServicesCalls: { [fileName: string]: number } = {};

function parseAndGenerateServices<T extends TSESTreeOptions = TSESTreeOptions>(
code: string,
options: T,
Expand Down Expand Up @@ -566,12 +568,43 @@ function parseAndGenerateServices<T extends TSESTreeOptions = TSESTreeOptions>(
*/
const shouldProvideParserServices =
extra.programs != null || (extra.projects && extra.projects.length > 0);
const { ast, program } = getProgramAndAST(
code,
extra.programs,
shouldProvideParserServices,
extra.createDefaultProgram,
)!;

/**
* If we are in singleRun mode but the parseAndGenerateServices() function has been called more than once for the current file,
* it must mean that we are in the middle of an ESLint automated fix cycle (in which parsing can be performed up to an additional
* 10 times in order to apply all possible fixes for the file).
*
* In this scenario we cannot rely upon the singleRun AOT compiled programs because the SourceFiles will not contain the source
* with the latest fixes applied. Therefore we fallback to creating the quickest possible isolated program from the updated source.
*/
let ast: ts.SourceFile;
let program: ts.Program;

if (extra.singleRun && options.filePath) {
parseAndGenerateServicesCalls[options.filePath] =
parseAndGenerateServicesCalls[options.filePath] || 0;
parseAndGenerateServicesCalls[options.filePath] =
parseAndGenerateServicesCalls[options.filePath] + 1;
}

if (
extra.singleRun &&
options.filePath &&
parseAndGenerateServicesCalls[options.filePath] > 1
) {
const isolatedAstAndProgram = createIsolatedProgram(code, extra);
ast = isolatedAstAndProgram.ast;
program = isolatedAstAndProgram.program;
} else {
const astAndProgram = getProgramAndAST(
code,
extra.programs,
shouldProvideParserServices,
extra.createDefaultProgram,
)!;
ast = astAndProgram.ast;
program = astAndProgram.program;
}

/**
* Convert the TypeScript AST to an ESTree-compatible one, and optionally preserve
Expand Down

0 comments on commit 86d0703

Please sign in to comment.