-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Closed
Labels
Area-CompilersConcept-APIThis issue involves adding, removing, clarification, or modification of an API.This issue involves adding, removing, clarification, or modification of an API.Feature Requestapi-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedhelp wantedThe issue is "up for grabs" - add a comment if you are interested in working on itThe issue is "up for grabs" - add a comment if you are interested in working on it
Description
Background and Motivation
In order to avoid shared state and allowing parallel invocations of the same visitor, it would be nice to be able to use a SymbolVisitor<TArgument, TResult>. We already have a similar pattern with OperationVisitor.
Proposed API
namespace Microsoft.CodeAnalysis
{
+ public abstract class SymbolVisitor<TArgument, TResult>
+ {
+ public virtual TResult? Visit(ISymbol? symbol, TArgument argument)
+ {
+ if (symbol != null)
+ {
+ return symbol.Accept(this, argument);
+ }
+
+ return default(TResult);
+ }
+
+ public virtual TResult? DefaultVisit(ISymbol symbol, TArgument argument)
+ {
+ return default(TResult);
+ }
+
+ public virtual TResult? VisitAlias(IAliasSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitArrayType(IArrayTypeSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitAssembly(IAssemblySymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitDiscard(IDiscardSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitDynamicType(IDynamicTypeSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitEvent(IEventSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitField(IFieldSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitLabel(ILabelSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitLocal(ILocalSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitMethod(IMethodSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitModule(IModuleSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitNamedType(INamedTypeSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitNamespace(INamespaceSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitParameter(IParameterSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitPointerType(IPointerTypeSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitFunctionPointerType(IFunctionPointerTypeSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitProperty(IPropertySymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitRangeVariable(IRangeVariableSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+
+ public virtual TResult? VisitTypeParameter(ITypeParameterSymbol symbol, TArgument argument)
+ {
+ return DefaultVisit(symbol, argument);
+ }
+ }
public interface ISymbol : IEquatable<ISymbol?>
{
// ...
void Accept(SymbolVisitor visitor);
TResult? Accept<TResult>(SymbolVisitor<TResult> visitor);
+ TResult? Accept<TArgument, TResult>(SymbolVisitor<TArgument, TResult> visitor, TArgument argument);
// ...
}
}Usage Examples
var result = symbol.Accept(new GenerateIdVisitor(), new GeneratorContext());Alternative Designs
It would be possible to implement a visitor based on dynamic invocation, however, I think this is not the optimal solution.
Risks
none I can think of
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Area-CompilersConcept-APIThis issue involves adding, removing, clarification, or modification of an API.This issue involves adding, removing, clarification, or modification of an API.Feature Requestapi-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedhelp wantedThe issue is "up for grabs" - add a comment if you are interested in working on itThe issue is "up for grabs" - add a comment if you are interested in working on it