-
Notifications
You must be signed in to change notification settings - Fork 91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Broken selectors after exactNode #146
base: master
Are you sure you want to change the base?
Conversation
it('fails has(>BlockStatement>ExpressionStatement)', function () { | ||
const matches = esquery(conditional, 'IfStatement:has(>BlockStatement>ExpressionStatement)'); | ||
assert.equal(3, matches.length); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cause seems to be that child
selector (BlockStatement>ExpressionStatement) matches on the nested node (selector.right ExpressionStatement, instead of selector.left BlockStatement). Then exactNode checks if parent node has any ancestors
Line 205 in 07ee329
return left(ancestry[0], ancestry.slice(1), options); |
Lines 130 to 133 in 07ee329
case 'exactNode': | |
return (node, ancestry) => { | |
return ancestry.length === 0; | |
}; |
within IfStatement:has(>BlockStatement>ExpressionStatement)
selector {
type: 'child',
left: { type: 'exactNode' },
right: {
type: 'child',
left: { type: 'identifier', value: 'BlockStatement' },
right: { type: 'identifier', value: 'ExpressionStatement' }
}
}
left matches when visiting BlockStatement - print parents and children:
IfStatement,[BlockStatement] ⚟ [ 'ExpressionStatement' ]
right matches when visiting ExpressionStatement - print parents and children:
IfStatement,BlockStatement,[ExpressionStatement] ⚟ [ 'CallExpression' ]
😱
right is false on BlockStatement. left is false on ExpressionStatement. no match 🔴
compare that to within IfStatement:has(>BlockStatement)
selector {
type: 'child',
left: { type: 'exactNode' },
right: { type: 'identifier', value: 'BlockStatement' }
}
left matches when visiting BlockStatement - print parents and children:
IfStatement,[BlockStatement] ⚟ [ 'ExpressionStatement' ]
right matches when visiting BlockStatement - print parents and children:
IfStatement,[BlockStatement] ⚟ [ 'ExpressionStatement' ]
left && right match on the same node ✔️
But even this doesn't look correct (should be [BlockStatement] ⚟ [ 'ExpressionStatement' ]
).
:has
injects IfStatement as an ancestor ❓ when checking the insides of :has(>BlockStatement)
. Then child
matches when visiting BlockStatement, and it checks left(ancestry[0], ancestry.slice(1), options)
:
- ancestry = [IfStatement]
- left = matcher for exactNode
- it checks if IfStatement has no ancestors ❓ not BlockStatement
An attempt to fix it: #148 |
Add more tests for #145 that show these selectors do not work correctly
:has(>BlockStatement>ExpressionStatement)
:has(>BlockStatement ExpressionStatement)
but there are workarounds:
:has(>BlockStatement:has(>ExpressionStatement))
:has(>BlockStatement:has(ExpressionStatement))