Skip to content

Commit a96d50c

Browse files
committed
Improve findOccurrencesWithin heuristics
Handle multiple variable assignments and declarations in one declaration command
1 parent fd9a01c commit a96d50c

File tree

1 file changed

+19
-24
lines changed

1 file changed

+19
-24
lines changed

server/src/analyser.ts

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ export default class Analyzer {
306306
* (after the equals sign) of the `definition` node (should be a declaration
307307
* command or variable assignment) given.
308308
*
309-
* Important in cases of `var="$var"`, if the `word` is `$var` then `var`
309+
* Important in cases of `var=$var`, if the `word` is `$var` then `var`
310310
* should be skipped and a higher scope should be checked for the original
311311
* declaration.
312312
*/
@@ -585,9 +585,6 @@ export default class Analyzer {
585585

586586
/**
587587
* A more scope-aware version of findOccurrences.
588-
*
589-
* TODO: Improve handling of multiple variable assignments and declarations in
590-
* one declaration command.
591588
*/
592589
public findOccurrencesWithin({
593590
uri,
@@ -632,20 +629,14 @@ export default class Analyzer {
632629
return false
633630
}
634631

635-
const parentScope = this.parentScope(n)
636-
const definition = TreeSitterUtil.findParentOfType(
637-
n,
638-
parentScope?.type === 'function_definition'
639-
? 'declaration_command'
640-
: 'variable_assignment',
641-
)
642-
const definedVariable = definition?.descendantsOfType('variable_name')?.at(0)
632+
const definition = TreeSitterUtil.findParentOfType(n, 'variable_assignment')
633+
const definedVariable = definition?.descendantsOfType('variable_name').at(0)
643634

644-
// Special handling for var="$var" cases
635+
// For var=$var cases, this decides whether $var is an occurrence or not.
645636
if (definedVariable?.text === word && !n.equals(definedVariable)) {
646637
// `start?.line` is assumed to be the same as the variable's original
647-
// declaration line; handles cases where var should be renamed but
648-
// $var shouldn't.
638+
// declaration line; handles cases where $var shouldn't be considered
639+
// an occurrence.
649640
if (definition?.startPosition.row === start?.line) {
650641
return false
651642
}
@@ -657,26 +648,30 @@ export default class Analyzer {
657648
return true
658649
}
659650

660-
if (!parentScope || baseNode.equals(parentScope)) {
651+
const parent = this.parentScope(n)
652+
653+
if (!parent || baseNode.equals(parent)) {
661654
return true
662655
}
663656

657+
const declarationCommand = TreeSitterUtil.findParentOfType(n, 'declaration_command')
664658
const includeDeclaration = !ignoredRanges.some(
665659
(r) => n.startPosition.row > r.start.line && n.endPosition.row < r.end.line,
666660
)
667661

668-
if (!definition) {
662+
if (!definition && !declarationCommand) {
669663
return includeDeclaration
670664
}
671665

672-
const isLocalDefinition =
673-
definedVariable?.text === word &&
674-
(parentScope.type === 'subshell'
675-
? !!definition
676-
: ['local', 'declare', 'typeset'].includes(definition.firstChild?.text as any))
677-
if (isLocalDefinition) {
666+
const isLocal =
667+
(definedVariable?.text === word || !!(!definition && declarationCommand)) &&
668+
(parent.type === 'subshell' ||
669+
['local', 'declare', 'typeset'].includes(
670+
declarationCommand?.firstChild?.text as any,
671+
))
672+
if (isLocal) {
678673
if (includeDeclaration) {
679-
ignoredRanges.push(TreeSitterUtil.range(parentScope))
674+
ignoredRanges.push(TreeSitterUtil.range(parent))
680675
}
681676

682677
return false

0 commit comments

Comments
 (0)