Skip to content
This repository was archived by the owner on Jan 19, 2019. It is now read-only.

Commit d26fec4

Browse files
authored
New: Automatically generate TS-specific nodes (#40)
* New: Automatically generate TS-specific nodes (fixes #41) * Fix no use before define, changed typescript src files to .ts for better development experience (#42)
1 parent 46b9c87 commit d26fec4

File tree

7 files changed

+844
-11
lines changed

7 files changed

+844
-11
lines changed

README.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# TypeScript ESLint Parser (Experimental)
22

3-
An parser that converts TypeScript into an [ESTree](https://github.com/estree/estree)-compatible form so it can be used in ESLint.
3+
A parser that converts TypeScript into an [ESTree](https://github.com/estree/estree)-compatible form so it can be used in ESLint. The goal is to allow TypeScript files to be parsed by ESLint (though not necessarily pass all ESLint rules).
44

55
**Important:** This parser is still in the very early stages and is considered experimental. There are likely a lot of bugs. You should not rely on this in a production environment yet.
66

@@ -22,23 +22,25 @@ And in your ESLint configuration file:
2222

2323
If you're familiar with TypeScript and ESLint, and you'd like to see this project progress, please consider contributing. We need people with a good knowledge of TypeScript to ensure this parser is useful.
2424

25+
## Reporting Bugs
26+
27+
**Do not** file bugs about ESLint rule failures. This is expected because ESLint doesn't know anything about TypeScript syntax. It's likely that many ESLint rules will have failures as a result. Longer-term, it's likely we'll need to create a custom set of ESLint rules that are TypeScript-specific.
28+
29+
Bugs should be filed for:
30+
31+
1. TypeScript syntax that fails to parse.
32+
1. TypeScript syntax that produces an unexpected AST.
33+
2534
## Contributing
2635

2736
Issues and pull requests will be triaged and responded to as quickly as possible. We operate under the [ESLint Contributor Guidelines](http://eslint.org/docs/developer-guide/contributing), so please be sure to read them before contributing. If you're not sure where to dig in, check out the [issues](https://github.com/eslint/typescript-eslint-parser/issues).
2837

29-
TypeScript ESLint Parser is licensed under a permissive BSD 2-clause license.
30-
3138
## Build Commands
3239

3340
* `npm test` - run all linting and tests
3441
* `npm run lint` - run all linting
3542

36-
## Development Plan
43+
## License
3744

38-
* **Phase 1:** Full ES6 support, stripping out all TypeScript-specific syntax.
39-
* **Phase 2:** Add JSX support.
40-
* **Phase 3:** Add support for attaching comments.
41-
* **Phase 4:** Add support for types.
42-
* **Phase 5:** Add support for top-level TypeScript syntax.
45+
TypeScript ESLint Parser is licensed under a permissive BSD 2-clause license.
4346

44-
The high-level goal is to have output that matches Espree v3.x.

lib/ast-converter.js

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,47 @@ module.exports = function(ast, extra) {
431431
return convert(child, node);
432432
}
433433

434+
/**
435+
* Converts a child into a type annotation. This creates an intermediary
436+
* TypeAnnotation node to match what Flow does.
437+
* @param {TSNode} child The TypeScript AST node to convert.
438+
* @returns {ESTreeNode} The type annotation node.
439+
*/
440+
function convertTypeAnnotation(child) {
441+
var annotation = convertChild(child);
442+
return {
443+
type: "TypeAnnotation",
444+
loc: annotation.loc,
445+
range: annotation.range,
446+
typeAnnotation: annotation
447+
};
448+
}
449+
450+
/**
451+
* For nodes that are copied directly from the TypeScript AST into
452+
* ESTree mostly as-is. The only difference is the addition of a type
453+
* property instead of a kind property. Recursively copies all children.
454+
* @returns {void}
455+
*/
456+
function deeplyCopy() {
457+
result.type = "TS" + SyntaxKind[node.kind];
458+
Object.keys(node).filter(function(key) {
459+
return !(/^(?:kind|parent|pos|end)$/.test(key));
460+
}).forEach(function(key) {
461+
if (key === "type") {
462+
result.typeAnnotation = convertTypeAnnotation(node.type);
463+
} else {
464+
if (Array.isArray(node[key])) {
465+
result[key] = node[key].map(convertChild);
466+
} else if (node[key] && typeof node[key] === "object") {
467+
result[key] = convertChild(node[key]);
468+
} else {
469+
result[key] = node[key];
470+
}
471+
}
472+
});
473+
}
474+
434475
/**
435476
* Converts a TypeScript JSX node.tagName into an ESTree node.name
436477
* @param {Object} tagName the tagName object from a JSX TSNode
@@ -636,6 +677,10 @@ module.exports = function(ast, extra) {
636677
body: convertChild(node.body)
637678
});
638679

680+
if (node.type) {
681+
result.returnType = convertTypeAnnotation(node.type);
682+
}
683+
639684
// check for exports
640685
result = fixExports(node, result, ast);
641686

@@ -647,6 +692,10 @@ module.exports = function(ast, extra) {
647692
id: convertChild(node.name),
648693
init: convertChild(node.initializer)
649694
});
695+
696+
if (node.type) {
697+
result.id.typeAnnotation = convertTypeAnnotation(node.type);
698+
}
650699
break;
651700

652701
case SyntaxKind.VariableStatement:
@@ -821,6 +870,10 @@ module.exports = function(ast, extra) {
821870
}
822871
};
823872

873+
if (node.type) {
874+
method.returnType = convertTypeAnnotation(node.type);
875+
}
876+
824877
if (parent.kind === SyntaxKind.ObjectLiteralExpression) {
825878
assign(result, {
826879
type: "Property",
@@ -936,6 +989,10 @@ module.exports = function(ast, extra) {
936989
body: convertChild(node.body),
937990
expression: false
938991
});
992+
993+
if (node.type) {
994+
result.returnType = convertTypeAnnotation(node.type);
995+
}
939996
break;
940997

941998
case SyntaxKind.SuperKeyword:
@@ -1010,6 +1067,11 @@ module.exports = function(ast, extra) {
10101067
body: convertChild(node.body),
10111068
expression: node.body.kind !== SyntaxKind.Block
10121069
});
1070+
1071+
if (node.type) {
1072+
result.returnType = convertTypeAnnotation(node.type);
1073+
}
1074+
10131075
break;
10141076

10151077
case SyntaxKind.YieldExpression:
@@ -1533,7 +1595,7 @@ module.exports = function(ast, extra) {
15331595
return convert(node.expression, parent);
15341596

15351597
default:
1536-
result = null;
1598+
deeplyCopy();
15371599
}
15381600

15391601
return result;

0 commit comments

Comments
 (0)