Skip to content

Commit

Permalink
Update: support class fields (refs eslint/eslint#14343)
Browse files Browse the repository at this point in the history
  • Loading branch information
mysticatea committed Apr 28, 2021
1 parent ae27ff3 commit ad618bc
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 3 deletions.
16 changes: 15 additions & 1 deletion lib/referencer.js
Expand Up @@ -303,7 +303,11 @@ class Referencer extends esrecurse.Visitor {
if (isMethodDefinition) {
previous = this.pushInnerMethodDefinition(true);
}
this.visit(node.value);

if (node.value) {
this.visit(node.value);
}

if (isMethodDefinition) {
this.popInnerMethodDefinition(previous);
}
Expand Down Expand Up @@ -434,6 +438,12 @@ class Referencer extends esrecurse.Visitor {
this.currentScope().__referencing(node);
}

// eslint-disable-next-line class-methods-use-this
PrivateIdentifier() {

// Do nothing.
}

UpdateExpression(node) {
if (PatternVisitor.isPattern(node.argument)) {
this.currentScope().__referencing(node.argument, Reference.RW, null);
Expand All @@ -453,6 +463,10 @@ class Referencer extends esrecurse.Visitor {
this.visitProperty(node);
}

PropertyDefinition(node) {
this.visitProperty(node);
}

MethodDefinition(node) {
this.visitProperty(node);
}
Expand Down
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -37,8 +37,8 @@
"eslint-config-eslint": "^5.0.1",
"eslint-plugin-node": "^9.1.0",
"eslint-release": "^1.0.0",
"eslint-visitor-keys": "^1.2.0",
"espree": "^7.1.0",
"eslint-visitor-keys": "github:eslint/eslint-visitor-keys#908fdf8c0d9a352c696c8c1f4901280d1a0795f7",
"espree": "github:eslint/espree#3e9caa787c0d4945401f1abf093b03be9fb44c6c",
"istanbul": "^0.4.5",
"mocha": "^6.1.4",
"npm-license": "^0.3.3",
Expand Down
95 changes: 95 additions & 0 deletions tests/class-fields.js
@@ -0,0 +1,95 @@
"use strict";

const assert = require("assert");
const espree = require("espree");
const { KEYS } = require("eslint-visitor-keys");
const { analyze } = require("../lib/index");

describe("Class fields", () => {
describe("class C { f = g }", () => {
let scopes;

beforeEach(() => {
const ast = espree.parse("class C { f = g }", { ecmaVersion: 13 });
const manager = analyze(ast, { ecmaVersion: 13, childVisitorKeys: KEYS });

scopes = [manager.globalScope, ...manager.globalScope.childScopes];
});

it("The class scope has only the reference 'g'.", () => {
const lastScope = scopes[scopes.length - 1];

assert.strictEqual(lastScope.references.length, 1);
assert.strictEqual(lastScope.references[0].identifier.name, "g");
});

it("The class scope has only the variable 'C' (doesn't have 'f').", () => {
const lastScope = scopes[scopes.length - 1];

assert.strictEqual(lastScope.variables.length, 1);
assert.strictEqual(lastScope.variables[0].name, "C");
});
});

describe("class C { #f = g }", () => {
let scopes;

beforeEach(() => {
const ast = espree.parse("class C { #f = g }", { ecmaVersion: 13 });
const manager = analyze(ast, { ecmaVersion: 13, childVisitorKeys: KEYS });

scopes = [manager.globalScope, ...manager.globalScope.childScopes];
});

it("The class scope has only the reference 'g'.", () => {
const lastScope = scopes[scopes.length - 1];

assert.strictEqual(lastScope.references.length, 1);
assert.strictEqual(lastScope.references[0].identifier.name, "g");
});

it("The class scope has only the variable 'C' (doesn't have '#f').", () => {
const lastScope = scopes[scopes.length - 1];

assert.strictEqual(lastScope.variables.length, 1);
assert.strictEqual(lastScope.variables[0].name, "C");
});
});

describe("class C { [fname] }", () => {
let scopes;

beforeEach(() => {
const ast = espree.parse("class C { [fname] }", { ecmaVersion: 13 });
const manager = analyze(ast, { ecmaVersion: 13, childVisitorKeys: KEYS });

scopes = [manager.globalScope, ...manager.globalScope.childScopes];
});

it("The class scope has only the reference 'fname'.", () => {
const lastScope = scopes[scopes.length - 1];

assert.strictEqual(lastScope.references.length, 1);
assert.strictEqual(lastScope.references[0].identifier.name, "fname");
});
});

describe("class C { [fname] = value }", () => {
let scopes;

beforeEach(() => {
const ast = espree.parse("class C { [fname] = value }", { ecmaVersion: 13 });
const manager = analyze(ast, { ecmaVersion: 13, childVisitorKeys: KEYS });

scopes = [manager.globalScope, ...manager.globalScope.childScopes];
});

it("The class scope has only the references 'fname' and 'value'.", () => {
const lastScope = scopes[scopes.length - 1];

assert.strictEqual(lastScope.references.length, 2);
assert.strictEqual(lastScope.references[0].identifier.name, "fname");
assert.strictEqual(lastScope.references[1].identifier.name, "value");
});
});
});

0 comments on commit ad618bc

Please sign in to comment.