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; @@ -30,7 +30,7 @@ namespace ICSharpCode.Decompiler.Generators;
[Generator]
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
// trailing "Role" removed (e.g. "Roles.EmbeddedStatement" -> "EmbeddedStatement", "LeftRole" ->
@ -107,27 +107,45 @@ internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator @@ -107,27 +107,45 @@ internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator
}
}
// Collect the slot schema: child properties tagged [Slot], in declaration order. The
// attribute names the Role expression to use; single vs collection comes from the type.
List<(string RoleExpr, bool IsCollection, string PropertyName, string PropertyType, string ElementType, bool IsOverride, bool IsNullable, string KindName)>? slots = null;
// Collect the slot schema: child properties tagged [Slot] or [NameSlot], in declaration order
// (the order is the node's child layout, so it must follow the source, not be grouped by kind).
// [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())
{
if (m is not IPropertySymbol property)
continue;
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;
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)));
}
var nameSlotAttr = property.GetAttributes().FirstOrDefault(a => a.AttributeClass?.Name == "NameSlotAttribute");
if (nameSlotAttr != null)
{
nameSlots ??= new();
slots ??= new();
string roleExpr = (string)nameSlotAttr.ConstructorArguments[0].Value!;
bool nullOnEmpty = nameSlotAttr.ConstructorArguments.Length > 1 && (bool)nameSlotAttr.ConstructorArguments[1].Value!;
string tokenName = property.Name + "Token";
slots.Add((roleExpr, false, tokenName, "Identifier", "Identifier", false, false, SlotKindName(roleExpr), false));
nameSlots.Add((property.Name, tokenName, nullOnEmpty));
}
}
return new(targetSymbol.Name, !targetSymbol.MemberNames.Contains("AcceptVisitor"),
@ -136,7 +154,7 @@ internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator @@ -136,7 +154,7 @@ internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator
NeedsPatternPlaceholder: (bool)attribute.ConstructorArguments[1].Value!,
NullNodeBaseCtorParamCount: targetSymbol.InstanceConstructors.Min(m => m.Parameters.Length),
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
@ -333,18 +351,19 @@ internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator @@ -333,18 +351,19 @@ internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator
// 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
// 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 partialKw = isPartial ? "partial " : "";
if (isCollection)
{
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
{
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\tget => {field}{(isNullable ? "" : $" ?? {roleExpr}.NullObject")};");
builder.AppendLine($"\t\tset => SetChildNode(ref {field}, value, {roleExpr});");
@ -353,6 +372,23 @@ internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator @@ -353,6 +372,23 @@ internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator
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
// (even when empty), a collection slot a contiguous run of its current length.
builder.Append("\tinternal override int GetChildCount() => ");
@ -471,7 +507,7 @@ internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator @@ -471,7 +507,7 @@ internal class DecompilerSyntaxTreeGenerator : IIncrementalGenerator
builder.AppendLine("namespace ICSharpCode.Decompiler.CSharp.Syntax;");
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();
WriteInterface("IAstVisitor", "void", "");
@ -549,6 +585,13 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -549,6 +585,13 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
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 @@ -1870,7 +1870,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
{
StartNode(gotoStatement);
WriteKeyword(GotoStatement.GotoKeywordRole);
WriteIdentifier(gotoStatement.NameToken);
WriteIdentifier(gotoStatement.LabelToken);
Semicolon();
EndNode(gotoStatement);
}

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

@ -46,19 +46,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -46,19 +46,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
SetChildByRole(Roles.Identifier, Decompiler.CSharp.Syntax.Identifier.Create(identifier, location));
}
public string Identifier {
get {
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; }
[NameSlot("Roles.Identifier")]
public partial string Identifier { get; set; }
[Slot("Roles.TypeArgument")]
public partial AstNodeCollection<AstType> TypeArguments { get; }

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

@ -37,19 +37,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -37,19 +37,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("Roles.TargetExpression")]
public partial Expression Target { get; set; }
public string MemberName {
get {
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; }
[NameSlot("Roles.Identifier")]
public partial string MemberName { get; set; }
[Slot("Roles.TypeArgument")]
public partial AstNodeCollection<AstType> TypeArguments { get; }

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

@ -35,19 +35,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -35,19 +35,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
this.Expression = expression;
}
public string Name {
get {
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; }
[NameSlot("Roles.Identifier")]
public partial string Name { get; set; }
[Slot("Roles.Expression")]
public partial Expression Expression { get; set; }

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

@ -43,19 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -43,19 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
this.Expression = expression;
}
public string Name {
get {
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; }
[NameSlot("Roles.Identifier")]
public partial string Name { get; set; }
[Slot("Roles.Expression")]
public partial Expression Expression { get; set; }

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

@ -37,19 +37,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -37,19 +37,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("Roles.TargetExpression")]
public partial Expression Target { get; set; }
public string MemberName {
get {
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; }
[NameSlot("Roles.Identifier")]
public partial string MemberName { get; set; }
[Slot("Roles.TypeArgument")]
public partial AstNodeCollection<AstType> TypeArguments { get; }

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

@ -49,19 +49,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -49,19 +49,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("PrecedingQueryRole")]
public partial QueryExpression PrecedingQuery { get; set; }
public string Identifier {
get {
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; }
[NameSlot("Roles.Identifier")]
public partial string Identifier { get; set; }
}
/// <summary>
@ -76,19 +65,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -76,19 +65,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("Roles.Type")]
public partial AstType Type { get; set; }
public string Identifier {
get {
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; }
[NameSlot("Roles.Identifier")]
public partial string Identifier { get; set; }
[Slot("Roles.Expression")]
public partial Expression Expression { get; set; }
@ -102,19 +80,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -102,19 +80,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
public readonly static TokenRole LetKeywordRole = new TokenRole("let");
public string Identifier {
get {
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; }
[NameSlot("Roles.Identifier")]
public partial string Identifier { get; set; }
[Slot("Roles.Expression")]
public partial Expression Expression { get; set; }
@ -166,19 +133,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -166,19 +133,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("TypeRole")]
public partial AstType Type { get; set; }
public string JoinIdentifier {
get {
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; }
[NameSlot("JoinIdentifierRole")]
public partial string JoinIdentifier { get; set; }
[Slot("InExpressionRole")]
public partial Expression InExpression { get; set; }
@ -189,19 +145,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -189,19 +145,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("EqualsExpressionRole")]
public partial Expression EqualsExpression { get; set; }
public string IntoIdentifier {
get {
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; }
[NameSlot("IntoIdentifierRole")]
public partial string IntoIdentifier { get; set; }
}
/// <summary>

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

@ -33,18 +33,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -33,18 +33,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
public partial class ExternAliasDeclaration : AstNode
{
public string Name {
get {
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; }
[NameSlot("Roles.Identifier")]
public partial string Name { get; set; }
}
}

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

@ -43,19 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -43,19 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
set { variance = value; }
}
public string Name {
get {
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; }
[NameSlot("Roles.Identifier")]
public partial string Name { get; set; }
public TypeParameterDeclaration()
{

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

@ -36,19 +36,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -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<AstType> ImportRole = UsingDeclaration.ImportRole;
public string Alias {
get {
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; }
[NameSlot("AliasRole")]
public partial string Alias { get; set; }
[Slot("ImportRole")]
public partial AstType Import { get; set; }

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

@ -48,19 +48,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -48,19 +48,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("TargetRole")]
public partial AstType Target { get; set; }
public string MemberName {
get {
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; }
[NameSlot("Roles.Identifier")]
public partial string MemberName { get; set; }
[Slot("Roles.TypeArgument")]
public partial AstNodeCollection<AstType> TypeArguments { get; }

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

@ -66,19 +66,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -66,19 +66,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
}
public string Identifier {
get {
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; }
[NameSlot("Roles.Identifier")]
public partial string Identifier { get; set; }
[Slot("Roles.TypeArgument")]
public partial AstNodeCollection<AstType> TypeArguments { get; }

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

@ -43,22 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -43,22 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
this.Label = label;
}
public string Label {
get {
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; }
[NameSlot("Roles.Identifier", nullOnEmpty: true)]
public partial string Label { get; set; }
}
/// <summary>

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

@ -32,18 +32,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -32,18 +32,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[DecompilerAstNode(hasNullNode: false)]
public partial class LabelStatement : Statement
{
public string Label {
get {
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; }
[NameSlot("Roles.Identifier")]
public partial string Label { get; set; }
}
}

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

@ -63,20 +63,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -63,20 +63,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("Roles.Type")]
public partial AstType Type { get; set; }
public string VariableName {
get { return GetChildByRole(Roles.Identifier).Name; }
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; }
[NameSlot("Roles.Identifier", nullOnEmpty: true)]
public partial string VariableName { get; set; }
[Slot("ConditionRole")]
public partial Expression Condition { get; set; }

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

@ -39,15 +39,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -39,15 +39,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("Roles.Type")]
public partial AstType Type { get; set; }
public string Name {
get { 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; }
[NameSlot("Roles.Identifier")]
public partial string Name { get; set; }
}
}

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

@ -43,19 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -43,19 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
this.CountExpression = initializer;
}
public string Name {
get {
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; }
[NameSlot("Roles.Identifier")]
public partial string Name { get; set; }
[Slot("Roles.Expression")]
public partial Expression CountExpression { get; set; }

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

@ -86,19 +86,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -86,19 +86,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[Slot("Roles.Type")]
public partial AstType Type { get; set; }
public string Name {
get {
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; }
[NameSlot("Roles.Identifier")]
public partial string Name { get; set; }
[Slot("Roles.Expression")]
public partial Expression DefaultExpression { get; set; }

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

@ -43,19 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -43,19 +43,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
this.Initializer = initializer;
}
public string Name {
get {
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; }
[NameSlot("Roles.Identifier")]
public partial string Name { get; set; }
[Slot("Roles.Expression")]
public partial Expression Initializer { get; set; }

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

@ -29,15 +29,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -29,15 +29,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
[DecompilerAstNode(hasNullNode: false)]
public partial class SingleVariableDesignation : VariableDesignation
{
public string Identifier {
get { 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; }
[NameSlot("Roles.Identifier")]
public partial string Identifier { get; set; }
}
/// <summary>

Loading…
Cancel
Save