Fix trivia handling

This commit is contained in:
Alexander Luzgarev 2020-07-25 12:11:07 +02:00
parent c70e94d166
commit 6c204846ce
10 changed files with 49 additions and 13 deletions

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Xunit;
namespace Parser.Tests
@ -57,6 +58,34 @@ namespace Parser.Tests
Assert.Equal(text.Length, actualWidth);
}
[Theory]
[MemberData(nameof(FilesData))]
public void TestLeadingAndTrailingTrivia(string fileName)
{
var text = File.ReadAllText(fileName);
var window = new TextWindowWithNull(text, fileName);
var parser = CreateParser(window);
var tree = parser.Parse();
var sb = new StringBuilder();
var maybeLeadingTrivia = tree.Root.LeadingTrivia;
var maybeTrailingTrivia = tree.Root.TrailingTrivia;
if (maybeLeadingTrivia is SyntaxTriviaList leadingTrivia)
{
sb.Append(leadingTrivia.FullText);
}
sb.Append(tree.Root.Text);
if (maybeTrailingTrivia is SyntaxTriviaList trailingTrivia)
{
sb.Append(trailingTrivia.FullText);
}
var actualText = sb.ToString();
Assert.Equal(text, actualText);
}
public static IEnumerable<object[]> FilesData()
{
return Files().Select(fileName => new object[] { fileName });

View File

@ -209,7 +209,6 @@ namespace Parser.Internal
}
return sb.ToString();
}
}

View File

@ -1175,9 +1175,14 @@ namespace Parser.Internal
return ParseExpressionStatement();
}
private BlockStatementSyntaxNode ParseBlockStatement()
private BlockStatementSyntaxNode? ParseBlockStatement()
{
var statements = ParseStatementList();
if (statements.Length == 0)
{
return null;
}
return Factory.BlockStatementSyntax(statements);
}

View File

@ -3,7 +3,7 @@ namespace Parser.Internal
{
internal partial class SyntaxFactory
{
public FileSyntaxNode FileSyntax(BlockStatementSyntaxNode body, SyntaxToken endOfFile)
public FileSyntaxNode FileSyntax(BlockStatementSyntaxNode? body, SyntaxToken endOfFile)
{
return new FileSyntaxNode(body, endOfFile);
}

View File

@ -3,9 +3,9 @@ namespace Parser.Internal
{
internal class FileSyntaxNode : SyntaxNode
{
internal readonly BlockStatementSyntaxNode _body;
internal readonly BlockStatementSyntaxNode? _body;
internal readonly SyntaxToken _endOfFile;
internal FileSyntaxNode(BlockStatementSyntaxNode body, SyntaxToken endOfFile): base(TokenKind.File)
internal FileSyntaxNode(BlockStatementSyntaxNode? body, SyntaxToken endOfFile): base(TokenKind.File)
{
Slots = 2;
this.AdjustWidth(body);
@ -14,7 +14,7 @@ namespace Parser.Internal
_endOfFile = endOfFile;
}
internal FileSyntaxNode(BlockStatementSyntaxNode body, SyntaxToken endOfFile, TokenDiagnostic[] diagnostics): base(TokenKind.File, diagnostics)
internal FileSyntaxNode(BlockStatementSyntaxNode? body, SyntaxToken endOfFile, TokenDiagnostic[] diagnostics): base(TokenKind.File, diagnostics)
{
Slots = 2;
this.AdjustWidth(body);

View File

@ -51,7 +51,7 @@ namespace Parser.Internal
return builder.ToString();
}
public override string FullText => CollectFullText();
//public override string FullText => CollectFullText();
public override GreenNode? LeadingTriviaCore => throw new NotImplementedException();
public override GreenNode? TrailingTriviaCore => throw new NotImplementedException();

View File

@ -20,6 +20,7 @@ namespace Parser.Internal
}
public override string Text => _text;
public override string FullText => _text;
public int Width => _text.Length;
public override GreenNode? GetSlot(int i)

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Syntax xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Class Name="FileSyntaxNode" BaseClass="SyntaxNode" Kind="File">
<Field Type="BlockStatementSyntaxNode" Name="body" />
<Field Type="BlockStatementSyntaxNode" Name="body" Nullable="true"/>
<Field Type="SyntaxToken" Name="endOfFile" />
</Class>
<Class Name="BlockStatementSyntaxNode" BaseClass="StatementSyntaxNode" Kind="BlockStatement">

View File

@ -16,12 +16,12 @@ namespace Parser
}
}
public BlockStatementSyntaxNode Body
public BlockStatementSyntaxNode? Body
{
get
{
var red = this.GetRed(ref this._body!, 0);
return red is null ? throw new System.Exception("body cannot be null.") : (BlockStatementSyntaxNode)red;
var red = this.GetRed(ref this._body, 0);
return red is null ? default : (BlockStatementSyntaxNode)red;
}
}
@ -29,7 +29,7 @@ namespace Parser
{
return i switch
{
0 => GetRed(ref _body!, 0), _ => null
0 => GetRed(ref _body, 0), _ => null
}
;

View File

@ -36,6 +36,8 @@ namespace Parser
}
}
public string FullText => Node?.FullText ?? string.Empty;
public IEnumerator<SyntaxTrivia> GetEnumerator()
{
for (var i = 0; i < Count; i++)