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 Diagnostics from BoundModule #111

Merged
merged 1 commit into from
Nov 30, 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 @@ -114,11 +114,8 @@ void func() {
}
b = a + 5;
}";
var syntaxTree = TestUtils.ParseSyntaxTree(inputText);
var boundModule = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });
boundModule.GetDiagnostics().Should().BeEmpty();
var func = TestUtils.BindMember<BoundFunctionMember>(inputText);

var func = boundModule.EntryPointType.BoundMembers[0].As<BoundFunctionMember>();
var conditionalStatement = func.Body.Statements[2].As<BoundConditionalStatement>();
var consequence = conditionalStatement.Consequence.As<BoundBlockStatement>();
consequence.Scope.Parent.Should().Be(func.FunctionScope);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,8 @@ void Main() {
Console.WriteLine();
}
";
var syntaxTree = TestUtils.ParseSyntaxTree(inputText);
var boundModule = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });
boundModule.GetDiagnostics().Should().BeEmpty();

TestUtils.BindModule(inputText).Should().NotBeNull();
}

[Fact]
Expand All @@ -109,10 +108,8 @@ int Main() {
return 0;
}
";
var syntaxTree = TestUtils.ParseSyntaxTree(inputText);
var boundModule = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });

boundModule.GetDiagnostics().Should().BeEmpty();
TestUtils.BindModule(inputText).Should().NotBeNull();
}

[Fact]
Expand All @@ -129,10 +126,8 @@ int Main() {
return 0;
}
";
var syntaxTree = TestUtils.ParseSyntaxTree(inputText);
var boundModule = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });

boundModule.GetDiagnostics().Should().BeEmpty();
TestUtils.BindModule(inputText).Should().NotBeNull();
}

[Fact]
Expand All @@ -151,9 +146,7 @@ int Main() {
return 0;
}
";
var syntaxTree = TestUtils.ParseSyntaxTree(inputText);
var boundModule = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });

boundModule.GetDiagnostics().Should().BeEmpty();
TestUtils.BindModule(inputText).Should().NotBeNull();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Todl.Compiler.CodeAnalysis.Symbols;
using Todl.Compiler.Diagnostics;
using Xunit;
using Xunit.Sdk;

namespace Todl.Compiler.Tests.CodeAnalysis;

Expand Down Expand Up @@ -140,21 +141,19 @@ public void TestOverloadedFunctionDeclarationMember()
int func() { return 20; }
int func(int a) { return a; }
";
var syntaxTree = TestUtils.ParseSyntaxTree(inputText);
var boundModule = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });

boundModule.GetDiagnostics().Should().BeEmpty();
TestUtils.BindModule(inputText).Should().NotBeNull();
}

[Theory]
[InlineData("void func(int a, int a) { }")]
[InlineData("void func(int a, string a) { }")]
public void FunctionParametersShouldHaveDistinctNames(string inputText)
{
var syntaxTree = TestUtils.ParseSyntaxTree(inputText);
var boundModule = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });
var diagnosticBuilder = new DiagnosticBag.Builder();
TestUtils.BindModule(inputText, diagnosticBuilder).Should().NotBeNull();

var diagnostics = boundModule.GetDiagnostics().ToList();
var diagnostics = diagnosticBuilder.Build().ToList();
diagnostics.Should().NotBeEmpty();
diagnostics[0].ErrorCode.Should().Be(ErrorCode.DuplicateParameterName);
}
Expand All @@ -166,10 +165,11 @@ public void FunctionsWithSameArgumentsShouldBeAmbiguous()
int func(int a, string b) { return b.Length + a; }
int func(int a, string b) { return b.Length + a + 1; }
";
var syntaxTree = TestUtils.ParseSyntaxTree(inputText);
var boundModule = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });

var diagnostics = boundModule.GetDiagnostics().ToList();
var diagnosticBuilder = new DiagnosticBag.Builder();
TestUtils.BindModule(inputText, diagnosticBuilder).Should().NotBeNull();

var diagnostics = diagnosticBuilder.Build().ToList();
diagnostics.Count.Should().Be(1);
diagnostics[0].ErrorCode.Should().Be(ErrorCode.AmbiguousFunctionDeclaration);
}
Expand All @@ -185,10 +185,11 @@ public void FunctionsWithSameArgumentsInDifferentOrderShouldBeAmbiguous()
int func(int a, string b) { return b.Length + a; }
int func(string b, int a) { return b.Length + a + 1; }
";
var syntaxTree = TestUtils.ParseSyntaxTree(inputText);
var boundModule = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });

var diagnostics = boundModule.GetDiagnostics().ToList();
var diagnosticBuilder = new DiagnosticBag.Builder();
TestUtils.BindModule(inputText, diagnosticBuilder).Should().NotBeNull();

var diagnostics = diagnosticBuilder.Build().ToList();
diagnostics.Count.Should().Be(1);
diagnostics[0].ErrorCode.Should().Be(ErrorCode.AmbiguousFunctionDeclaration);
}
Expand All @@ -200,10 +201,11 @@ public void FunctionsWithSameArgumentsButDifferentNamesShouldBeAmbiguous()
int func(int a, string b) { return b.Length + a; }
int func(int b, string a) { return a.Length + b + 1; }
";
var syntaxTree = TestUtils.ParseSyntaxTree(inputText);
var boundModule = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });

var diagnostics = boundModule.GetDiagnostics().ToList();
var diagnosticBuilder = new DiagnosticBag.Builder();
TestUtils.BindModule(inputText, diagnosticBuilder).Should().NotBeNull();

var diagnostics = diagnosticBuilder.Build().ToList();
diagnostics.Count.Should().Be(1);
diagnostics[0].ErrorCode.Should().Be(ErrorCode.AmbiguousFunctionDeclaration);
}
Expand All @@ -217,7 +219,6 @@ public void FunctionsThatReturnsVoidShouldNotHaveDuplicateReturnStatements(strin
{
var function = TestUtils.BindMember<BoundFunctionMember>(inputText);
function.Body.Statements.Should().NotBeEmpty();

function.Body.Statements.OfType<BoundReturnStatement>().Should().HaveCount(1);

var lastStatement = function.Body.Statements[^1];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Todl.Compiler.CodeAnalysis.Binding.BoundTree;
using Todl.Compiler.CodeAnalysis.Syntax;
using Todl.Compiler.CodeAnalysis.Text;
using Todl.Compiler.Diagnostics;
using Xunit;

namespace Todl.Compiler.Tests.CodeAnalysis;
Expand All @@ -30,9 +31,10 @@ 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, new());
var module = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });
module.GetDiagnostics().Should().BeEmpty();
var diagnosticBuilder = new DiagnosticBag.Builder();
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
var module = BoundModule.Create(TestDefaults.DefaultClrTypeCache, [syntaxTree], diagnosticBuilder);
diagnosticBuilder.Build().Should().BeEmpty();

var variableMember = module.EntryPointType.Variables.ToList()[^1].As<BoundVariableMember>();
variableMember.BoundVariableDeclarationStatement.Variable.Constant.Should().Be(true);
Expand All @@ -54,9 +56,10 @@ 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, new());
var module = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });
module.GetDiagnostics().Should().BeEmpty();
var diagnosticBuilder = new DiagnosticBag.Builder();
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
var module = BoundModule.Create(TestDefaults.DefaultClrTypeCache, [syntaxTree], diagnosticBuilder);
diagnosticBuilder.Build().Should().BeEmpty();

var variableMember = module.EntryPointType.Variables.ToList()[^1].As<BoundVariableMember>();
variableMember.BoundVariableDeclarationStatement.Variable.Constant.Should().Be(true);
Expand All @@ -76,9 +79,10 @@ 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, new());
var module = BoundModule.Create(TestDefaults.DefaultClrTypeCache, new[] { syntaxTree });
module.GetDiagnostics().Should().BeEmpty();
var diagnosticBuilder = new DiagnosticBag.Builder();
var syntaxTree = SyntaxTree.Parse(SourceText.FromString(inputText), TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
var module = BoundModule.Create(TestDefaults.DefaultClrTypeCache, [syntaxTree], diagnosticBuilder);
diagnosticBuilder.Build().Should().BeEmpty();

var variableMember = module.EntryPointType.Variables.ToList()[^1].As<BoundVariableMember>();
var boundVariableDeclarationStatement = variableMember.BoundVariableDeclarationStatement;
Expand All @@ -88,9 +92,10 @@ public void BasicConstantFoldingNegativeTests(string inputText)
[Fact]
public void PartiallyFoldedConstantTests()
{
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();
var diagnosticBuilder = new DiagnosticBag.Builder();
var syntaxTree = SyntaxTree.Parse(SourceText.FromString("let a = 10 + 10;"), TestDefaults.DefaultClrTypeCache, diagnosticBuilder);
var module = BoundModule.Create(TestDefaults.DefaultClrTypeCache, [syntaxTree], diagnosticBuilder);
diagnosticBuilder.Build().Should().BeEmpty();

var statement = module.EntryPointType.Variables.ToList()[^1].As<BoundVariableMember>().BoundVariableDeclarationStatement;
statement.Variable.Constant.Should().Be(false);
Expand Down
15 changes: 15 additions & 0 deletions src/Todl.Compiler.Tests/TestUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using Todl.Compiler.CodeAnalysis.Binding;
using Todl.Compiler.CodeAnalysis.Binding.BoundTree;
using Todl.Compiler.CodeAnalysis.Symbols;
using Todl.Compiler.CodeAnalysis.Syntax;
Expand Down Expand Up @@ -78,6 +79,20 @@ internal static TBoundMember BindMember<TBoundMember>(string inputText)
return boundMember;
}

internal static BoundModule BindModule(string inputText, DiagnosticBag.Builder diagnosticBuilder)
{
var syntaxTree = ParseSyntaxTree(inputText, diagnosticBuilder);
return BoundModule.Create(TestDefaults.DefaultClrTypeCache, [syntaxTree], diagnosticBuilder);
}

internal static BoundModule BindModule(string inputText)
{
var diagnosticBuilder = new DiagnosticBag.Builder();
var boundModule = BindModule(inputText, diagnosticBuilder);
diagnosticBuilder.Build().Should().BeEmpty();
return boundModule;
}

internal static void EmitExpressionAndVerify(string input, params TestInstruction[] expectedInstructions)
{
var diagnosticBuilder = new DiagnosticBag.Builder();
Expand Down
10 changes: 1 addition & 9 deletions src/Todl.Compiler/CodeAnalysis/Binding/BoundModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,13 @@

namespace Todl.Compiler.CodeAnalysis.Binding;

internal sealed class BoundModule : IDiagnosable
internal sealed class BoundModule
{
public IReadOnlyCollection<SyntaxTree> SyntaxTrees { get; private init; }
public BoundEntryPointTypeDefinition EntryPointType { get; private init; }
public BoundFunctionMember EntryPoint => EntryPointType.EntryPointFunctionMember;
public DiagnosticBag.Builder DiagnosticBuilder { get; private init; }

public static BoundModule Create(
ClrTypeCache clrTypeCache,
IReadOnlyList<SyntaxTree> syntaxTrees)
=> Create(clrTypeCache, syntaxTrees, new());

public static BoundModule Create(
ClrTypeCache clrTypeCache,
IReadOnlyList<SyntaxTree> syntaxTrees,
Expand Down Expand Up @@ -48,7 +43,4 @@ public static BoundModule Create(
DiagnosticBuilder = diagnosticBuilder
};
}

public IEnumerable<Diagnostic> GetDiagnostics()
=> DiagnosticBuilder.Build();
}
7 changes: 2 additions & 5 deletions src/Todl.Compiler/CodeGeneration/Compilation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public Compilation(
ClrTypeCache = ClrTypeCache.FromAssemblies(metadataLoadContext.GetAssemblies(), metadataLoadContext.CoreAssembly);

var syntaxTrees = sourceTexts.Select(s => SyntaxTree.Parse(s, ClrTypeCache, diagnosticBuilder));
MainModule = BoundModule.Create(ClrTypeCache, syntaxTrees.ToImmutableList());
MainModule = BoundModule.Create(ClrTypeCache, syntaxTrees.ToImmutableList(), diagnosticBuilder);

if (MainModule.EntryPoint is null)
{
Expand All @@ -77,8 +77,5 @@ public void Dispose()
}

public IEnumerable<Diagnostic> GetDiagnostics()
{
diagnosticBuilder.Add(MainModule);
return diagnosticBuilder.Build();
}
=> diagnosticBuilder.Build();
}