Skip to content

Commit 840d33e

Browse files
committed
Fix resolution issue
1 parent b9c69c6 commit 840d33e

2 files changed

Lines changed: 43 additions & 1 deletion

File tree

src/text_scan.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,14 @@ fn same_line_continuation_prefix(trimmed: &str) -> Option<&str> {
432432
let mut saw_closer = false;
433433
for (idx, ch) in trimmed.char_indices() {
434434
match ch {
435-
')' | '}' | ']' => {
435+
// Only `)`/`}` are recognized here because the backward balance
436+
// scan below (and in `collapse_continuation_lines`) only tracks
437+
// paren/brace depth, not bracket depth. Treating `]` as a
438+
// trigger would let this collapse a multi-line array subscript
439+
// (`$config[\n 'key',\n]->foo`) while never accounting for
440+
// the `[`, so the walk stops one line too early and silently
441+
// drops the base expression instead of producing no match.
442+
')' | '}' => {
436443
saw_closer = true;
437444
end = idx + ch.len_utf8();
438445
}

tests/integration/completion_multiline_chains.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,3 +559,38 @@ async fn test_multiline_chain_same_line_after_closure_arg_close() {
559559
"Should offer Collection::all() after same-line closure close, got: {names:?}"
560560
);
561561
}
562+
563+
#[tokio::test]
564+
async fn test_multiline_chain_same_line_after_bracket_close_does_not_misresolve() {
565+
// Bracket depth (`[`/`]`) is not tracked by the backward balance scan
566+
// used to reconstruct the base expression, so a chain operator that
567+
// follows a closing `]` on its own line must not be treated as a
568+
// same-line continuation: doing so would drop everything before the
569+
// bracket close (e.g. the `$this->items[` base) and hand the resolver
570+
// a malformed expression instead of the real receiver. Falling back to
571+
// "no completions" is correct here; resolving to the wrong receiver's
572+
// members would not be.
573+
let backend = create_test_backend();
574+
let uri = Url::parse("file:///multiline_bracket_same_line.php").unwrap();
575+
let text = concat!(
576+
"<?php\n",
577+
"class Box {\n",
578+
" public function open(): string { return ''; }\n",
579+
"}\n",
580+
"class Container {\n",
581+
" /** @var array<string, Box> */\n",
582+
" public array $items = [];\n",
583+
" public function run(): void {\n",
584+
" $this->items[\n",
585+
" 'key'\n",
586+
" ]->o\n",
587+
" }\n",
588+
"}\n",
589+
);
590+
591+
let names = complete_at(&backend, &uri, text, 10, 12).await;
592+
assert!(
593+
!names.iter().any(|n| n.starts_with("open(")),
594+
"Should not resolve Box::open() from a malformed collapsed expression, got: {names:?}"
595+
);
596+
}

0 commit comments

Comments
 (0)