Annotate AST node classes with their C# grammar productions
Each concrete syntax node now carries, in an XML-doc <remarks> block, the
matching production from the C# language specification grammar (ECMA/Microsoft,
ANTLR notation), quoted verbatim. Aggregate nodes (e.g. BinaryOperatorExpression,
ComposedType, TypeDeclaration) list every production they span; lexical/trivia
nodes (Comment, the preprocessor directives, Identifier) cite the lexical rule.
Nodes with no spec production -- ErrorExpression, UndocumentedExpression,
InvocationAstType, TypeReferenceExpression, NamedExpression, DocumentationReference,
and the C# 14 ExtensionDeclaration -- carry a hand-written EBNF plus a note
explaining why no official production exists.
Assisted-by: Claude:claude-opus-4-8:Claude Code
/// Operator precedence is not represented in the syntax tree; required parentheses are reconstructed by <see cref="ICSharpCode.Decompiler.CSharp.OutputVisitor.InsertParenthesesVisitor"/>.
/// <c>as_expression : expression 'as' type ;</c> (C# grammar §12.15.1)
@ -30,7 +30,9 @@ using System.Linq.Expressions;
@@ -30,7 +30,9 @@ using System.Linq.Expressions;
namespaceICSharpCode.Decompiler.CSharp.Syntax
{
/// <summary>
/// Left Operator= Right
/// Operator precedence is not represented in the syntax tree; required parentheses are reconstructed by <see cref="ICSharpCode.Decompiler.CSharp.OutputVisitor.InsertParenthesesVisitor"/>.
@ -30,7 +30,9 @@ using System.Linq.Expressions;
@@ -30,7 +30,9 @@ using System.Linq.Expressions;
namespaceICSharpCode.Decompiler.CSharp.Syntax
{
/// <summary>
/// Left Operator Right
/// Operator precedence is not represented in the syntax tree; required parentheses are reconstructed by <see cref="ICSharpCode.Decompiler.CSharp.OutputVisitor.InsertParenthesesVisitor"/>.
/// Operator precedence is not represented in the syntax tree; required parentheses are reconstructed by <see cref="ICSharpCode.Decompiler.CSharp.OutputVisitor.InsertParenthesesVisitor"/>.
/// Operator precedence is not represented in the syntax tree; required parentheses are reconstructed by <see cref="ICSharpCode.Decompiler.CSharp.OutputVisitor.InsertParenthesesVisitor"/>.
/// This isn't the same as 'assign' even though it has the same syntax.
/// This expression is used in object initializers and for named attribute arguments [Attr(FieldName = value)].
/// No standalone expression production: 'name = value' as used in object initializers (member_initializer), anonymous-object members (member_declarator), and named attribute arguments.
/// Operator precedence is not represented in the syntax tree; required parentheses are reconstructed by <see cref="ICSharpCode.Decompiler.CSharp.OutputVisitor.InsertParenthesesVisitor"/>.
@ -30,7 +30,10 @@ using System.Linq.Expressions;
@@ -30,7 +30,10 @@ using System.Linq.Expressions;
namespaceICSharpCode.Decompiler.CSharp.Syntax
{
/// <summary>
/// Operator Expression
/// Operator precedence is not represented in the syntax tree; required parentheses are reconstructed by <see cref="ICSharpCode.Decompiler.CSharp.OutputVisitor.InsertParenthesesVisitor"/>.
@ -21,7 +21,8 @@ using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
@@ -21,7 +21,8 @@ using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
namespaceICSharpCode.Decompiler.CSharp.Syntax
{
/// <summary>
/// Expression with Initializer
/// Operator precedence is not represented in the syntax tree; required parentheses are reconstructed by <see cref="ICSharpCode.Decompiler.CSharp.OutputVisitor.InsertParenthesesVisitor"/>.
@ -21,7 +21,8 @@ using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
@@ -21,7 +21,8 @@ using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
namespaceICSharpCode.Decompiler.CSharp.Syntax
{
/// <summary>
/// BaseType "(" Argument { "," Argument } ")"
/// No C# spec grammar production: ILSpy-internal type form used when a type appears applied to arguments (e.g. an attribute type written with its constructor arguments).
/// <c>invocation_ast_type : type '(' argument_list? ')' ;</c>