Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove DiagnosticBag from SyntaxNode #110

Merged
merged 1 commit into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -113,15 +113,15 @@ public static IEnumerable<object[]> GetAllSyntaxNodesForTest()

foreach (var inputText in testExpressions)
{
var expression = SyntaxTree.ParseExpression(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache);
var expression = SyntaxTree.ParseExpression(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
var binder = Binder.CreateScriptBinder(TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
yield return new object[] { expression, binder.BindExpression(expression) };
}

// BoundVariableExpression requires special logic to work
{
var sourceText = SourceText.FromString("{ const a = 5; a; }");
var blockStatement = SyntaxTree.ParseStatement(sourceText, TestDefaults.DefaultClrTypeCache);
var blockStatement = SyntaxTree.ParseStatement(sourceText, TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
var binder = Binder.CreateModuleBinder(TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
var boundBlockStatement =
binder.BindStatement(blockStatement).As<BoundBlockStatement>();
Expand All @@ -133,14 +133,14 @@ public static IEnumerable<object[]> GetAllSyntaxNodesForTest()

foreach (var inputText in testStatements)
{
var statement = SyntaxTree.ParseStatement(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache);
var statement = SyntaxTree.ParseStatement(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
var binder = Binder.CreateModuleBinder(TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
yield return new object[] { statement, binder.BindStatement(statement) };
}

foreach (var inputText in testMembers)
{
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache);
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
var member = syntaxTree.Members[0];
var binder = Binder.CreateModuleBinder(TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
if (member is FunctionDeclarationMember functionDeclarationMember)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public sealed class ConstantFoldingTests
[InlineData("const a = ~10UL;", ~10UL)]
public void ConstantFoldingUnaryOperatorTest(string inputText, object expectedValue)
{
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache);
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache, new());
var module = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });
module.GetDiagnostics().Should().BeEmpty();

Expand All @@ -54,7 +54,7 @@ public void ConstantFoldingUnaryOperatorTest(string inputText, object expectedVa
[InlineData("const a = -20;", -20)]
public void BasicConstantFoldingTests(string inputText, object expectedValue)
{
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache);
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache, new());
var module = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });
module.GetDiagnostics().Should().BeEmpty();

Expand All @@ -76,7 +76,7 @@ public void BasicConstantFoldingTests(string inputText, object expectedValue)
[InlineData("const a = 10; let b = a + 10; const c = a + b;")]
public void BasicConstantFoldingNegativeTests(string inputText)
{
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache);
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache, new());
var module = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });
module.GetDiagnostics().Should().BeEmpty();

Expand All @@ -88,7 +88,7 @@ public void BasicConstantFoldingNegativeTests(string inputText)
[Fact]
public void PartiallyFoldedConstantTests()
{
var syntaxTree = SyntaxTree.Parse(SourceText.FromString("let a = 10 + 10;"), TestDefaults.DefaultClrTypeCache);
var syntaxTree = SyntaxTree.Parse(SourceText.FromString("let a = 10 + 10;"), TestDefaults.DefaultClrTypeCache, new());
var module = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });
module.GetDiagnostics().Should().BeEmpty();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void TestResolveBuiltInTypes(string typeName, Type targetType, SpecialTyp
[InlineData("System.Uri", "import { Console, Uri } from System;", typeof(Uri))]
public void TestResolveImportedTypes(string typeName, string importDirective, Type targetType)
{
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(importDirective), TestDefaults.DefaultClrTypeCache);
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(importDirective), TestDefaults.DefaultClrTypeCache, new());
var resolvedType = syntaxTree.ClrTypeCacheView.ResolveBaseType(typeName);
resolvedType.ClrType.AssemblyQualifiedName.Should().Be(targetType.AssemblyQualifiedName);
resolvedType.SpecialType.Should().Be(SpecialType.None);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ public void IfUnlessStatementsCanHaveMultipleElseClauses(string inputText, int e
var ifUnlessStatement = TestUtils.ParseStatement<IfUnlessStatement>(inputText);
ifUnlessStatement.Should().NotBeNull();
ifUnlessStatement.ElseClauses.Should().HaveCount(expectedCount);
ifUnlessStatement.GetDiagnostics().Should().BeEmpty();
}

[Theory]
Expand All @@ -93,17 +92,17 @@ public void IfUnlessStatementsCanBeNested(string inputText)
var ifUnlessStatement = TestUtils.ParseStatement<IfUnlessStatement>(inputText);
ifUnlessStatement.Should().NotBeNull();
ifUnlessStatement.ElseClauses.Should().HaveCount(1);
ifUnlessStatement.GetDiagnostics().Should().BeEmpty();
}

[Fact]
public void IfUnlessStatementsCannotHaveMoreThanOneBareElseClauses()
{
var ifUnlessStatement = TestUtils.ParseStatement<IfUnlessStatement>("if a == 0 { } else { } else { }");
var diagnosticBuilder = new DiagnosticBag.Builder();
var ifUnlessStatement = TestUtils.ParseStatement<IfUnlessStatement>("if a == 0 { } else { } else { }", diagnosticBuilder);
ifUnlessStatement.Should().NotBeNull();
ifUnlessStatement.ElseClauses.Should().HaveCount(2);

var diagnostics = ifUnlessStatement.GetDiagnostics();
var diagnostics = diagnosticBuilder.Build();
diagnostics.Should().NotBeEmpty();
diagnostics.Count(d => d.ErrorCode == ErrorCode.DuplicateBareElseClauses).Should().Be(2);

Expand All @@ -116,11 +115,12 @@ public void IfUnlessStatementsCannotHaveMoreThanOneBareElseClauses()
[Fact]
public void IfUnlessStatementsCannotHaveMisplacedElseClause()
{
var ifUnlessStatement = TestUtils.ParseStatement<IfUnlessStatement>("if a == 0 { } else { } else if b == 0 { }");
var diagnosticBuilder = new DiagnosticBag.Builder();
var ifUnlessStatement = TestUtils.ParseStatement<IfUnlessStatement>("if a == 0 { } else { } else if b == 0 { }", diagnosticBuilder);
ifUnlessStatement.Should().NotBeNull();
ifUnlessStatement.ElseClauses.Should().HaveCount(2);

var diagnostics = ifUnlessStatement.GetDiagnostics();
var diagnostics = diagnosticBuilder.Build();
diagnostics.Should().NotBeEmpty();
diagnostics.Count(d => d.ErrorCode == ErrorCode.MisplacedBareElseClauses).Should().Be(1);

Expand All @@ -133,11 +133,12 @@ public void IfUnlessStatementsCannotHaveMisplacedElseClause()
[Fact]
public void IfUnlessStatementsCannotHaveMismatchedIfOrUnlessKeywords()
{
var ifUnlessStatement = TestUtils.ParseStatement<IfUnlessStatement>("if a == 0 { } else unless b == 0 { }");
var diagnosticBuilder = new DiagnosticBag.Builder();
var ifUnlessStatement = TestUtils.ParseStatement<IfUnlessStatement>("if a == 0 { } else unless b == 0 { }", diagnosticBuilder);
ifUnlessStatement.Should().NotBeNull();
ifUnlessStatement.ElseClauses.Should().HaveCount(1);

var diagnostics = ifUnlessStatement.GetDiagnostics();
var diagnostics = diagnosticBuilder.Build();
diagnostics.Should().NotBeEmpty();
diagnostics.Count(d => d.ErrorCode == ErrorCode.IfUnlessKeywordMismatch).Should().Be(1);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using FluentAssertions;
using Todl.Compiler.CodeAnalysis.Syntax;
using Todl.Compiler.CodeAnalysis.Text;
using Todl.Compiler.Diagnostics;
using Xunit;

namespace Todl.Compiler.Tests.CodeAnalysis;
Expand All @@ -26,14 +27,6 @@ public void SyntaxTreePropertyShouldNotBeNull(string inputTextIgnored, SyntaxNod
syntaxNode.SyntaxTree.Should().NotBeNull();
}

[Theory]
[MemberData(nameof(GetAllSyntaxNodesForTest))]
[SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
public void DiagnosticBagShouldNotBeNull(string inputTextIgnored, SyntaxNode syntaxNode)
{
syntaxNode.GetDiagnostics().Should().NotBeNull();
}

[Fact]
public void AllSyntaxNodeTypesNeedsToBeCoveredInTests()
{
Expand Down Expand Up @@ -99,27 +92,29 @@ public void AllSyntaxNodeTypesNeedsToBeCoveredInTests()

public static IEnumerable<object[]> GetAllSyntaxNodesForTest()
{
var diagnosticBuilder = new DiagnosticBag.Builder();

foreach (var inputText in testExpressions)
{
var expression = SyntaxTree.ParseExpression(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache);
var expression = SyntaxTree.ParseExpression(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
yield return new object[] { inputText, expression };
}

foreach (var inputText in testStatements)
{
var statement = SyntaxTree.ParseStatement(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache);
var statement = SyntaxTree.ParseStatement(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
yield return new object[] { inputText, statement };
}

foreach (var inputText in testDirectives)
{
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache);
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
yield return new object[] { inputText, syntaxTree.Directives[0] };
}

foreach (var inputText in testMembers)
{
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache);
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
yield return new object[] { inputText, syntaxTree.Members[0] };
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ public void EmptyBreakStatementCanBeParsed()
{
var breakStatement = TestUtils.ParseStatement<BreakStatement>("break;");
breakStatement.Should().NotBeNull();
breakStatement.GetDiagnostics().Should().BeEmpty();

breakStatement.BreakKeywordToken.Kind.Should().Be(SyntaxKind.BreakKeywordToken);
breakStatement.SemicolonToken.Kind.Should().Be(SyntaxKind.SemicolonToken);
Expand All @@ -23,7 +22,6 @@ public void EmptyContinueStatementCanBeParsed()
{
var continueStatement = TestUtils.ParseStatement<ContinueStatement>("continue;");
continueStatement.Should().NotBeNull();
continueStatement.GetDiagnostics().Should().BeEmpty();

continueStatement.ContinueKeywordToken.Kind.Should().Be(SyntaxKind.ContinueKeywordToken);
continueStatement.SemicolonToken.Kind.Should().Be(SyntaxKind.SemicolonToken);
Expand All @@ -37,7 +35,6 @@ public void WhileUntilStatementsCanHaveEmptyBody(string inputText, SyntaxKind ex
{
var whileUntilStatement = TestUtils.ParseStatement<WhileUntilStatement>(inputText);
whileUntilStatement.Should().NotBeNull();
whileUntilStatement.GetDiagnostics().Should().BeEmpty();

whileUntilStatement.WhileOrUntilToken.Kind.Should().Be(expectedSyntaxKind);
whileUntilStatement.BlockStatement.InnerStatements.Should().BeEmpty();
Expand All @@ -56,7 +53,6 @@ public void WhileUntilStatementsCanHaveOneOrMoreInnerStatements(string inputText
{
var whileUntilStatement = TestUtils.ParseStatement<WhileUntilStatement>(inputText);
whileUntilStatement.Should().NotBeNull();
whileUntilStatement.GetDiagnostics().Should().BeEmpty();
whileUntilStatement.BlockStatement.InnerStatements.Should().HaveCount(expectedStatementsCount);
}
}
66 changes: 56 additions & 10 deletions src/Todl.Compiler.Tests/TestUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal static TBoundExpression BindExpression<TBoundExpression>(
string inputText, DiagnosticBag.Builder diagnosticBuilder)
where TBoundExpression : BoundExpression
{
var expression = SyntaxTree.ParseExpression(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache);
var expression = SyntaxTree.ParseExpression(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
var binder = Binder.CreateModuleBinder(TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
return binder.BindExpression(expression).As<TBoundExpression>();
}
Expand All @@ -39,7 +39,7 @@ internal static TBoundStatement BindStatement<TBoundStatement>(
string inputText, DiagnosticBag.Builder diagnosticBuilder)
where TBoundStatement : BoundStatement
{
var statement = SyntaxTree.ParseStatement(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache);
var statement = SyntaxTree.ParseStatement(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
var binder = Binder.CreateModuleBinder(TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
return binder.BindStatement(statement).As<TBoundStatement>();
}
Expand Down Expand Up @@ -104,33 +104,79 @@ internal static void EmitStatementAndVerify(string input, params TestInstruction
emitter.ILProcessor.Body.Instructions.ShouldHaveExactInstructionSequence(expectedInstructions);
}

internal static SyntaxTree ParseSyntaxTree(string inputText, DiagnosticBag.Builder diagnosticBuilder)
=> SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache, diagnosticBuilder);

internal static SyntaxTree ParseSyntaxTree(string inputText)
=> SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache);
{
var diagnosticBuilder = new DiagnosticBag.Builder();
var syntaxTree = ParseSyntaxTree(inputText, diagnosticBuilder);
diagnosticBuilder.Build().Should().BeEmpty();
return syntaxTree;
}

internal static TExpression ParseExpression<TExpression>(string sourceText, DiagnosticBag.Builder diagnosticBuilder)
where TExpression : Expression
=> SyntaxTree.ParseExpression(
SourceText.FromString(sourceText),
TestDefaults.DefaultClrTypeCache,
diagnosticBuilder).As<TExpression>();

internal static TExpression ParseExpression<TExpression>(string sourceText)
where TExpression : Expression
where TExpression : Expression
{
return SyntaxTree.ParseExpression(SourceText.FromString(sourceText), TestDefaults.DefaultClrTypeCache).As<TExpression>();
var diagnosticBuilder = new DiagnosticBag.Builder();
var expression = ParseExpression<TExpression>(sourceText, diagnosticBuilder);
diagnosticBuilder.Build().Should().BeEmpty();
return expression;
}

internal static TStatement ParseStatement<TStatement>(string sourceText, DiagnosticBag.Builder diagnosticBuilder)
where TStatement : Statement
=> SyntaxTree.ParseStatement(
SourceText.FromString(sourceText),
TestDefaults.DefaultClrTypeCache,
diagnosticBuilder).As<TStatement>();

internal static TStatement ParseStatement<TStatement>(string sourceText)
where TStatement : Statement
{
return SyntaxTree.ParseStatement(SourceText.FromString(sourceText), TestDefaults.DefaultClrTypeCache).As<TStatement>();
var diagnosticBuilder = new DiagnosticBag.Builder();
var statement = ParseStatement<TStatement>(sourceText, diagnosticBuilder);
diagnosticBuilder.Build().Should().BeEmpty();
return statement;
}

internal static TDirective ParseDirective<TDirective>(string sourceText, DiagnosticBag.Builder diagnosticBuilder)
where TDirective : Directive
=> SyntaxTree.Parse(
SourceText.FromString(sourceText),
TestDefaults.DefaultClrTypeCache,
diagnosticBuilder).Directives[0].As<TDirective>();

internal static TDirective ParseDirective<TDirective>(string sourceText)
where TDirective : Directive
{
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(sourceText), TestDefaults.DefaultClrTypeCache);
return syntaxTree.Directives[0].As<TDirective>();
var diagnosticBuilder = new DiagnosticBag.Builder();
var directive = ParseDirective<TDirective>(sourceText, diagnosticBuilder);
diagnosticBuilder.Build().Should().BeEmpty();
return directive;
}

internal static TMember ParseMember<TMember>(string sourceText, DiagnosticBag.Builder diagnosticBuilder)
where TMember : Member
=> SyntaxTree.Parse(
SourceText.FromString(sourceText),
TestDefaults.DefaultClrTypeCache,
diagnosticBuilder).Members[0].As<TMember>();

internal static TMember ParseMember<TMember>(string sourceText)
where TMember : Member
{
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(sourceText), TestDefaults.DefaultClrTypeCache);
return syntaxTree.Members[0].As<TMember>();
var diagnosticBuilder = new DiagnosticBag.Builder();
var member = ParseMember<TMember>(sourceText, diagnosticBuilder);
diagnosticBuilder.Build().Should().BeEmpty();
return member;
}

internal static void ShouldHaveExactInstructionSequence(
Expand Down
7 changes: 6 additions & 1 deletion src/Todl.Compiler/CodeAnalysis/Binding/BoundModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ internal sealed class BoundModule : IDiagnosable
public static BoundModule Create(
ClrTypeCache clrTypeCache,
IReadOnlyList<SyntaxTree> syntaxTrees)
=> Create(clrTypeCache, syntaxTrees, new());

public static BoundModule Create(
ClrTypeCache clrTypeCache,
IReadOnlyList<SyntaxTree> syntaxTrees,
DiagnosticBag.Builder diagnosticBuilder)
{
syntaxTrees ??= Array.Empty<SyntaxTree>();
var diagnosticBuilder = new DiagnosticBag.Builder();
var binder = Binder.CreateModuleBinder(clrTypeCache, diagnosticBuilder);
var entryPointType = binder.BindEntryPointTypeDefinition(syntaxTrees);

Expand Down
Loading