Fix trivia handling
This commit is contained in:
parent
c70e94d166
commit
6c204846ce
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Parser.Tests
|
namespace Parser.Tests
|
||||||
@ -56,7 +57,35 @@ namespace Parser.Tests
|
|||||||
Assert.Equal(text, actualText);
|
Assert.Equal(text, actualText);
|
||||||
Assert.Equal(text.Length, actualWidth);
|
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()
|
public static IEnumerable<object[]> FilesData()
|
||||||
{
|
{
|
||||||
return Files().Select(fileName => new object[] { fileName });
|
return Files().Select(fileName => new object[] { fileName });
|
||||||
|
@ -209,7 +209,6 @@ namespace Parser.Internal
|
|||||||
}
|
}
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1175,9 +1175,14 @@ namespace Parser.Internal
|
|||||||
return ParseExpressionStatement();
|
return ParseExpressionStatement();
|
||||||
}
|
}
|
||||||
|
|
||||||
private BlockStatementSyntaxNode ParseBlockStatement()
|
private BlockStatementSyntaxNode? ParseBlockStatement()
|
||||||
{
|
{
|
||||||
var statements = ParseStatementList();
|
var statements = ParseStatementList();
|
||||||
|
if (statements.Length == 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return Factory.BlockStatementSyntax(statements);
|
return Factory.BlockStatementSyntax(statements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ namespace Parser.Internal
|
|||||||
{
|
{
|
||||||
internal partial class SyntaxFactory
|
internal partial class SyntaxFactory
|
||||||
{
|
{
|
||||||
public FileSyntaxNode FileSyntax(BlockStatementSyntaxNode body, SyntaxToken endOfFile)
|
public FileSyntaxNode FileSyntax(BlockStatementSyntaxNode? body, SyntaxToken endOfFile)
|
||||||
{
|
{
|
||||||
return new FileSyntaxNode(body, endOfFile);
|
return new FileSyntaxNode(body, endOfFile);
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,9 @@ namespace Parser.Internal
|
|||||||
{
|
{
|
||||||
internal class FileSyntaxNode : SyntaxNode
|
internal class FileSyntaxNode : SyntaxNode
|
||||||
{
|
{
|
||||||
internal readonly BlockStatementSyntaxNode _body;
|
internal readonly BlockStatementSyntaxNode? _body;
|
||||||
internal readonly SyntaxToken _endOfFile;
|
internal readonly SyntaxToken _endOfFile;
|
||||||
internal FileSyntaxNode(BlockStatementSyntaxNode body, SyntaxToken endOfFile): base(TokenKind.File)
|
internal FileSyntaxNode(BlockStatementSyntaxNode? body, SyntaxToken endOfFile): base(TokenKind.File)
|
||||||
{
|
{
|
||||||
Slots = 2;
|
Slots = 2;
|
||||||
this.AdjustWidth(body);
|
this.AdjustWidth(body);
|
||||||
@ -14,7 +14,7 @@ namespace Parser.Internal
|
|||||||
_endOfFile = endOfFile;
|
_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;
|
Slots = 2;
|
||||||
this.AdjustWidth(body);
|
this.AdjustWidth(body);
|
||||||
|
@ -51,7 +51,7 @@ namespace Parser.Internal
|
|||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string FullText => CollectFullText();
|
//public override string FullText => CollectFullText();
|
||||||
|
|
||||||
public override GreenNode? LeadingTriviaCore => throw new NotImplementedException();
|
public override GreenNode? LeadingTriviaCore => throw new NotImplementedException();
|
||||||
public override GreenNode? TrailingTriviaCore => throw new NotImplementedException();
|
public override GreenNode? TrailingTriviaCore => throw new NotImplementedException();
|
||||||
|
@ -20,6 +20,7 @@ namespace Parser.Internal
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override string Text => _text;
|
public override string Text => _text;
|
||||||
|
public override string FullText => _text;
|
||||||
public int Width => _text.Length;
|
public int Width => _text.Length;
|
||||||
|
|
||||||
public override GreenNode? GetSlot(int i)
|
public override GreenNode? GetSlot(int i)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?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">
|
<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">
|
<Class Name="FileSyntaxNode" BaseClass="SyntaxNode" Kind="File">
|
||||||
<Field Type="BlockStatementSyntaxNode" Name="body" />
|
<Field Type="BlockStatementSyntaxNode" Name="body" Nullable="true"/>
|
||||||
<Field Type="SyntaxToken" Name="endOfFile" />
|
<Field Type="SyntaxToken" Name="endOfFile" />
|
||||||
</Class>
|
</Class>
|
||||||
<Class Name="BlockStatementSyntaxNode" BaseClass="StatementSyntaxNode" Kind="BlockStatement">
|
<Class Name="BlockStatementSyntaxNode" BaseClass="StatementSyntaxNode" Kind="BlockStatement">
|
||||||
|
@ -16,12 +16,12 @@ namespace Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockStatementSyntaxNode Body
|
public BlockStatementSyntaxNode? Body
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var red = this.GetRed(ref this._body!, 0);
|
var red = this.GetRed(ref this._body, 0);
|
||||||
return red is null ? throw new System.Exception("body cannot be null.") : (BlockStatementSyntaxNode)red;
|
return red is null ? default : (BlockStatementSyntaxNode)red;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ namespace Parser
|
|||||||
{
|
{
|
||||||
return i switch
|
return i switch
|
||||||
{
|
{
|
||||||
0 => GetRed(ref _body!, 0), _ => null
|
0 => GetRed(ref _body, 0), _ => null
|
||||||
}
|
}
|
||||||
|
|
||||||
;
|
;
|
||||||
|
@ -36,6 +36,8 @@ namespace Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string FullText => Node?.FullText ?? string.Empty;
|
||||||
|
|
||||||
public IEnumerator<SyntaxTrivia> GetEnumerator()
|
public IEnumerator<SyntaxTrivia> GetEnumerator()
|
||||||
{
|
{
|
||||||
for (var i = 0; i < Count; i++)
|
for (var i = 0; i < Count; i++)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user