Skip to content

Commit cf5b4e1

Browse files
committed
Use a new IdentifierNode type instead of raw strings for identifiers
1 parent f05a4ff commit cf5b4e1

4 files changed

Lines changed: 71 additions & 38 deletions

File tree

UnityShaderParser.Tests/PreProcessorTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public void PreProcessWithPredefinedFunctionLikeMacro()
2828

2929
var varDecl = decl as VariableDeclarationStatementNode;
3030
Assert.IsNotNull(varDecl);
31-
Assert.AreEqual("bar", varDecl?.Declarators[0].Name);
31+
Assert.AreEqual("bar", varDecl?.Declarators[0].Name.Identifier);
3232

3333
var typeDecl = varDecl?.Kind as PredefinedObjectTypeNode;
3434
Assert.AreEqual(PredefinedObjectType.Texture2D, typeDecl?.Kind);

UnityShaderParser/HLSL/HLSLParser.cs

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,15 @@ private bool IsNextPossiblyFunctionDeclaration()
282282
});
283283
}
284284

285+
private new IdentifierNode ParseIdentifier()
286+
{
287+
string identifier = base.ParseIdentifier();
288+
return new IdentifierNode(new List<HLSLToken> { Previous() })
289+
{
290+
Identifier = identifier,
291+
};
292+
}
293+
285294
public StatePropertyNode ParseStateProperty()
286295
{
287296
var firstTok = Peek();
@@ -290,7 +299,13 @@ public StatePropertyNode ParseStateProperty()
290299
if (Match(TokenKind.TextureKeyword))
291300
{
292301
var nameTok = Advance();
293-
name = new NamedTypeNode(Range(nameTok, nameTok)) { Name = "texture" };
302+
name = new NamedTypeNode(new List<HLSLToken> { nameTok })
303+
{
304+
Name = new IdentifierNode(new List<HLSLToken> { nameTok })
305+
{
306+
Identifier = "texture"
307+
}
308+
};
294309
}
295310
else
296311
{
@@ -359,7 +374,7 @@ public SamplerStateLiteralExpressionNode ParseSamplerStateLiteral()
359374
public CompileExpressionNode ParseCompileExpression()
360375
{
361376
var keywordTok = Eat(TokenKind.CompileKeyword);
362-
string target = ParseIdentifier();
377+
var target = ParseIdentifier();
363378

364379
var name = ParseNamedExpression();
365380
var param = ParseParameterList();
@@ -596,7 +611,7 @@ public ExpressionNode ParsePrefixOrPostFixExpression()
596611

597612
case TokenKind.DotToken:
598613
Eat(TokenKind.DotToken);
599-
string identifier = ParseIdentifier();
614+
var identifier = ParseIdentifier();
600615

601616
if (Match(TokenKind.OpenParenToken))
602617
{
@@ -620,7 +635,7 @@ public ExpressionNode ParsePrefixOrPostFixExpression()
620635
public NamedExpressionNode ParseNamedExpression()
621636
{
622637
var firstTok = Peek();
623-
string identifier = ParseIdentifier();
638+
var identifier = ParseIdentifier();
624639

625640
var name = new IdentifierExpressionNode(Range(firstTok, firstTok)) { Name = identifier };
626641

@@ -698,7 +713,7 @@ public AttributeNode ParseAttribute()
698713
{
699714
var openTok = Eat(TokenKind.OpenBracketToken);
700715

701-
string identifier = ParseIdentifier();
716+
var identifier = ParseIdentifier();
702717

703718
List<LiteralExpressionNode> args = new List<LiteralExpressionNode>();
704719
if (Match(TokenKind.OpenParenToken))
@@ -1060,7 +1075,7 @@ public NumericTypeNode ParseNumericType(bool allowVoid = false)
10601075
public UserDefinedNamedTypeNode ParseUserDefinedNamedType()
10611076
{
10621077
var firstTok = Peek();
1063-
string identifier = ParseIdentifier();
1078+
var identifier = ParseIdentifier();
10641079
var name = new NamedTypeNode(Range(firstTok, firstTok)) { Name = identifier };
10651080

10661081
if (Match(TokenKind.ColonColonToken))
@@ -1118,7 +1133,7 @@ public ArrayRankNode ParseArrayRank()
11181133
public VariableDeclaratorNode ParseVariableDeclarator(bool allowCompoundInitializer = true)
11191134
{
11201135
var firstTok = Peek();
1121-
string identifier = ParseIdentifier();
1136+
var identifier = ParseIdentifier();
11221137

11231138
List<ArrayRankNode> arrayRanks = new List<ArrayRankNode>();
11241139
while (Match(TokenKind.OpenBracketToken))
@@ -1204,7 +1219,7 @@ public VariableDeclaratorQualifierNode ParseVariableDeclaratorQualifierNode()
12041219
public SemanticNode ParseSemantic()
12051220
{
12061221
var colTok = Eat(TokenKind.ColonToken);
1207-
string identifier = ParseIdentifier();
1222+
var identifier = ParseIdentifier();
12081223
return new SemanticNode(Range(colTok, Previous())) { Name = identifier };
12091224
}
12101225

@@ -1214,7 +1229,7 @@ public RegisterLocationNode ParseRegisterLocation()
12141229
Eat(TokenKind.RegisterKeyword);
12151230
Eat(TokenKind.OpenParenToken);
12161231

1217-
string location = ParseIdentifier();
1232+
string location = base.ParseIdentifier();
12181233
RegisterKind kind = default;
12191234
int index = 0;
12201235
switch (location.ToLower().FirstOrDefault())
@@ -1236,7 +1251,7 @@ public RegisterLocationNode ParseRegisterLocation()
12361251
{
12371252
Eat(TokenKind.CommaToken);
12381253

1239-
string space = ParseIdentifier();
1254+
string space = base.ParseIdentifier();
12401255
string spaceLexeme = string.Concat(space.SkipWhile(x => !char.IsNumber(x)));
12411256
if (int.TryParse(spaceLexeme, out int parsedIndex))
12421257
{
@@ -1264,7 +1279,7 @@ public PackoffsetNode ParsePackoffsetNode()
12641279
Eat(TokenKind.PackoffsetKeyword);
12651280
Eat(TokenKind.OpenParenToken);
12661281

1267-
string location = ParseIdentifier();
1282+
string location = base.ParseIdentifier();
12681283
int index = 0;
12691284
string indexLexeme = string.Concat(location.SkipWhile(x => !char.IsNumber(x)));
12701285
if (!int.TryParse(indexLexeme, out index))
@@ -1276,7 +1291,7 @@ public PackoffsetNode ParsePackoffsetNode()
12761291
if (Match(TokenKind.DotToken))
12771292
{
12781293
Eat(TokenKind.DotToken);
1279-
swizzle = ParseIdentifier();
1294+
swizzle = base.ParseIdentifier();
12801295
}
12811296

12821297
var closeTok = Eat(TokenKind.CloseParenToken);
@@ -1746,13 +1761,13 @@ public PreProcessorDirectiveNode ParsePreProcessorDirective(Func<HLSLSyntaxNode>
17461761
public PreProcessorDirectiveNode ParseDefineDirective()
17471762
{
17481763
var keywordTok = Eat(TokenKind.DefineDirectiveKeyword);
1749-
string ident = ParseIdentifier();
1764+
string ident = base.ParseIdentifier();
17501765

17511766
// Function like
17521767
if (Match(TokenKind.OpenFunctionLikeMacroParenToken))
17531768
{
17541769
Eat(TokenKind.OpenFunctionLikeMacroParenToken);
1755-
var args = ParseSeparatedList0(TokenKind.CloseParenToken, TokenKind.CommaToken, ParseIdentifier);
1770+
var args = ParseSeparatedList0(TokenKind.CloseParenToken, TokenKind.CommaToken, base.ParseIdentifier);
17561771
Eat(TokenKind.CloseParenToken);
17571772
var tokens = ParseMany0(() => !Match(TokenKind.EndDirectiveToken), () => Advance());
17581773
var endTok = Eat(TokenKind.EndDirectiveToken);
@@ -1798,7 +1813,7 @@ public LineDirectiveNode ParseLineDirective()
17981813
public UndefDirectiveNode ParseUndefDirective()
17991814
{
18001815
var keywordTok = Eat(TokenKind.UndefDirectiveKeyword);
1801-
string ident = ParseIdentifier();
1816+
string ident = base.ParseIdentifier();
18021817
var endTok = Eat(TokenKind.EndDirectiveToken);
18031818
RecoverTo(TokenKind.EndDirectiveToken);
18041819
return new UndefDirectiveNode(Range(keywordTok, endTok)) { Name = ident };
@@ -1841,7 +1856,7 @@ public IfDirectiveNode ParseIfDirective(Func<HLSLSyntaxNode> recurse, bool elif)
18411856
public IfDefDirectiveNode ParseIfDefDirective(Func<HLSLSyntaxNode> recurse)
18421857
{
18431858
var keywordTok = Eat(TokenKind.IfdefDirectiveKeyword);
1844-
string ident = ParseIdentifier();
1859+
string ident = base.ParseIdentifier();
18451860
var endTok = Eat(TokenKind.EndDirectiveToken);
18461861
RecoverTo(TokenKind.EndDirectiveToken);
18471862
var body = ParseMany0(() => !Match(TokenKind.ElseDirectiveKeyword, TokenKind.ElifDirectiveKeyword, TokenKind.EndifDirectiveKeyword), recurse);
@@ -1857,7 +1872,7 @@ public IfDefDirectiveNode ParseIfDefDirective(Func<HLSLSyntaxNode> recurse)
18571872
public IfNotDefDirectiveNode ParseIfNotDefDirective(Func<HLSLSyntaxNode> recurse)
18581873
{
18591874
var keywordTok = Eat(TokenKind.IfndefDirectiveKeyword);
1860-
string ident = ParseIdentifier();
1875+
string ident = base.ParseIdentifier();
18611876
var endTok = Eat(TokenKind.EndDirectiveToken);
18621877
RecoverTo(TokenKind.EndDirectiveToken);
18631878
var body = ParseMany0(() => !Match(TokenKind.ElseDirectiveKeyword, TokenKind.ElifDirectiveKeyword, TokenKind.EndifDirectiveKeyword), recurse);

UnityShaderParser/HLSL/HLSLSyntaxElements.cs

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,22 @@ public HLSLSyntaxNode(List<HLSLToken> tokens)
715715
}
716716
}
717717

718+
public class IdentifierNode : HLSLSyntaxNode
719+
{
720+
public string Identifier { get; set; }
721+
722+
public static implicit operator string(IdentifierNode node) => node.Identifier;
723+
public override string ToString() => Identifier;
724+
725+
protected override IEnumerable<HLSLSyntaxNode> GetChildren =>
726+
Enumerable.Empty<HLSLSyntaxNode>();
727+
728+
public override void Accept(HLSLSyntaxVisitor visitor) => visitor.VisitIdentifierNode(this);
729+
public override T Accept<T>(HLSLSyntaxVisitor<T> visitor) => visitor.VisitIdentifierNode(this);
730+
731+
public IdentifierNode(List<HLSLToken> tokens) : base(tokens) { }
732+
}
733+
718734
public abstract class FunctionNode : HLSLSyntaxNode
719735
{
720736
public List<AttributeNode> Attributes { get; set; }
@@ -748,14 +764,14 @@ public FormalParameterNode(List<HLSLToken> tokens) : base(tokens) { }
748764

749765
public class VariableDeclaratorNode : HLSLSyntaxNode
750766
{
751-
public string Name { get; set; }
767+
public IdentifierNode Name { get; set; }
752768
public List<ArrayRankNode> ArrayRanks { get; set; }
753769
public List<VariableDeclaratorQualifierNode> Qualifiers { get; set; }
754770
public List<VariableDeclarationStatementNode> Annotations { get; set; }
755771
public InitializerNode Initializer { get; set; } // Optional
756772

757773
protected override IEnumerable<HLSLSyntaxNode> GetChildren =>
758-
MergeChildren(ArrayRanks, Qualifiers, Annotations, OptionalChild(Initializer));
774+
MergeChildren(Child(Name), ArrayRanks, Qualifiers, Annotations, OptionalChild(Initializer));
759775

760776
public override void Accept(HLSLSyntaxVisitor visitor) => visitor.VisitVariableDeclaratorNode(this);
761777
public override T Accept<T>(HLSLSyntaxVisitor<T> visitor) => visitor.VisitVariableDeclaratorNode(this);
@@ -923,10 +939,10 @@ public VariableDeclaratorQualifierNode(List<HLSLToken> tokens) : base(tokens) {
923939

924940
public class SemanticNode : VariableDeclaratorQualifierNode
925941
{
926-
public string Name { get; set; }
942+
public IdentifierNode Name { get; set; }
927943

928944
protected override IEnumerable<HLSLSyntaxNode> GetChildren =>
929-
Enumerable.Empty<HLSLSyntaxNode>();
945+
Child(Name);
930946

931947
public override void Accept(HLSLSyntaxVisitor visitor) => visitor.VisitSemanticNode(this);
932948
public override T Accept<T>(HLSLSyntaxVisitor<T> visitor) => visitor.VisitSemanticNode(this);
@@ -1192,11 +1208,11 @@ public ExpressionStatementNode(List<HLSLToken> tokens) : base(tokens) { }
11921208

11931209
public class AttributeNode : HLSLSyntaxNode
11941210
{
1195-
public string Name { get; set; }
1211+
public IdentifierNode Name { get; set; }
11961212
public List<LiteralExpressionNode> Arguments { get; set; }
11971213

11981214
protected override IEnumerable<HLSLSyntaxNode> GetChildren =>
1199-
Arguments;
1215+
MergeChildren(Child(Name), Arguments);
12001216

12011217
public override void Accept(HLSLSyntaxVisitor visitor) => visitor.VisitAttributeNode(this);
12021218
public override T Accept<T>(HLSLSyntaxVisitor<T> visitor) => visitor.VisitAttributeNode(this);
@@ -1236,13 +1252,13 @@ public QualifiedIdentifierExpressionNode(List<HLSLToken> tokens) : base(tokens)
12361252

12371253
public class IdentifierExpressionNode : NamedExpressionNode
12381254
{
1239-
public string Name { get; set; }
1255+
public IdentifierNode Name { get; set; }
12401256

1241-
public override string GetName() => Name;
1242-
public override string GetUnqualifiedName() => Name;
1257+
public override string GetName() => Name.Identifier;
1258+
public override string GetUnqualifiedName() => Name.Identifier;
12431259

12441260
protected override IEnumerable<HLSLSyntaxNode> GetChildren =>
1245-
Enumerable.Empty<HLSLSyntaxNode>();
1261+
Child(Name);
12461262

12471263
public override void Accept(HLSLSyntaxVisitor visitor) => visitor.VisitIdentifierExpressionNode(this);
12481264
public override T Accept<T>(HLSLSyntaxVisitor<T> visitor) => visitor.VisitIdentifierExpressionNode(this);
@@ -1339,10 +1355,10 @@ public PostfixUnaryExpressionNode(List<HLSLToken> tokens) : base(tokens) { }
13391355
public class FieldAccessExpressionNode : ExpressionNode
13401356
{
13411357
public ExpressionNode Target { get; set; }
1342-
public string Name { get; set; }
1358+
public IdentifierNode Name { get; set; }
13431359

13441360
protected override IEnumerable<HLSLSyntaxNode> GetChildren =>
1345-
Child(Target);
1361+
new HLSLSyntaxNode[] { Target, Name };
13461362

13471363
public override void Accept(HLSLSyntaxVisitor visitor) => visitor.VisitFieldAccessExpressionNode(this);
13481364
public override T Accept<T>(HLSLSyntaxVisitor<T> visitor) => visitor.VisitFieldAccessExpressionNode(this);
@@ -1353,11 +1369,11 @@ public FieldAccessExpressionNode(List<HLSLToken> tokens) : base(tokens) { }
13531369
public class MethodCallExpressionNode : ExpressionNode
13541370
{
13551371
public ExpressionNode Target { get; set; }
1356-
public string Name { get; set; }
1372+
public IdentifierNode Name { get; set; }
13571373
public List<ExpressionNode> Arguments { get; set; }
13581374

13591375
protected override IEnumerable<HLSLSyntaxNode> GetChildren =>
1360-
MergeChildren(Child(Target), Arguments);
1376+
MergeChildren(Child(Name), Child(Target), Arguments);
13611377

13621378
public override void Accept(HLSLSyntaxVisitor visitor) => visitor.VisitMethodCallExpressionNode(this);
13631379
public override T Accept<T>(HLSLSyntaxVisitor<T> visitor) => visitor.VisitMethodCallExpressionNode(this);
@@ -1467,11 +1483,11 @@ public SamplerStateLiteralExpressionNode(List<HLSLToken> tokens) : base(tokens)
14671483
// From FX framework
14681484
public class CompileExpressionNode : ExpressionNode
14691485
{
1470-
public string Target { get; set; }
1486+
public IdentifierNode Target { get; set; }
14711487
public FunctionCallExpressionNode Invocation { get; set; }
14721488

14731489
protected override IEnumerable<HLSLSyntaxNode> GetChildren =>
1474-
Child(Invocation);
1490+
new HLSLSyntaxNode[] { Target, Invocation };
14751491

14761492
public override void Accept(HLSLSyntaxVisitor visitor) => visitor.VisitCompileExpressionNode(this);
14771493
public override T Accept<T>(HLSLSyntaxVisitor<T> visitor) => visitor.VisitCompileExpressionNode(this);
@@ -1518,13 +1534,13 @@ public QualifiedNamedTypeNode(List<HLSLToken> tokens) : base(tokens) { }
15181534

15191535
public class NamedTypeNode : UserDefinedNamedTypeNode
15201536
{
1521-
public string Name { get; set; }
1537+
public IdentifierNode Name { get; set; }
15221538

1523-
public override string GetName() => Name;
1524-
public override string GetUnqualifiedName() => Name;
1539+
public override string GetName() => Name.Identifier;
1540+
public override string GetUnqualifiedName() => Name.Identifier;
15251541

15261542
protected override IEnumerable<HLSLSyntaxNode> GetChildren =>
1527-
Enumerable.Empty<HLSLSyntaxNode>();
1543+
Child(Name);
15281544

15291545
public override void Accept(HLSLSyntaxVisitor visitor) => visitor.VisitNamedTypeNode(this);
15301546
public override T Accept<T>(HLSLSyntaxVisitor<T> visitor) => visitor.VisitNamedTypeNode(this);

UnityShaderParser/HLSL/HLSLSyntaxVisitor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public void VisitMany<T>(IList<T> nodes, Action runBetween)
3333
}
3434

3535
public virtual void Visit(HLSLSyntaxNode node) => node?.Accept(this);
36+
public virtual void VisitIdentifierNode(IdentifierNode node) => DefaultVisit(node);
3637
public virtual void VisitFormalParameterNode(FormalParameterNode node) => DefaultVisit(node);
3738
public virtual void VisitVariableDeclaratorNode(VariableDeclaratorNode node) => DefaultVisit(node);
3839
public virtual void VisitArrayRankNode(ArrayRankNode node) => DefaultVisit(node);
@@ -145,6 +146,7 @@ public List<TReturn> VisitMany<T>(IList<T> nodes, Action runBetween)
145146
}
146147

147148
public virtual TReturn Visit(HLSLSyntaxNode node) => node == null ? default : node.Accept(this);
149+
public virtual TReturn VisitIdentifierNode(IdentifierNode node) => DefaultVisit(node);
148150
public virtual TReturn VisitFormalParameterNode(FormalParameterNode node) => DefaultVisit(node);
149151
public virtual TReturn VisitVariableDeclaratorNode(VariableDeclaratorNode node) => DefaultVisit(node);
150152
public virtual TReturn VisitArrayRankNode(ArrayRankNode node) => DefaultVisit(node);

0 commit comments

Comments
 (0)