Skip to content

Commit 75c3600

Browse files
authored
Better Identifier Emission & State Handling (#891)
1 parent d40fdf3 commit 75c3600

File tree

2 files changed

+82
-3
lines changed

2 files changed

+82
-3
lines changed

src/generators/Silk.NET.SilkTouch.Emitter/CSharpEmitter.cs

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.Diagnostics;
56
using Microsoft.CodeAnalysis;
67
using Microsoft.CodeAnalysis.CSharp;
78
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -50,14 +51,22 @@ private class Visitor : Silk.NET.SilkTouch.Symbols.SymbolVisitor
5051
{
5152
public CSharpSyntaxNode? Syntax => _syntax;
5253
private CSharpSyntaxNode? _syntax = null;
54+
private SyntaxToken? _syntaxToken = null;
5355

5456
protected override StructSymbol VisitStruct(StructSymbol structSymbol)
5557
{
58+
AssertClearState();
59+
60+
VisitIdentifier(structSymbol.Identifier);
61+
if (_syntaxToken is not { } identifierToken)
62+
throw new InvalidOperationException("Field Identifier was not visited correctly");
63+
ClearState();
64+
5665
var members = List<MemberDeclarationSyntax>();
5766
var modifiers = TokenList(Token(SyntaxTriviaList.Empty, SyntaxKind.PublicKeyword, TriviaList(Space)));
5867
_syntax = StructDeclaration
5968
(
60-
List<AttributeListSyntax>(), modifiers, Identifier(structSymbol.Identifier.Value), null, null,
69+
List<AttributeListSyntax>(), modifiers, identifierToken, null, null,
6170
List<TypeParameterConstraintClauseSyntax>(), members
6271
)
6372
.WithKeyword(Token(SyntaxTriviaList.Empty, SyntaxKind.StructKeyword, TriviaList(Space)));
@@ -66,21 +75,55 @@ protected override StructSymbol VisitStruct(StructSymbol structSymbol)
6675

6776
protected override FieldSymbol VisitField(FieldSymbol fieldSymbol)
6877
{
78+
AssertClearState();
79+
80+
VisitIdentifier(fieldSymbol.Type.Identifier);
81+
if (_syntax is not IdentifierNameSyntax typeIdentifierSyntax)
82+
throw new InvalidOperationException("Field type Identifier was not visited correctly");
83+
ClearState();
84+
85+
VisitIdentifier(fieldSymbol.Identifier);
86+
if (_syntaxToken is not { } identifierToken)
87+
throw new InvalidOperationException("Field Identifier was not visited correctly");
88+
ClearState();
89+
6990
_syntax = FieldDeclaration
7091
(
7192
List<AttributeListSyntax>(),
7293
TokenList(Token(SyntaxTriviaList.Empty, SyntaxKind.PublicKeyword, TriviaList(Space))),
7394
VariableDeclaration
7495
(
75-
IdentifierName(fieldSymbol.Type.Identifier.Value),
96+
typeIdentifierSyntax,
7697
SingletonSeparatedList
7798
(
7899
VariableDeclarator
79-
(Identifier(TriviaList(Space), fieldSymbol.Identifier.Value, SyntaxTriviaList.Empty))
100+
(identifierToken.WithLeadingTrivia(TriviaList(Space)))
80101
)
81102
)
82103
);
83104
return fieldSymbol;
84105
}
106+
107+
protected override IdentifierSymbol VisitIdentifier(IdentifierSymbol identifierSymbol)
108+
{
109+
AssertClearState();
110+
111+
_syntaxToken = Identifier(SyntaxTriviaList.Empty, identifierSymbol.Value, SyntaxTriviaList.Empty);
112+
_syntax = IdentifierName(_syntaxToken.Value);
113+
return identifierSymbol;
114+
}
115+
116+
[Conditional("DEBUG")]
117+
private void AssertClearState()
118+
{
119+
Debug.Assert(_syntax is null);
120+
Debug.Assert(!_syntaxToken.HasValue);
121+
}
122+
123+
private void ClearState()
124+
{
125+
_syntax = null;
126+
_syntaxToken = null;
127+
}
85128
}
86129
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Silk.NET.SilkTouch.Symbols;
5+
using Xunit;
6+
7+
namespace Silk.NET.SilkTouch.Emitter.Tests;
8+
9+
public sealed class IdentifierTests : EmitterTest
10+
{
11+
[Fact]
12+
public void IdentifierHasNoLeadingTrivia()
13+
{
14+
var node = Transform(new IdentifierSymbol("Test"));
15+
16+
Assert.Empty(node.GetLeadingTrivia());
17+
Assert.False(node.HasLeadingTrivia);
18+
}
19+
20+
[Fact]
21+
public void IdentifierHasNoTrailingTrivia()
22+
{
23+
var node = Transform(new IdentifierSymbol("Test"));
24+
25+
Assert.Empty(node.GetTrailingTrivia());
26+
Assert.False(node.HasTrailingTrivia);
27+
}
28+
29+
[Fact]
30+
public void IdentifierIntegration()
31+
{
32+
var node = Transform(new IdentifierSymbol("Test"));
33+
34+
Assert.Equal("Test", node.ToFullString());
35+
}
36+
}

0 commit comments

Comments
 (0)