Skip to content
Permalink
Browse files

feat(typescript-estree): add flag EXPERIMENTAL_useSourceOfProjectRefe…

…renceRedirect (#2669)
  • Loading branch information
bradzacher committed Oct 15, 2020
1 parent 2c4b838 commit 90a587845088da1b205e4d7d77dbc3f9447b1c5a
@@ -26,6 +26,7 @@ module.exports = {
],
tsconfigRootDir: __dirname,
warnOnUnsupportedTypeScriptVersion: false,
EXPERIMENTAL_useSourceOfProjectReferenceRedirect: true,
},
rules: {
//
@@ -4,5 +4,6 @@
"composite": false,
"rootDir": "."
},
"include": ["src", "typings", "tests"]
"include": ["src", "typings", "tests"],
"references": [{ "path": "../experimental-utils/tsconfig.build.json" }]
}
@@ -6,9 +6,5 @@
"resolveJsonModule": true
},
"include": ["src"],
"references": [
{ "path": "../experimental-utils/tsconfig.build.json" },
{ "path": "../parser/tsconfig.build.json" },
{ "path": "../typescript-estree/tsconfig.build.json" }
]
"references": [{ "path": "../experimental-utils/tsconfig.build.json" }]
}
@@ -5,5 +5,6 @@
"rootDir": "."
},
"include": ["src", "tests"],
"exclude": ["tests/test-project", "tests/test-tslint-rules-directory"]
"exclude": ["tests/test-project", "tests/test-tslint-rules-directory"],
"references": [{ "path": "../experimental-utils/tsconfig.build.json" }]
}
@@ -12,7 +12,6 @@
"references": [
{ "path": "../experimental-utils/tsconfig.build.json" },
{ "path": "../parser/tsconfig.build.json" },
{ "path": "../scope-manager/tsconfig.build.json" },
{ "path": "../typescript-estree/tsconfig.build.json" }
{ "path": "../scope-manager/tsconfig.build.json" }
]
}
@@ -4,5 +4,10 @@
"composite": false,
"rootDir": "."
},
"include": ["src", "typings", "tests", "tools"]
"include": ["src", "typings", "tests", "tools"],
"references": [
{ "path": "../experimental-utils/tsconfig.build.json" },
{ "path": "../parser/tsconfig.build.json" },
{ "path": "../scope-manager/tsconfig.build.json" }
]
}
@@ -4,5 +4,10 @@
"composite": false,
"rootDir": "."
},
"include": ["src", "typings", "tests", "tools"]
"include": ["src", "typings", "tests", "tools"],
"references": [
{ "path": "../scope-manager/tsconfig.build.json" },
{ "path": "../types/tsconfig.build.json" },
{ "path": "../typescript-estree/tsconfig.build.json" }
]
}
@@ -9,9 +9,9 @@
"include": ["src"],
"references": [
{ "path": "../experimental-utils/tsconfig.build.json" },
{ "path": "../types/tsconfig.build.json" },
{ "path": "../typescript-estree/tsconfig.build.json" },
{ "path": "../scope-manager/tsconfig.build.json" },
{ "path": "../shared-fixtures/tsconfig.build.json" }
{ "path": "../shared-fixtures/tsconfig.build.json" },
{ "path": "../types/tsconfig.build.json" },
{ "path": "../typescript-estree/tsconfig.build.json" }
]
}
@@ -5,5 +5,12 @@
"rootDir": "."
},
"include": ["src", "tests", "tools"],
"exclude": ["tests/fixtures"]
"exclude": ["tests/fixtures"],
"references": [
{ "path": "../experimental-utils/tsconfig.build.json" },
{ "path": "../scope-manager/tsconfig.build.json" },
{ "path": "../shared-fixtures/tsconfig.build.json" },
{ "path": "../types/tsconfig.build.json" },
{ "path": "../typescript-estree/tsconfig.build.json" }
]
}
@@ -4,5 +4,10 @@
"composite": false,
"rootDir": "."
},
"include": ["src", "typings", "tests", "tools"]
"include": ["src", "typings", "tests", "tools"],
"references": [
{ "path": "../types/tsconfig.build.json" },
{ "path": "../typescript-estree/tsconfig.build.json" },
{ "path": "../visitor-keys/tsconfig.build.json" }
]
}
@@ -37,6 +37,7 @@ interface ParserOptions {
debugLevel?: DebugLevel;
errorOnTypeScriptSyntacticAndSemanticIssues?: boolean;
errorOnUnknownASTType?: boolean;
EXPERIMENTAL_useSourceOfProjectReferenceRedirect?: boolean; // purposely undocumented for now
extraFileExtensions?: string[];
filePath?: string;
loc?: boolean;
@@ -152,6 +152,18 @@ interface ParseAndGenerateServicesOptions extends ParseOptions {
*/
errorOnTypeScriptSyntacticAndSemanticIssues?: boolean;
/**
* ***EXPERIMENTAL FLAG*** - Use this at your own risk.
*
* Causes TS to use the source files for referenced projects instead of the compiled .d.ts files.
* This feature is not yet optimized, and is likely to cause OOMs for medium to large projects.
*
* This flag REQUIRES at least TS v3.9, otherwise it does nothing.
*
* See: https://github.com/typescript-eslint/typescript-eslint/issues/2094
*/
EXPERIMENTAL_useSourceOfProjectReferenceRedirect?: boolean;
/**
* When `project` is provided, this controls the non-standard file extensions which will be parsed.
* It accepts an array of file extensions, each preceded by a `.`.
@@ -117,6 +117,20 @@ function createHash(content: string): string {
return content;
}

function updateCachedFileList(
tsconfigPath: CanonicalPath,
program: ts.Program,
extra: Extra,
): Set<CanonicalPath> {
const fileList = extra.EXPERIMENTAL_useSourceOfProjectReferenceRedirect
? new Set(
program.getSourceFiles().map(sf => getCanonicalFileName(sf.fileName)),
)
: new Set(program.getRootFileNames().map(f => getCanonicalFileName(f)));
programFileListCache.set(tsconfigPath, fileList);
return fileList;
}

/**
* Calculate project environments using options provided by consumer and paths from config
* @param code The code being linted
@@ -154,21 +168,12 @@ function getProgramsForProjects(
* before we go into the process of attempting to find and update every program
* see if we know of a program that contains this file
*/
for (const rawTsconfigPath of extra.projects) {
const tsconfigPath = getTsconfigPath(rawTsconfigPath, extra);
const existingWatch = knownWatchProgramMap.get(tsconfigPath);
if (!existingWatch) {
continue;
}

for (const [tsconfigPath, existingWatch] of knownWatchProgramMap.entries()) {
let fileList = programFileListCache.get(tsconfigPath);
let updatedProgram: ts.Program | null = null;
if (!fileList) {
updatedProgram = existingWatch.getProgram().getProgram();
fileList = new Set(
updatedProgram.getRootFileNames().map(f => getCanonicalFileName(f)),
);
programFileListCache.set(tsconfigPath, fileList);
fileList = updateCachedFileList(tsconfigPath, updatedProgram, extra);
}

if (fileList.has(filePath)) {
@@ -209,18 +214,38 @@ function getProgramsForProjects(

// sets parent pointers in source files
updatedProgram.getTypeChecker();
results.push(updatedProgram);

// cache and check the file list
const fileList = updateCachedFileList(
tsconfigPath,
updatedProgram,
extra,
);
if (fileList.has(filePath)) {
log('Found updated program for file. %s', filePath);
// we can return early because we know this program contains the file
return [updatedProgram];
}

results.push(updatedProgram);
continue;
}

const programWatch = createWatchProgram(tsconfigPath, extra);
const program = programWatch.getProgram().getProgram();

// cache watch program and return current program
knownWatchProgramMap.set(tsconfigPath, programWatch);

const program = programWatch.getProgram().getProgram();
// sets parent pointers in source files
program.getTypeChecker();

// cache and check the file list
const fileList = updateCachedFileList(tsconfigPath, program, extra);
if (fileList.has(filePath)) {
log('Found program for file. %s', filePath);
// we can return early because we know this program contains the file
return [program];
}

results.push(program);
}

@@ -324,6 +349,13 @@ function createWatchProgram(
);
watchCompilerHost.trace = log;

/**
* TODO: this needs refinement and development, but we're allowing users to opt-in to this for now for testing and feedback.
* See https://github.com/typescript-eslint/typescript-eslint/issues/2094
*/
watchCompilerHost.useSourceOfProjectReferenceRedirect = (): boolean =>
extra.EXPERIMENTAL_useSourceOfProjectReferenceRedirect;

// Since we don't want to asynchronously update program we want to disable timeout methods
// So any changes in the program will be delayed and updated when getProgram is called on watch
let callback: (() => void) | undefined;
@@ -12,6 +12,7 @@ export interface Extra {
debugLevel: Set<DebugModule>;
errorOnTypeScriptSyntacticAndSemanticIssues: boolean;
errorOnUnknownASTType: boolean;
EXPERIMENTAL_useSourceOfProjectReferenceRedirect: boolean;
extraFileExtensions: string[];
filePath: string;
jsx: boolean;
@@ -111,6 +112,18 @@ interface ParseAndGenerateServicesOptions extends ParseOptions {
*/
errorOnTypeScriptSyntacticAndSemanticIssues?: boolean;

/**
* ***EXPERIMENTAL FLAG*** - Use this at your own risk.
*
* Causes TS to use the source files for referenced projects instead of the compiled .d.ts files.
* This feature is not yet optimized, and is likely to cause OOMs for medium to large projects.
*
* This flag REQUIRES at least TS v3.9, otherwise it does nothing.
*
* See: https://github.com/typescript-eslint/typescript-eslint/issues/2094
*/
EXPERIMENTAL_useSourceOfProjectReferenceRedirect?: boolean;

/**
* When `project` is provided, this controls the non-standard file extensions which will be parsed.
* It accepts an array of file extensions, each preceded by a `.`.
@@ -93,6 +93,7 @@ function resetExtra(): void {
debugLevel: new Set(),
errorOnTypeScriptSyntacticAndSemanticIssues: false,
errorOnUnknownASTType: false,
EXPERIMENTAL_useSourceOfProjectReferenceRedirect: false,
extraFileExtensions: [],
filePath: getFileName(),
jsx: false,
@@ -168,7 +169,7 @@ function applyParserOptionsToExtra(options: TSESTreeOptions): void {
if (
extra.debugLevel.has('eslint') ||
// make sure we don't turn off the eslint debug if it was enabled via --debug
debug.enabled('eslint:*')
debug.enabled('eslint:*,-eslint:code-path')
) {
// https://github.com/eslint/eslint/blob/9dfc8501fb1956c90dc11e6377b4cb38a6bea65d/bin/eslint.js#L25
namespaces.push('eslint:*,-eslint:code-path');
@@ -284,6 +285,10 @@ function applyParserOptionsToExtra(options: TSESTreeOptions): void {
extra.createDefaultProgram =
typeof options.createDefaultProgram === 'boolean' &&
options.createDefaultProgram;

extra.EXPERIMENTAL_useSourceOfProjectReferenceRedirect =
typeof options.EXPERIMENTAL_useSourceOfProjectReferenceRedirect ===
'boolean' && options.EXPERIMENTAL_useSourceOfProjectReferenceRedirect;
}

function warnAboutTSVersion(): void {
@@ -6,5 +6,10 @@
"rootDir": "./src",
"resolveJsonModule": true
},
"include": ["src", "typings"]
"include": ["src", "typings"],
"references": [
{ "path": "../shared-fixtures/tsconfig.build.json" },
{ "path": "../types/tsconfig.build.json" },
{ "path": "../visitor-keys/tsconfig.build.json" }
]
}

0 comments on commit 90a5878

Please sign in to comment.
You can’t perform that action at this time.