Skip to content
Permalink
Browse files

πŸ› fix reference tracker false positive

  • Loading branch information...
mysticatea committed Oct 20, 2019
1 parent 6633278 commit 8f9e481ecc1204c7a1331b697f97903f90c75154
Showing with 36 additions and 2 deletions.
  1. +23 βˆ’2 src/reference-tracker.js
  2. +13 βˆ’0 test/reference-tracker.js
@@ -2,7 +2,6 @@ import { findVariable } from "./find-variable"
import { getPropertyName } from "./get-property-name"
import { getStringIfConstant } from "./get-string-if-constant"

const SENTINEL_TYPE = /^(?:.+?Statement|.+?Declaration|(?:Array|ArrowFunction|Assignment|Call|Class|Function|Member|New|Object)Expression|AssignmentPattern|Program|VariableDeclarator)$/u
const IMPORT_TYPE = /^(?:Import|Export(?:All|Default|Named))Declaration$/u
const has = Function.call.bind(Object.hasOwnProperty)

@@ -26,6 +25,28 @@ function isModifiedGlobal(variable) {
)
}

/**
* Check if the value of a given node is passed through to the parent syntax as-is.
* For example, `a` and `b` in (`a || b` and `c ? a : b`) are passed through.
* @param {Node} node A node to check.
* @returns {boolean} `true` if the node is passed through.
*/
function isPassThrough(node) {
const parent = node.parent

switch (parent && parent.type) {
case "ConditionalExpression":
return parent.consequent === node || parent.alternate === node
case "LogicalExpression":
return true
case "SequenceExpression":
return parent.expressions[parent.expressions.length - 1] === node

default:
return false
}
}

/**
* The reference tracker.
*/
@@ -227,7 +248,7 @@ export class ReferenceTracker {
//eslint-disable-next-line complexity
*_iteratePropertyReferences(rootNode, path, traceMap) {
let node = rootNode
while (!SENTINEL_TYPE.test(node.parent.type)) {
while (isPassThrough(node)) {
node = node.parent
}

@@ -4,6 +4,7 @@ import { CALL, CONSTRUCT, ESM, READ, ReferenceTracker } from "../src/"

const config = {
parserOptions: { ecmaVersion: 2018, sourceType: "module" },
globals: { Reflect: false },
rules: { test: "error" },
}

@@ -369,6 +370,18 @@ describe("The 'ReferenceTracker' class:", () => {
},
expected: [],
},
{
description:
"should not iterate the references through unary/binary expressions.",
code: [
'var construct = typeof Reflect !== "undefined" ? Reflect.construct : undefined',
"construct()",
].join("\n"),
traceMap: {
Reflect: { [CALL]: 1 },
},
expected: [],
},
]) {
it(description, () => {
const linter = new eslint.Linter()

0 comments on commit 8f9e481

Please sign in to comment.
You can’t perform that action at this time.