Summary
When a generic method void Process<T>(T item) is called through a reference (e.g., Process<IFoo>(x)), the reference graph records a direct call to Process but does not track which concrete type T resolves to. This causes impact analysis to miss callers when the method is overridden in a base class with a different type parameter constraint or when analyzing constrained generic method chains.
Where
src/CodeIndex/Database/DbReader.GraphQueries.cs:697-780 (GetCallersExact treats generics as opaque)
src/CodeIndex/Database/DbReader.CSharpResolution.cs (no generic type parameter substitution tracking)
Suggested approach
- Parse generic type arguments from call sites and store them as metadata in symbol_references (add generic_args column)
- When resolving transitive callers, match method signatures against stored generic constraints
- For base-class generic methods, emit implicit edges to all derived overrides parameterized with the same type
- Trace type parameter flow across method call chains to validate consistency
Summary
When a generic method
void Process<T>(T item)is called through a reference (e.g.,Process<IFoo>(x)), the reference graph records a direct call toProcessbut does not track which concrete type T resolves to. This causes impact analysis to miss callers when the method is overridden in a base class with a different type parameter constraint or when analyzing constrained generic method chains.Where
src/CodeIndex/Database/DbReader.GraphQueries.cs:697-780(GetCallersExact treats generics as opaque)src/CodeIndex/Database/DbReader.CSharpResolution.cs(no generic type parameter substitution tracking)Suggested approach