diff --git a/packages/scope-manager/src/referencer/Referencer.ts b/packages/scope-manager/src/referencer/Referencer.ts
index 10273bfb6b3..3190af3a56c 100644
--- a/packages/scope-manager/src/referencer/Referencer.ts
+++ b/packages/scope-manager/src/referencer/Referencer.ts
@@ -509,17 +509,27 @@ 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) {
- 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..4a3190a5a6d
--- /dev/null
+++ b/packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx
@@ -0,0 +1,12 @@
+declare const React;
+
+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
new file mode 100644
index 00000000000..713e659bb5b
--- /dev/null
+++ b/packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx.shot
@@ -0,0 +1,143 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`jsx this-jsxidentifier 1`] = `
+ScopeManager {
+ variables: Array [
+ ImplicitGlobalConstTypeVariable,
+ Variable$2 {
+ defs: Array [
+ VariableDefinition$1 {
+ name: Identifier<"React">,
+ node: VariableDeclarator$1,
+ },
+ ],
+ name: "React",
+ references: Array [
+ Reference$1 {
+ identifier: Identifier<"React">,
+ isRead: true,
+ isTypeReference: false,
+ isValueReference: true,
+ isWrite: false,
+ resolved: Variable$2,
+ },
+ ],
+ isValueVariable: true,
+ isTypeVariable: false,
+ },
+ Variable$3 {
+ defs: Array [
+ ClassNameDefinition$2 {
+ name: Identifier<"Foo">,
+ node: ClassDeclaration$2,
+ },
+ ],
+ name: "Foo",
+ references: Array [],
+ isValueVariable: true,
+ isTypeVariable: true,
+ },
+ Variable$4 {
+ defs: Array [
+ ClassNameDefinition$3 {
+ name: Identifier<"Foo">,
+ node: ClassDeclaration$2,
+ },
+ ],
+ name: "Foo",
+ 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$1,
+ ],
+ set: Map {
+ "const" => ImplicitGlobalConstTypeVariable,
+ "React" => Variable$2,
+ "Foo" => Variable$3,
+ },
+ type: "global",
+ upper: null,
+ variables: Array [
+ ImplicitGlobalConstTypeVariable,
+ Variable$2,
+ Variable$3,
+ ],
+ },
+ ClassScope$2 {
+ block: ClassDeclaration$2,
+ isStrict: true,
+ references: Array [],
+ set: Map {
+ "Foo" => Variable$4,
+ },
+ type: "class",
+ upper: GlobalScope$1,
+ variables: Array [
+ Variable$4,
+ ],
+ },
+ ClassFieldInitializerScope$3 {
+ block: ObjectExpression$4,
+ isStrict: true,
+ references: Array [],
+ set: Map {},
+ type: "class-field-initializer",
+ upper: ClassScope$2,
+ variables: Array [],
+ },
+ FunctionScope$4 {
+ 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$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,
+ isWrite: false,
+ resolved: null,
+ },
+ ],
+ set: Map {
+ "arguments" => Variable$5,
+ },
+ type: "function",
+ upper: ClassScope$2,
+ variables: Array [
+ Variable$5,
+ ],
+ },
+ ],
+}
+`;