Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: create TSTypeQuery node when TSImportType has isTypeOf#3076

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
JoshuaKGoldberg merged 6 commits intov6fromfeat/ts-import-type
Oct 26, 2022
Merged
Show file tree
Hide file tree
Changes fromall 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
27 changes: 27 additions & 0 deletionsdocs/linting/typed-linting/MONOREPOS.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -62,6 +62,33 @@ module.exports = {
};
```

### Wide globs in `parserOptions.project`

Using wide globs `**` in your `parserOptions.project` may degrade linting performance.
Instead of globs that use `**` to recursively check all folders, prefer paths that use a single `*` at a time.

```js title=".eslintrc.js"
module.exports = {
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
],
parser: '@typescript-eslint/parser',
parserOptions: {
tsconfigRootDir: __dirname,
// Remove this line
project: ['./tsconfig.eslint.json', './**/tsconfig.json'],
// Add this line
project: ['./tsconfig.eslint.json', './packages/*/tsconfig.json'],
},
plugins: ['@typescript-eslint'],
root: true,
};
```

See [Glob pattern in parser's option "project" slows down linting](https://github.com/typescript-eslint/typescript-eslint/issues/2611) for more details.

### Important note regarding large (> 10) multi-package monorepos

We've had reports that for sufficiently large and/or interdependent projects, you may run into OOMs using this approach.
Expand Down
3 changes: 1 addition & 2 deletionspackages/ast-spec/src/type/TSImportType/spec.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,8 +6,7 @@ import type { TypeNode } from '../../unions/TypeNode';

export interface TSImportType extends BaseNode {
type: AST_NODE_TYPES.TSImportType;
isTypeOf: boolean;
parameter: TypeNode;
argument: TypeNode;
qualifier: EntityName | null;
typeParameters: TSTypeParameterInstantiation | null;
}
3 changes: 2 additions & 1 deletionpackages/ast-spec/src/type/TSTypeQuery/spec.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,9 +2,10 @@ import type { AST_NODE_TYPES } from '../../ast-node-types';
import type { BaseNode } from '../../base/BaseNode';
import type { TSTypeParameterInstantiation } from '../../special/spec';
import type { EntityName } from '../../unions/EntityName';
import type { TSImportType } from '../TSImportType/spec';

export interface TSTypeQuery extends BaseNode {
type: AST_NODE_TYPES.TSTypeQuery;
exprName: EntityName;
exprName: EntityName | TSImportType;
typeParameters?: TSTypeParameterInstantiation;
}
2 changes: 2 additions & 0 deletionspackages/parser/README.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -164,6 +164,8 @@ This option allows you to provide a path to your project's `tsconfig.json`. **Th

- If you use project references, TypeScript will not automatically use project references to resolve files. This means that you will have to add each referenced tsconfig to the `project` field either separately, or via a glob.

- Note that using wide globs `**` in your `parserOptions.project` may cause performance implications. Instead of globs that use `**` to recursively check all folders, prefer paths that use a single `*` at a time. For more info see [#2611](https://github.com/typescript-eslint/typescript-eslint/issues/2611).

- TypeScript will ignore files with duplicate filenames in the same folder (for example, `src/file.ts` and `src/file.js`). TypeScript purposely ignore all but one of the files, only keeping the one file with the highest priority extension (the extension priority order (from highest to lowest) is `.ts`, `.tsx`, `.d.ts`, `.js`, `.jsx`). For more info see #955.

- Note that if this setting is specified and `createDefaultProgram` is not, you must only lint files that are included in the projects as defined by the provided `tsconfig.json` files. If your existing configuration does not include all of the files you would like to lint, you can create a separate `tsconfig.eslint.json` as follows:
Expand Down
9 changes: 8 additions & 1 deletionpackages/scope-manager/src/referencer/TypeVisitor.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -260,7 +260,10 @@ class TypeVisitor extends Visitor {

// a type query `typeof foo` is a special case that references a _non-type_ variable,
protected TSTypeQuery(node: TSESTree.TSTypeQuery): void {
let entityName: TSESTree.Identifier | TSESTree.ThisExpression;
let entityName:
| TSESTree.Identifier
| TSESTree.ThisExpression
| TSESTree.TSImportType;
if (node.exprName.type === AST_NODE_TYPES.TSQualifiedName) {
let iter = node.exprName;
while (iter.left.type === AST_NODE_TYPES.TSQualifiedName) {
Expand All@@ -269,6 +272,10 @@ class TypeVisitor extends Visitor {
entityName = iter.left;
} else {
entityName = node.exprName;

if (node.exprName.type === AST_NODE_TYPES.TSImportType) {
this.visit(node.exprName);
}
}
if (entityName.type === AST_NODE_TYPES.Identifier) {
this.#referencer.currentScope().referenceValue(entityName);
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
type A = typeof import('A');
type B = import("B").X<Y>;
type B = import('B').X<Y>;
18 changes: 9 additions & 9 deletionspackages/typescript-estree/src/ast-converter.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,13 +4,13 @@ import type { ASTMaps } from './convert';
import { Converter, convertError } from './convert';
import { convertComments } from './convert-comments';
import { convertTokens } from './node-utils';
import type {Extra } from './parser-options';
import type {ParseSettings } from './parseSettings';
import { simpleTraverse } from './simple-traverse';
import type { TSESTree } from './ts-estree';

export function astConverter(
ast: SourceFile,
extra: Extra,
parseSettings: ParseSettings,
shouldPreserveNodeMaps: boolean,
): { estree: TSESTree.Program; astMaps: ASTMaps } {
/**
Expand All@@ -26,7 +26,7 @@ export function astConverter(
* Recursively convert the TypeScript AST into an ESTree-compatible AST
*/
const instance = new Converter(ast, {
errorOnUnknownASTType:extra.errorOnUnknownASTType || false,
errorOnUnknownASTType:parseSettings.errorOnUnknownASTType || false,
shouldPreserveNodeMaps,
});

Expand All@@ -35,15 +35,15 @@ export function astConverter(
/**
* Optionally remove range and loc if specified
*/
if (!extra.range || !extra.loc) {
if (!parseSettings.range || !parseSettings.loc) {
simpleTraverse(estree, {
enter: node => {
if (!extra.range) {
if (!parseSettings.range) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TS 4.0 made this an error because the types aren't optional
// @ts-expect-error
delete node.range;
}
if (!extra.loc) {
if (!parseSettings.loc) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TS 4.0 made this an error because the types aren't optional
// @ts-expect-error
delete node.loc;
Expand All@@ -55,15 +55,15 @@ export function astConverter(
/**
* Optionally convert and include all tokens in the AST
*/
if (extra.tokens) {
if (parseSettings.tokens) {
estree.tokens = convertTokens(ast);
}

/**
* Optionally convert and include all comments in the AST
*/
if (extra.comment) {
estree.comments = convertComments(ast,extra.code);
if (parseSettings.comment) {
estree.comments = convertComments(ast,parseSettings.code);
}

const astMaps = instance.getASTMaps();
Expand Down
21 changes: 17 additions & 4 deletionspackages/typescript-estree/src/convert.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2730,19 +2730,32 @@ export class Converter {
return result;
}

case SyntaxKind.ImportType:
return this.createNode<TSESTree.TSImportType>(node, {
case SyntaxKind.ImportType: {
const range = getRange(node, this.ast);
if (node.isTypeOf) {
const token = findNextToken(node.getFirstToken()!, node, this.ast)!;
range[0] = token.getStart(this.ast);
}
const result = this.createNode<TSESTree.TSImportType>(node, {
type: AST_NODE_TYPES.TSImportType,
isTypeOf: !!node.isTypeOf,
parameter: this.convertChild(node.argument),
argument: this.convertChild(node.argument),
Comment on lines -2737 to +2741
Copy link
CollaboratorAuthor

@armano2armano2Feb 19, 2021
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

i renamed this property from parameter to argument as is more aligned with typescript/babel and rest of types

eg, call expression hasarguments

JoshuaKGoldberg reacted with thumbs up emoji
qualifier: this.convertChild(node.qualifier),
typeParameters: node.typeArguments
? this.convertTypeArgumentsToTypeParameters(
node.typeArguments,
node,
)
: null,
range: range,
});
if (node.isTypeOf) {
return this.createNode<TSESTree.TSTypeQuery>(node, {
type: AST_NODE_TYPES.TSTypeQuery,
exprName: result,
});
}
return result;
}

case SyntaxKind.EnumDeclaration: {
const result = this.createNode<TSESTree.TSEnumDeclaration>(node, {
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,8 +2,8 @@ import debug from 'debug';
import path from 'path';
import * as ts from 'typescript';

import type {Extra } from '../parser-options';
import type { ASTAndProgram, CanonicalPath } from './shared';
import type {ParseSettings } from '../parseSettings';
import type { ASTAndProgram } from './shared';
import {
createDefaultCompilerOptionsFromExtra,
getModuleResolver,
Expand All@@ -12,27 +12,26 @@ import {
const log = debug('typescript-eslint:typescript-estree:createDefaultProgram');

/**
* @param code The code of the file being linted
* @param extra The config object
* @param extra.tsconfigRootDir The root directory for relative tsconfig paths
* @param extra.projects Provided tsconfig paths
* @param parseSettings Internal settings for parsing the file
* @returns If found, returns the source file corresponding to the code and the containing program
*/
function createDefaultProgram(
code: string,
extra: Extra,
parseSettings: ParseSettings,
): ASTAndProgram | undefined {
log('Getting default program for: %s', extra.filePath || 'unnamed file');
log(
'Getting default program for: %s',
parseSettings.filePath || 'unnamed file',
);

if (!extra.projects || extra.projects.length !== 1) {
if (parseSettings.projects?.length !== 1) {
return undefined;
}

const tsconfigPath: CanonicalPath = extra.projects[0];
const tsconfigPath = parseSettings.projects[0];

const commandLine = ts.getParsedCommandLineOfConfigFile(
tsconfigPath,
createDefaultCompilerOptionsFromExtra(extra),
createDefaultCompilerOptionsFromExtra(parseSettings),
{ ...ts.sys, onUnRecoverableConfigFileDiagnostic: () => {} },
);

Expand All@@ -45,24 +44,24 @@ function createDefaultProgram(
/* setParentNodes */ true,
);

if (extra.moduleResolver) {
if (parseSettings.moduleResolver) {
compilerHost.resolveModuleNames = getModuleResolver(
extra.moduleResolver,
parseSettings.moduleResolver,
).resolveModuleNames;
}

const oldReadFile = compilerHost.readFile;
compilerHost.readFile = (fileName: string): string | undefined =>
path.normalize(fileName) === path.normalize(extra.filePath)
? code
path.normalize(fileName) === path.normalize(parseSettings.filePath)
?parseSettings.code
: oldReadFile(fileName);

const program = ts.createProgram(
[extra.filePath],
[parseSettings.filePath],
commandLine.options,
compilerHost,
);
const ast = program.getSourceFile(extra.filePath);
const ast = program.getSourceFile(parseSettings.filePath);

return ast && { ast, program };
}
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
import debug from 'debug';
import * as ts from 'typescript';

import type {Extra } from '../parser-options';
import type {ParseSettings } from '../parseSettings';
import { getScriptKind } from './getScriptKind';
import type { ASTAndProgram } from './shared';
import { createDefaultCompilerOptionsFromExtra } from './shared';
Expand All@@ -12,19 +12,19 @@ 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 {
function createIsolatedProgram(parseSettings: ParseSettings): ASTAndProgram {
log(
'Getting isolated program in %s mode for: %s',
extra.jsx ? 'TSX' : 'TS',
extra.filePath,
parseSettings.jsx ? 'TSX' : 'TS',
parseSettings.filePath,
);

const compilerHost: ts.CompilerHost = {
fileExists() {
return true;
},
getCanonicalFileName() {
returnextra.filePath;
returnparseSettings.filePath;
},
getCurrentDirectory() {
return '';
Expand All@@ -43,10 +43,10 @@ function createIsolatedProgram(code: string, extra: Extra): ASTAndProgram {
getSourceFile(filename: string) {
return ts.createSourceFile(
filename,
code,
parseSettings.code,
ts.ScriptTarget.Latest,
/* setParentNodes */ true,
getScriptKind(extra.filePath,extra.jsx),
getScriptKind(parseSettings.filePath,parseSettings.jsx),
);
},
readFile() {
Expand All@@ -61,17 +61,17 @@ function createIsolatedProgram(code: string, extra: Extra): ASTAndProgram {
};

const program = ts.createProgram(
[extra.filePath],
[parseSettings.filePath],
{
noResolve: true,
target: ts.ScriptTarget.Latest,
jsx:extra.jsx ? ts.JsxEmit.Preserve : undefined,
...createDefaultCompilerOptionsFromExtra(extra),
jsx:parseSettings.jsx ? ts.JsxEmit.Preserve : undefined,
...createDefaultCompilerOptionsFromExtra(parseSettings),
},
compilerHost,
);

const ast = program.getSourceFile(extra.filePath);
const ast = program.getSourceFile(parseSettings.filePath);
if (!ast) {
throw new Error(
'Expected an ast to be returned for the single-file isolated program.',
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp