Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(typescript-estree): support long running lint without watch (#1106)
- Loading branch information
1 parent
0c85ac3
commit ed5564d
Showing
15 changed files
with
882 additions
and
700 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
packages/typescript-estree/src/create-program/createDefaultProgram.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import debug from 'debug'; | ||
import path from 'path'; | ||
import ts from 'typescript'; | ||
import { Extra } from '../parser-options'; | ||
import { | ||
getTsconfigPath, | ||
DEFAULT_COMPILER_OPTIONS, | ||
ASTAndProgram, | ||
} from './shared'; | ||
|
||
const log = debug('typescript-eslint:typescript-estree:createDefaultProgram'); | ||
|
||
/** | ||
* @param code The code of the file being linted | ||
* @param options The config object | ||
* @param extra.tsconfigRootDir The root directory for relative tsconfig paths | ||
* @param extra.projects Provided tsconfig paths | ||
* @returns If found, returns the source file corresponding to the code and the containing program | ||
*/ | ||
function createDefaultProgram( | ||
code: string, | ||
extra: Extra, | ||
): ASTAndProgram | undefined { | ||
log('Getting default program for: %s', extra.filePath || 'unnamed file'); | ||
|
||
if (!extra.projects || extra.projects.length !== 1) { | ||
return undefined; | ||
} | ||
|
||
const tsconfigPath = getTsconfigPath(extra.projects[0], extra); | ||
|
||
const commandLine = ts.getParsedCommandLineOfConfigFile( | ||
tsconfigPath, | ||
DEFAULT_COMPILER_OPTIONS, | ||
{ ...ts.sys, onUnRecoverableConfigFileDiagnostic: () => {} }, | ||
); | ||
|
||
if (!commandLine) { | ||
return undefined; | ||
} | ||
|
||
const compilerHost = ts.createCompilerHost(commandLine.options, true); | ||
const oldReadFile = compilerHost.readFile; | ||
compilerHost.readFile = (fileName: string): string | undefined => | ||
path.normalize(fileName) === path.normalize(extra.filePath) | ||
? code | ||
: oldReadFile(fileName); | ||
|
||
const program = ts.createProgram( | ||
[extra.filePath], | ||
commandLine.options, | ||
compilerHost, | ||
); | ||
const ast = program.getSourceFile(extra.filePath); | ||
|
||
return ast && { ast, program }; | ||
} | ||
|
||
export { createDefaultProgram }; |
71 changes: 71 additions & 0 deletions
71
packages/typescript-estree/src/create-program/createIsolatedProgram.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import debug from 'debug'; | ||
import ts from 'typescript'; | ||
import { Extra } from '../parser-options'; | ||
import { ASTAndProgram, DEFAULT_COMPILER_OPTIONS } from './shared'; | ||
|
||
const log = debug('typescript-eslint:typescript-estree:createIsolatedProgram'); | ||
|
||
/** | ||
* @param code The code of the file being linted | ||
* @returns Returns a new source file and program corresponding to the linted code | ||
*/ | ||
function createIsolatedProgram(code: string, extra: Extra): ASTAndProgram { | ||
log('Getting isolated program for: %s', extra.filePath); | ||
|
||
const compilerHost: ts.CompilerHost = { | ||
fileExists() { | ||
return true; | ||
}, | ||
getCanonicalFileName() { | ||
return extra.filePath; | ||
}, | ||
getCurrentDirectory() { | ||
return ''; | ||
}, | ||
getDirectories() { | ||
return []; | ||
}, | ||
getDefaultLibFileName() { | ||
return 'lib.d.ts'; | ||
}, | ||
|
||
// TODO: Support Windows CRLF | ||
getNewLine() { | ||
return '\n'; | ||
}, | ||
getSourceFile(filename: string) { | ||
return ts.createSourceFile(filename, code, ts.ScriptTarget.Latest, true); | ||
}, | ||
readFile() { | ||
return undefined; | ||
}, | ||
useCaseSensitiveFileNames() { | ||
return true; | ||
}, | ||
writeFile() { | ||
return null; | ||
}, | ||
}; | ||
|
||
const program = ts.createProgram( | ||
[extra.filePath], | ||
{ | ||
noResolve: true, | ||
target: ts.ScriptTarget.Latest, | ||
jsx: extra.jsx ? ts.JsxEmit.Preserve : undefined, | ||
...DEFAULT_COMPILER_OPTIONS, | ||
}, | ||
compilerHost, | ||
); | ||
|
||
const ast = program.getSourceFile(extra.filePath); | ||
if (!ast) { | ||
throw new Error( | ||
'Expected an ast to be returned for the single-file isolated program.', | ||
); | ||
} | ||
|
||
return { ast, program }; | ||
} | ||
|
||
export { createIsolatedProgram }; |
72 changes: 72 additions & 0 deletions
72
packages/typescript-estree/src/create-program/createProjectProgram.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import debug from 'debug'; | ||
import path from 'path'; | ||
import { getProgramsForProjects } from './createWatchProgram'; | ||
import { firstDefined } from '../node-utils'; | ||
import { Extra } from '../parser-options'; | ||
import { ASTAndProgram } from './shared'; | ||
|
||
const log = debug('typescript-eslint:typescript-estree:createProjectProgram'); | ||
|
||
/** | ||
* @param code The code of the file being linted | ||
* @param options The config object | ||
* @returns If found, returns the source file corresponding to the code and the containing program | ||
*/ | ||
function createProjectProgram( | ||
code: string, | ||
createDefaultProgram: boolean, | ||
extra: Extra, | ||
): ASTAndProgram | undefined { | ||
log('Creating project program for: %s', extra.filePath); | ||
|
||
const astAndProgram = firstDefined( | ||
getProgramsForProjects(code, extra.filePath, extra), | ||
currentProgram => { | ||
const ast = currentProgram.getSourceFile(extra.filePath); | ||
return ast && { ast, program: currentProgram }; | ||
}, | ||
); | ||
|
||
if (!astAndProgram && !createDefaultProgram) { | ||
// the file was either not matched within the tsconfig, or the extension wasn't expected | ||
const errorLines = [ | ||
'"parserOptions.project" has been set for @typescript-eslint/parser.', | ||
`The file does not match your project config: ${path.relative( | ||
process.cwd(), | ||
extra.filePath, | ||
)}.`, | ||
]; | ||
let hasMatchedAnError = false; | ||
|
||
const fileExtension = path.extname(extra.filePath); | ||
if (!['.ts', '.tsx', '.js', '.jsx'].includes(fileExtension)) { | ||
const nonStandardExt = `The extension for the file (${fileExtension}) is non-standard`; | ||
if (extra.extraFileExtensions && extra.extraFileExtensions.length > 0) { | ||
if (!extra.extraFileExtensions.includes(fileExtension)) { | ||
errorLines.push( | ||
`${nonStandardExt}. It should be added to your existing "parserOptions.extraFileExtensions".`, | ||
); | ||
hasMatchedAnError = true; | ||
} | ||
} else { | ||
errorLines.push( | ||
`${nonStandardExt}. You should add "parserOptions.extraFileExtensions" to your config.`, | ||
); | ||
hasMatchedAnError = true; | ||
} | ||
} | ||
|
||
if (!hasMatchedAnError) { | ||
errorLines.push( | ||
'The file must be included in at least one of the projects provided.', | ||
); | ||
hasMatchedAnError = true; | ||
} | ||
|
||
throw new Error(errorLines.join('\n')); | ||
} | ||
|
||
return astAndProgram; | ||
} | ||
|
||
export { createProjectProgram }; |
18 changes: 18 additions & 0 deletions
18
packages/typescript-estree/src/create-program/createSourceFile.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import debug from 'debug'; | ||
import ts from 'typescript'; | ||
import { Extra } from '../parser-options'; | ||
|
||
const log = debug('typescript-eslint:typescript-estree:createIsolatedProgram'); | ||
|
||
function createSourceFile(code: string, extra: Extra): ts.SourceFile { | ||
log('Getting AST without type information for: %s', extra.filePath); | ||
|
||
return ts.createSourceFile( | ||
extra.filePath, | ||
code, | ||
ts.ScriptTarget.Latest, | ||
/* setParentNodes */ true, | ||
); | ||
} | ||
|
||
export { createSourceFile }; |
Oops, something went wrong.