From ea71966a29370e2777c37a8534f24ea0055ff95a Mon Sep 17 00:00:00 2001 From: Armano Date: Wed, 21 Nov 2018 21:21:49 +0100 Subject: [PATCH 1/3] Fix: visiting superTypeParameters in classes --- analyze-scope.js | 8 + .../scope-analysis/class-supper-type.ts | 11 + .../lib/__snapshots__/scope-analysis.js.snap | 383 ++++++++++++++++++ visitor-keys.js | 6 +- 4 files changed, 405 insertions(+), 3 deletions(-) create mode 100644 tests/fixtures/scope-analysis/class-supper-type.ts diff --git a/analyze-scope.js b/analyze-scope.js index 0fb87e9..a49fb2d 100644 --- a/analyze-scope.js +++ b/analyze-scope.js @@ -215,6 +215,14 @@ class Referencer extends OriginalReferencer { */ visitClass(node) { this.visitDecorators(node.decorators); + + if (node.superTypeParameters) { + const upperTypeMode = this.typeMode; + this.typeMode = true; + this.visit(node.superTypeParameters); + this.typeMode = upperTypeMode; + } + super.visitClass(node); } diff --git a/tests/fixtures/scope-analysis/class-supper-type.ts b/tests/fixtures/scope-analysis/class-supper-type.ts new file mode 100644 index 0000000..14ad843 --- /dev/null +++ b/tests/fixtures/scope-analysis/class-supper-type.ts @@ -0,0 +1,11 @@ +abstract class Foo extends Bar { + +} + +declare class Foo2 extends Bar { + +} + +class Foo3 extends Bar { + +} diff --git a/tests/lib/__snapshots__/scope-analysis.js.snap b/tests/lib/__snapshots__/scope-analysis.js.snap index 8cf1838..7dd3f4f 100644 --- a/tests/lib/__snapshots__/scope-analysis.js.snap +++ b/tests/lib/__snapshots__/scope-analysis.js.snap @@ -565,6 +565,389 @@ Object { } `; +exports[`TypeScript scope analysis tests/fixtures/scope-analysis/class-supper-type.ts 1`] = ` +Object { + "$id": 11, + "block": Object { + "range": Array [ + 0, + 117, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 6, + "block": Object { + "range": Array [ + 0, + 40, + ], + "type": "TSAbstractClassDeclaration", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "class", + "upperScope": Object { + "$ref": 11, + }, + "variableMap": Object { + "Foo": Object { + "$ref": 5, + }, + }, + "variableScope": Object { + "$ref": 11, + }, + "variables": Array [ + Object { + "$id": 5, + "defs": Array [ + Object { + "name": Object { + "name": "Foo", + "range": Array [ + 15, + 18, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 0, + 40, + ], + "type": "TSAbstractClassDeclaration", + }, + "parent": undefined, + "type": "ClassName", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "Foo", + "range": Array [ + 15, + 18, + ], + "type": "Identifier", + }, + ], + "name": "Foo", + "references": Array [], + "scope": Object { + "$ref": 6, + }, + }, + ], + }, + Object { + "$id": 8, + "block": Object { + "range": Array [ + 42, + 82, + ], + "type": "ClassDeclaration", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "class", + "upperScope": Object { + "$ref": 11, + }, + "variableMap": Object { + "Foo2": Object { + "$ref": 7, + }, + }, + "variableScope": Object { + "$ref": 11, + }, + "variables": Array [ + Object { + "$id": 7, + "defs": Array [ + Object { + "name": Object { + "name": "Foo2", + "range": Array [ + 56, + 60, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 42, + 82, + ], + "type": "ClassDeclaration", + }, + "parent": undefined, + "type": "ClassName", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "Foo2", + "range": Array [ + 56, + 60, + ], + "type": "Identifier", + }, + ], + "name": "Foo2", + "references": Array [], + "scope": Object { + "$ref": 8, + }, + }, + ], + }, + Object { + "$id": 10, + "block": Object { + "range": Array [ + 84, + 116, + ], + "type": "ClassDeclaration", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "class", + "upperScope": Object { + "$ref": 11, + }, + "variableMap": Object { + "Foo3": Object { + "$ref": 9, + }, + }, + "variableScope": Object { + "$ref": 11, + }, + "variables": Array [ + Object { + "$id": 9, + "defs": Array [ + Object { + "name": Object { + "name": "Foo3", + "range": Array [ + 90, + 94, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 84, + 116, + ], + "type": "ClassDeclaration", + }, + "parent": undefined, + "type": "ClassName", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "Foo3", + "range": Array [ + 90, + 94, + ], + "type": "Identifier", + }, + ], + "name": "Foo3", + "references": Array [], + "scope": Object { + "$ref": 10, + }, + }, + ], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [ + Object { + "$id": 2, + "from": Object { + "$ref": 11, + }, + "identifier": Object { + "name": "Bar", + "range": Array [ + 27, + 30, + ], + "type": "Identifier", + }, + "kind": "r", + "resolved": null, + "writeExpr": undefined, + }, + Object { + "$id": 3, + "from": Object { + "$ref": 11, + }, + "identifier": Object { + "name": "Bar", + "range": Array [ + 69, + 72, + ], + "type": "Identifier", + }, + "kind": "r", + "resolved": null, + "writeExpr": undefined, + }, + Object { + "$id": 4, + "from": Object { + "$ref": 11, + }, + "identifier": Object { + "name": "Bar", + "range": Array [ + 103, + 106, + ], + "type": "Identifier", + }, + "kind": "r", + "resolved": null, + "writeExpr": undefined, + }, + ], + "throughReferences": Array [ + Object { + "$ref": 2, + }, + Object { + "$ref": 3, + }, + Object { + "$ref": 4, + }, + ], + "type": "global", + "upperScope": null, + "variableMap": Object { + "Foo2": Object { + "$ref": 0, + }, + "Foo3": Object { + "$ref": 1, + }, + }, + "variableScope": Object { + "$ref": 11, + }, + "variables": Array [ + Object { + "$id": 0, + "defs": Array [ + Object { + "name": Object { + "name": "Foo2", + "range": Array [ + 56, + 60, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 42, + 82, + ], + "type": "ClassDeclaration", + }, + "parent": null, + "type": "ClassName", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "Foo2", + "range": Array [ + 56, + 60, + ], + "type": "Identifier", + }, + ], + "name": "Foo2", + "references": Array [], + "scope": Object { + "$ref": 11, + }, + }, + Object { + "$id": 1, + "defs": Array [ + Object { + "name": Object { + "name": "Foo3", + "range": Array [ + 90, + 94, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 84, + 116, + ], + "type": "ClassDeclaration", + }, + "parent": null, + "type": "ClassName", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "Foo3", + "range": Array [ + 90, + 94, + ], + "type": "Identifier", + }, + ], + "name": "Foo3", + "references": Array [], + "scope": Object { + "$ref": 11, + }, + }, + ], +} +`; + exports[`TypeScript scope analysis tests/fixtures/scope-analysis/computed-properties-in-interface.ts 1`] = ` Object { "$id": 8, diff --git a/visitor-keys.js b/visitor-keys.js index 1de50cd..eeabea1 100644 --- a/visitor-keys.js +++ b/visitor-keys.js @@ -12,8 +12,8 @@ module.exports = Evk.unionWith({ // Additional Properties. ArrayPattern: ["elements", "typeAnnotation"], ArrowFunctionExpression: ["typeParameters", "params", "returnType", "body"], - ClassDeclaration: ["decorators", "id", "typeParameters", "superClass", "body"], - ClassExpression: ["decorators", "id", "typeParameters", "superClass", "body"], + ClassDeclaration: ["decorators", "id", "typeParameters", "superClass", "superTypeParameters", "body"], + ClassExpression: ["decorators", "id", "typeParameters", "superClass", "superTypeParameters", "body"], FunctionDeclaration: ["id", "typeParameters", "params", "returnType", "body"], FunctionExpression: ["id", "typeParameters", "params", "returnType", "body"], Identifier: ["decorators", "typeAnnotation"], @@ -24,7 +24,7 @@ module.exports = Evk.unionWith({ ClassProperty: ["decorators", "key", "typeAnnotation", "value"], Decorator: ["expression"], TSAbstractClassProperty: ["typeAnnotation", "key", "value"], - TSAbstractClassDeclaration: ["id", "body", "superClass", "implements"], + TSAbstractClassDeclaration: ["id", "superClass", "superTypeParameters", "implements", "body"], TSAbstractKeyword: [], TSAbstractMethodDefinition: ["key", "value"], TSAnyKeyword: [], From 4e402519970323cf84bc64ef7aff266f80370637 Mon Sep 17 00:00:00 2001 From: Armano Date: Wed, 21 Nov 2018 22:18:20 +0100 Subject: [PATCH 2/3] Add missing decorators in TSAbstractClassDeclaration its already supported in visitClass --- visitor-keys.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visitor-keys.js b/visitor-keys.js index eeabea1..03473a9 100644 --- a/visitor-keys.js +++ b/visitor-keys.js @@ -24,7 +24,7 @@ module.exports = Evk.unionWith({ ClassProperty: ["decorators", "key", "typeAnnotation", "value"], Decorator: ["expression"], TSAbstractClassProperty: ["typeAnnotation", "key", "value"], - TSAbstractClassDeclaration: ["id", "superClass", "superTypeParameters", "implements", "body"], + TSAbstractClassDeclaration: ["decorators", "id", "superClass", "superTypeParameters", "implements", "body"], TSAbstractKeyword: [], TSAbstractMethodDefinition: ["key", "value"], TSAnyKeyword: [], From 8504e44da4873809af9ce9f1ba15e7016fc341fc Mon Sep 17 00:00:00 2001 From: Armano Date: Wed, 21 Nov 2018 22:20:35 +0100 Subject: [PATCH 3/3] Add missing typeParameters in TSAbstractClassDeclaration its using same logic as ClassDeclaration --- visitor-keys.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visitor-keys.js b/visitor-keys.js index 03473a9..fd1574c 100644 --- a/visitor-keys.js +++ b/visitor-keys.js @@ -24,7 +24,7 @@ module.exports = Evk.unionWith({ ClassProperty: ["decorators", "key", "typeAnnotation", "value"], Decorator: ["expression"], TSAbstractClassProperty: ["typeAnnotation", "key", "value"], - TSAbstractClassDeclaration: ["decorators", "id", "superClass", "superTypeParameters", "implements", "body"], + TSAbstractClassDeclaration: ["decorators", "id", "typeParameters", "superClass", "superTypeParameters", "implements", "body"], TSAbstractKeyword: [], TSAbstractMethodDefinition: ["key", "value"], TSAnyKeyword: [],