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(parser): support ecmaFeatures.jsx flag and tests#85

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
JamesHenry merged 3 commits intotypescript-eslint:masterfromarmano2:parser-options
Jan 20, 2019
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
6 changes: 4 additions & 2 deletionspackages/parser/README.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,7 +32,7 @@ By far the most common case will be installing the [@typescript-eslint/eslint-pl

The following additional configuration options are available by specifying them in [`parserOptions`](https://eslint.org/docs/user-guide/configuring#specifying-parser-options) in your ESLint configuration file.

- **`jsx`** - default `false`. Enable parsing JSX when `true`. More details can be found [here](https://www.typescriptlang.org/docs/handbook/jsx.html).
- **`ecmaFeatures.jsx`** - default `false`. Enable parsing JSX when `true`. More details can be found [here](https://www.typescriptlang.org/docs/handbook/jsx.html).

- It's `false` on `*.ts` files regardless of this option.
- It's `true` on `*.tsx` files regardless of this option.
Expand All@@ -46,7 +46,9 @@ The following additional configuration options are available by specifying them
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"jsx": true,
"ecmaFeatures": {
"jsx": true
},
"useJSXTextNode": true
}
}
Expand Down
23 changes: 13 additions & 10 deletionspackages/parser/src/parser-options.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
export interface ParserOptions {
useJSXTextNode?: boolean;
loc?: true;
range?: true;
tokens?: true;
filePath?: string;
loc?: boolean;
comment?: boolean;
range?: boolean;
tokens?: boolean;
sourceType?: 'script' | 'module';
ecmaVersion?: number;
ecmaFeatures?: {
globalReturn?: boolean;
jsx?: boolean;
};
/**
* @deprecated We should finalize the work from
* https://github.com/eslint/typescript-eslint-parser#595
*/
jsx?: boolean;
// ts-estree specific
filePath?: string;
project?: string | string[];
useJSXTextNode?: boolean;
errorOnUnknownASTType?: boolean;
errorOnTypeScriptSyntacticAndSemanticIssues?: boolean;
tsconfigRootDir?: string;
extraFileExtensions?: string[];
}
69 changes: 44 additions & 25 deletionspackages/parser/src/parser.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
import traverser from 'eslint/lib/util/traverser';
import * as typescriptESTree from '@typescript-eslint/typescript-estree';
import {
AST_NODE_TYPES,
parseAndGenerateServices,
ParserOptions as ParserOptionsTsESTree
} from '@typescript-eslint/typescript-estree';
import { analyzeScope } from './analyze-scope';
import { ParserOptions } from './parser-options';
import { visitorKeys } from './visitor-keys';
Expand All@@ -20,52 +24,67 @@ interface ParseForESLintResult {
scopeManager: ReturnType<typeof analyzeScope>;
}

function validateBoolean(
value: boolean | undefined,
fallback: boolean = false
): boolean {
if (typeof value !== 'boolean') {
return fallback;
}
return value;
}

//------------------------------------------------------------------------------
// Public
//------------------------------------------------------------------------------

export const version = packageJSON.version;

export const Syntax = Object.freeze(AST_NODE_TYPES);

export function parse(code: string, options?: ParserOptions) {
return parseForESLint(code, options).ast;
}

export const Syntax = Object.freeze(typescriptESTree.AST_NODE_TYPES);

export function parseForESLint<T extends ParserOptions = ParserOptions>(
export function parseForESLint(
code: string,
options?:T | null
options?:ParserOptions | null
): ParseForESLintResult {
if (typeof options !== 'object' || options === null) {
options = { useJSXTextNode: true } as T;
} else if (typeof options.useJSXTextNode !== 'boolean') {
options = Object.assign({}, options, { useJSXTextNode: true });
}
if (typeof options.filePath === 'string') {
const tsx = options.filePath.endsWith('.tsx');
if (tsx || options.filePath.endsWith('.ts')) {
options = Object.assign({}, options, { jsx: tsx });
}
if (!options || typeof options !== 'object') {
options = {};
}

// https://eslint.org/docs/user-guide/configuring#specifying-parser-options
// if sourceType is not provided by default eslint expect that it will be set to "script"
options.sourceType = options.sourceType || 'script';
if (options.sourceType !== 'module' && options.sourceType !== 'script') {
options.sourceType = 'script';
}
if (typeof options.ecmaFeatures !== 'object') {
options.ecmaFeatures = {};
}

const parserOptions: ParserOptionsTsESTree = {};
Object.assign(parserOptions, options, {
useJSXTextNode: validateBoolean(options.useJSXTextNode, true),
jsx: validateBoolean(options.ecmaFeatures.jsx)
});

if (typeof options.filePath === 'string') {
const tsx = options.filePath.endsWith('.tsx');
if (tsx || options.filePath.endsWith('.ts')) {
parserOptions.jsx = tsx;
}
}

const { ast, services } = typescriptESTree.parseAndGenerateServices(
code,
options
);
const { ast, services } = parseAndGenerateServices(code, parserOptions);
ast.sourceType = options.sourceType;

traverser.traverse(ast, {
enter:(node: any) => {
enter(node: any) {
switch (node.type) {
// Function#body cannot be null in ESTree spec.
case 'FunctionExpression':
if (!node.body) {
node.type = `TSEmptyBody${
node.type
}` as typescriptESTree.AST_NODE_TYPES;
node.type = `TSEmptyBody${node.type}` as AST_NODE_TYPES;
}
break;
// no default
Expand Down
6 changes: 4 additions & 2 deletionspackages/parser/tests/lib/comments.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,8 +15,10 @@ describe('Comments', () => {
testFiles.forEach(filename => {
const code = fs.readFileSync(filename, 'utf8');
const config: ParserOptions = {
jsx: true,
sourceType: 'module'
sourceType: 'module',
ecmaFeatures: {
jsx: true
}
};
it(
testUtils.formatSnapshotName(filename, FIXTURES_DIR),
Expand Down
4 changes: 3 additions & 1 deletionpackages/parser/tests/lib/jsx.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,7 +28,9 @@ describe('JSX', () => {
const code = fs.readFileSync(filename, 'utf8');
const config = {
useJSXTextNode,
jsx: true
ecmaFeatures: {
jsx: true
}
};
it(
testUtils.formatSnapshotName(filename, fixturesDir),
Expand Down
54 changes: 54 additions & 0 deletionspackages/parser/tests/lib/parser.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
import * as typescriptESTree from '@typescript-eslint/typescript-estree';
import { parse, parseForESLint, Syntax } from '../../src/parser';
import * as scope from '../../src/analyze-scope';

describe('parser', () => {
it('parse() should return just the AST from parseForESLint()', () => {
Expand All@@ -15,11 +16,64 @@ describe('parser', () => {
it('parseForESLint() should set the sourceType to script, if an invalid one is provided', () => {
const code = 'const valid = true;';
const spy = jest.spyOn(typescriptESTree, 'parseAndGenerateServices');
const spyScope = jest.spyOn(scope, 'analyzeScope');
parseForESLint(code, { sourceType: 'foo' as any });
expect(spy).toHaveBeenCalledWith(code, {
ecmaFeatures: {},
jsx: false,
sourceType: 'script',
useJSXTextNode: true
});
expect(spyScope).toHaveBeenCalledWith(jasmine.any(Object), {
ecmaFeatures: {},
sourceType: 'script'
});
});

it('parseAndGenerateServices() should be called with options', () => {
const code = 'const valid = true;';
const spy = jest.spyOn(typescriptESTree, 'parseAndGenerateServices');
parseForESLint(code, {
loc: false,
comment: false,
range: false,
tokens: false,
sourceType: 'module',
ecmaVersion: 10,
ecmaFeatures: {
globalReturn: false,
jsx: false
},
// ts-estree specific
filePath: 'test/foo',
project: 'tsconfig.json',
useJSXTextNode: false,
errorOnUnknownASTType: false,
errorOnTypeScriptSyntacticAndSemanticIssues: false,
tsconfigRootDir: '../../',
extraFileExtensions: ['foo']
});
expect(spy).toHaveBeenCalledWith(code, {
jsx: false,
loc: false,
comment: false,
range: false,
tokens: false,
sourceType: 'module',
ecmaVersion: 10,
ecmaFeatures: {
globalReturn: false,
jsx: false
},
// ts-estree specific
filePath: 'test/foo',
project: 'tsconfig.json',
useJSXTextNode: false,
errorOnUnknownASTType: false,
errorOnTypeScriptSyntacticAndSemanticIssues: false,
tsconfigRootDir: '../../',
extraFileExtensions: ['foo']
});
});

it('Syntax should contain a frozen object of typescriptESTree.AST_NODE_TYPES', () => {
Expand Down
16 changes: 12 additions & 4 deletionspackages/parser/tests/lib/tsx.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,9 @@ describe('TSX', () => {
const code = fs.readFileSync(filename, 'utf8');
const config = {
useJSXTextNode: true,
jsx: true
ecmaFeatures: {
jsx: true
}
};
it(
testUtils.formatSnapshotName(filename, FIXTURES_DIR, '.tsx'),
Expand DownExpand Up@@ -53,7 +55,9 @@ describe('TSX', () => {
const config = {
parser: '@typescript-eslint/parser',
parserOptions: {
jsx: true
ecmaFeatures: {
jsx: true
}
}
};
const messages = linter.verify(code, config);
Expand DownExpand Up@@ -85,7 +89,9 @@ describe('TSX', () => {
const config = {
parser: '@typescript-eslint/parser',
parserOptions: {
jsx: true
ecmaFeatures: {
jsx: true
}
}
};
const messages = linter.verify(code, config, { filename: 'test.ts' });
Expand DownExpand Up@@ -117,7 +123,9 @@ describe('TSX', () => {
const config = {
parser: '@typescript-eslint/parser',
parserOptions: {
jsx: false
ecmaFeatures: {
jsx: false
}
}
};
const messages = linter.verify(code, config, { filename: 'test.tsx' });
Expand Down
8 changes: 4 additions & 4 deletionspackages/typescript-estree/src/parser.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -350,10 +350,7 @@ function generateAST<T extends ParserOptions = ParserOptions>(
// Public
//------------------------------------------------------------------------------

export { AST_NODE_TYPES } from './ast-node-types';
export { version };

const version = packageJSON.version;
export const version: string = packageJSON.version;

export function parse<T extends ParserOptions = ParserOptions>(
code: string,
Expand All@@ -378,3 +375,6 @@ export function parseAndGenerateServices(code: string, options: ParserOptions) {
}
};
}

export { AST_NODE_TYPES } from './ast-node-types';
export { ParserOptions };

[8]ページ先頭

©2009-2025 Movatter.jp