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

Breaking: typescript-estree to 18.0.0 and typescript to 3.2.1 #596

Merged
merged 18 commits into from
Jan 12, 2019
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ _test.js
.vscode
yarn.lock
.eslint-release-info.json
.idea
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ The following additional configuration options are available by specifying them

We will always endeavor to support the latest stable version of TypeScript.

The version of TypeScript currently supported by this parser is `~3.1.1`. This is reflected in the `devDependency` requirement within the package.json file, and it is what the tests will be run against. We have an open `peerDependency` requirement in order to allow for experimentation on newer/beta versions of TypeScript.
The version of TypeScript currently supported by this parser is `~3.2.1`. This is reflected in the `devDependency` requirement within the package.json file, and it is what the tests will be run against. We have an open `peerDependency` requirement in order to allow for experimentation on newer/beta versions of TypeScript.

If you use a non-supported version of TypeScript, the parser will log a warning to the console.

Expand Down
258 changes: 203 additions & 55 deletions analyze-scope.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ class PatternVisitor extends OriginalPatternVisitor {
this.rightHandNodes.push(node.typeAnnotation);
}
}

RestElement(node) {
super.RestElement(node);
if (node.typeAnnotation) {
this.rightHandNodes.push(node.typeAnnotation);
}
}
}

class Referencer extends OriginalReferencer {
Expand Down Expand Up @@ -120,7 +127,7 @@ class Referencer extends OriginalReferencer {
const { defs, identifiers } = upperScope.set.get(id.name);
for (let i = 0; i < defs.length; ++i) {
const def = defs[i];
if (def.type === "FunctionName" && def.node.type === "TSEmptyBodyFunctionDeclaration") {
if (def.type === "FunctionName" && def.node.type === "TSDeclareFunction") {
defs.splice(i, 1);
identifiers.splice(i, 1);
break;
Expand Down Expand Up @@ -239,28 +246,9 @@ class Referencer extends OriginalReferencer {
super.MethodDefinition(node);
}

/**
* Override.
* Don't make variable if `kind === "type"`.
* It doesn't declare variables but declare types.
* @param {VariableDeclaration} node The VariableDeclaration node to visit.
* @returns {void}
*/
VariableDeclaration(node) {
if (node.kind !== "type") {
super.VariableDeclaration(node);
return;
}

// To detect typeof.
this.typeMode = true;
this.visitChildren(node);
this.typeMode = false;
}

/**
* Don't create the reference object for the key if not computed.
* @param {TSEmptyBodyFunctionDeclaration} node The TSEmptyBodyFunctionDeclaration node to visit.
* @param {ClassProperty} node The ClassProperty node to visit.
* @returns {void}
*/
ClassProperty(node) {
Expand Down Expand Up @@ -311,23 +299,25 @@ class Referencer extends OriginalReferencer {
/**
* Define the variable of this function declaration only once.
* Because to avoid confusion of `no-redeclare` rule by overloading.
* @param {TSEmptyBodyFunctionDeclaration} node The TSEmptyBodyFunctionDeclaration node to visit.
* @param {TSDeclareFunction} node The TSDeclareFunction node to visit.
* @returns {void}
*/
TSEmptyBodyFunctionDeclaration(node) {
TSDeclareFunction(node) {
const upperTypeMode = this.typeMode;
const scope = this.currentScope();
const { id, typeParameters, params, returnType } = node;

// Ignore this if other overloadings have already existed.
const variable = scope.set.get(id.name);
const defs = variable && variable.defs;
const existed = defs && defs.some(d => d.type === "FunctionName");
if (!existed) {
scope.__define(
id,
new Definition("FunctionName", id, node, null, null, null)
);
if (id) {
const variable = scope.set.get(id.name);
const defs = variable && variable.defs;
const existed = defs && defs.some(d => d.type === "FunctionName");
if (!existed) {
scope.__define(
id,
new Definition("FunctionName", id, node, null, null, null)
);
}
}

// Find `typeof` expressions.
Expand All @@ -337,9 +327,6 @@ class Referencer extends OriginalReferencer {
this.visit(returnType);
this.typeMode = upperTypeMode;
}
TSEmptyBodyDeclareFunction(node) {
this.TSEmptyBodyFunctionDeclaration(node);
}

/**
* Create reference objects for the references in parameters and return type.
Expand All @@ -364,43 +351,79 @@ class Referencer extends OriginalReferencer {
* @returns {void}
*/
TSInterfaceDeclaration(node) {
this.visitTypeNodes(node);
}

/**
* Don't make variable because it declares only types.
* Switch to the type mode and visit child nodes to find `typeof x` expression in type declarations.
* @param {TSClassImplements} node The TSClassImplements node to visit.
* @returns {void}
*/
TSClassImplements(node) {
this.visitTypeNodes(node);
}

/**
* Don't make variable because it declares only types.
* Switch to the type mode and visit child nodes to find `typeof x` expression in type declarations.
* @param {TSIndexSignature} node The TSIndexSignature node to visit.
* @returns {void}
*/
TSIndexSignature(node) {
this.visitTypeNodes(node);
}

/**
* Visit type assertion.
* @param {TSTypeAssertion} node The TSTypeAssertion node to visit.
* @returns {void}
*/
TSTypeAssertion(node) {
if (this.typeMode) {
this.visitChildren(node);
this.visit(node.typeAnnotation);
} else {
this.typeMode = true;
this.visitChildren(node);
this.visit(node.typeAnnotation);
this.typeMode = false;
}

this.visit(node.expression);
}

/**
* Switch to the type mode and visit child nodes to find `typeof x` expression in type declarations.
* @param {TSTypeAnnotation} node The TSTypeAnnotation node to visit.
* Visit as expression.
* @param {TSAsExpression} node The TSAsExpression node to visit.
* @returns {void}
*/
TSTypeAnnotation(node) {
TSAsExpression(node) {
this.visit(node.expression);

if (this.typeMode) {
this.visitChildren(node);
this.visit(node.typeAnnotation);
} else {
this.typeMode = true;
this.visitChildren(node);
this.visit(node.typeAnnotation);
this.typeMode = false;
}
}

/**
* Switch to the type mode and visit child nodes to find `typeof x` expression in type declarations.
* @param {TSTypeAnnotation} node The TSTypeAnnotation node to visit.
* @returns {void}
*/
TSTypeAnnotation(node) {
this.visitTypeNodes(node);
}

/**
* Switch to the type mode and visit child nodes to find `typeof x` expression in type declarations.
* @param {TSTypeParameterDeclaration} node The TSTypeParameterDeclaration node to visit.
* @returns {void}
*/
TSTypeParameterDeclaration(node) {
if (this.typeMode) {
this.visitChildren(node);
} else {
this.typeMode = true;
this.visitChildren(node);
this.typeMode = false;
}
this.visitTypeNodes(node);
}

/**
Expand All @@ -418,9 +441,113 @@ class Referencer extends OriginalReferencer {
}
}

/**
* @param {TSTypeParameter} node The TSTypeParameter node to visit.
* @returns {void}
*/
TSTypeParameter(node) {
this.visitTypeNodes(node);
}

/**
* @param {TSInferType} node The TSInferType node to visit.
* @returns {void}
*/
TSInferType(node) {
this.visitTypeNodes(node);
}

/**
* @param {TSTypeReference} node The TSTypeReference node to visit.
* @returns {void}
*/
TSTypeReference(node) {
this.visitTypeNodes(node);
}

/**
* @param {TSTypeLiteral} node The TSTypeLiteral node to visit.
* @returns {void}
*/
TSTypeLiteral(node) {
this.visitTypeNodes(node);
}

/**
* @param {TSLiteralType} node The TSLiteralType node to visit.
* @returns {void}
*/
TSLiteralType(node) {
this.visitTypeNodes(node);
}

/**
* @param {TSIntersectionType} node The TSIntersectionType node to visit.
* @returns {void}
*/
TSIntersectionType(node) {
this.visitTypeNodes(node);
}

/**
* @param {TSConditionalType} node The TSConditionalType node to visit.
* @returns {void}
*/
TSConditionalType(node) {
this.visitTypeNodes(node);
}

/**
* @param {TSIndexedAccessType} node The TSIndexedAccessType node to visit.
* @returns {void}
*/
TSIndexedAccessType(node) {
this.visitTypeNodes(node);
}

/**
* @param {TSMappedType} node The TSMappedType node to visit.
* @returns {void}
*/
TSMappedType(node) {
this.visitTypeNodes(node);
}

/**
* @param {TSOptionalType} node The TSOptionalType node to visit.
* @returns {void}
*/
TSOptionalType(node) {
this.visitTypeNodes(node);
}

/**
* @param {TSParenthesizedType} node The TSParenthesizedType node to visit.
* @returns {void}
*/
TSParenthesizedType(node) {
this.visitTypeNodes(node);
}

/**
* @param {TSRestType} node The TSRestType node to visit.
* @returns {void}
*/
TSRestType(node) {
this.visitTypeNodes(node);
}

/**
* @param {TSTupleType} node The TSTupleType node to visit.
* @returns {void}
*/
TSTupleType(node) {
this.visitTypeNodes(node);
}

/**
* Create reference objects for the object part. (This is `obj.prop`)
* @param {TSTypeQuery} node The TSTypeQuery node to visit.
* @param {TSQualifiedName} node The TSQualifiedName node to visit.
* @returns {void}
*/
TSQualifiedName(node) {
Expand Down Expand Up @@ -457,7 +584,7 @@ class Referencer extends OriginalReferencer {
*/
TSMethodSignature(node) {
const upperTypeMode = this.typeMode;
const { computed, key, typeParameters, params, typeAnnotation } = node;
const { computed, key, typeParameters, params, returnType } = node;

if (computed) {
this.typeMode = false;
Expand All @@ -469,7 +596,7 @@ class Referencer extends OriginalReferencer {
}
this.visit(typeParameters);
params.forEach(this.visit, this);
this.visit(typeAnnotation); // Maybe returnType?
this.visit(returnType);

this.typeMode = upperTypeMode;
}
Expand Down Expand Up @@ -556,6 +683,12 @@ class Referencer extends OriginalReferencer {
this.visit(body);
}

TSTypeAliasDeclaration(node) {
this.typeMode = true;
this.visitChildren(node);
this.typeMode = false;
}

/**
* Process the module block.
* @param {TSModuleBlock} node The TSModuleBlock node to visit.
Expand Down Expand Up @@ -583,11 +716,11 @@ class Referencer extends OriginalReferencer {
* @returns {void}
*/
TSImportEqualsDeclaration(node) {
const { name, moduleReference } = node;
if (name && name.type === "Identifier") {
const { id, moduleReference } = node;
if (id && id.type === "Identifier") {
this.currentScope().__define(
name,
new Definition("ImportBinding", name, node, null, null, null)
id,
new Definition("ImportBinding", id, node, null, null, null)
);
}
this.visit(moduleReference);
Expand Down Expand Up @@ -628,6 +761,21 @@ class Referencer extends OriginalReferencer {
decorators.forEach(this.visit, this);
}
}

/**
* Process all child of type nodes
* @param {any} node node to be processed
* @returns {void}
*/
visitTypeNodes(node) {
if (this.typeMode) {
this.visitChildren(node);
} else {
this.typeMode = true;
this.visitChildren(node);
this.typeMode = false;
}
}
}

module.exports = function(ast, parserOptions, extraOptions) {
Expand Down
Loading