-
|
I want to retrieve all references to a method at compile time and obtain the generic types they pass. What are some good methods |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
Unfortunately, there's no direct way to retrieve all callers of a method and their generic type arguments from within an aspect at compile time to use that information for code generation. However, there are a few approaches depending on your goal: 1. Validation Only: Using Metalama.Extensions.ArchitectureIf you want to validate how your method is called (and report diagnostics), you can use inbound reference validation: [AttributeUsage(AttributeTargets.Method)]
public class JsonMethodAttribute : Attribute, IAspect<IMethod>
{
private static readonly DiagnosticDefinition<INamedType> _info = new(
"JSON001",
Severity.Info,
"Method is called with type argument '{0}'");
public void BuildAspect(IAspectBuilder<IMethod> builder)
{
builder.Outbound.ValidateInboundReferences(
this.ValidateReference,
ReferenceGranularity.Member);
}
private void ValidateReference(ReferenceValidationContext context)
{
// You can inspect the reference here
if (context.Origin is IMethod originMethod)
{
// Access generic arguments of the call
// But you can only REPORT diagnostics, not generate code
context.Diagnostics.Report(_info.WithArguments(...));
}
}
}Important: This approach only allows you to report diagnostics (warnings, errors, info messages). You cannot use it to add attributes or generate code based on what you find. See: Validating code from an aspect 2. For Aspect Code Generation: No SolutionIf you want to generate code (like adding The fundamental issue is that aspects execute during compilation before all call sites are known, and there's no mechanism to collect caller information and use it for code generation. 3. Analysis Tool: Using Metalama.Framework.WorkspacesIf you want to analyze your codebase to find all callers (for example, as part of a build tool or code analysis utility), you can use using Metalama.Framework.Workspaces;
var workspace = Workspace.Load(@"MySolution.sln");
// Find your class
var myClass = workspace.SourceCode.Types
.FirstOrDefault(t => t.Name == "MyJsonHelper");
if (myClass != null)
{
// Find the ToJson method
var toJsonMethod = myClass.Methods
.FirstOrDefault(m => m.Name == "ToJson" && m.IsGeneric);
if (toJsonMethod != null)
{
// Get all inbound references (callers)
var references = toJsonMethod.GetInboundReferences();
foreach (var reference in references)
{
// Analyze each call site
// You could generate a source file based on this analysis
}
}
}This runs outside the normal compilation process and would be suitable for a build-time code generator or analysis tool, but not for runtime aspect weaving. Could you provide more details about what you're trying to achieve? Specifically:
This will help us suggest the best approach for your scenario. — Claude for Gael Fraiteur |
Beta Was this translation helpful? Give feedback.
Unfortunately, there's no direct way to retrieve all callers of a method and their generic type arguments from within an aspect at compile time to use that information for code generation.
However, there are a few approaches depending on your goal:
1. Validation Only: Using Metalama.Extensions.Architecture
If you want to validate how your method is called (and report diagnostics), you can use inbound reference validation: