From d93fbb36cc88891c526f99a9328f3a9594c115b7 Mon Sep 17 00:00:00 2001 From: Shararvev Date: Wed, 10 Apr 2024 09:29:15 +0500 Subject: [PATCH] Line directive has optional filename argument. --- .../Parser/PreprocessorTests.cs | 46 +++++----------- .../Diagnostics/DiagnosticId.cs | 1 - .../Parser/DirectiveParser.cs | 54 +++++++++---------- .../Parser/HlslLexer.Preprocessor.cs | 4 +- .../Properties/Resources.Designer.cs | 11 +--- .../Properties/Resources.resx | 3 -- 6 files changed, 42 insertions(+), 77 deletions(-) diff --git a/src/ShaderTools.CodeAnalysis.Hlsl.Tests/Parser/PreprocessorTests.cs b/src/ShaderTools.CodeAnalysis.Hlsl.Tests/Parser/PreprocessorTests.cs index 080f9ce4..9ff72309 100644 --- a/src/ShaderTools.CodeAnalysis.Hlsl.Tests/Parser/PreprocessorTests.cs +++ b/src/ShaderTools.CodeAnalysis.Hlsl.Tests/Parser/PreprocessorTests.cs @@ -874,13 +874,19 @@ public void TestIfTrueSingleLineCommentAndDefine() public void TestLine() { const string text = @" +#line 190 #line 3 ""a\path\to.hlsl"" -"; +#line 8 + +#line 30"; var node = Parse(text); TestRoundTripping(node, text); VerifyDirectivesSpecial(node, - new DirectiveInfo { Kind = SyntaxKind.LineDirectiveTrivia, Status = NodeStatus.IsActive, Number = 3, Text = @"a\path\to.hlsl" }); + new DirectiveInfo { Kind = SyntaxKind.LineDirectiveTrivia, Status = NodeStatus.IsActive, Number = 190 }, + new DirectiveInfo { Kind = SyntaxKind.LineDirectiveTrivia, Status = NodeStatus.IsActive, Number = 3, Text = @"a\path\to.hlsl" }, + new DirectiveInfo { Kind = SyntaxKind.LineDirectiveTrivia, Status = NodeStatus.IsActive, Number = 8 }, + new DirectiveInfo { Kind = SyntaxKind.LineDirectiveTrivia, Status = NodeStatus.IsActive, Number = 30 }); } [Fact] @@ -1305,36 +1311,12 @@ private void VerifyDirectivesSpecial(SyntaxNode node, params DirectiveInfo[] exp case SyntaxKind.LineDirectiveTrivia: var ld = dt as LineDirectiveTriviaSyntax; - // default number = 0 - no number - if (exp.Number == -1) - { - Assert.Equal(SyntaxKind.LineKeyword, ld.LineKeyword.Kind); - Assert.Equal(SyntaxKind.DefaultKeyword, ld.Line.Kind); - } - else if (exp.Number == -2) - { - Assert.Equal(SyntaxKind.LineKeyword, ld.LineKeyword.Kind); - //Assert.Equal(SyntaxKind.HiddenKeyword, ld.Line.Kind); - } - else if (exp.Number == 0) - { - Assert.Equal(String.Empty, ld.Line.Text); - } - else if (exp.Number > 0) - { - Assert.Equal(exp.Number, ld.Line.Value); // Number - Assert.Equal(exp.Number, Int32.Parse(ld.Line.Text)); - } - - if (null == exp.Text) - { - Assert.Equal(SyntaxKind.None, ld.File.Kind); - } - else - { - Assert.NotEqual(SyntaxKind.None, ld.File.Kind); - Assert.Equal(exp.Text, ld.File.Value); - } + Assert.True(exp.Number >= 0); + Assert.Equal(exp.Number, ld.Line.Value); // Number + Assert.Equal(exp.Number, Int32.Parse(ld.Line.Text)); + + Assert.NotEqual(SyntaxKind.None, ld.File.Kind); + Assert.Equal(exp.Text, ld.File.Value); break; } // switch diff --git a/src/ShaderTools.CodeAnalysis.Hlsl/Diagnostics/DiagnosticId.cs b/src/ShaderTools.CodeAnalysis.Hlsl/Diagnostics/DiagnosticId.cs index a0cf4346..823eebe0 100644 --- a/src/ShaderTools.CodeAnalysis.Hlsl/Diagnostics/DiagnosticId.cs +++ b/src/ShaderTools.CodeAnalysis.Hlsl/Diagnostics/DiagnosticId.cs @@ -21,7 +21,6 @@ public enum DiagnosticId AlreadyDefined, BadDirectivePlacement, EndOfPreprocessorLineExpected, - MissingPreprocessorFile, IncludeNotFound, IncludeUnexpectedError, NotEnoughMacroParameters, diff --git a/src/ShaderTools.CodeAnalysis.Hlsl/Parser/DirectiveParser.cs b/src/ShaderTools.CodeAnalysis.Hlsl/Parser/DirectiveParser.cs index 5b520d42..e31a3320 100644 --- a/src/ShaderTools.CodeAnalysis.Hlsl/Parser/DirectiveParser.cs +++ b/src/ShaderTools.CodeAnalysis.Hlsl/Parser/DirectiveParser.cs @@ -268,7 +268,9 @@ private IncludeDirectiveTriviaSyntax ParseIncludeDirective(SyntaxToken hash, Syn private LineDirectiveTriviaSyntax ParseLineDirective(SyntaxToken hash, SyntaxToken keyword, bool isActive) { var line = Match(SyntaxKind.IntegerLiteralToken); - var filename = Match(SyntaxKind.StringLiteralToken); + var filename = Current.Kind != SyntaxKind.EndOfDirectiveToken ? Match(SyntaxKind.StringLiteralToken) : new SyntaxToken(SyntaxKind.EndOfDirectiveToken, true, + GetDiagnosticSourceRangeForMissingToken(), + GetDiagnosticTextSpanForMissingToken()); var eod = ParseEndOfDirective(line.IsMissing || !isActive); return new LineDirectiveTriviaSyntax(hash, keyword, line, filename, eod, isActive); @@ -437,7 +439,7 @@ private ExpressionSyntax ParseDirectiveParenthesizedExpression() return new ParenthesizedExpressionSyntax(openParen, expression, closeParen); } - private SyntaxToken ParseEndOfDirective(bool ignoreErrors, bool afterLineNumber = false) + private SyntaxToken ParseEndOfDirective(bool ignoreErrors) { var skippedTokens = new List(); @@ -448,13 +450,7 @@ private SyntaxToken ParseEndOfDirective(bool ignoreErrors, bool afterLineNumber skippedTokens = new List(10); if (!ignoreErrors) - { - var errorCode = DiagnosticId.EndOfPreprocessorLineExpected; - if (afterLineNumber) - errorCode = DiagnosticId.MissingPreprocessorFile; - - skippedTokens.Add(WithDiagnostic(NextToken().WithoutDiagnostics(), errorCode)); - } + skippedTokens.Add(WithDiagnostic(NextToken().WithoutDiagnostics(), DiagnosticId.EndOfPreprocessorLineExpected)); while (Current.Kind != SyntaxKind.EndOfDirectiveToken && Current.Kind != SyntaxKind.EndOfFileToken) @@ -492,9 +488,9 @@ private bool EvaluateBool(ExpressionSyntax expr) { var result = Evaluate(expr); if (result is bool) - return (bool)result; + return (bool) result; if (result is int) - return (int)result != 0; + return (int) result != 0; return false; } @@ -503,7 +499,7 @@ private int EvaluateInt(ExpressionSyntax expr) { var result = Evaluate(expr); if (result is int) - return (int)result; + return (int) result; return 0; } @@ -516,49 +512,49 @@ private object Evaluate(ExpressionSyntax expr) switch (expr.Kind) { case SyntaxKind.ParenthesizedExpression: - return Evaluate(((ParenthesizedExpressionSyntax)expr).Expression); + return Evaluate(((ParenthesizedExpressionSyntax) expr).Expression); case SyntaxKind.TrueLiteralExpression: case SyntaxKind.FalseLiteralExpression: case SyntaxKind.NumericLiteralExpression: - return ((LiteralExpressionSyntax)expr).Token.Value; + return ((LiteralExpressionSyntax) expr).Token.Value; case SyntaxKind.LogicalAndExpression: case SyntaxKind.BitwiseAndExpression: - return EvaluateBool(((BinaryExpressionSyntax)expr).Left) && EvaluateBool(((BinaryExpressionSyntax)expr).Right); + return EvaluateBool(((BinaryExpressionSyntax) expr).Left) && EvaluateBool(((BinaryExpressionSyntax) expr).Right); case SyntaxKind.LogicalOrExpression: case SyntaxKind.BitwiseOrExpression: - return EvaluateBool(((BinaryExpressionSyntax)expr).Left) || EvaluateBool(((BinaryExpressionSyntax)expr).Right); + return EvaluateBool(((BinaryExpressionSyntax) expr).Left) || EvaluateBool(((BinaryExpressionSyntax) expr).Right); case SyntaxKind.EqualsExpression: - return Equals(Evaluate(((BinaryExpressionSyntax)expr).Left), Evaluate(((BinaryExpressionSyntax)expr).Right)); + return Equals(Evaluate(((BinaryExpressionSyntax) expr).Left), Evaluate(((BinaryExpressionSyntax) expr).Right)); case SyntaxKind.NotEqualsExpression: - return !Equals(Evaluate(((BinaryExpressionSyntax)expr).Left), Evaluate(((BinaryExpressionSyntax)expr).Right)); + return !Equals(Evaluate(((BinaryExpressionSyntax) expr).Left), Evaluate(((BinaryExpressionSyntax) expr).Right)); case SyntaxKind.LogicalNotExpression: - return !EvaluateBool(((PrefixUnaryExpressionSyntax)expr).Operand); + return !EvaluateBool(((PrefixUnaryExpressionSyntax) expr).Operand); case SyntaxKind.AddExpression: - return EvaluateInt(((BinaryExpressionSyntax)expr).Left) + EvaluateInt(((BinaryExpressionSyntax)expr).Right); + return EvaluateInt(((BinaryExpressionSyntax) expr).Left) + EvaluateInt(((BinaryExpressionSyntax) expr).Right); case SyntaxKind.SubtractExpression: - return EvaluateInt(((BinaryExpressionSyntax)expr).Left) - EvaluateInt(((BinaryExpressionSyntax)expr).Right); + return EvaluateInt(((BinaryExpressionSyntax) expr).Left) - EvaluateInt(((BinaryExpressionSyntax) expr).Right); case SyntaxKind.MultiplyExpression: - return EvaluateInt(((BinaryExpressionSyntax)expr).Left) * EvaluateInt(((BinaryExpressionSyntax)expr).Right); + return EvaluateInt(((BinaryExpressionSyntax) expr).Left) * EvaluateInt(((BinaryExpressionSyntax) expr).Right); case SyntaxKind.DivideExpression: var divisor = EvaluateInt(((BinaryExpressionSyntax) expr).Right); return (divisor != 0) ? EvaluateInt(((BinaryExpressionSyntax) expr).Left) / divisor : int.MaxValue; case SyntaxKind.GreaterThanExpression: - return EvaluateInt(((BinaryExpressionSyntax)expr).Left) > EvaluateInt(((BinaryExpressionSyntax)expr).Right); + return EvaluateInt(((BinaryExpressionSyntax) expr).Left) > EvaluateInt(((BinaryExpressionSyntax) expr).Right); case SyntaxKind.GreaterThanOrEqualExpression: - return EvaluateInt(((BinaryExpressionSyntax)expr).Left) >= EvaluateInt(((BinaryExpressionSyntax)expr).Right); + return EvaluateInt(((BinaryExpressionSyntax) expr).Left) >= EvaluateInt(((BinaryExpressionSyntax) expr).Right); case SyntaxKind.LessThanExpression: - return EvaluateInt(((BinaryExpressionSyntax)expr).Left) < EvaluateInt(((BinaryExpressionSyntax)expr).Right); + return EvaluateInt(((BinaryExpressionSyntax) expr).Left) < EvaluateInt(((BinaryExpressionSyntax) expr).Right); case SyntaxKind.LessThanOrEqualExpression: - return EvaluateInt(((BinaryExpressionSyntax)expr).Left) <= EvaluateInt(((BinaryExpressionSyntax)expr).Right); + return EvaluateInt(((BinaryExpressionSyntax) expr).Left) <= EvaluateInt(((BinaryExpressionSyntax) expr).Right); case SyntaxKind.IdentifierName: - var id = ((IdentifierNameSyntax)expr).Name.Text; + var id = ((IdentifierNameSyntax) expr).Name.Text; return IsDirectiveDefined(id); case SyntaxKind.FunctionInvocationExpression: // It must be a call to "defined" - that's the only one allowed by the parser. - var functionCall = (FunctionInvocationExpressionSyntax)expr; - var identifierName = ((IdentifierNameSyntax)functionCall.ArgumentList.Arguments[0]).Name; + var functionCall = (FunctionInvocationExpressionSyntax) expr; + var identifierName = ((IdentifierNameSyntax) functionCall.ArgumentList.Arguments[0]).Name; return IsDirectiveDefined(identifierName.Text); default: return false; diff --git a/src/ShaderTools.CodeAnalysis.Hlsl/Parser/HlslLexer.Preprocessor.cs b/src/ShaderTools.CodeAnalysis.Hlsl/Parser/HlslLexer.Preprocessor.cs index f9afe8eb..4c533b70 100644 --- a/src/ShaderTools.CodeAnalysis.Hlsl/Parser/HlslLexer.Preprocessor.cs +++ b/src/ShaderTools.CodeAnalysis.Hlsl/Parser/HlslLexer.Preprocessor.cs @@ -24,7 +24,7 @@ private SyntaxToken LexDirectiveToken() { _kind = SyntaxKind.BadToken; _contextualKind = SyntaxKind.BadToken; - + _value = null; _diagnostics.Clear(); _start = _charReader.Position; @@ -82,7 +82,7 @@ private SyntaxToken LexDirectiveToken() LexDirectiveTrailingTrivia(trailingTrivia, kind, isEndOfLine); - var token = new SyntaxToken(kind, _contextualKind, false, MakeAbsolute(span), fileSpan, text, _value, + var token = new SyntaxToken(kind, _contextualKind, false, MakeAbsolute(span), fileSpan, text, _value, ImmutableArray.Empty, trailingTrivia.ToImmutableArray(), diagnostics, null, false); diff --git a/src/ShaderTools.CodeAnalysis.Hlsl/Properties/Resources.Designer.cs b/src/ShaderTools.CodeAnalysis.Hlsl/Properties/Resources.Designer.cs index 2d0ffaf7..18a4a8f7 100644 --- a/src/ShaderTools.CodeAnalysis.Hlsl/Properties/Resources.Designer.cs +++ b/src/ShaderTools.CodeAnalysis.Hlsl/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace ShaderTools.CodeAnalysis.Hlsl.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -366,15 +366,6 @@ internal static string MethodOverloadResolutionFailure { } } - /// - /// Looks up a localized string similar to Quoted file name, single-line comment or end-of-line expected.. - /// - internal static string MissingPreprocessorFile { - get { - return ResourceManager.GetString("MissingPreprocessorFile", resourceCulture); - } - } - /// /// Looks up a localized string similar to Not enough actual parameters for macro '{0}'.. /// diff --git a/src/ShaderTools.CodeAnalysis.Hlsl/Properties/Resources.resx b/src/ShaderTools.CodeAnalysis.Hlsl/Properties/Resources.resx index 3513d274..d0883300 100644 --- a/src/ShaderTools.CodeAnalysis.Hlsl/Properties/Resources.resx +++ b/src/ShaderTools.CodeAnalysis.Hlsl/Properties/Resources.resx @@ -213,9 +213,6 @@ No overload for method '{0}' takes {1} arguments. - - Quoted file name, single-line comment or end-of-line expected. - Not enough actual parameters for macro '{0}'.