Skip to content

Fix #3797: resolve ilspycmd -t type names with fuzzy matching - #3801

Merged
siegfriedpammer merged 1 commit into
masterfrom
fix-3797-ilspycmd-type-name-matching
Jun 22, 2026
Merged

Fix #3797: resolve ilspycmd -t type names with fuzzy matching#3801
siegfriedpammer merged 1 commit into
masterfrom
fix-3797-ilspycmd-type-name-matching

Conversation

@siegfriedpammer

@siegfriedpammer siegfriedpammer commented Jun 22, 2026

Copy link
Copy Markdown
Member

Fixes #3797.

--list-* printed generic types without their `n arity suffix, but -t only accepted the exact reflection name. So a type name copied straight from the listing (e.g. JetBrains.ReSharper.Psi.CachedPsiValue) threw Could not find type definition and the user had to know to append `1 by hand.

Changes

  • Listing now prints FullTypeName.ReflectionName, so the names it emits are directly usable with -t.
  • -t resolution goes through a ladder of progressively looser, uniqueness-checked rules:
    1. the engine's exact reflection-name lookup (Ns.List`1);
    2. an arity- and nesting-separator-insensitive FullName match (Ns.List, Ns.A`1+B`2);
    3. a case-insensitive FullName match;
    4. a namespace-less simple name (List);
    5. a trailing segment path (Dictionary.KeyCollection...Generic.Dictionary`2+KeyCollection, matched on whole .-separated segments so ReadOnlyDictionary.KeyCollection is not a false hit).
  • The input is parsed with System.Reflection.Metadata.TypeName and reduced to its underlying definition first, so assembly qualification, generic arguments, and array/pointer/byref decorations cannot corrupt the comparison key.
  • Error reporting: an ambiguous name reports its candidate reflection names instead of guessing; a miss prints "did you mean" suggestions (substring, falling back to subsequence for typos) and returns EX_DATAERR instead of dumping a stack trace.

Verified

Built and run against System.Private.CoreLib.dll, ICSharpCode.Decompiler.dll, and a purpose-built nested-generic assembly:

  • -t Ns.EmptyList (arity-stripped) and -t EmptyList (simple) resolve the generic type.
  • -t Dictionary.KeyCollection resolves the nested type; -t ReadOnlyDictionary.KeyCollection resolves its own distinct type.
  • Constructed-generic (List`1[[System.String, ...]]), assembly-qualified, array (List`1[]) and byref forms all reduce to the type definition.
  • -t KeyCollection reports the ambiguity with candidates; an unknown name returns exit code 65 with suggestions.

This PR description was written by an AI agent (Claude, claude-opus-4-8, via Claude Code).

--list-* printed generic types without their `n arity suffix, yet -t only
accepted the exact reflection name, so a name copied straight from the listing
threw "Could not find type definition". The listing now prints the reflection
name, and -t resolves through a ladder of progressively looser, uniqueness-
checked rules: the engine's exact lookup, an arity- and nesting-separator-
insensitive FullName match, a case-insensitive match, a namespace-less simple
name, and a trailing segment path ("Dictionary.KeyCollection"). The input is
parsed with System.Reflection.Metadata.TypeName and reduced to its underlying
definition first, so assembly qualification, generic arguments, and
array/pointer/byref decorations cannot corrupt the comparison key. An ambiguous
name reports its candidates instead of guessing, and a miss prints name
suggestions and returns EX_DATAERR rather than dumping a stack trace.

Assisted-by: Claude:claude-opus-4-8:Claude Code
@siegfriedpammer
siegfriedpammer merged commit 53498c5 into master Jun 22, 2026
13 checks passed
@siegfriedpammer
siegfriedpammer deleted the fix-3797-ilspycmd-type-name-matching branch June 22, 2026 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

System.InvalidOperationException: Could not find type definition, but for types that do exist

1 participant