This API review was also recorded and is available on Google Hangouts.
Status: Needs work | API Reference | Video
With IOperation
, Roslyn will provide a language agnostic model for code (statements, expressions) that is implemented by both C# and VB, and potentially even IL. This will allow FxCop like tools to be able to have rules that can reason about code without having to drop down to the language specific syntax- and semantic APIs. It also allows to unify source and binary based analysis tools.
The entry point APIs for analyzers are RegisterOperationAction and RegisterOperationBlockAction. You can find usages here. They provide you the hierarchy of IOperation nodes to analyze.
- Roslyn has a unified symbol API
- For the code, they currently don't share a common API -- you're directly exposed to syntax
IOperation
provides a unified view over the internal bound tree represent the compiler has- Another goal is to raise the
IOperation
tree from IL - The compiler lowers the bound tree
- Roslyn currently exposes the highest level, because it's closest to source
- Since we can raise from IL, the believe is that we could expose all lowered representations as well, if needed. It might, however, require adding additional nodes.
- The name
IOperation
: the name needs to convey for unification of expressions and expressions. We believeoperation
is the closest term without dropping too much down to compiler lingo (such asISemanticNode
) - Should we follow the syntax and symbols and move some core concepts like
IOperation
andOperationKind
toMicrosoft.CodeAnalysis
?- This would leave breadcrumbs in the root that can aid with discoverability
- Consistency with syntax and symbols
- Consider an
IHasArgument
interface - Right now, consumers can't extend the syntax nor the symbol APIs
- The IL implementation has to
IOperation
has different kinds:OperationKind
,BinaryOperatorKind
,CaseKind
- Syntax doesn't do that
- Enum members should be organized so that common checks can be expressed efficient via be lower/higher bound checks
BinaryOperatorKind
seems a bit big, like it multiplies the operators, the specific argument types, and the specific semantics (like VB equals vs regular equals)
IExpression
andIStatement
should be purely abstract, i.e. there shouldn't be instances whose only public type isIExpression
/IStatement
. There should be specific subtypes, even if they have no members. This makes visitors much more logical.
Additional comments from @nguerrera:
-
IInstanceReferenceExpression
is currently also anIParameterReferenceExpression
to the hidden 'this' parameter. AFAICT, the hidden 'this' parameter is not otherwise exposed fromIMethodSymbol
and isn't really very useful so we might preferIInstanceReferenceExpression
inheriting directly fromIReferenceExpression
. This would resolve another case of a node-type that can be both interior and leaf, which came up as something to avoid across the board. -
Nodes of type
ICase
haveOperationKind.SwitchSection
and nodes of typeICatch
haveOperationKind.CatchHandler
. These are rare departures from the 1:1 between interface names and operation kinds. We should rename one way or the other to make them match. -
Consider having a single
OperationKind.Branch
forIBranchStatement
with a separateBranchKind
enum member withGoTo
,Break
,Exit
andContinue
values. In general, I'd fined a strict 1:1 between the operation kinds and the leaf-node interfaces cleaner and easier for analyzer authors to internalize as a pattern. -
There are both
ILabeledStatement
andILabelStatement
corresponding to differences in C#/VB.IOperation
should choose one representation or the other and normalize accordingly.
More comments are in the API reference.