Skip to content

Commit

Permalink
Added verification to highlight records which have a vtable but no co…
Browse files Browse the repository at this point in the history
…nstructors since they can't be initialized from C# yet.

Relates to #31
  • Loading branch information
PathogenDavid committed Dec 19, 2021
1 parent 8b453cb commit 357f884
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Biohazrd.CSharp/#Transformations/CSharpTranslationVerifier.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Biohazrd.CSharp.Metadata;
using Biohazrd.Expressions;
using Biohazrd.Transformation;
using ClangSharp;
using ClangSharp.Pathogen;
using System.Collections.Immutable;
using System.Linq;
Expand Down Expand Up @@ -298,6 +299,13 @@ protected override TransformationResult TransformRecord(TransformationContext co
else if (declaration.VTable is not null && declaration.VTableField is null)
{ declaration = declaration.WithError("Records should not have a VTable without a VTable field."); }

// We don't currently provide a way to initialize a virtual type without a constructor
// https://github.com/MochiLibraries/Biohazrd/issues/31
if (declaration.VTable is not null
&& !declaration.Members.OfType<TranslatedFunction>().Any(f => f.SpecialFunctionKind is SpecialFunctionKind.Constructor)
&& declaration.Declaration is not CXXRecordDecl { IsAbstract: true })
{ declaration = declaration.WithWarning("Virtual records without a constructor cannot be initialized from C#. See https://github.com/MochiLibraries/Biohazrd/issues/31"); }

return base.TransformRecord(context, declaration);
}

Expand Down
58 changes: 58 additions & 0 deletions Tests/Biohazrd.CSharp.Tests/CSharpTranslationVerifierTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -385,5 +385,63 @@ public void Constant_UnsupportedConstantNotOk()
// Unsupported constants should mention the failure reason
Assert.Single(constant.Diagnostics.Where(d => d.Message.Contains(nameof(Constant_UnsupportedConstantNotOk))));
}

[Fact]
[RelatedIssue("https://github.com/MochiLibraries/Biohazrd/issues/31")]
public void Record_CannotInitializeConstructorlessVirtual()
{
TranslatedLibrary library = CreateLibrary
(@"
class MyClass
{
public:
virtual void Test() { }
};
"
);

Assert.Empty(library.FindDeclaration<TranslatedRecord>("MyClass").Diagnostics);
library = new CSharpTranslationVerifier().Transform(library);
Assert.Contains(library.FindDeclaration<TranslatedRecord>("MyClass").Diagnostics, d => d.Severity >= Severity.Warning);
}

[Fact]
[RelatedIssue("https://github.com/MochiLibraries/Biohazrd/issues/31")]
public void Record_CannotInitializeConstructorlessVirtual_IgnoreAbstract()
{
TranslatedLibrary library = CreateLibrary
(@"
class MyClass
{
public:
virtual void Test() = 0;
};
"
);

Assert.Empty(library.FindDeclaration<TranslatedRecord>("MyClass").Diagnostics);
library = new CSharpTranslationVerifier().Transform(library);
Assert.Empty(library.FindDeclaration<TranslatedRecord>("MyClass").Diagnostics);
}

[Fact]
[RelatedIssue("https://github.com/MochiLibraries/Biohazrd/issues/31")]
public void Record_CannotInitializeConstructorlessVirtual_ExplicitConstructorOk()
{
TranslatedLibrary library = CreateLibrary
(@"
class MyClass
{
public:
MyClass() { }
virtual void Test() { }
};
"
);

Assert.Empty(library.FindDeclaration<TranslatedRecord>("MyClass").Diagnostics);
library = new CSharpTranslationVerifier().Transform(library);
Assert.Empty(library.FindDeclaration<TranslatedRecord>("MyClass").Diagnostics);
}
}
}

0 comments on commit 357f884

Please sign in to comment.