Skip to content

Commit 60a3f65

Browse files
committed
Encode SPL suggestions the same as other suggestions
1 parent 43d2ea8 commit 60a3f65

3 files changed

Lines changed: 32 additions & 6 deletions

File tree

build.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,26 @@ fn parse_map_entry(line: &str) -> Option<(String, String)> {
237237
let key = lhs.trim().strip_prefix('\'')?.strip_suffix('\'')?;
238238
let value = rhs.trim().strip_prefix('\'')?.strip_suffix('\'')?;
239239

240-
Some((key.to_string(), value.to_string()))
240+
// Unescape PHP single-quoted string escapes:
241+
// `\\` → `\` and `\'` → `'`
242+
// This is needed because the PhpStormStubsMap.php file uses PHP
243+
// single-quoted strings where namespace separators are written as
244+
// `\\` (e.g. `'Couchbase\\GetUserOptions'` → `Couchbase\GetUserOptions`).
245+
let key = php_unescape_single_quoted(key);
246+
let value = php_unescape_single_quoted(value);
247+
248+
Some((key, value))
249+
}
250+
251+
/// Unescape a PHP single-quoted string value.
252+
///
253+
/// PHP single-quoted strings only recognise two escape sequences:
254+
/// - `\\` → `\`
255+
/// - `\'` → `'`
256+
fn php_unescape_single_quoted(s: &str) -> String {
257+
s.replace("\\\\", "\x00")
258+
.replace("\\'", "'")
259+
.replace('\x00', "\\")
241260
}
242261

243262
/// Escape a string for embedding in a Rust string literal.

src/completion/builder.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,13 +409,14 @@ impl Backend {
409409
if !seen_fqns.insert(name.to_string()) {
410410
continue;
411411
}
412+
let short_name = name.rsplit('\\').next().unwrap_or(name);
412413
items.push(CompletionItem {
413-
label: name.to_string(),
414+
label: short_name.to_string(),
414415
kind: Some(CompletionItemKind::CLASS),
415416
detail: Some(name.to_string()),
416-
insert_text: Some(name.to_string()),
417-
filter_text: Some(name.to_string()),
418-
sort_text: Some(format!("2_{}", name.to_lowercase())),
417+
insert_text: Some(short_name.to_string()),
418+
filter_text: Some(short_name.to_string()),
419+
sort_text: Some(format!("2_{}", short_name.to_lowercase())),
419420
..CompletionItem::default()
420421
});
421422
}

tests/completion_class_names.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,13 @@ async fn test_class_name_completion_from_classmap() {
447447
);
448448

449449
// Check that detail shows the FQN
450-
let collection = classes.iter().find(|i| i.label == "Collection").unwrap();
450+
let collection = classes
451+
.iter()
452+
.find(|i| {
453+
i.label == "Collection"
454+
&& i.detail.as_deref() == Some("Illuminate\\Support\\Collection")
455+
})
456+
.expect("Should have a Collection item with FQN Illuminate\\Support\\Collection in detail");
451457
assert_eq!(
452458
collection.detail.as_deref(),
453459
Some("Illuminate\\Support\\Collection"),

0 commit comments

Comments
 (0)