From 34baff0eade9a731cec3d47ee2194c1acfaa1a34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Garc=C3=ADa?= Date: Wed, 2 Feb 2022 19:36:20 -0500 Subject: [PATCH 1/3] fix: ignore jsx-identifier when name is this --- packages/scope-manager/src/referencer/Referencer.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/scope-manager/src/referencer/Referencer.ts b/packages/scope-manager/src/referencer/Referencer.ts index 10273bfb6b3..046d443fdc2 100644 --- a/packages/scope-manager/src/referencer/Referencer.ts +++ b/packages/scope-manager/src/referencer/Referencer.ts @@ -509,10 +509,15 @@ class Referencer extends Visitor { } protected JSXMemberExpression(node: TSESTree.JSXMemberExpression): void { - this.visit(node.object); + if (node.object.type !== AST_NODE_TYPES.JSXIdentifier) { + this.visit(node.object); + } else { + if (node.object.name !== 'this') { + this.visit(node.object); + } + } // we don't ever reference the property as it's always going to be a property on the thing } - protected JSXOpeningElement(node: TSESTree.JSXOpeningElement): void { this.referenceJsxPragma(); if (node.name.type === AST_NODE_TYPES.JSXIdentifier) { From f4adccd3a2df280df9de907ac96f49fa38315085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Garc=C3=ADa?= Date: Wed, 23 Feb 2022 18:53:18 -0500 Subject: [PATCH 2/3] fix: reference jsx identifier when name is solely this --- .../src/referencer/Referencer.ts | 7 +- .../tests/fixtures/jsx/this-jsxidentifier.tsx | 7 + .../fixtures/jsx/this-jsxidentifier.tsx.shot | 145 ++++++++++++++++++ 3 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx create mode 100644 packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx.shot diff --git a/packages/scope-manager/src/referencer/Referencer.ts b/packages/scope-manager/src/referencer/Referencer.ts index 046d443fdc2..3190af3a56c 100644 --- a/packages/scope-manager/src/referencer/Referencer.ts +++ b/packages/scope-manager/src/referencer/Referencer.ts @@ -521,10 +521,15 @@ class Referencer extends Visitor { protected JSXOpeningElement(node: TSESTree.JSXOpeningElement): void { this.referenceJsxPragma(); if (node.name.type === AST_NODE_TYPES.JSXIdentifier) { - if (node.name.name[0].toUpperCase() === node.name.name[0]) { + if ( + node.name.name[0].toUpperCase() === node.name.name[0] || + node.name.name === 'this' + ) { // lower cased component names are always treated as "intrinsic" names, and are converted to a string, // not a variable by JSX transforms: //
=> React.createElement("div", null) + + // the only case we want to visit a lower-cased component has its name as "this", this.visit(node.name); } } else { diff --git a/packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx b/packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx new file mode 100644 index 00000000000..bc1ef1d755a --- /dev/null +++ b/packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +class Hello extends React.Component<{ tag: () => JSX.Element }> { + inline() { + return [, ]; + } +} diff --git a/packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx.shot b/packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx.shot new file mode 100644 index 00000000000..afa67b8b501 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx.shot @@ -0,0 +1,145 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`jsx this-jsxidentifier 1`] = ` +ScopeManager { + variables: Array [ + ImplicitGlobalConstTypeVariable, + Variable$2 { + defs: Array [ + ImportBindingDefinition$1 { + name: Identifier<"React">, + node: ImportDefaultSpecifier$1, + }, + ], + name: "React", + references: Array [ + Reference$3 { + identifier: Identifier<"React">, + isRead: true, + isTypeReference: false, + isValueReference: true, + isWrite: false, + resolved: Variable$2, + }, + Reference$1 { + identifier: Identifier<"React">, + isRead: true, + isTypeReference: false, + isValueReference: true, + isWrite: false, + resolved: Variable$2, + }, + ], + isValueVariable: true, + isTypeVariable: true, + }, + Variable$3 { + defs: Array [ + ClassNameDefinition$2 { + name: Identifier<"Hello">, + node: ClassDeclaration$2, + }, + ], + name: "Hello", + references: Array [], + isValueVariable: true, + isTypeVariable: true, + }, + Variable$4 { + defs: Array [ + ClassNameDefinition$3 { + name: Identifier<"Hello">, + node: ClassDeclaration$2, + }, + ], + name: "Hello", + references: Array [], + isValueVariable: true, + isTypeVariable: true, + }, + Variable$5 { + defs: Array [], + name: "arguments", + references: Array [], + isValueVariable: true, + isTypeVariable: true, + }, + ], + scopes: Array [ + GlobalScope$1 { + block: Program$3, + isStrict: false, + references: Array [ + Reference$3, + ], + set: Map { + "const" => ImplicitGlobalConstTypeVariable, + "React" => Variable$2, + "Hello" => Variable$3, + }, + type: "global", + upper: null, + variables: Array [ + ImplicitGlobalConstTypeVariable, + Variable$2, + Variable$3, + ], + }, + ClassScope$2 { + block: ClassDeclaration$2, + isStrict: true, + references: Array [ + Reference$1, + ], + set: Map { + "Hello" => Variable$4, + }, + type: "class", + upper: GlobalScope$1, + variables: Array [ + Variable$4, + ], + }, + FunctionTypeScope$3 { + block: TSFunctionType$4, + isStrict: true, + references: Array [ + Reference$2 { + identifier: Identifier<"JSX">, + isRead: true, + isTypeReference: true, + isValueReference: false, + isWrite: false, + resolved: null, + }, + ], + set: Map {}, + type: "functionType", + upper: ClassScope$2, + variables: Array [], + }, + FunctionScope$4 { + block: FunctionExpression$5, + isStrict: true, + references: Array [ + Reference$4 { + identifier: JSXIdentifier$6, + isRead: true, + isTypeReference: false, + isValueReference: true, + isWrite: false, + resolved: null, + }, + ], + set: Map { + "arguments" => Variable$5, + }, + type: "function", + upper: ClassScope$2, + variables: Array [ + Variable$5, + ], + }, + ], +} +`; From 6b9bbdcb9ec17999654a39fbcae30f3f81f75e33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Garc=C3=ADa?= Date: Fri, 25 Feb 2022 18:49:10 -0500 Subject: [PATCH 3/3] fix: add a better suited test for jsx member expressions --- .../tests/fixtures/jsx/this-jsxidentifier.tsx | 13 ++-- .../fixtures/jsx/this-jsxidentifier.tsx.shot | 72 +++++++++---------- 2 files changed, 44 insertions(+), 41 deletions(-) diff --git a/packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx b/packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx index bc1ef1d755a..4a3190a5a6d 100644 --- a/packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx +++ b/packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx @@ -1,7 +1,12 @@ -import React from 'react'; +declare const React; -class Hello extends React.Component<{ tag: () => JSX.Element }> { - inline() { - return [, ]; +class Foo { + foo: any; + Div = { + Element: () =>
, + }; + method() { + ; + ()(); } } diff --git a/packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx.shot b/packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx.shot index afa67b8b501..713e659bb5b 100644 --- a/packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx.shot +++ b/packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx.shot @@ -6,21 +6,13 @@ ScopeManager { ImplicitGlobalConstTypeVariable, Variable$2 { defs: Array [ - ImportBindingDefinition$1 { + VariableDefinition$1 { name: Identifier<"React">, - node: ImportDefaultSpecifier$1, + node: VariableDeclarator$1, }, ], name: "React", references: Array [ - Reference$3 { - identifier: Identifier<"React">, - isRead: true, - isTypeReference: false, - isValueReference: true, - isWrite: false, - resolved: Variable$2, - }, Reference$1 { identifier: Identifier<"React">, isRead: true, @@ -31,16 +23,16 @@ ScopeManager { }, ], isValueVariable: true, - isTypeVariable: true, + isTypeVariable: false, }, Variable$3 { defs: Array [ ClassNameDefinition$2 { - name: Identifier<"Hello">, + name: Identifier<"Foo">, node: ClassDeclaration$2, }, ], - name: "Hello", + name: "Foo", references: Array [], isValueVariable: true, isTypeVariable: true, @@ -48,11 +40,11 @@ ScopeManager { Variable$4 { defs: Array [ ClassNameDefinition$3 { - name: Identifier<"Hello">, + name: Identifier<"Foo">, node: ClassDeclaration$2, }, ], - name: "Hello", + name: "Foo", references: Array [], isValueVariable: true, isTypeVariable: true, @@ -70,12 +62,12 @@ ScopeManager { block: Program$3, isStrict: false, references: Array [ - Reference$3, + Reference$1, ], set: Map { "const" => ImplicitGlobalConstTypeVariable, "React" => Variable$2, - "Hello" => Variable$3, + "Foo" => Variable$3, }, type: "global", upper: null, @@ -88,11 +80,9 @@ ScopeManager { ClassScope$2 { block: ClassDeclaration$2, isStrict: true, - references: Array [ - Reference$1, - ], + references: Array [], set: Map { - "Hello" => Variable$4, + "Foo" => Variable$4, }, type: "class", upper: GlobalScope$1, @@ -100,30 +90,38 @@ ScopeManager { Variable$4, ], }, - FunctionTypeScope$3 { - block: TSFunctionType$4, + ClassFieldInitializerScope$3 { + block: ObjectExpression$4, isStrict: true, - references: Array [ - Reference$2 { - identifier: Identifier<"JSX">, - isRead: true, - isTypeReference: true, - isValueReference: false, - isWrite: false, - resolved: null, - }, - ], + references: Array [], set: Map {}, - type: "functionType", + type: "class-field-initializer", upper: ClassScope$2, variables: Array [], }, FunctionScope$4 { - block: FunctionExpression$5, + block: ArrowFunctionExpression$5, + isStrict: true, + references: Array [], + set: Map {}, + type: "function", + upper: ClassFieldInitializerScope$3, + variables: Array [], + }, + FunctionScope$5 { + block: FunctionExpression$6, isStrict: true, references: Array [ - Reference$4 { - identifier: JSXIdentifier$6, + Reference$2 { + identifier: JSXIdentifier$7, + isRead: true, + isTypeReference: false, + isValueReference: true, + isWrite: false, + resolved: null, + }, + Reference$3 { + identifier: JSXIdentifier$8, isRead: true, isTypeReference: false, isValueReference: true,