Skip to content

Commit

Permalink
fix(scope-manager): incorrect reference for this within a jsx identif…
Browse files Browse the repository at this point in the history
…ier (#4535)
  • Loading branch information
juank1809 committed Mar 18, 2022
1 parent f3a97ff commit dd49280
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 3 deletions.
16 changes: 13 additions & 3 deletions packages/scope-manager/src/referencer/Referencer.ts
Expand Up @@ -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:
// <div /> => 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 {
Expand Down
12 changes: 12 additions & 0 deletions packages/scope-manager/tests/fixtures/jsx/this-jsxidentifier.tsx
@@ -0,0 +1,12 @@
declare const React;

class Foo {
foo: any;
Div = {
Element: () => <div />,
};
method() {
<this.foo />;
(<Div.Element />)(<this />);
}
}
143 changes: 143 additions & 0 deletions 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,
],
},
],
}
`;

0 comments on commit dd49280

Please sign in to comment.