Skip to content

Commit 46ff27a

Browse files
committed
Resolve Foo::class parameter defaults to FQN in extract_parameters
1 parent 5e4a597 commit 46ff27a

1 file changed

Lines changed: 38 additions & 1 deletion

File tree

src/parser/mod.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -938,7 +938,15 @@ pub(crate) fn extract_parameters(
938938
let span = dv.value.span();
939939
let start = span.start.offset as usize;
940940
let end = span.end.offset as usize;
941-
src.get(start..end).map(|s| s.trim().to_string())
941+
let raw = src.get(start..end)?.trim().to_string();
942+
// Resolve `ClassName::class` to its FQN so that
943+
// downstream template substitution can find the class.
944+
if let Some(class_name) = raw.strip_suffix("::class") {
945+
let fqn = resolve_default_class_name(class_name, doc_ctx);
946+
Some(format!("{}::class", fqn))
947+
} else {
948+
Some(raw)
949+
}
942950
});
943951

944952
ParameterInfo {
@@ -956,6 +964,35 @@ pub(crate) fn extract_parameters(
956964
.collect()
957965
}
958966

967+
/// Resolve a class name from a parameter default (`Foo::class`) to its FQN
968+
/// using the file's use-map and namespace from [`DocblockCtx`].
969+
fn resolve_default_class_name(name: &str, doc_ctx: Option<&DocblockCtx<'_>>) -> String {
970+
// Already fully-qualified.
971+
if let Some(stripped) = name.strip_prefix('\\') {
972+
return stripped.to_string();
973+
}
974+
let Some(ctx) = doc_ctx else {
975+
return name.to_string();
976+
};
977+
// Check use-map (handles `use App\Application;` → "Application" → "App\Application").
978+
if let Some(fqn) = ctx.use_map.get(name) {
979+
return fqn.clone();
980+
}
981+
// If the name has a namespace prefix (e.g. `Sub\Foo`), check the first segment.
982+
if let Some(first_seg) = name.split('\\').next()
983+
&& first_seg != name
984+
&& let Some(base) = ctx.use_map.get(first_seg)
985+
{
986+
let rest = &name[first_seg.len() + 1..];
987+
return format!("{}\\{}", base, rest);
988+
}
989+
// Prepend file namespace if present.
990+
if let Some(ref ns) = ctx.namespace {
991+
return format!("{}\\{}", ns, name);
992+
}
993+
name.to_string()
994+
}
995+
959996
/// Extract visibility from a set of modifiers.
960997
/// Defaults to `Public` if no visibility modifier is present.
961998
pub(crate) fn extract_visibility<'a>(

0 commit comments

Comments
 (0)