Closed
Description
I like the approach taken by the SyntaxWalker
. It separates the traversal scaffolding code from my implementation. It would be nice to have a similar API available at the symbol level. Currently to traverse the symbols in a given compilation we must inherit from SymbolVisitor
and write all the scaffolding ourselves.
If you think this is relatively simple (the SyntaxWalker
seems pretty basic) you can mark is at "Up for grabs" and I'll take a stab at it.
Activity
CyrusNajmabadi commentedon Oct 19, 2015
THe problem here is that Syntax is a tree, while Symbols are a graph. How does the SymbolWalker terminate?
JoshVarty commentedon Oct 20, 2015
My thought was to visit them from the global namespace descending to child namespaces and types. Then from those types to methods and properties. Then from those methods/properties to their parameters, type arguments and locals. (Perhaps I'm missing something, but can we not think of this approach as traversing a tree?)
However, in looking over
IMethodSymbol
andIPropertySymbol
I don't see any ways in which we can get to locals. I don't believe we should build this unless we could cover all the symbols in the compilation, so I'm going to close this for now.CyrusNajmabadi commentedon Oct 20, 2015
Ok. So now you get to an IParameterSymbol. Would you then 'walk' into it's type? If so, then you face recursion problems. If not, then what are you walking, just trees?
If that's the case, you could simply use a SyntaxWalker and call GetDeclaredSymbol on all the nodes it hits. You'll then have a SymbolWalker.
JoshVarty commentedon Oct 20, 2015
No I wasn't thinking about walking the type of the
IParameterSymbol
, we'd stop when we reached it. The idea is that the underlying type there would have been visited elsewhere. (It's anINamedTypeSymbol
so it would have been visited as the child of a namespace at some point).I think you're thinking about visiting symbols on a document level. My thought process was to create something that would visit symbols on the compilation level.
I'm trying to (maybe wrongly?) think of symbols in a child-parent relationship. A namespace contains types. Types contain members. Members contain parameters, locals, type arguments etc. Unfortunately I think my approach breaks down once we reach the member level. There's no way I can see to easily get their "Child Symbols".
CyrusNajmabadi commentedon Oct 20, 2015
I don't think it's wrong. I think it's just an interesting view over something intrinsically graph-like.
Why not, once you hit a member, just go back to the syntax and go dive in and get the symbols from it and a semantic model?
jnm2 commentedon Oct 13, 2018
So I'm interested in walking only declarations of things (types, members, parameters), not references (base class, parameter type, etc). I think this neatly solves the graph problem.
SymbolDeclarationWalker
?CyrusNajmabadi commentedon Oct 13, 2018
@jnm2
:)
jnm2 commentedon Oct 13, 2018
@CyrusNajmabadi But I don't want to walk syntax. I want a unified semantic view of things like partial classes. Also, walking the syntax and calling
GetDeclaredSymbol
on every node can't be as smart as looking through ISymbol members.jnm2 commentedon Oct 13, 2018
Also, it's not inconceivable that there will be members in the symbolic model that are not present in the syntax. For example, With* methods if we get withers.
CyrusNajmabadi commentedon Oct 13, 2018
Gotcha. FWIW though, what you're describing is just a small handlful of LOCs. I'm skeptical about the overal value here. It may be good for your very specific case. But it's unclear to me if it's going to be suitable elsewhere. I mean, some users will say "i don't want implicit members" some will say " i want to walk into some of these referenced types". some will say "i don't want members from other parts not in this file", etc. etc.
The walking code is so trivial that just writing it yourself seems super simple and easy to just do that way.
jnm2 commentedon Oct 13, 2018
Does this cover every
ISymbol
that represents an actual declaration in today's Roslyn?CyrusNajmabadi commentedon Oct 13, 2018
i don't see it handling things like local declarations.
jnm2 commentedon Oct 13, 2018
You often don't want most of what a walker walks through. The concept of filtering out what you don't care about is well understood.
They can override and add a
symbol.BaseType?.Accept(this);
call then.Seems like they care enough about syntax in this scenario that they should start there.
CyrusNajmabadi commentedon Oct 13, 2018
also fields.
25 remaining items