mirror of
https://github.com/openharmony/third_party_typescript_eslint.git
synced 2026-06-30 21:27:59 -04:00
feat(typescript-estree): add option to ignore certain folders from glob resolution (#1802)
This commit is contained in:
@@ -16,6 +16,7 @@ interface ParserOptions {
|
||||
loc?: boolean;
|
||||
noWatch?: boolean;
|
||||
project?: string | string[];
|
||||
projectFolderIgnoreList?: (string | RegExp)[];
|
||||
range?: boolean;
|
||||
sourceType?: 'script' | 'module';
|
||||
tokens?: boolean;
|
||||
|
||||
@@ -54,6 +54,7 @@ interface ParserOptions {
|
||||
jsx?: boolean;
|
||||
};
|
||||
project?: string | string[];
|
||||
projectFolderIgnoreList?: (string | RegExp)[];
|
||||
tsconfigRootDir?: string;
|
||||
extraFileExtensions?: string[];
|
||||
warnOnUnsupportedTypeScriptVersion?: boolean;
|
||||
@@ -118,26 +119,36 @@ This option allows you to provide a path to your project's `tsconfig.json`. **Th
|
||||
}
|
||||
```
|
||||
|
||||
### `tsconfigRootDir`
|
||||
### `parserOptions.tsconfigRootDir`
|
||||
|
||||
Default `undefined`.
|
||||
|
||||
This option allows you to provide the root directory for relative tsconfig paths specified in the `project` option above.
|
||||
|
||||
### `extraFileExtensions`
|
||||
### `parserOptions.projectFolderIgnoreList`
|
||||
|
||||
Default `["/node_modules/"]`.
|
||||
|
||||
This option allows you to ignore folders from being included in your provided list of `project`s.
|
||||
Any resolved project path that matches one or more of the provided regular expressions will be removed from the list.
|
||||
This is useful if you have configured glob patterns, but want to make sure you ignore certain folders.
|
||||
|
||||
For example, by default it will ensure that a glob like `./**/tsconfig.json` will not match any `tsconfig`s within your `node_modules` folder (some npm packages do not exclude their source files from their published packages).
|
||||
|
||||
### `parserOptions.extraFileExtensions`
|
||||
|
||||
Default `undefined`.
|
||||
|
||||
This option allows you to provide one or more additional file extensions which should be considered in the TypeScript Program compilation.
|
||||
The default extensions are `.ts`, `.tsx`, `.js`, and `.jsx`. Add extensions starting with `.`, followed by the file extension. E.g. for a `.vue` file use `"extraFileExtensions: [".vue"]`.
|
||||
|
||||
### `warnOnUnsupportedTypeScriptVersion`
|
||||
### `parserOptions.warnOnUnsupportedTypeScriptVersion`
|
||||
|
||||
Default `true`.
|
||||
|
||||
This option allows you to toggle the warning that the parser will give you if you use a version of TypeScript which is not explicitly supported
|
||||
|
||||
### `createDefaultProgram`
|
||||
### `parserOptions.createDefaultProgram`
|
||||
|
||||
Default `false`.
|
||||
|
||||
|
||||
@@ -182,6 +182,16 @@ interface ParseAndGenerateServicesOptions extends ParseOptions {
|
||||
*/
|
||||
project?: string | string[];
|
||||
|
||||
/**
|
||||
* If you provide a glob (or globs) to the project option, you can use this option to blacklist
|
||||
* certain folders from being matched by the globs.
|
||||
* Any project path that matches one or more of the provided regular expressions will be removed from the list.
|
||||
*
|
||||
* Accepts an array of strings that are passed to new RegExp(), or an array of regular expressions.
|
||||
* By default, this is set to ["/node_modules/"]
|
||||
*/
|
||||
projectFolderIgnoreList?: (string | RegExp)[];
|
||||
|
||||
/**
|
||||
* The absolute path to the root directory for all provided `project`s.
|
||||
*/
|
||||
@@ -205,6 +215,7 @@ const PARSE_AND_GENERATE_SERVICES_DEFAULT_OPTIONS: ParseOptions = {
|
||||
extraFileExtensions: [],
|
||||
preserveNodeMaps: false, // or true, if you do not set this, but pass `project`
|
||||
project: undefined,
|
||||
projectFolderIgnoreList: ['/node_modules/'],
|
||||
tsconfigRootDir: process.cwd(),
|
||||
};
|
||||
|
||||
|
||||
@@ -29,28 +29,23 @@ export interface Extra {
|
||||
// MAKE SURE THIS IS KEPT IN SYNC WITH THE README //
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
export interface TSESTreeOptions {
|
||||
interface ParseOptions {
|
||||
/**
|
||||
* create a top-level comments array containing all comments
|
||||
*/
|
||||
comment?: boolean;
|
||||
|
||||
/**
|
||||
* For convenience:
|
||||
* - true === ['typescript-eslint']
|
||||
* - false === []
|
||||
*
|
||||
* An array of modules to turn explicit debugging on for.
|
||||
* - 'typescript-eslint' is the same as setting the env var `DEBUG=typescript-eslint:*`
|
||||
* - 'eslint' is the same as setting the env var `DEBUG=eslint:*`
|
||||
* - 'typescript' is the same as setting `extendedDiagnostics: true` in your tsconfig compilerOptions
|
||||
*
|
||||
* For convenience, also supports a boolean:
|
||||
* - true === ['typescript-eslint']
|
||||
* - false === []
|
||||
*/
|
||||
debugLevel?: boolean | DebugModule[];
|
||||
|
||||
/**
|
||||
* Causes the parser to error if the TypeScript compiler returns any unexpected syntax/semantic errors.
|
||||
*/
|
||||
errorOnTypeScriptSyntacticAndSemanticIssues?: boolean;
|
||||
debugLevel?: boolean | ('typescript-eslint' | 'eslint' | 'typescript')[];
|
||||
|
||||
/**
|
||||
* Cause the parser to error if it encounters an unknown AST node type (useful for testing).
|
||||
@@ -59,14 +54,7 @@ export interface TSESTreeOptions {
|
||||
errorOnUnknownASTType?: 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 `.`.
|
||||
*/
|
||||
extraFileExtensions?: string[];
|
||||
|
||||
/**
|
||||
* Absolute (or relative to `tsconfigRootDir`) path to the file being parsed.
|
||||
* When `project` is provided, this is required, as it is used to fetch the file from the TypeScript compiler's cache.
|
||||
* Absolute (or relative to `cwd`) path to the file being parsed.
|
||||
*/
|
||||
filePath?: string;
|
||||
|
||||
@@ -95,6 +83,45 @@ export interface TSESTreeOptions {
|
||||
*/
|
||||
loggerFn?: Function | false;
|
||||
|
||||
/**
|
||||
* Controls whether the `range` property is included on AST nodes.
|
||||
* The `range` property is a [number, number] which indicates the start/end index of the node in the file contents.
|
||||
* This is similar to the `loc` property, except this is the absolute index.
|
||||
*/
|
||||
range?: boolean;
|
||||
|
||||
/**
|
||||
* Set to true to create a top-level array containing all tokens from the file.
|
||||
*/
|
||||
tokens?: boolean;
|
||||
|
||||
/*
|
||||
* The JSX AST changed the node type for string literals
|
||||
* inside a JSX Element from `Literal` to `JSXText`.
|
||||
* When value is `true`, these nodes will be parsed as type `JSXText`.
|
||||
* When value is `false`, these nodes will be parsed as type `Literal`.
|
||||
*/
|
||||
useJSXTextNode?: boolean;
|
||||
}
|
||||
|
||||
interface ParseAndGenerateServicesOptions extends ParseOptions {
|
||||
/**
|
||||
* Causes the parser to error if the TypeScript compiler returns any unexpected syntax/semantic errors.
|
||||
*/
|
||||
errorOnTypeScriptSyntacticAndSemanticIssues?: 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 `.`.
|
||||
*/
|
||||
extraFileExtensions?: string[];
|
||||
|
||||
/**
|
||||
* Absolute (or relative to `tsconfigRootDir`) path to the file being parsed.
|
||||
* When `project` is provided, this is required, as it is used to fetch the file from the TypeScript compiler's cache.
|
||||
*/
|
||||
filePath?: string;
|
||||
|
||||
/**
|
||||
* Allows the user to control whether or not two-way AST node maps are preserved
|
||||
* during the AST conversion process.
|
||||
@@ -114,30 +141,20 @@ export interface TSESTreeOptions {
|
||||
project?: string | string[];
|
||||
|
||||
/**
|
||||
* Controls whether the `range` property is included on AST nodes.
|
||||
* The `range` property is a [number, number] which indicates the start/end index of the node in the file contents.
|
||||
* This is similar to the `loc` property, except this is the absolute index.
|
||||
* If you provide a glob (or globs) to the project option, you can use this option to blacklist
|
||||
* certain folders from being matched by the globs.
|
||||
* Any project path that matches one or more of the provided regular expressions will be removed from the list.
|
||||
*
|
||||
* Accepts an array of strings that are passed to new RegExp(), or an array of regular expressions.
|
||||
* By default, this is set to ["/node_modules/"]
|
||||
*/
|
||||
range?: boolean;
|
||||
|
||||
/**
|
||||
* Set to true to create a top-level array containing all tokens from the file.
|
||||
*/
|
||||
tokens?: boolean;
|
||||
projectFolderIgnoreList?: (string | RegExp)[];
|
||||
|
||||
/**
|
||||
* The absolute path to the root directory for all provided `project`s.
|
||||
*/
|
||||
tsconfigRootDir?: string;
|
||||
|
||||
/*
|
||||
* The JSX AST changed the node type for string literals
|
||||
* inside a JSX Element from `Literal` to `JSXText`.
|
||||
* When value is `true`, these nodes will be parsed as type `JSXText`.
|
||||
* When value is `false`, these nodes will be parsed as type `Literal`.
|
||||
*/
|
||||
useJSXTextNode?: boolean;
|
||||
|
||||
/**
|
||||
***************************************************************************************
|
||||
* IT IS RECOMMENDED THAT YOU DO NOT USE THIS OPTION, AS IT CAUSES PERFORMANCE ISSUES. *
|
||||
@@ -150,6 +167,8 @@ export interface TSESTreeOptions {
|
||||
createDefaultProgram?: boolean;
|
||||
}
|
||||
|
||||
export type TSESTreeOptions = ParseAndGenerateServicesOptions;
|
||||
|
||||
// This lets us use generics to type the return value, and removes the need to
|
||||
// handle the undefined type in the get method
|
||||
export interface ParserWeakMap<TKey, TValueBase> {
|
||||
|
||||
@@ -14,6 +14,8 @@ import { getFirstSemanticOrSyntacticError } from './semantic-or-syntactic-errors
|
||||
import { TSESTree } from './ts-estree';
|
||||
import { ensureAbsolutePath } from './create-program/shared';
|
||||
|
||||
const log = debug('typescript-eslint:typescript-estree:parser');
|
||||
|
||||
/**
|
||||
* This needs to be kept in sync with the top-level README.md in the
|
||||
* typescript-eslint monorepo
|
||||
@@ -111,6 +113,74 @@ function resetExtra(): void {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes, sanitizes, resolves and filters the provided
|
||||
*/
|
||||
function prepareAndTransformProjects(
|
||||
projectsInput: string | string[] | undefined,
|
||||
ignoreListInput: (string | RegExp)[] | undefined,
|
||||
): string[] {
|
||||
let projects: string[] = [];
|
||||
|
||||
// Normalize and sanitize the project paths
|
||||
if (typeof projectsInput === 'string') {
|
||||
projects.push(projectsInput);
|
||||
} else if (Array.isArray(projectsInput)) {
|
||||
for (const project of projectsInput) {
|
||||
if (typeof project === 'string') {
|
||||
projects.push(project);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (projects.length === 0) {
|
||||
return projects;
|
||||
}
|
||||
|
||||
// Transform glob patterns into paths
|
||||
projects = projects.reduce<string[]>(
|
||||
(projects, project) =>
|
||||
projects.concat(
|
||||
isGlob(project)
|
||||
? globSync(project, {
|
||||
cwd: extra.tsconfigRootDir,
|
||||
})
|
||||
: project,
|
||||
),
|
||||
[],
|
||||
);
|
||||
|
||||
// Normalize and sanitize the ignore regex list
|
||||
const ignoreRegexes: RegExp[] = [];
|
||||
if (Array.isArray(ignoreListInput)) {
|
||||
for (const ignore of ignoreListInput) {
|
||||
if (ignore instanceof RegExp) {
|
||||
ignoreRegexes.push(ignore);
|
||||
} else if (typeof ignore === 'string') {
|
||||
ignoreRegexes.push(new RegExp(ignore));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ignoreRegexes.push(/\/node_modules\//);
|
||||
}
|
||||
|
||||
// Remove any paths that match the ignore list
|
||||
const filtered = projects.filter(project => {
|
||||
for (const ignore of ignoreRegexes) {
|
||||
if (ignore.test(project)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
log('parserOptions.project matched projects: %s', projects);
|
||||
log('ignore list applied to parserOptions.project: %s', filtered);
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
function applyParserOptionsToExtra(options: TSESTreeOptions): void {
|
||||
/**
|
||||
* Configure Debug logging
|
||||
@@ -205,34 +275,18 @@ function applyParserOptionsToExtra(options: TSESTreeOptions): void {
|
||||
extra.log = Function.prototype;
|
||||
}
|
||||
|
||||
if (typeof options.project === 'string') {
|
||||
extra.projects = [options.project];
|
||||
} else if (
|
||||
Array.isArray(options.project) &&
|
||||
options.project.every(projectPath => typeof projectPath === 'string')
|
||||
) {
|
||||
extra.projects = options.project;
|
||||
}
|
||||
|
||||
if (typeof options.tsconfigRootDir === 'string') {
|
||||
extra.tsconfigRootDir = options.tsconfigRootDir;
|
||||
}
|
||||
|
||||
// NOTE - ensureAbsolutePath relies upon having the correct tsconfigRootDir in extra
|
||||
extra.filePath = ensureAbsolutePath(extra.filePath, extra);
|
||||
|
||||
// Transform glob patterns into paths
|
||||
if (extra.projects) {
|
||||
extra.projects = extra.projects.reduce<string[]>(
|
||||
(projects, project) =>
|
||||
projects.concat(
|
||||
isGlob(project)
|
||||
? globSync(project, {
|
||||
cwd: extra.tsconfigRootDir || process.cwd(),
|
||||
})
|
||||
: project,
|
||||
),
|
||||
[],
|
||||
);
|
||||
}
|
||||
// NOTE - prepareAndTransformProjects relies upon having the correct tsconfigRootDir in extra
|
||||
extra.projects = prepareAndTransformProjects(
|
||||
options.project,
|
||||
options.projectFolderIgnoreList,
|
||||
);
|
||||
|
||||
if (
|
||||
Array.isArray(options.extraFileExtensions) &&
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
export const x = 1;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"include": ["./file.ts"]
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
export const x = 2;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"include": ["./file.ts"]
|
||||
}
|
||||
@@ -557,4 +557,49 @@ describe('parse()', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('projectFolderIgnoreList', () => {
|
||||
beforeEach(() => {
|
||||
parser.clearCaches();
|
||||
});
|
||||
|
||||
const PROJECT_DIR = resolve(FIXTURES_DIR, '../projectFolderIgnoreList');
|
||||
const code = 'var a = true';
|
||||
const config: TSESTreeOptions = {
|
||||
comment: true,
|
||||
tokens: true,
|
||||
range: true,
|
||||
loc: true,
|
||||
tsconfigRootDir: PROJECT_DIR,
|
||||
project: './**/tsconfig.json',
|
||||
};
|
||||
|
||||
const testParse = (
|
||||
filePath: 'ignoreme' | 'includeme',
|
||||
projectFolderIgnoreList: TSESTreeOptions['projectFolderIgnoreList'] = [],
|
||||
) => (): void => {
|
||||
parser.parseAndGenerateServices(code, {
|
||||
...config,
|
||||
projectFolderIgnoreList,
|
||||
filePath: join(PROJECT_DIR, filePath, './file.ts'),
|
||||
});
|
||||
};
|
||||
|
||||
it('ignores nothing when given nothing', () => {
|
||||
expect(testParse('ignoreme')).not.toThrow();
|
||||
expect(testParse('includeme')).not.toThrow();
|
||||
});
|
||||
|
||||
it('ignores a folder when given a string regexp', () => {
|
||||
const ignore = ['/ignoreme/'];
|
||||
expect(testParse('ignoreme', ignore)).toThrow();
|
||||
expect(testParse('includeme', ignore)).not.toThrow();
|
||||
});
|
||||
|
||||
it('ignores a folder when given a RegExp', () => {
|
||||
const ignore = [/\/ignoreme\//];
|
||||
expect(testParse('ignoreme', ignore)).toThrow();
|
||||
expect(testParse('includeme', ignore)).not.toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"extends": "./tsconfig.base.json",
|
||||
"include": ["tests/**/*.ts", "tools/**/*.ts"]
|
||||
"include": ["tests/**/*.ts", "tools/**/*.ts", ".eslintrc.js"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user