From cc6cc6cf6ccd74762e7e81aebe4d974533f2a22c Mon Sep 17 00:00:00 2001 From: Luthetus <45454132+huntercfreeman@users.noreply.github.com> Date: Sun, 15 Dec 2024 08:24:41 -0500 Subject: [PATCH 1/9] Update versions --- Source/Lib/Ide/Ide.RazorLib/Luthetus.Ide.RazorLib.csproj | 2 +- .../Shareds/Displays/Internals/IdeInfoDisplay.razor | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Source/Lib/Ide/Ide.RazorLib/Luthetus.Ide.RazorLib.csproj b/Source/Lib/Ide/Ide.RazorLib/Luthetus.Ide.RazorLib.csproj index fedec9484..4e70b26a0 100644 --- a/Source/Lib/Ide/Ide.RazorLib/Luthetus.Ide.RazorLib.csproj +++ b/Source/Lib/Ide/Ide.RazorLib/Luthetus.Ide.RazorLib.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 0.9.7.7 + 0.9.7.8 diff --git a/Source/Lib/Ide/Ide.RazorLib/Shareds/Displays/Internals/IdeInfoDisplay.razor b/Source/Lib/Ide/Ide.RazorLib/Shareds/Displays/Internals/IdeInfoDisplay.razor index 97edacd22..1b6bf405d 100644 --- a/Source/Lib/Ide/Ide.RazorLib/Shareds/Displays/Internals/IdeInfoDisplay.razor +++ b/Source/Lib/Ide/Ide.RazorLib/Shareds/Displays/Internals/IdeInfoDisplay.razor @@ -172,7 +172,13 @@ Recent Changes:
-
v 0.9.7.7 (WIP_DATE)
+
v 0.9.7.8 (WIP_DATE)
+
    +
  • WIP_DESCRIPTION
  • +
+
+
+
v 0.9.7.7 (2024-12-15)
  • Reduce object allocations when parsing.
  • Reduce memory usage from parsing by 25%.
  • From 4e2de8fa3a038e6f09e930d7280056bb873b4086 Mon Sep 17 00:00:00 2001 From: Luthetus <45454132+huntercfreeman@users.noreply.github.com> Date: Sun, 15 Dec 2024 09:59:32 -0500 Subject: [PATCH 2/9] Invoke 'ResourceWasModified(...)' first open of file --- .../Models/Internals/DisplayTracker.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Source/Lib/TextEditor/TextEditors/Models/Internals/DisplayTracker.cs b/Source/Lib/TextEditor/TextEditors/Models/Internals/DisplayTracker.cs index 742d2429c..25df1d18a 100644 --- a/Source/Lib/TextEditor/TextEditors/Models/Internals/DisplayTracker.cs +++ b/Source/Lib/TextEditor/TextEditors/Models/Internals/DisplayTracker.cs @@ -129,11 +129,27 @@ public void IncrementLinks() if (modelModifier is null) return Task.CompletedTask; - + + // If this 'ApplySyntaxHighlighting(...)' isn't redundantly invoked prior to + // the upcoming 'ResourceWasModified(...)' invocation, + // then there is an obnoxious "flicker" upon opening a file for the first time. + // + // This is because it initially opens with 'plain text' syntax highlighting + // for all the text. + // + // Then very soon after it gets the correct syntax highlighting applied. + // The issue is specifically how quickly it gets the correct syntax highlighting. + // + // It is the same issue as putting a 'loading...' icon or text + // for an asynchronous event, but that event finishes in sub 200ms so the user + // sees a "flicker" of the 'loading...' text and it just is disorienting to see. editContext.TextEditorService.ModelApi.ApplySyntaxHighlighting( editContext, modelModifier); + if (modelModifier.CompilerService is not null) + modelModifier.CompilerService.ResourceWasModified(_resourceUri, Array.Empty()); + return Task.CompletedTask; }); From 25514ef47030e40646ce0c49c30454a1d56f0c5a Mon Sep 17 00:00:00 2001 From: Luthetus <45454132+huntercfreeman@users.noreply.github.com> Date: Sun, 15 Dec 2024 10:29:02 -0500 Subject: [PATCH 3/9] Out, in, ref, params (maybe in future change to check for any keyword?) --- .../CSharp/BinderCase/CSharpBinder.Expressions.cs | 1 + .../CSharp/ParserCase/Internals/ParseFunctions.cs | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/Source/Lib/CompilerServices/CSharp/BinderCase/CSharpBinder.Expressions.cs b/Source/Lib/CompilerServices/CSharp/BinderCase/CSharpBinder.Expressions.cs index 925489398..7929b2ac0 100644 --- a/Source/Lib/CompilerServices/CSharp/BinderCase/CSharpBinder.Expressions.cs +++ b/Source/Lib/CompilerServices/CSharp/BinderCase/CSharpBinder.Expressions.cs @@ -828,6 +828,7 @@ public IExpressionNode EmptyMergeToken( return emptyExpressionNode; case SyntaxKind.InTokenKeyword: case SyntaxKind.RefTokenKeyword: + case SyntaxKind.ParamsTokenKeyword: return emptyExpressionNode; case SyntaxKind.OpenAngleBracketToken: var genericParametersListingNode = new GenericParametersListingNode( diff --git a/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseFunctions.cs b/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseFunctions.cs index b93a5baac..5d8f964a4 100644 --- a/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseFunctions.cs +++ b/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseFunctions.cs @@ -153,6 +153,14 @@ public static FunctionArgumentsListingNode HandleFunctionArguments(CSharpCompila } else if (!corruptState) { + if (parserModel.TokenWalker.Current.SyntaxKind == SyntaxKind.OutTokenKeyword || + parserModel.TokenWalker.Current.SyntaxKind == SyntaxKind.InTokenKeyword || + parserModel.TokenWalker.Current.SyntaxKind == SyntaxKind.RefTokenKeyword || + parserModel.TokenWalker.Current.SyntaxKind == SyntaxKind.ParamsTokenKeyword) + { + _ = parserModel.TokenWalker.Consume(); + } + var tokenIndexOriginal = parserModel.TokenWalker.Index; var successTypeClauseNode = ParseOthers.TryParseExpression(SyntaxKind.TypeClauseNode, compilationUnit, ref parserModel, out var typeClauseNode); var successName = false; From e8343d9975268b478db839aaec941d069fdd20a8 Mon Sep 17 00:00:00 2001 From: Luthetus <45454132+huntercfreeman@users.noreply.github.com> Date: Sun, 15 Dec 2024 11:18:56 -0500 Subject: [PATCH 4/9] GetNodePositionIndices(...) ConstructorDefinitionNode --- .../CSharp/BinderCase/CSharpBinder.Main.cs | 9 +++++ .../Symbols/FunctionSyntaxDisplay.razor | 39 ++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/Source/Lib/CompilerServices/CSharp/BinderCase/CSharpBinder.Main.cs b/Source/Lib/CompilerServices/CSharp/BinderCase/CSharpBinder.Main.cs index 06042e1f5..b6f156035 100644 --- a/Source/Lib/CompilerServices/CSharp/BinderCase/CSharpBinder.Main.cs +++ b/Source/Lib/CompilerServices/CSharp/BinderCase/CSharpBinder.Main.cs @@ -1707,6 +1707,15 @@ public bool TryAddReturnTypeClauseNodeByScope( goto default; } + case SyntaxKind.ConstructorDefinitionNode: + { + var constructorDefinitionNode = (ConstructorDefinitionNode)syntaxNode; + + if (constructorDefinitionNode.FunctionIdentifier.ConstructorWasInvoked) + return (constructorDefinitionNode.FunctionIdentifier.TextSpan.StartingIndexInclusive, constructorDefinitionNode.FunctionIdentifier.TextSpan.EndingIndexExclusive); + + goto default; + } case SyntaxKind.VariableDeclarationNode: { var variableDeclarationNode = (VariableDeclarationNode)syntaxNode; diff --git a/Source/Lib/TextEditor/TextEditors/Displays/Internals/Symbols/FunctionSyntaxDisplay.razor b/Source/Lib/TextEditor/TextEditors/Displays/Internals/Symbols/FunctionSyntaxDisplay.razor index 5a82982c2..e7e323861 100644 --- a/Source/Lib/TextEditor/TextEditors/Displays/Internals/Symbols/FunctionSyntaxDisplay.razor +++ b/Source/Lib/TextEditor/TextEditors/Displays/Internals/Symbols/FunctionSyntaxDisplay.razor @@ -14,6 +14,7 @@ string? methodName; GenericParametersListingNode? genericParametersListingNode; + FunctionArgumentsListingNode? functionArgumentsListingNode; bool isConstructorInvocation = false; if (syntaxViewModelLocal.DefinitionNode is null && syntaxViewModelLocal.TargetNode is null && syntaxViewModelLocal.TargetSymbol is null) @@ -23,6 +24,7 @@ returnTypeClauseNodeText = null; methodName = null; genericParametersListingNode = null; + functionArgumentsListingNode = null; } else if (syntaxViewModelLocal.DefinitionNode is not null && (syntaxViewModelLocal.DefinitionNode.SyntaxKind == SyntaxKind.FunctionDefinitionNode || @@ -37,6 +39,7 @@ returnTypeClauseNodeText = null; methodName = functionDefinitionNode.FunctionIdentifierToken.TextSpan.GetText(); genericParametersListingNode = functionDefinitionNode.GenericArgumentsListingNode; + functionArgumentsListingNode = functionDefinitionNode.FunctionArgumentsListingNode; } else if (syntaxViewModelLocal.DefinitionNode.SyntaxKind == SyntaxKind.ConstructorDefinitionNode) { @@ -45,6 +48,7 @@ returnTypeClauseNodeText = null; methodName = null; genericParametersListingNode = null; + functionArgumentsListingNode = constructorDefinitionNode.FunctionArgumentsListingNode; } else { @@ -52,6 +56,7 @@ returnTypeClauseNodeText = null; methodName = "unknown syntax"; genericParametersListingNode = null; + functionArgumentsListingNode = null; } } else if (syntaxViewModelLocal.TargetNode is not null && @@ -67,6 +72,7 @@ returnTypeClauseNodeText = null; methodName = functionInvocationNode.FunctionInvocationIdentifierToken.TextSpan.GetText(); genericParametersListingNode = functionInvocationNode.GenericParametersListingNode; + functionArgumentsListingNode = null; } else if (syntaxViewModelLocal.TargetNode.SyntaxKind == SyntaxKind.ConstructorInvocationExpressionNode) { @@ -75,6 +81,7 @@ returnTypeClauseNodeText = null; methodName = null; genericParametersListingNode = null; + functionArgumentsListingNode = null; } else { @@ -82,6 +89,7 @@ returnTypeClauseNodeText = null; methodName = "unknown syntax"; genericParametersListingNode = null; + functionArgumentsListingNode = null; } } else if (syntaxViewModelLocal.TargetSymbol is not null && @@ -96,6 +104,7 @@ returnTypeClauseNodeText = null; methodName = syntaxViewModelLocal.TargetSymbol.TextSpan.GetText(); genericParametersListingNode = null; + functionArgumentsListingNode = null; } else if (syntaxViewModelLocal.TargetSymbol.SyntaxKind == SyntaxKind.ConstructorSymbol) { @@ -103,6 +112,7 @@ returnTypeClauseNodeText = syntaxViewModelLocal.TargetSymbol.TextSpan.GetText(); methodName = null; genericParametersListingNode = null; + functionArgumentsListingNode = null; } else { @@ -110,6 +120,7 @@ returnTypeClauseNodeText = null; methodName = null; genericParametersListingNode = null; + functionArgumentsListingNode = null; } } else @@ -119,6 +130,7 @@ returnTypeClauseNodeText = null; methodName = null; genericParametersListingNode = null; + functionArgumentsListingNode = null; } } @@ -171,5 +183,30 @@ } - () + @if (functionArgumentsListingNode is null) + { + () + } + else + { + ( + @for (int badIndex = 0; badIndex < functionArgumentsListingNode.FunctionArgumentEntryNodeList.Count; badIndex++) + { + var index = badIndex; + var argumentEntryNode = functionArgumentsListingNode.FunctionArgumentEntryNodeList[index]; + + var syntaxViewModel = new SyntaxViewModel( + targetSymbol: null, + targetNode: argumentEntryNode.VariableDeclarationNode, + definitionNode: argumentEntryNode.VariableDeclarationNode, + depth: syntaxViewModelLocal.Depth + 1); + + + if (badIndex < functionArgumentsListingNode.FunctionArgumentEntryNodeList.Count - 1) + { + , + } + } + ) + } From 2e8ded832477762a6a48c488fda0536a8ea7557f Mon Sep 17 00:00:00 2001 From: Luthetus <45454132+huntercfreeman@users.noreply.github.com> Date: Sun, 15 Dec 2024 15:38:26 -0500 Subject: [PATCH 5/9] Luthetus.CompilerServices.CSharp.Tests.csproj builds --- .../CSharp/SmokeTests/Binders/BinderTests.cs | 18 +- .../CSharp/SmokeTests/Lexers/LexerTests.cs | 256 ++++++++---------- .../Parsers/ExpressionAsStatementTests.cs | 21 +- .../SmokeTests/Parsers/ExpressionTests.cs | 21 +- .../CSharp/SmokeTests/Parsers/ScopeTests.cs | 11 +- .../SmokeTests/Parsers/StatementTests.cs | 12 +- 6 files changed, 151 insertions(+), 188 deletions(-) diff --git a/Source/Tests/CompilerServices/CSharp/SmokeTests/Binders/BinderTests.cs b/Source/Tests/CompilerServices/CSharp/SmokeTests/Binders/BinderTests.cs index cae000a58..d9c29769d 100644 --- a/Source/Tests/CompilerServices/CSharp/SmokeTests/Binders/BinderTests.cs +++ b/Source/Tests/CompilerServices/CSharp/SmokeTests/Binders/BinderTests.cs @@ -23,17 +23,15 @@ public Test(string sourceText) { SourceText = sourceText; ResourceUri = new ResourceUri("./unitTesting.txt"); - Lexer = new CSharpLexer(ResourceUri, SourceText); - Lexer.Lex(); - Parser = new CSharpParser(Lexer); - CompilationUnit = Parser.Parse(); + CompilationUnit.LexerOutput = CSharpLexer.Lex(ResourceUri, SourceText); + CSharpParser.Parse(CompilationUnit); } public string SourceText { get; set; } public ResourceUri ResourceUri { get; set; } - public CSharpLexer Lexer { get; set; } - public CSharpParser Parser { get; set; } - public CompilationUnit CompilationUnit { get; set; } + public CSharpLexerOutput LexerOutput { get; set; } + public IBinder Binder => CompilationUnit.Binder; + public CSharpCompilationUnit CompilationUnit { get; set; } } [Fact] @@ -49,7 +47,7 @@ public void TypeDefinitionNode_IdentifierToken() var cSharpResource = new CSharpResource(test.ResourceUri, null); cSharpResource.CompilationUnit = test.CompilationUnit; - var node = binder.GetSyntaxNode(13, test.ResourceUri, cSharpResource); + var node = binder.GetSyntaxNode(test.CompilationUnit, 13, test.ResourceUri, cSharpResource); Assert.NotNull(node); Assert.Equal(SyntaxKind.TypeDefinitionNode, node.SyntaxKind); @@ -68,7 +66,7 @@ public void FunctionDefinitionNode_IdentifierToken() var cSharpResource = new CSharpResource(test.ResourceUri, null); cSharpResource.CompilationUnit = test.CompilationUnit; - var node = binder.GetSyntaxNode(12, test.ResourceUri, cSharpResource); + var node = binder.GetSyntaxNode(test.CompilationUnit, 12, test.ResourceUri, cSharpResource); Assert.NotNull(node); Assert.Equal(SyntaxKind.FunctionDefinitionNode, node.SyntaxKind); @@ -96,7 +94,7 @@ public class BackgroundTask : IBackgroundTask var cSharpResource = new CSharpResource(test.ResourceUri, null); cSharpResource.CompilationUnit = test.CompilationUnit; - var node = binder.GetSyntaxNode(119, test.ResourceUri, cSharpResource); + var node = binder.GetSyntaxNode(test.CompilationUnit, 119, test.ResourceUri, cSharpResource); Assert.NotNull(node); Assert.Equal(SyntaxKind.TypeDefinitionNode, node.SyntaxKind); diff --git a/Source/Tests/CompilerServices/CSharp/SmokeTests/Lexers/LexerTests.cs b/Source/Tests/CompilerServices/CSharp/SmokeTests/Lexers/LexerTests.cs index 65715052a..244d53bb7 100644 --- a/Source/Tests/CompilerServices/CSharp/SmokeTests/Lexers/LexerTests.cs +++ b/Source/Tests/CompilerServices/CSharp/SmokeTests/Lexers/LexerTests.cs @@ -1,10 +1,12 @@ using System.Text; using Luthetus.TextEditor.RazorLib.Lexers.Models; +using Luthetus.TextEditor.RazorLib.CompilerServices.Interfaces; using Luthetus.TextEditor.RazorLib.CompilerServices.Syntax; using Luthetus.TextEditor.RazorLib.CompilerServices.Syntax.Tokens; using Luthetus.TextEditor.RazorLib.CompilerServices.Syntax.Nodes; using Luthetus.CompilerServices.CSharp.LexerCase; using Luthetus.CompilerServices.CSharp.ParserCase; +using Luthetus.CompilerServices.CSharp.CompilerServiceCase; namespace Luthetus.CompilerServices.CSharp.Tests.SmokeTests.Lexers; @@ -16,17 +18,15 @@ public Test(string sourceText) { SourceText = sourceText; ResourceUri = new ResourceUri("./unitTesting.txt"); - Lexer = new CSharpLexer(ResourceUri, SourceText); - Lexer.Lex(); - Parser = new CSharpParser(Lexer); - CompilationUnit = Parser.Parse(); + CompilationUnit.LexerOutput = CSharpLexer.Lex(ResourceUri, SourceText); + CSharpParser.Parse(CompilationUnit); } public string SourceText { get; set; } public ResourceUri ResourceUri { get; set; } - public CSharpLexer Lexer { get; set; } - public CSharpParser Parser { get; set; } - public CompilationUnit CompilationUnit { get; set; } + public CSharpLexerOutput LexerOutput { get; set; } + public IBinder Binder => CompilationUnit.Binder; + public CSharpCompilationUnit CompilationUnit { get; set; } } /// @@ -141,12 +141,11 @@ public void LEX_BangToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "!"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var bangToken = (BangToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var bangToken = (BangToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.BangToken, bangToken.SyntaxKind); } @@ -156,12 +155,11 @@ public void LEX_CloseAngleBracketToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = ">"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var closeAngleBracketToken = (CloseAngleBracketToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var closeAngleBracketToken = (CloseAngleBracketToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.CloseAngleBracketToken, closeAngleBracketToken.SyntaxKind); } @@ -177,12 +175,11 @@ public void LEX_CloseBraceToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "}"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var closeBraceToken = (CloseBraceToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var closeBraceToken = (CloseBraceToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.CloseBraceToken, closeBraceToken.SyntaxKind); } @@ -192,12 +189,11 @@ public void LEX_CloseParenthesisToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = ")"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var closeParenthesisToken = (CloseParenthesisToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var closeParenthesisToken = (CloseParenthesisToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.CloseParenthesisToken, closeParenthesisToken.SyntaxKind); } @@ -207,12 +203,11 @@ public void LEX_CloseSquareBracketToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "]"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var closeSquareBracketToken = (CloseSquareBracketToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var closeSquareBracketToken = (CloseSquareBracketToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.CloseSquareBracketToken, closeSquareBracketToken.SyntaxKind); } @@ -222,12 +217,11 @@ public void LEX_ColonToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = ":"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var colonToken = (ColonToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var colonToken = (ColonToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.ColonToken, colonToken.SyntaxKind); } @@ -237,12 +231,11 @@ public void LEX_CommaToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = ","; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var commaToken = (CommaToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var commaToken = (CommaToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.CommaToken, commaToken.SyntaxKind); } @@ -264,12 +257,11 @@ public void LEX_DollarSignToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "$"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var dollarSignToken = (DollarSignToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var dollarSignToken = (DollarSignToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.DollarSignToken, dollarSignToken.SyntaxKind); } @@ -285,12 +277,11 @@ public void LEX_EqualsEqualsToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "=="; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var equalsEqualsToken = (EqualsEqualsToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var equalsEqualsToken = (EqualsEqualsToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.EqualsEqualsToken, equalsEqualsToken.SyntaxKind); } @@ -300,12 +291,11 @@ public void LEX_EqualsToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "="; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var equalsToken = (EqualsToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var equalsToken = (EqualsToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.EqualsToken, equalsToken.SyntaxKind); } @@ -366,12 +356,11 @@ public void LEX_EqualsToken() public void LEX_IdentifierToken(string sourceText) { var resourceUri = new ResourceUri("UnitTests"); - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var identifierToken = (IdentifierToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var identifierToken = (IdentifierToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.IdentifierToken, identifierToken.SyntaxKind); } @@ -399,12 +388,11 @@ public void LEX_MemberAccessToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "."; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var memberAccessToken = (MemberAccessToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var memberAccessToken = (MemberAccessToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.MemberAccessToken, memberAccessToken.SyntaxKind); } @@ -414,12 +402,11 @@ public void LEX_MinusMinusToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "--"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var minusMinusToken = (MinusMinusToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var minusMinusToken = (MinusMinusToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.MinusMinusToken, minusMinusToken.SyntaxKind); } @@ -429,12 +416,11 @@ public void LEX_MinusToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "-"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var minusToken = (MinusToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var minusToken = (MinusToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.MinusToken, minusToken.SyntaxKind); } @@ -444,12 +430,11 @@ public void LEX_NumericLiteralToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "2"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var numericLiteralToken = (NumericLiteralToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var numericLiteralToken = (NumericLiteralToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.NumericLiteralToken, numericLiteralToken.SyntaxKind); } @@ -459,12 +444,11 @@ public void LEX_OpenAngleBracketToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "<"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var openAngleBracketToken = (OpenAngleBracketToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var openAngleBracketToken = (OpenAngleBracketToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.OpenAngleBracketToken, openAngleBracketToken.SyntaxKind); } @@ -480,12 +464,11 @@ public void LEX_OpenBraceToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "{"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var openBraceToken = (OpenBraceToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var openBraceToken = (OpenBraceToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.OpenBraceToken, openBraceToken.SyntaxKind); } @@ -495,12 +478,11 @@ public void LEX_OpenParenthesisToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "("; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var openParenthesisToken = (OpenParenthesisToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var openParenthesisToken = (OpenParenthesisToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.OpenParenthesisToken, openParenthesisToken.SyntaxKind); } @@ -510,12 +492,11 @@ public void LEX_OpenSquareBracketToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "["; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var openSquareBracketToken = (OpenSquareBracketToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var openSquareBracketToken = (OpenSquareBracketToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.OpenSquareBracketToken, openSquareBracketToken.SyntaxKind); } @@ -525,12 +506,11 @@ public void LEX_PlusPlusToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "++"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var plusPlusToken = (PlusPlusToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var plusPlusToken = (PlusPlusToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.PlusPlusToken, plusPlusToken.SyntaxKind); } @@ -540,12 +520,11 @@ public void LEX_PlusToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "+"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var plusToken = (PlusToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var plusToken = (PlusToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.PlusToken, plusToken.SyntaxKind); } @@ -561,12 +540,11 @@ public void LEX_QuestionMarkQuestionMarkToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "??"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var questionMarkQuestionMarkToken = (QuestionMarkQuestionMarkToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var questionMarkQuestionMarkToken = (QuestionMarkQuestionMarkToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.QuestionMarkQuestionMarkToken, questionMarkQuestionMarkToken.SyntaxKind); } @@ -576,12 +554,11 @@ public void LEX_QuestionMarkToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "?"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var questionMarkToken = (QuestionMarkToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var questionMarkToken = (QuestionMarkToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.QuestionMarkToken, questionMarkToken.SyntaxKind); } @@ -591,12 +568,11 @@ public void LEX_StarToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "*"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var starToken = (StarToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var starToken = (StarToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.StarToken, starToken.SyntaxKind); } @@ -606,12 +582,11 @@ public void LEX_StatementDelimiterToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = ";"; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var statementDelimiterToken = (StatementDelimiterToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var statementDelimiterToken = (StatementDelimiterToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.StatementDelimiterToken, statementDelimiterToken.SyntaxKind); } @@ -621,12 +596,11 @@ public void LEX_StringLiteralToken() { var resourceUri = new ResourceUri("UnitTests"); var sourceText = "\"Hello World!\""; - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); - Assert.Equal(2, lexer.SyntaxTokenList.Length); - var stringLiteralToken = (StringLiteralToken)lexer.SyntaxTokenList[0]; - var endOfFileToken = (EndOfFileToken)lexer.SyntaxTokenList[1]; + Assert.Equal(2, lexerOutput.SyntaxTokenList.Count); + var stringLiteralToken = (StringLiteralToken)lexerOutput.SyntaxTokenList[0]; + var endOfFileToken = (EndOfFileToken)lexerOutput.SyntaxTokenList[1]; Assert.Equal(SyntaxKind.StringLiteralToken, stringLiteralToken.SyntaxKind); } @@ -642,8 +616,7 @@ public void LEX_EscapedStrings() { var sourceText = @"public const string Tag = ""`'\"";luth_clipboard"";".ReplaceLineEndings("\n"); var resourceUri = new ResourceUri("UnitTests"); - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); throw new NotImplementedException(); } @@ -656,11 +629,10 @@ public void LEX_ClassDefinition() }".ReplaceLineEndings("\n"); var resourceUri = new ResourceUri("UnitTests"); - var lexer = new CSharpLexer(resourceUri, sourceText); - lexer.Lex(); + var lexerOutput = CSharpLexer.Lex(resourceUri, sourceText); // Tokens: 'public' 'class' 'MyClass' '{' '}' 'EndOfFileToken' - Assert.Equal(6, lexer.SyntaxTokenList.Length); + Assert.Equal(6, lexerOutput.SyntaxTokenList.Count); } private void WriteChildrenIndented(ISyntaxNode node, string name = "node") diff --git a/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/ExpressionAsStatementTests.cs b/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/ExpressionAsStatementTests.cs index e7dbd6a4c..84f6b4e66 100644 --- a/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/ExpressionAsStatementTests.cs +++ b/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/ExpressionAsStatementTests.cs @@ -11,6 +11,7 @@ using Luthetus.CompilerServices.CSharp.ParserCase; using Luthetus.CompilerServices.CSharp.ParserCase.Internals; using Luthetus.CompilerServices.CSharp.Facts; +using Luthetus.CompilerServices.CSharp.CompilerServiceCase; namespace Luthetus.CompilerServices.CSharp.Tests.SmokeTests.Parsers; @@ -38,17 +39,15 @@ public Test(string sourceText) { SourceText = sourceText; ResourceUri = new ResourceUri("./unitTesting.txt"); - Lexer = new CSharpLexer(ResourceUri, SourceText); - Lexer.Lex(); - Parser = new CSharpParser(Lexer); - CompilationUnit = Parser.Parse(); + CompilationUnit.LexerOutput = CSharpLexer.Lex(ResourceUri, SourceText); + CSharpParser.Parse(CompilationUnit); } public string SourceText { get; set; } public ResourceUri ResourceUri { get; set; } - public CSharpLexer Lexer { get; set; } - public CSharpParser Parser { get; set; } - public CompilationUnit CompilationUnit { get; set; } + public CSharpLexerOutput LexerOutput { get; set; } + public IBinder Binder => CompilationUnit.Binder; + public CSharpCompilationUnit CompilationUnit { get; set; } } [Fact] @@ -580,7 +579,7 @@ public void ConstructorInvocationNode_Generic_Parameters_MISSING_NumericLiteralT // The constructor parameters are nonsensical and just exist for the sake of this test case. var test = new Test("new Dictionary(0, \"Test\")"); - foreach (var token in test.Lexer.SyntaxTokenList) + foreach (var token in test.LexerOutput.SyntaxTokenList) { Console.WriteLine(token.SyntaxKind); } @@ -609,7 +608,7 @@ Someone needs to take away my keyboard because I am dangerously stupid. // The constructor parameters are nonsensical and just exist for the sake of this test case. var test = new Test("0"); - foreach (var token in test.Lexer.SyntaxTokenList) + foreach (var token in test.LexerOutput.SyntaxTokenList) { Console.WriteLine(token.SyntaxKind); } @@ -1545,7 +1544,7 @@ public void WhileLoop_DoNotBreakScope() var whileStatementNode = (WhileStatementNode)topCodeBlock.GetChildList().Single(); - ((IBinder)test.Parser.Binder).TryGetBinderSession(test.ResourceUri, out var binderSession); + ((IBinder)test.Binder).TryGetBinderSession(test.ResourceUri, out var binderSession); Assert.Equal(2, binderSession.ScopeList.Count); } @@ -1568,7 +1567,7 @@ void Aaa() "); var topCodeBlock = test.CompilationUnit.RootCodeBlockNode; - ((IBinder)test.Parser.Binder).TryGetBinderSession(test.ResourceUri, out var binderSession); + ((IBinder)test.Binder).TryGetBinderSession(test.ResourceUri, out var binderSession); Assert.Equal(3, binderSession.ScopeList.Count); foreach (var child in topCodeBlock.GetChildList()) diff --git a/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/ExpressionTests.cs b/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/ExpressionTests.cs index 75e6371bf..684e6e0f2 100644 --- a/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/ExpressionTests.cs +++ b/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/ExpressionTests.cs @@ -11,6 +11,7 @@ using Luthetus.CompilerServices.CSharp.ParserCase; using Luthetus.CompilerServices.CSharp.ParserCase.Internals; using Luthetus.CompilerServices.CSharp.Facts; +using Luthetus.CompilerServices.CSharp.CompilerServiceCase; namespace Luthetus.CompilerServices.CSharp.Tests.SmokeTests.Parsers; @@ -22,17 +23,15 @@ public Test(string sourceText) { SourceText = sourceText; ResourceUri = new ResourceUri("./unitTesting.txt"); - Lexer = new CSharpLexer(ResourceUri, SourceText); - Lexer.Lex(); - Parser = new CSharpParser(Lexer); - CompilationUnit = Parser.Parse(); + CompilationUnit.LexerOutput = CSharpLexer.Lex(ResourceUri, SourceText); + CSharpParser.Parse(CompilationUnit); } public string SourceText { get; set; } public ResourceUri ResourceUri { get; set; } - public CSharpLexer Lexer { get; set; } - public CSharpParser Parser { get; set; } - public CompilationUnit CompilationUnit { get; set; } + public CSharpLexerOutput LexerOutput { get; set; } + public IBinder Binder => CompilationUnit.Binder; + public CSharpCompilationUnit CompilationUnit { get; set; } } [Fact] @@ -624,7 +623,7 @@ public void ConstructorInvocationNode_Generic_Parameters_MISSING_NumericLiteralT // The constructor parameters are nonsensical and just exist for the sake of this test case. var test = new Test("new Dictionary(0, \"Test\")"); - foreach (var token in test.Lexer.SyntaxTokenList) + foreach (var token in test.LexerOutput.SyntaxTokenList) { Console.WriteLine(token.SyntaxKind); } @@ -655,7 +654,7 @@ Someone needs to take away my keyboard because I am dangerously stupid. // The constructor parameters are nonsensical and just exist for the sake of this test case. var test = new Test("0"); - foreach (var token in test.Lexer.SyntaxTokenList) + foreach (var token in test.LexerOutput.SyntaxTokenList) { Console.WriteLine(token.SyntaxKind); } @@ -1652,7 +1651,7 @@ public void WhileLoop_DoNotBreakScope() var whileStatementNode = (WhileStatementNode)topCodeBlock.GetChildList().Single(); - ((IBinder)test.Parser.Binder).TryGetBinderSession(test.ResourceUri, out var binderSession); + ((IBinder)test.Binder).TryGetBinderSession(test.ResourceUri, out var binderSession); Assert.Equal(2, binderSession.ScopeList.Count); throw new NotImplementedException("See ExpressionAsStatementTests"); @@ -1677,7 +1676,7 @@ void Aaa() "); var topCodeBlock = test.CompilationUnit.RootCodeBlockNode; - ((IBinder)test.Parser.Binder).TryGetBinderSession(test.ResourceUri, out var binderSession); + ((IBinder)test.Binder).TryGetBinderSession(test.ResourceUri, out var binderSession); Assert.Equal(3, binderSession.ScopeList.Count); foreach (var child in topCodeBlock.GetChildList()) diff --git a/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/ScopeTests.cs b/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/ScopeTests.cs index 9f1ee0671..728bec331 100644 --- a/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/ScopeTests.cs +++ b/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/ScopeTests.cs @@ -11,6 +11,7 @@ using Luthetus.CompilerServices.CSharp.ParserCase; using Luthetus.CompilerServices.CSharp.ParserCase.Internals; using Luthetus.CompilerServices.CSharp.Facts; +using Luthetus.CompilerServices.CSharp.CompilerServiceCase; namespace Luthetus.CompilerServices.CSharp.Tests.SmokeTests.Parsers; @@ -41,18 +42,14 @@ public Test(string sourceText) { SourceText = sourceText; ResourceUri = new ResourceUri("./unitTesting.txt"); - Lexer = new CSharpLexer(ResourceUri, SourceText); - Lexer.Lex(); - Parser = new CSharpParser(Lexer); - CompilationUnit = Parser.Parse(); + CompilationUnit.LexerOutput = CSharpLexer.Lex(ResourceUri, SourceText); + CSharpParser.Parse(CompilationUnit); } public string SourceText { get; set; } public ResourceUri ResourceUri { get; set; } - public CSharpLexer Lexer { get; set; } - public CSharpParser Parser { get; set; } public IBinder Binder => CompilationUnit.Binder; - public CompilationUnit CompilationUnit { get; set; } + public CSharpCompilationUnit CompilationUnit { get; set; } } [Fact] diff --git a/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/StatementTests.cs b/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/StatementTests.cs index 40e858601..7c5af6355 100644 --- a/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/StatementTests.cs +++ b/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/StatementTests.cs @@ -11,6 +11,7 @@ using Luthetus.CompilerServices.CSharp.ParserCase; using Luthetus.CompilerServices.CSharp.ParserCase.Internals; using Luthetus.CompilerServices.CSharp.Facts; +using Luthetus.CompilerServices.CSharp.CompilerServiceCase; namespace Luthetus.CompilerServices.CSharp.Tests.SmokeTests.Parsers; @@ -22,17 +23,14 @@ public Test(string sourceText) { SourceText = sourceText; ResourceUri = new ResourceUri("./unitTesting.txt"); - Lexer = new CSharpLexer(ResourceUri, SourceText); - Lexer.Lex(); - Parser = new CSharpParser(Lexer); - CompilationUnit = Parser.Parse(); + CompilationUnit.LexerOutput = CSharpLexer.Lex(ResourceUri, SourceText); + CSharpParser.Parse(CompilationUnit); } public string SourceText { get; set; } public ResourceUri ResourceUri { get; set; } - public CSharpLexer Lexer { get; set; } - public CSharpParser Parser { get; set; } - public CompilationUnit CompilationUnit { get; set; } + public IBinder Binder => CompilationUnit.Binder; + public CSharpCompilationUnit CompilationUnit { get; set; } } [Fact] From 0c92c8b5a29ebc33971b0c500e74e70a57d03c6c Mon Sep 17 00:00:00 2001 From: Luthetus <45454132+huntercfreeman@users.noreply.github.com> Date: Mon, 16 Dec 2024 15:38:00 -0500 Subject: [PATCH 6/9] Fix function invocation as a statement. --- .../ParserCase/Internals/ParseOthers.cs | 41 ++++++++++++++++++- .../ParserCase/Internals/ParseTokens.cs | 28 ++++++++++++- .../Parsers/ExpressionAsStatementTests.cs | 16 +++++++- 3 files changed, 81 insertions(+), 4 deletions(-) diff --git a/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseOthers.cs b/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseOthers.cs index 7df7707c1..0484f640e 100644 --- a/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseOthers.cs +++ b/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseOthers.cs @@ -78,6 +78,42 @@ public static void StartStatement_Expression(CSharpCompilationUnit compilationUn /// In order to "short circut" or "force exit" from the expression code back to the statement code, /// if the root primary expression is not equal to the parserModel.ForceParseExpressionSyntaxKind /// then stop. + /// + /// ------------------------------ + /// Retrospective comment (2024-12-16): + /// It appears that the 'SyntaxKind? syntaxKind' + /// argument is nullable in order to permit + /// usage of 'parserModel.ForceParseExpressionInitialPrimaryExpression' + /// without specifying a specific syntax kind? + /// + /// The use case: + /// FunctionInvocationNode as a statement + /// will currently erroneously parse as a TypeClauseNode. + /// + /// But, once the statement code receives the 'TypeClauseNode' result + /// from 'TryParseExpression', the next ISyntaxToken + /// is OpenParenthesisToken. + /// + /// Therefore, it is obvious at this point that we really wanted + /// to parse a function invocation node. + /// + /// But, if there is any code that comes after the function invocation, + /// and prior to the statement delimiter. + /// + /// Then a FunctionInvocationNode would not sufficiently represent the statement-expression. + /// + /// i.e.: MyMethod() + 2; + /// + /// So, I cannot 'TryParseExpression' for a SyntaxKind.FunctionInvocationNode for this reason. + /// + /// But, I need to initialize the 'ParseExpression' method with the 'TypeClauseNode' + /// (the 'TypeClauseNode' is in reality the function identifier / generic arguments to the function if there are any). + /// + /// Then, the 'ParseExpression(...)' code can see that there is a 'TypeClauseNode' merging with an OpenParenthesisToken, + /// and that the only meaning this can have is function invocation. + /// + /// At that point, go on to move the 'TypeClauseNode' to be a function identifier, and the + /// generic arguments for the function invocation, and go on from there. /// public static bool TryParseExpression(SyntaxKind? syntaxKind, CSharpCompilationUnit compilationUnit, ref CSharpParserModel parserModel, out IExpressionNode expressionNode) { @@ -94,7 +130,10 @@ public static bool TryParseExpression(SyntaxKind? syntaxKind, CSharpCompilationU Console.WriteLine($"try => {expressionNode.SyntaxKind}\n"); #endif - return parserModel.TryParseExpressionSyntaxKindList.Contains(expressionNode.SyntaxKind); + if (parserModel.TryParseExpressionSyntaxKindList.Count == 0) + return true; + else + return parserModel.TryParseExpressionSyntaxKindList.Contains(expressionNode.SyntaxKind); } finally { diff --git a/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseTokens.cs b/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseTokens.cs index 7247c52b7..6f76d2500 100644 --- a/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseTokens.cs +++ b/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseTokens.cs @@ -57,8 +57,15 @@ public static void ParseIdentifierToken(CSharpCompilationUnit compilationUnit, r switch (expressionNode.SyntaxKind) { - case SyntaxKind.TypeClauseNode: - MoveToHandleTypeClauseNode(originalTokenIndex, (TypeClauseNode)expressionNode, compilationUnit, ref parserModel); + case SyntaxKind.TypeClauseNode: + if (parserModel.TokenWalker.Current.SyntaxKind == SyntaxKind.OpenParenthesisToken || + parserModel.TokenWalker.Current.SyntaxKind == SyntaxKind.OpenAngleBracketToken) + { + MoveToHandleFunctionInvocation((TypeClauseNode)expressionNode, compilationUnit, ref parserModel); + return; + } + + MoveToHandleTypeClauseNode(originalTokenIndex, (TypeClauseNode)expressionNode, compilationUnit, ref parserModel); return; case SyntaxKind.VariableDeclarationNode: if (parserModel.TokenWalker.Current.SyntaxKind == SyntaxKind.OpenParenthesisToken || @@ -124,6 +131,23 @@ public static void MoveToHandleVariableDeclarationNode(IVariableDeclarationNode } } + public static void MoveToHandleFunctionInvocation(TypeClauseNode typeClauseNode, CSharpCompilationUnit compilationUnit, ref CSharpParserModel parserModel) + { + parserModel.ForceParseExpressionInitialPrimaryExpression = typeClauseNode; + + var successParse = ParseOthers.TryParseExpression(null, compilationUnit, ref parserModel, out var expressionNode); + + if (!successParse) + { + expressionNode = ParseOthers.ParseExpression(compilationUnit, ref parserModel); + parserModel.StatementBuilder.ChildList.Add(expressionNode); + } + else + { + parserModel.StatementBuilder.ChildList.Add(expressionNode); + } + } + public static void MoveToHandleTypeClauseNode(int originalTokenIndex, TypeClauseNode typeClauseNode, CSharpCompilationUnit compilationUnit, ref CSharpParserModel parserModel) { if (parserModel.TokenWalker.Current.SyntaxKind == SyntaxKind.StatementDelimiterToken || diff --git a/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/ExpressionAsStatementTests.cs b/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/ExpressionAsStatementTests.cs index 84f6b4e66..da95e9263 100644 --- a/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/ExpressionAsStatementTests.cs +++ b/Source/Tests/CompilerServices/CSharp/SmokeTests/Parsers/ExpressionAsStatementTests.cs @@ -10,8 +10,9 @@ using Luthetus.CompilerServices.CSharp.LexerCase; using Luthetus.CompilerServices.CSharp.ParserCase; using Luthetus.CompilerServices.CSharp.ParserCase.Internals; -using Luthetus.CompilerServices.CSharp.Facts; +using Luthetus.CompilerServices.CSharp.BinderCase; using Luthetus.CompilerServices.CSharp.CompilerServiceCase; +using Luthetus.CompilerServices.CSharp.Facts; namespace Luthetus.CompilerServices.CSharp.Tests.SmokeTests.Parsers; @@ -39,7 +40,9 @@ public Test(string sourceText) { SourceText = sourceText; ResourceUri = new ResourceUri("./unitTesting.txt"); + CompilationUnit = new CSharpCompilationUnit(ResourceUri, new CSharpBinder()); CompilationUnit.LexerOutput = CSharpLexer.Lex(ResourceUri, SourceText); + CompilationUnit.BinderSession = (CSharpBinderSession)CompilationUnit.Binder.StartBinderSession(ResourceUri); CSharpParser.Parse(CompilationUnit); } @@ -1967,6 +1970,17 @@ public void VariableAssignmentExpressionNode() Assert.Equal(SyntaxKind.VariableAssignmentExpressionNode, variableAssignmentExpressionNode.SyntaxKind); } + [Fact] + public void Array() + { + var test = new Test(@"return someList[0];"); + var topCodeBlock = test.CompilationUnit.RootCodeBlockNode; + WriteChildrenIndentedRecursive(topCodeBlock, nameof(topCodeBlock)); + var returnStatementNode = (ReturnStatementNode)topCodeBlock.GetChildList().Single(); + Assert.Equal(SyntaxKind.ReturnStatementNode, returnStatementNode.SyntaxKind); + + } + private void WriteChildrenIndented(ISyntaxNode node, string name = "node") { Console.WriteLine($"foreach (var child in {name}.GetChildList())"); From 64e91358cff25b97d1d70e56157f19f11154c219 Mon Sep 17 00:00:00 2001 From: Luthetus <45454132+huntercfreeman@users.noreply.github.com> Date: Mon, 16 Dec 2024 16:07:07 -0500 Subject: [PATCH 7/9] Fix function invocation as a statement... for real this time --- .../ParserCase/Internals/ParseTokens.cs | 30 ++----------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseTokens.cs b/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseTokens.cs index 6f76d2500..b3165b4a8 100644 --- a/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseTokens.cs +++ b/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseTokens.cs @@ -30,8 +30,8 @@ public static void ParseIdentifierToken(CSharpCompilationUnit compilationUnit, r parserModel.TryParseExpressionSyntaxKindList.Add(SyntaxKind.VariableReferenceNode); parserModel.TryParseExpressionSyntaxKindList.Add(SyntaxKind.ConstructorInvocationExpressionNode); - if (parserModel.CurrentCodeBlockBuilder.CodeBlockOwner is not null && - parserModel.CurrentCodeBlockBuilder.CodeBlockOwner.SyntaxKind != SyntaxKind.TypeDefinitionNode) + if ((parserModel.CurrentCodeBlockBuilder.CodeBlockOwner?.SyntaxKind ?? SyntaxKind.EmptyNode) != + SyntaxKind.TypeDefinitionNode) { // There is a syntax conflict between a ConstructorDefinitionNode and a FunctionInvocationNode. // @@ -58,14 +58,7 @@ public static void ParseIdentifierToken(CSharpCompilationUnit compilationUnit, r switch (expressionNode.SyntaxKind) { case SyntaxKind.TypeClauseNode: - if (parserModel.TokenWalker.Current.SyntaxKind == SyntaxKind.OpenParenthesisToken || - parserModel.TokenWalker.Current.SyntaxKind == SyntaxKind.OpenAngleBracketToken) - { - MoveToHandleFunctionInvocation((TypeClauseNode)expressionNode, compilationUnit, ref parserModel); - return; - } - - MoveToHandleTypeClauseNode(originalTokenIndex, (TypeClauseNode)expressionNode, compilationUnit, ref parserModel); + MoveToHandleTypeClauseNode(originalTokenIndex, (TypeClauseNode)expressionNode, compilationUnit, ref parserModel); return; case SyntaxKind.VariableDeclarationNode: if (parserModel.TokenWalker.Current.SyntaxKind == SyntaxKind.OpenParenthesisToken || @@ -131,23 +124,6 @@ public static void MoveToHandleVariableDeclarationNode(IVariableDeclarationNode } } - public static void MoveToHandleFunctionInvocation(TypeClauseNode typeClauseNode, CSharpCompilationUnit compilationUnit, ref CSharpParserModel parserModel) - { - parserModel.ForceParseExpressionInitialPrimaryExpression = typeClauseNode; - - var successParse = ParseOthers.TryParseExpression(null, compilationUnit, ref parserModel, out var expressionNode); - - if (!successParse) - { - expressionNode = ParseOthers.ParseExpression(compilationUnit, ref parserModel); - parserModel.StatementBuilder.ChildList.Add(expressionNode); - } - else - { - parserModel.StatementBuilder.ChildList.Add(expressionNode); - } - } - public static void MoveToHandleTypeClauseNode(int originalTokenIndex, TypeClauseNode typeClauseNode, CSharpCompilationUnit compilationUnit, ref CSharpParserModel parserModel) { if (parserModel.TokenWalker.Current.SyntaxKind == SyntaxKind.StatementDelimiterToken || From b7519bc101b36217f8348d5b156484cc8cd76ebb Mon Sep 17 00:00:00 2001 From: Luthetus <45454132+huntercfreeman@users.noreply.github.com> Date: Mon, 16 Dec 2024 17:39:05 -0500 Subject: [PATCH 8/9] Fix: single statement bodies (if (true) aaa;) --- .../CSharp/ParserCase/Internals/ParseTokens.cs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseTokens.cs b/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseTokens.cs index b3165b4a8..947e7b0fb 100644 --- a/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseTokens.cs +++ b/Source/Lib/CompilerServices/CSharp/ParserCase/Internals/ParseTokens.cs @@ -413,12 +413,10 @@ public static void ParseStatementDelimiterToken(StatementDelimiterToken statemen { if (parserModel.SyntaxStack.TryPeek(out var syntax) && syntax.SyntaxKind == SyntaxKind.NamespaceStatementNode) { - var closureCurrentCompilationUnitBuilder = parserModel.CurrentCodeBlockBuilder; - ICodeBlockOwner? nextCodeBlockOwner = null; + var namespaceStatementNode = (NamespaceStatementNode)parserModel.SyntaxStack.Pop(); + + ICodeBlockOwner? nextCodeBlockOwner = namespaceStatementNode; TypeClauseNode? scopeReturnTypeClauseNode = null; - - var namespaceStatementNode = (NamespaceStatementNode)parserModel.SyntaxStack.Pop(); - nextCodeBlockOwner = namespaceStatementNode; namespaceStatementNode.SetStatementDelimiterToken(statementDelimiterToken, parserModel.DiagnosticBag, parserModel.TokenWalker); @@ -440,15 +438,12 @@ public static void ParseStatementDelimiterToken(StatementDelimiterToken statemen var pendingChild = parserModel.CurrentCodeBlockBuilder.InnerPendingCodeBlockOwner; compilationUnit.Binder.OpenScope(pendingChild, CSharpFacts.Types.Void.ToTypeClause(), statementDelimiterToken.TextSpan, compilationUnit); - parserModel.CurrentCodeBlockBuilder = new(parserModel.CurrentCodeBlockBuilder, pendingChild); + + parserModel.CurrentCodeBlockBuilder = new(parent: parserModel.CurrentCodeBlockBuilder, codeBlockOwner: pendingChild); + pendingChild.SetStatementDelimiterToken(statementDelimiterToken, parserModel.DiagnosticBag, parserModel.TokenWalker); compilationUnit.Binder.OnBoundScopeCreatedAndSetAsCurrent(pendingChild, compilationUnit); compilationUnit.Binder.CloseScope(statementDelimiterToken.TextSpan, compilationUnit, ref parserModel); - - if (parserModel.CurrentCodeBlockBuilder.Parent is not null) - parserModel.CurrentCodeBlockBuilder = parserModel.CurrentCodeBlockBuilder.Parent; - - parserModel.CurrentCodeBlockBuilder.InnerPendingCodeBlockOwner = null; } } From bf123087544772fd2164ea7af69f5b76391308c7 Mon Sep 17 00:00:00 2001 From: Luthetus <45454132+huntercfreeman@users.noreply.github.com> Date: Mon, 16 Dec 2024 17:50:30 -0500 Subject: [PATCH 9/9] Update IdeInfoDisplay.razor --- .../Displays/Internals/IdeInfoDisplay.razor | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Source/Lib/Ide/Ide.RazorLib/Shareds/Displays/Internals/IdeInfoDisplay.razor b/Source/Lib/Ide/Ide.RazorLib/Shareds/Displays/Internals/IdeInfoDisplay.razor index 1b6bf405d..c99c1f657 100644 --- a/Source/Lib/Ide/Ide.RazorLib/Shareds/Displays/Internals/IdeInfoDisplay.razor +++ b/Source/Lib/Ide/Ide.RazorLib/Shareds/Displays/Internals/IdeInfoDisplay.razor @@ -172,9 +172,26 @@ Recent Changes:
    -
    v 0.9.7.8 (WIP_DATE)
    +
    v 0.9.7.8 (2024-12-16)
      -
    • WIP_DESCRIPTION
    • +
    • + Show function arguments in the tooltip. +
    • +
    • + Fix: single statement bodies 'if (true) aaa;'. This was breaking the scope logic. +
    • +
    • + Fix: function invocation as a statement. +
    • +
    • + Invoke 'ResourceWasModified(...)' first open of file. This permits consistent go-to definition resolution cross file. +
    • +
    • + Out, in, ref, params in function arguments listing (maybe in future change to check for any keyword?). +
    • +
    • + GetNodePositionIndices(...) for ConstructorDefinitionNode so the tooltip works. +