Browse Source

Generate name-token slots from [NameSlot] string properties

A [NameSlot("role")] partial string property makes the generator own the
backing Identifier token slot, the string accessor, and the match term, so a
convenience name string and its hand-written token slot collapse to a single
declaration. A nullOnEmpty option stores a null token for an empty name, used
where the output visitor keys off an absent token. Apply it across every
name-token node.
Assisted-by: Claude:claude-opus-4-8:Claude Code
pull/3807/head
Siegfried Pammer 3 weeks ago committed by Siegfried Pammer
parent
commit
126cb3b18d
  1. 85
      ICSharpCode.Decompiler.Generators/DecompilerSyntaxTreeGenerator.cs
  2. 2
      ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs
  3. 15
      ICSharpCode.Decompiler/CSharp/Syntax/Expressions/IdentifierExpression.cs
  4. 15
      ICSharpCode.Decompiler/CSharp/Syntax/Expressions/MemberReferenceExpression.cs
  5. 15
      ICSharpCode.Decompiler/CSharp/Syntax/Expressions/NamedArgumentExpression.cs
  6. 15
      ICSharpCode.Decompiler/CSharp/Syntax/Expressions/NamedExpression.cs
  7. 15
      ICSharpCode.Decompiler/CSharp/Syntax/Expressions/PointerReferenceExpression.cs
  8. 75
      ICSharpCode.Decompiler/CSharp/Syntax/Expressions/QueryExpression.cs
  9. 15
      ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/ExternAliasDeclaration.cs
  10. 15
      ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/TypeParameterDeclaration.cs
  11. 15
      ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/UsingAliasDeclaration.cs
  12. 15
      ICSharpCode.Decompiler/CSharp/Syntax/MemberType.cs
  13. 15
      ICSharpCode.Decompiler/CSharp/Syntax/SimpleType.cs
  14. 18
      ICSharpCode.Decompiler/CSharp/Syntax/Statements/GotoStatement.cs
  15. 15
      ICSharpCode.Decompiler/CSharp/Syntax/Statements/LabelStatement.cs
  16. 16
      ICSharpCode.Decompiler/CSharp/Syntax/Statements/TryCatchStatement.cs
  17. 11
      ICSharpCode.Decompiler/CSharp/Syntax/TupleAstType.cs
  18. 15
      ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/FixedVariableInitializer.cs
  19. 15
      ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/ParameterDeclaration.cs
  20. 15
      ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/VariableInitializer.cs
  21. 11
      ICSharpCode.Decompiler/CSharp/Syntax/VariableDesignation.cs

85
ICSharpCode.Decompiler.Generators/DecompilerSyntaxTreeGenerator.cs

@ -30,7 +30,7 @@ namespace ICSharpCode.Decompiler.Generators;
[Generator] [Generator]
internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator
{ {
record AstNodeAdditions(string NodeName, bool NeedsAcceptImpls, bool NeedsVisitor, bool NeedsNullNode, bool NeedsPatternPlaceholder, int NullNodeBaseCtorParamCount, bool IsTypeNode, string VisitMethodName, string VisitMethodParamType, EquatableArray<(string Member, string TypeName, bool RecursiveMatch, bool MatchAny, bool Nullable)>? MembersToMatch, EquatableArray<(string RoleExpr, bool IsCollection, string PropertyName, string PropertyType, string ElementType, bool IsOverride, bool IsNullable, string KindName)>? Slots); record AstNodeAdditions(string NodeName, bool NeedsAcceptImpls, bool NeedsVisitor, bool NeedsNullNode, bool NeedsPatternPlaceholder, int NullNodeBaseCtorParamCount, bool IsTypeNode, string VisitMethodName, string VisitMethodParamType, EquatableArray<(string Member, string TypeName, bool RecursiveMatch, bool MatchAny, bool Nullable)>? MembersToMatch, EquatableArray<(string RoleExpr, bool IsCollection, string PropertyName, string PropertyType, string ElementType, bool IsOverride, bool IsNullable, string KindName, bool IsPartial)>? Slots, EquatableArray<(string StringName, string TokenName, bool NullOnEmpty)>? NameSlots);
// Derives the shared SlotKind name from a [Slot] role expression: the last dotted segment with a // Derives the shared SlotKind name from a [Slot] role expression: the last dotted segment with a
// trailing "Role" removed (e.g. "Roles.EmbeddedStatement" -> "EmbeddedStatement", "LeftRole" -> // trailing "Role" removed (e.g. "Roles.EmbeddedStatement" -> "EmbeddedStatement", "LeftRole" ->
@ -107,27 +107,45 @@ internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator
} }
} }
// Collect the slot schema: child properties tagged [Slot], in declaration order. The // Collect the slot schema: child properties tagged [Slot] or [NameSlot], in declaration order
// attribute names the Role expression to use; single vs collection comes from the type. // (the order is the node's child layout, so it must follow the source, not be grouped by kind).
List<(string RoleExpr, bool IsCollection, string PropertyName, string PropertyType, string ElementType, bool IsOverride, bool IsNullable, string KindName)>? slots = null; // [Slot] names the Role expression and infers single vs collection from the type. [NameSlot("role")]
// string X declares only the convenience string; the generator owns the backing Identifier XToken
// child slot (emitted like a [Slot], but non-partial since the source does not declare it) plus the
// string body. DoMatch matches X (a string) and never sees XToken.
List<(string RoleExpr, bool IsCollection, string PropertyName, string PropertyType, string ElementType, bool IsOverride, bool IsNullable, string KindName, bool IsPartial)>? slots = null;
List<(string StringName, string TokenName, bool NullOnEmpty)>? nameSlots = null;
foreach (var m in targetSymbol.GetMembers()) foreach (var m in targetSymbol.GetMembers())
{ {
if (m is not IPropertySymbol property) if (m is not IPropertySymbol property)
continue; continue;
var slotAttr = property.GetAttributes().FirstOrDefault(a => a.AttributeClass?.Name == "SlotAttribute"); var slotAttr = property.GetAttributes().FirstOrDefault(a => a.AttributeClass?.Name == "SlotAttribute");
if (slotAttr == null) if (slotAttr != null)
{
slots ??= new();
string roleExpr = (string)slotAttr.ConstructorArguments[0].Value!;
bool isCollection = property.Type.MetadataName == "AstNodeCollection`1";
bool isNullable = property.Type.NullableAnnotation == NullableAnnotation.Annotated;
var unannotated = property.Type.WithNullableAnnotation(NullableAnnotation.NotAnnotated);
string propertyType = unannotated.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
// For a collection slot, the element type is the single type argument of AstNodeCollection<T>.
string elementType = isCollection
? ((INamedTypeSymbol)property.Type).TypeArguments[0].ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)
: propertyType;
slots.Add((roleExpr, isCollection, property.Name, propertyType, elementType, property.IsOverride, isNullable, SlotKindName(roleExpr), true));
continue; continue;
slots ??= new(); }
string roleExpr = (string)slotAttr.ConstructorArguments[0].Value!; var nameSlotAttr = property.GetAttributes().FirstOrDefault(a => a.AttributeClass?.Name == "NameSlotAttribute");
bool isCollection = property.Type.MetadataName == "AstNodeCollection`1"; if (nameSlotAttr != null)
bool isNullable = property.Type.NullableAnnotation == NullableAnnotation.Annotated; {
var unannotated = property.Type.WithNullableAnnotation(NullableAnnotation.NotAnnotated); nameSlots ??= new();
string propertyType = unannotated.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat); slots ??= new();
// For a collection slot, the element type is the single type argument of AstNodeCollection<T>. string roleExpr = (string)nameSlotAttr.ConstructorArguments[0].Value!;
string elementType = isCollection bool nullOnEmpty = nameSlotAttr.ConstructorArguments.Length > 1 && (bool)nameSlotAttr.ConstructorArguments[1].Value!;
? ((INamedTypeSymbol)property.Type).TypeArguments[0].ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat) string tokenName = property.Name + "Token";
: propertyType; slots.Add((roleExpr, false, tokenName, "Identifier", "Identifier", false, false, SlotKindName(roleExpr), false));
slots.Add((roleExpr, isCollection, property.Name, propertyType, elementType, property.IsOverride, isNullable, SlotKindName(roleExpr))); nameSlots.Add((property.Name, tokenName, nullOnEmpty));
}
} }
return new(targetSymbol.Name, !targetSymbol.MemberNames.Contains("AcceptVisitor"), return new(targetSymbol.Name, !targetSymbol.MemberNames.Contains("AcceptVisitor"),
@ -136,7 +154,7 @@ internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator
NeedsPatternPlaceholder: (bool)attribute.ConstructorArguments[1].Value!, NeedsPatternPlaceholder: (bool)attribute.ConstructorArguments[1].Value!,
NullNodeBaseCtorParamCount: targetSymbol.InstanceConstructors.Min(m => m.Parameters.Length), NullNodeBaseCtorParamCount: targetSymbol.InstanceConstructors.Min(m => m.Parameters.Length),
IsTypeNode: targetSymbol.Name == "AstType" || targetSymbol.BaseType?.Name == "AstType", IsTypeNode: targetSymbol.Name == "AstType" || targetSymbol.BaseType?.Name == "AstType",
visitMethodName, paramTypeName, membersToMatch?.ToEquatableArray(), slots?.ToEquatableArray()); visitMethodName, paramTypeName, membersToMatch?.ToEquatableArray(), slots?.ToEquatableArray(), nameSlots?.ToEquatableArray());
} }
// Backing-field name for a slot property. Prefixed to avoid colliding with hand-written fields // Backing-field name for a slot property. Prefixed to avoid colliding with hand-written fields
@ -333,18 +351,19 @@ internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator
// substitutes the role's null object when empty (pre-NRT); a collection slot owns a lazily // substitutes the role's null object when empty (pre-NRT); a collection slot owns a lazily
// created AstNodeCollection bound to this node. A slot re-declared from an inherited contract // created AstNodeCollection bound to this node. A slot re-declared from an inherited contract
// member (Part I.3 flatten) is an override. // member (Part I.3 flatten) is an override.
foreach (var (roleExpr, isCollection, name, type, elementType, isOverride, isNullable, kindName) in slots) foreach (var (roleExpr, isCollection, name, type, elementType, isOverride, isNullable, kindName, isPartial) in slots)
{ {
string field = FieldName(name); string field = FieldName(name);
string partialKw = isPartial ? "partial " : "";
if (isCollection) if (isCollection)
{ {
builder.AppendLine($"\tAstNodeCollection<{elementType}>? {field};"); builder.AppendLine($"\tAstNodeCollection<{elementType}>? {field};");
builder.AppendLine($"\tpublic {(isOverride ? "override " : "")}partial AstNodeCollection<{elementType}> {name} => {field} ??= new AstNodeCollection<{elementType}>(this, {roleExpr});"); builder.AppendLine($"\tpublic {(isOverride ? "override " : "")}{partialKw}AstNodeCollection<{elementType}> {name} => {field} ??= new AstNodeCollection<{elementType}>(this, {roleExpr});");
} }
else else
{ {
builder.AppendLine($"\t{type}? {field};"); builder.AppendLine($"\t{type}? {field};");
builder.AppendLine($"\tpublic {(isOverride ? "override " : "")}partial {type} {name}"); builder.AppendLine($"\tpublic {(isOverride ? "override " : "")}{partialKw}{type} {name}");
builder.AppendLine("\t{"); builder.AppendLine("\t{");
builder.AppendLine($"\t\tget => {field}{(isNullable ? "" : $" ?? {roleExpr}.NullObject")};"); builder.AppendLine($"\t\tget => {field}{(isNullable ? "" : $" ?? {roleExpr}.NullObject")};");
builder.AppendLine($"\t\tset => SetChildNode(ref {field}, value, {roleExpr});"); builder.AppendLine($"\t\tset => SetChildNode(ref {field}, value, {roleExpr});");
@ -353,6 +372,23 @@ internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator
builder.AppendLine(); builder.AppendLine();
} }
// A [NameSlot] string is a convenience accessor over its generated Identifier token slot.
if (source.NameSlots is { } nameSlotsArray)
{
foreach (var (stringName, tokenName, nullOnEmpty) in nameSlotsArray)
{
builder.AppendLine($"\tpublic partial string {stringName}");
builder.AppendLine("\t{");
builder.AppendLine($"\t\tget => {tokenName}.Name;");
if (nullOnEmpty)
builder.AppendLine($"\t\tset => {tokenName} = string.IsNullOrEmpty(value) ? null! : global::ICSharpCode.Decompiler.CSharp.Syntax.Identifier.Create(value);");
else
builder.AppendLine($"\t\tset => {tokenName} = global::ICSharpCode.Decompiler.CSharp.Syntax.Identifier.Create(value);");
builder.AppendLine("\t}");
builder.AppendLine();
}
}
// Flattened child-index space: slots in declaration order, a single slot occupying one index // Flattened child-index space: slots in declaration order, a single slot occupying one index
// (even when empty), a collection slot a contiguous run of its current length. // (even when empty), a collection slot a contiguous run of its current length.
builder.Append("\tinternal override int GetChildCount() => "); builder.Append("\tinternal override int GetChildCount() => ");
@ -471,7 +507,7 @@ internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator
builder.AppendLine("namespace ICSharpCode.Decompiler.CSharp.Syntax;"); builder.AppendLine("namespace ICSharpCode.Decompiler.CSharp.Syntax;");
source = source source = source
.Concat([new("NullNode", false, true, false, false, 0, false, "NullNode", "AstNode", null, null), new("PatternPlaceholder", false, true, false, false, 0, false, "PatternPlaceholder", "AstNode", null, null)]) .Concat([new("NullNode", false, true, false, false, 0, false, "NullNode", "AstNode", null, null, null), new("PatternPlaceholder", false, true, false, false, 0, false, "PatternPlaceholder", "AstNode", null, null, null)])
.ToImmutableArray(); .ToImmutableArray();
WriteInterface("IAstVisitor", "void", ""); WriteInterface("IAstVisitor", "void", "");
@ -549,6 +585,13 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{ {
public SlotAttribute(string role) { } public SlotAttribute(string role) { }
} }
[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
[global::System.AttributeUsage(global::System.AttributeTargets.Property)]
sealed class NameSlotAttribute : global::System.Attribute
{
public NameSlotAttribute(string role, bool nullOnEmpty = false) { }
}
} }
")); "));

2
ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs

@ -1870,7 +1870,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
{ {
StartNode(gotoStatement); StartNode(gotoStatement);
WriteKeyword(GotoStatement.GotoKeywordRole); WriteKeyword(GotoStatement.GotoKeywordRole);
WriteIdentifier(gotoStatement.NameToken); WriteIdentifier(gotoStatement.LabelToken);
Semicolon(); Semicolon();
EndNode(gotoStatement); EndNode(gotoStatement);
} }

15
ICSharpCode.Decompiler/CSharp/Syntax/Expressions/IdentifierExpression.cs

@ -46,19 +46,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
SetChildByRole(Roles.Identifier, Decompiler.CSharp.Syntax.Identifier.Create(identifier, location)); SetChildByRole(Roles.Identifier, Decompiler.CSharp.Syntax.Identifier.Create(identifier, location));
} }
public string Identifier { [NameSlot("Roles.Identifier")]
get { public partial string Identifier { get; set; }
return GetChildByRole(Roles.Identifier).Name;
}
set {
SetChildByRole(Roles.Identifier, Decompiler.CSharp.Syntax.Identifier.Create(value));
}
}
// The Identifier string is what DoMatch compares; the token slot is excluded to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier IdentifierToken { get; set; }
[Slot("Roles.TypeArgument")] [Slot("Roles.TypeArgument")]
public partial AstNodeCollection<AstType> TypeArguments { get; } public partial AstNodeCollection<AstType> TypeArguments { get; }

15
ICSharpCode.Decompiler/CSharp/Syntax/Expressions/MemberReferenceExpression.cs

@ -37,19 +37,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("Roles.TargetExpression")] [Slot("Roles.TargetExpression")]
public partial Expression Target { get; set; } public partial Expression Target { get; set; }
public string MemberName { [NameSlot("Roles.Identifier")]
get { public partial string MemberName { get; set; }
return GetChildByRole(Roles.Identifier).Name;
}
set {
SetChildByRole(Roles.Identifier, Identifier.Create(value));
}
}
// DoMatch compares the MemberName string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier MemberNameToken { get; set; }
[Slot("Roles.TypeArgument")] [Slot("Roles.TypeArgument")]
public partial AstNodeCollection<AstType> TypeArguments { get; } public partial AstNodeCollection<AstType> TypeArguments { get; }

15
ICSharpCode.Decompiler/CSharp/Syntax/Expressions/NamedArgumentExpression.cs

@ -35,19 +35,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
this.Expression = expression; this.Expression = expression;
} }
public string Name { [NameSlot("Roles.Identifier")]
get { public partial string Name { get; set; }
return GetChildByRole(Roles.Identifier).Name;
}
set {
SetChildByRole(Roles.Identifier, Identifier.Create(value));
}
}
// DoMatch compares the Name string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier NameToken { get; set; }
[Slot("Roles.Expression")] [Slot("Roles.Expression")]
public partial Expression Expression { get; set; } public partial Expression Expression { get; set; }

15
ICSharpCode.Decompiler/CSharp/Syntax/Expressions/NamedExpression.cs

@ -43,19 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
this.Expression = expression; this.Expression = expression;
} }
public string Name { [NameSlot("Roles.Identifier")]
get { public partial string Name { get; set; }
return GetChildByRole(Roles.Identifier).Name;
}
set {
SetChildByRole(Roles.Identifier, Identifier.Create(value));
}
}
// DoMatch compares the Name string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier NameToken { get; set; }
[Slot("Roles.Expression")] [Slot("Roles.Expression")]
public partial Expression Expression { get; set; } public partial Expression Expression { get; set; }

15
ICSharpCode.Decompiler/CSharp/Syntax/Expressions/PointerReferenceExpression.cs

@ -37,19 +37,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("Roles.TargetExpression")] [Slot("Roles.TargetExpression")]
public partial Expression Target { get; set; } public partial Expression Target { get; set; }
public string MemberName { [NameSlot("Roles.Identifier")]
get { public partial string MemberName { get; set; }
return GetChildByRole(Roles.Identifier).Name;
}
set {
SetChildByRole(Roles.Identifier, Identifier.Create(value));
}
}
// DoMatch compares the MemberName string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier MemberNameToken { get; set; }
[Slot("Roles.TypeArgument")] [Slot("Roles.TypeArgument")]
public partial AstNodeCollection<AstType> TypeArguments { get; } public partial AstNodeCollection<AstType> TypeArguments { get; }

75
ICSharpCode.Decompiler/CSharp/Syntax/Expressions/QueryExpression.cs

@ -49,19 +49,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("PrecedingQueryRole")] [Slot("PrecedingQueryRole")]
public partial QueryExpression PrecedingQuery { get; set; } public partial QueryExpression PrecedingQuery { get; set; }
public string Identifier { [NameSlot("Roles.Identifier")]
get { public partial string Identifier { get; set; }
return IdentifierToken.Name;
}
set {
IdentifierToken = Decompiler.CSharp.Syntax.Identifier.Create(value);
}
}
// DoMatch compares the Identifier string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier IdentifierToken { get; set; }
} }
/// <summary> /// <summary>
@ -76,19 +65,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("Roles.Type")] [Slot("Roles.Type")]
public partial AstType Type { get; set; } public partial AstType Type { get; set; }
public string Identifier { [NameSlot("Roles.Identifier")]
get { public partial string Identifier { get; set; }
return IdentifierToken.Name;
}
set {
IdentifierToken = Decompiler.CSharp.Syntax.Identifier.Create(value);
}
}
// DoMatch compares the Identifier string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier IdentifierToken { get; set; }
[Slot("Roles.Expression")] [Slot("Roles.Expression")]
public partial Expression Expression { get; set; } public partial Expression Expression { get; set; }
@ -102,19 +80,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{ {
public readonly static TokenRole LetKeywordRole = new TokenRole("let"); public readonly static TokenRole LetKeywordRole = new TokenRole("let");
public string Identifier { [NameSlot("Roles.Identifier")]
get { public partial string Identifier { get; set; }
return IdentifierToken.Name;
}
set {
IdentifierToken = Decompiler.CSharp.Syntax.Identifier.Create(value);
}
}
// DoMatch compares the Identifier string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier IdentifierToken { get; set; }
[Slot("Roles.Expression")] [Slot("Roles.Expression")]
public partial Expression Expression { get; set; } public partial Expression Expression { get; set; }
@ -166,19 +133,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("TypeRole")] [Slot("TypeRole")]
public partial AstType Type { get; set; } public partial AstType Type { get; set; }
public string JoinIdentifier { [NameSlot("JoinIdentifierRole")]
get { public partial string JoinIdentifier { get; set; }
return JoinIdentifierToken.Name;
}
set {
JoinIdentifierToken = Identifier.Create(value);
}
}
// DoMatch compares the JoinIdentifier string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("JoinIdentifierRole")]
public partial Identifier JoinIdentifierToken { get; set; }
[Slot("InExpressionRole")] [Slot("InExpressionRole")]
public partial Expression InExpression { get; set; } public partial Expression InExpression { get; set; }
@ -189,19 +145,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("EqualsExpressionRole")] [Slot("EqualsExpressionRole")]
public partial Expression EqualsExpression { get; set; } public partial Expression EqualsExpression { get; set; }
public string IntoIdentifier { [NameSlot("IntoIdentifierRole")]
get { public partial string IntoIdentifier { get; set; }
return IntoIdentifierToken.Name;
}
set {
IntoIdentifierToken = Identifier.Create(value);
}
}
// DoMatch compares the IntoIdentifier string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("IntoIdentifierRole")]
public partial Identifier IntoIdentifierToken { get; set; }
} }
/// <summary> /// <summary>

15
ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/ExternAliasDeclaration.cs

@ -33,18 +33,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
public partial class ExternAliasDeclaration : AstNode public partial class ExternAliasDeclaration : AstNode
{ {
public string Name { [NameSlot("Roles.Identifier")]
get { public partial string Name { get; set; }
return GetChildByRole(Roles.Identifier).Name;
}
set {
SetChildByRole(Roles.Identifier, Identifier.Create(value));
}
}
// DoMatch compares the name string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier NameToken { get; set; }
} }
} }

15
ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/TypeParameterDeclaration.cs

@ -43,19 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
set { variance = value; } set { variance = value; }
} }
public string Name { [NameSlot("Roles.Identifier")]
get { public partial string Name { get; set; }
return GetChildByRole(Roles.Identifier).Name;
}
set {
SetChildByRole(Roles.Identifier, Identifier.Create(value));
}
}
// DoMatch compares the name string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier NameToken { get; set; }
public TypeParameterDeclaration() public TypeParameterDeclaration()
{ {

15
ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/UsingAliasDeclaration.cs

@ -36,19 +36,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
public static readonly Role<Identifier> AliasRole = new Role<Identifier>("Alias", Identifier.Null); public static readonly Role<Identifier> AliasRole = new Role<Identifier>("Alias", Identifier.Null);
public static readonly Role<AstType> ImportRole = UsingDeclaration.ImportRole; public static readonly Role<AstType> ImportRole = UsingDeclaration.ImportRole;
public string Alias { [NameSlot("AliasRole")]
get { public partial string Alias { get; set; }
return AliasToken.Name;
}
set {
AliasToken = Identifier.Create(value);
}
}
// DoMatch compares the name string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("AliasRole")]
public partial Identifier AliasToken { get; set; }
[Slot("ImportRole")] [Slot("ImportRole")]
public partial AstType Import { get; set; } public partial AstType Import { get; set; }

15
ICSharpCode.Decompiler/CSharp/Syntax/MemberType.cs

@ -48,19 +48,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("TargetRole")] [Slot("TargetRole")]
public partial AstType Target { get; set; } public partial AstType Target { get; set; }
public string MemberName { [NameSlot("Roles.Identifier")]
get { public partial string MemberName { get; set; }
return GetChildByRole(Roles.Identifier).Name;
}
set {
SetChildByRole(Roles.Identifier, Identifier.Create(value));
}
}
// DoMatch compares the name string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier MemberNameToken { get; set; }
[Slot("Roles.TypeArgument")] [Slot("Roles.TypeArgument")]
public partial AstNodeCollection<AstType> TypeArguments { get; } public partial AstNodeCollection<AstType> TypeArguments { get; }

15
ICSharpCode.Decompiler/CSharp/Syntax/SimpleType.cs

@ -66,19 +66,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{ {
} }
public string Identifier { [NameSlot("Roles.Identifier")]
get { public partial string Identifier { get; set; }
return GetChildByRole(Roles.Identifier).Name;
}
set {
SetChildByRole(Roles.Identifier, Syntax.Identifier.Create(value));
}
}
// DoMatch compares the name string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier IdentifierToken { get; set; }
[Slot("Roles.TypeArgument")] [Slot("Roles.TypeArgument")]
public partial AstNodeCollection<AstType> TypeArguments { get; } public partial AstNodeCollection<AstType> TypeArguments { get; }

18
ICSharpCode.Decompiler/CSharp/Syntax/Statements/GotoStatement.cs

@ -43,22 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
this.Label = label; this.Label = label;
} }
public string Label { [NameSlot("Roles.Identifier", nullOnEmpty: true)]
get { public partial string Label { get; set; }
return NameToken.Name;
}
set {
if (string.IsNullOrEmpty(value))
NameToken = null;
else
NameToken = Identifier.Create(value);
}
}
// DoMatch compares the name string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier NameToken { get; set; }
} }
/// <summary> /// <summary>

15
ICSharpCode.Decompiler/CSharp/Syntax/Statements/LabelStatement.cs

@ -32,18 +32,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[DecompilerAstNode(hasNullNode: false)] [DecompilerAstNode(hasNullNode: false)]
public partial class LabelStatement : Statement public partial class LabelStatement : Statement
{ {
public string Label { [NameSlot("Roles.Identifier")]
get { public partial string Label { get; set; }
return GetChildByRole(Roles.Identifier).Name;
}
set {
SetChildByRole(Roles.Identifier, Identifier.Create(value));
}
}
// DoMatch compares the name string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier LabelToken { get; set; }
} }
} }

16
ICSharpCode.Decompiler/CSharp/Syntax/Statements/TryCatchStatement.cs

@ -63,20 +63,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("Roles.Type")] [Slot("Roles.Type")]
public partial AstType Type { get; set; } public partial AstType Type { get; set; }
public string VariableName { [NameSlot("Roles.Identifier", nullOnEmpty: true)]
get { return GetChildByRole(Roles.Identifier).Name; } public partial string VariableName { get; set; }
set {
if (string.IsNullOrEmpty(value))
SetChildByRole(Roles.Identifier, null);
else
SetChildByRole(Roles.Identifier, Identifier.Create(value));
}
}
// DoMatch compares the name string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier VariableNameToken { get; set; }
[Slot("ConditionRole")] [Slot("ConditionRole")]
public partial Expression Condition { get; set; } public partial Expression Condition { get; set; }

11
ICSharpCode.Decompiler/CSharp/Syntax/TupleAstType.cs

@ -39,15 +39,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("Roles.Type")] [Slot("Roles.Type")]
public partial AstType Type { get; set; } public partial AstType Type { get; set; }
public string Name { [NameSlot("Roles.Identifier")]
get { return GetChildByRole(Roles.Identifier).Name; } public partial string Name { get; set; }
set { SetChildByRole(Roles.Identifier, Identifier.Create(value)); }
}
// DoMatch compares the name string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier NameToken { get; set; }
} }
} }

15
ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/FixedVariableInitializer.cs

@ -43,19 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
this.CountExpression = initializer; this.CountExpression = initializer;
} }
public string Name { [NameSlot("Roles.Identifier")]
get { public partial string Name { get; set; }
return GetChildByRole(Roles.Identifier).Name;
}
set {
SetChildByRole(Roles.Identifier, Identifier.Create(value));
}
}
// DoMatch compares the Name string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier NameToken { get; set; }
[Slot("Roles.Expression")] [Slot("Roles.Expression")]
public partial Expression CountExpression { get; set; } public partial Expression CountExpression { get; set; }

15
ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/ParameterDeclaration.cs

@ -86,19 +86,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("Roles.Type")] [Slot("Roles.Type")]
public partial AstType Type { get; set; } public partial AstType Type { get; set; }
public string Name { [NameSlot("Roles.Identifier")]
get { public partial string Name { get; set; }
return GetChildByRole(Roles.Identifier).Name;
}
set {
SetChildByRole(Roles.Identifier, Identifier.Create(value));
}
}
// DoMatch compares the Name string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier NameToken { get; set; }
[Slot("Roles.Expression")] [Slot("Roles.Expression")]
public partial Expression DefaultExpression { get; set; } public partial Expression DefaultExpression { get; set; }

15
ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/VariableInitializer.cs

@ -43,19 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
this.Initializer = initializer; this.Initializer = initializer;
} }
public string Name { [NameSlot("Roles.Identifier")]
get { public partial string Name { get; set; }
return GetChildByRole(Roles.Identifier).Name;
}
set {
SetChildByRole(Roles.Identifier, Identifier.Create(value));
}
}
// DoMatch compares the Name string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier NameToken { get; set; }
[Slot("Roles.Expression")] [Slot("Roles.Expression")]
public partial Expression Initializer { get; set; } public partial Expression Initializer { get; set; }

11
ICSharpCode.Decompiler/CSharp/Syntax/VariableDesignation.cs

@ -29,15 +29,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[DecompilerAstNode(hasNullNode: false)] [DecompilerAstNode(hasNullNode: false)]
public partial class SingleVariableDesignation : VariableDesignation public partial class SingleVariableDesignation : VariableDesignation
{ {
public string Identifier { [NameSlot("Roles.Identifier")]
get { return GetChildByRole(Roles.Identifier).Name; } public partial string Identifier { get; set; }
set { SetChildByRole(Roles.Identifier, Syntax.Identifier.Create(value)); }
}
// DoMatch compares the name string; exclude the token slot to avoid matching it twice.
[ExcludeFromMatch]
[Slot("Roles.Identifier")]
public partial Identifier IdentifierToken { get; set; }
} }
/// <summary> /// <summary>

Loading…
Cancel
Save