From 3aae6574403ec33b493ebc4a0cb1b5bacd24eee2 Mon Sep 17 00:00:00 2001 From: Armano Date: Tue, 20 Nov 2018 01:10:04 +0100 Subject: [PATCH 1/3] Fix: missing visitor-keys - typeParameters in TSInterfaceDeclaration - decorators in Identifier - parameters in TSFunctionType --- analyze-scope.js | 3 + .../scope-analysis/identifier-decorators.ts | 4 + .../fixtures/scope-analysis/interface-type.ts | 7 + .../lib/__snapshots__/scope-analysis.js.snap | 274 ++++++++++++++++++ visitor-keys.js | 6 +- 5 files changed, 291 insertions(+), 3 deletions(-) create mode 100644 tests/fixtures/scope-analysis/identifier-decorators.ts create mode 100644 tests/fixtures/scope-analysis/interface-type.ts diff --git a/analyze-scope.js b/analyze-scope.js index 339091e..0cc81c9 100644 --- a/analyze-scope.js +++ b/analyze-scope.js @@ -216,9 +216,12 @@ class Referencer extends OriginalReferencer { * @returns {void} */ Identifier(node) { + this.visitDecorators(node.decorators); + if (!this.typeMode) { super.Identifier(node); } + this.visit(node.typeAnnotation); } diff --git a/tests/fixtures/scope-analysis/identifier-decorators.ts b/tests/fixtures/scope-analysis/identifier-decorators.ts new file mode 100644 index 0000000..00d0463 --- /dev/null +++ b/tests/fixtures/scope-analysis/identifier-decorators.ts @@ -0,0 +1,4 @@ +export class Test { + constructor(@Decorator config) { + } +} diff --git a/tests/fixtures/scope-analysis/interface-type.ts b/tests/fixtures/scope-analysis/interface-type.ts new file mode 100644 index 0000000..2590bf7 --- /dev/null +++ b/tests/fixtures/scope-analysis/interface-type.ts @@ -0,0 +1,7 @@ +interface C { + +} + +interface R { + foo: C +} diff --git a/tests/lib/__snapshots__/scope-analysis.js.snap b/tests/lib/__snapshots__/scope-analysis.js.snap index 5fe0286..428796f 100644 --- a/tests/lib/__snapshots__/scope-analysis.js.snap +++ b/tests/lib/__snapshots__/scope-analysis.js.snap @@ -2927,6 +2927,255 @@ Object { } `; +exports[`TypeScript scope analysis tests/fixtures/scope-analysis/identifier-decorators.ts 1`] = ` +Object { + "$id": 7, + "block": Object { + "range": Array [ + 0, + 65, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 6, + "block": Object { + "range": Array [ + 0, + 65, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 5, + "block": Object { + "range": Array [ + 7, + 64, + ], + "type": "ClassDeclaration", + }, + "childScopes": Array [ + Object { + "$id": 4, + "block": Object { + "range": Array [ + 35, + 62, + ], + "type": "FunctionExpression", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "function", + "upperScope": Object { + "$ref": 5, + }, + "variableMap": Object { + "arguments": Object { + "$ref": 2, + }, + "config": Object { + "$ref": 3, + }, + }, + "variableScope": Object { + "$ref": 4, + }, + "variables": Array [ + Object { + "$id": 2, + "defs": Array [], + "eslintUsed": undefined, + "identifiers": Array [], + "name": "arguments", + "references": Array [], + "scope": Object { + "$ref": 4, + }, + }, + Object { + "$id": 3, + "defs": Array [ + Object { + "name": Object { + "name": "config", + "range": Array [ + 47, + 53, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 35, + 62, + ], + "type": "FunctionExpression", + }, + "parent": null, + "type": "Parameter", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "config", + "range": Array [ + 47, + 53, + ], + "type": "Identifier", + }, + ], + "name": "config", + "references": Array [], + "scope": Object { + "$ref": 4, + }, + }, + ], + }, + ], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "class", + "upperScope": Object { + "$ref": 6, + }, + "variableMap": Object { + "Test": Object { + "$ref": 1, + }, + }, + "variableScope": Object { + "$ref": 6, + }, + "variables": Array [ + Object { + "$id": 1, + "defs": Array [ + Object { + "name": Object { + "name": "Test", + "range": Array [ + 13, + 17, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 7, + 64, + ], + "type": "ClassDeclaration", + }, + "parent": undefined, + "type": "ClassName", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "Test", + "range": Array [ + 13, + 17, + ], + "type": "Identifier", + }, + ], + "name": "Test", + "references": Array [], + "scope": Object { + "$ref": 5, + }, + }, + ], + }, + ], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "module", + "upperScope": Object { + "$ref": 7, + }, + "variableMap": Object { + "Test": Object { + "$ref": 0, + }, + }, + "variableScope": Object { + "$ref": 6, + }, + "variables": Array [ + Object { + "$id": 0, + "defs": Array [ + Object { + "name": Object { + "name": "Test", + "range": Array [ + 13, + 17, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 7, + 64, + ], + "type": "ClassDeclaration", + }, + "parent": null, + "type": "ClassName", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "Test", + "range": Array [ + 13, + 17, + ], + "type": "Identifier", + }, + ], + "name": "Test", + "references": Array [], + "scope": Object { + "$ref": 6, + }, + }, + ], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 7, + }, + "variables": Array [], +} +`; + exports[`TypeScript scope analysis tests/fixtures/scope-analysis/ignore-type-only-stuff.ts 1`] = ` Object { "$id": 1, @@ -3003,6 +3252,31 @@ Object { } `; +exports[`TypeScript scope analysis tests/fixtures/scope-analysis/interface-type.ts 1`] = ` +Object { + "$id": 0, + "block": Object { + "range": Array [ + 0, + 67, + ], + "type": "Program", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 0, + }, + "variables": Array [], +} +`; + exports[`TypeScript scope analysis tests/fixtures/scope-analysis/method-overload.ts 1`] = ` Object { "$id": 10, diff --git a/visitor-keys.js b/visitor-keys.js index 2fbefd5..035dc67 100644 --- a/visitor-keys.js +++ b/visitor-keys.js @@ -16,7 +16,7 @@ module.exports = Evk.unionWith({ ClassExpression: ["decorators", "id", "typeParameters", "superClass", "body"], FunctionDeclaration: ["id", "typeParameters", "params", "returnType", "body"], FunctionExpression: ["id", "typeParameters", "params", "returnType", "body"], - Identifier: ["typeAnnotation"], + Identifier: ["decorators", "typeAnnotation"], MethodDefinition: ["decorators", "key", "value"], ObjectPattern: ["properties", "typeAnnotation"], @@ -46,9 +46,9 @@ module.exports = Evk.unionWith({ TSLiteralType: ["literal"], TSIndexSignature: ["typeAnnotation", "index"], TSInterfaceBody: ["body"], - TSInterfaceDeclaration: ["body", "id", "heritage"], + TSInterfaceDeclaration: ["body", "id", "heritage", "typeParameters"], TSInterfaceHeritage: ["id", "typeParameters"], - TSFunctionType: ["typeAnnotation"], + TSFunctionType: ["parameters", "typeAnnotation"], TSMethodSignature: ["typeAnnotation", "typeParameters", "key", "params"], TSModuleBlock: ["body"], TSModuleDeclaration: ["id", "body"], From 9e7874789c34058c6b5445776b77ce8003a68c18 Mon Sep 17 00:00:00 2001 From: Armano Date: Tue, 20 Nov 2018 01:47:19 +0100 Subject: [PATCH 2/3] Fix order of visiting in TSInterfaceDeclaration --- visitor-keys.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visitor-keys.js b/visitor-keys.js index 035dc67..945da9e 100644 --- a/visitor-keys.js +++ b/visitor-keys.js @@ -46,7 +46,7 @@ module.exports = Evk.unionWith({ TSLiteralType: ["literal"], TSIndexSignature: ["typeAnnotation", "index"], TSInterfaceBody: ["body"], - TSInterfaceDeclaration: ["body", "id", "heritage", "typeParameters"], + TSInterfaceDeclaration: ["id", "typeParameters", "heritage", "body"], TSInterfaceHeritage: ["id", "typeParameters"], TSFunctionType: ["parameters", "typeAnnotation"], TSMethodSignature: ["typeAnnotation", "typeParameters", "key", "params"], From 80bde1d5c81e022c7cb401ec3cad996d8265824d Mon Sep 17 00:00:00 2001 From: Toru Nagashima Date: Tue, 20 Nov 2018 03:16:04 +0100 Subject: [PATCH 3/3] Fix issue with scope analyze found by @mysticatea --- analyze-scope.js | 9 +++ .../lib/__snapshots__/scope-analysis.js.snap | 74 ++++++++++++++----- 2 files changed, 63 insertions(+), 20 deletions(-) diff --git a/analyze-scope.js b/analyze-scope.js index 0cc81c9..0fb87e9 100644 --- a/analyze-scope.js +++ b/analyze-scope.js @@ -69,6 +69,9 @@ class EnumScope extends Scope { class PatternVisitor extends OriginalPatternVisitor { Identifier(node) { super.Identifier(node); + if (node.decorators) { + this.rightHandNodes.push(...node.decorators); + } if (node.typeAnnotation) { this.rightHandNodes.push(node.typeAnnotation); } @@ -76,6 +79,9 @@ class PatternVisitor extends OriginalPatternVisitor { ArrayPattern(node) { node.elements.forEach(this.visit, this); + if (node.decorators) { + this.rightHandNodes.push(...node.decorators); + } if (node.typeAnnotation) { this.rightHandNodes.push(node.typeAnnotation); } @@ -83,6 +89,9 @@ class PatternVisitor extends OriginalPatternVisitor { ObjectPattern(node) { node.properties.forEach(this.visit, this); + if (node.decorators) { + this.rightHandNodes.push(...node.decorators); + } if (node.typeAnnotation) { this.rightHandNodes.push(node.typeAnnotation); } diff --git a/tests/lib/__snapshots__/scope-analysis.js.snap b/tests/lib/__snapshots__/scope-analysis.js.snap index 428796f..5d4c741 100644 --- a/tests/lib/__snapshots__/scope-analysis.js.snap +++ b/tests/lib/__snapshots__/scope-analysis.js.snap @@ -2929,7 +2929,7 @@ Object { exports[`TypeScript scope analysis tests/fixtures/scope-analysis/identifier-decorators.ts 1`] = ` Object { - "$id": 7, + "$id": 8, "block": Object { "range": Array [ 0, @@ -2939,7 +2939,7 @@ Object { }, "childScopes": Array [ Object { - "$id": 6, + "$id": 7, "block": Object { "range": Array [ 0, @@ -2949,7 +2949,7 @@ Object { }, "childScopes": Array [ Object { - "$id": 5, + "$id": 6, "block": Object { "range": Array [ 7, @@ -2959,7 +2959,7 @@ Object { }, "childScopes": Array [ Object { - "$id": 4, + "$id": 5, "block": Object { "range": Array [ 35, @@ -2970,11 +2970,33 @@ Object { "childScopes": Array [], "functionExpressionScope": false, "isStrict": true, - "references": Array [], - "throughReferences": Array [], + "references": Array [ + Object { + "$id": 4, + "from": Object { + "$ref": 5, + }, + "identifier": Object { + "name": "Decorator", + "range": Array [ + 37, + 46, + ], + "type": "Identifier", + }, + "kind": "r", + "resolved": null, + "writeExpr": undefined, + }, + ], + "throughReferences": Array [ + Object { + "$ref": 4, + }, + ], "type": "function", "upperScope": Object { - "$ref": 5, + "$ref": 6, }, "variableMap": Object { "arguments": Object { @@ -2985,7 +3007,7 @@ Object { }, }, "variableScope": Object { - "$ref": 4, + "$ref": 5, }, "variables": Array [ Object { @@ -2996,7 +3018,7 @@ Object { "name": "arguments", "references": Array [], "scope": Object { - "$ref": 4, + "$ref": 5, }, }, Object { @@ -3036,7 +3058,7 @@ Object { "name": "config", "references": Array [], "scope": Object { - "$ref": 4, + "$ref": 5, }, }, ], @@ -3045,10 +3067,14 @@ Object { "functionExpressionScope": false, "isStrict": true, "references": Array [], - "throughReferences": Array [], + "throughReferences": Array [ + Object { + "$ref": 4, + }, + ], "type": "class", "upperScope": Object { - "$ref": 6, + "$ref": 7, }, "variableMap": Object { "Test": Object { @@ -3056,7 +3082,7 @@ Object { }, }, "variableScope": Object { - "$ref": 6, + "$ref": 7, }, "variables": Array [ Object { @@ -3096,7 +3122,7 @@ Object { "name": "Test", "references": Array [], "scope": Object { - "$ref": 5, + "$ref": 6, }, }, ], @@ -3105,10 +3131,14 @@ Object { "functionExpressionScope": false, "isStrict": true, "references": Array [], - "throughReferences": Array [], + "throughReferences": Array [ + Object { + "$ref": 4, + }, + ], "type": "module", "upperScope": Object { - "$ref": 7, + "$ref": 8, }, "variableMap": Object { "Test": Object { @@ -3116,7 +3146,7 @@ Object { }, }, "variableScope": Object { - "$ref": 6, + "$ref": 7, }, "variables": Array [ Object { @@ -3156,7 +3186,7 @@ Object { "name": "Test", "references": Array [], "scope": Object { - "$ref": 6, + "$ref": 7, }, }, ], @@ -3165,12 +3195,16 @@ Object { "functionExpressionScope": false, "isStrict": false, "references": Array [], - "throughReferences": Array [], + "throughReferences": Array [ + Object { + "$ref": 4, + }, + ], "type": "global", "upperScope": null, "variableMap": Object {}, "variableScope": Object { - "$ref": 7, + "$ref": 8, }, "variables": Array [], }