Skip to content

Commit

Permalink
Merge pull request #260 from adrianoc/staging
Browse files Browse the repository at this point in the history
Promoting staging to production (feb/2024)
  • Loading branch information
adrianoc authored Feb 2, 2024
2 parents 3f6109d + ecbb4d1 commit c8fa196
Show file tree
Hide file tree
Showing 1,380 changed files with 491,431 additions and 394,302 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/cecilifier-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3
with:
dotnet-version: '7.0.x'
- run: dotnet tool install --global dotnet-ilverify --version 7.0.0
dotnet-version: '8.0.x'
- run: dotnet tool install --global dotnet-ilverify --version 8.0.0
- run: dotnet restore
- run: dotnet test --filter 'TestCategory !~ Issues' --collect:"XPlat Code Coverage"
- run: dotnet format style --verify-no-changes
Expand Down
2 changes: 1 addition & 1 deletion Cecilifier.Benchmarks/Cecilifier.Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
6 changes: 3 additions & 3 deletions Cecilifier.Common.props
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project>
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<LangVersion>11</LangVersion>
<AssemblyVersion>2.6.0</AssemblyVersion>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>12</LangVersion>
<AssemblyVersion>2.8.0</AssemblyVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion Cecilifier.CommonPackages.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp"><Version>4.7.0-2.final</Version></PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp"><Version>4.8.0</Version></PackageReference>
<PackageReference Include="Mono.Cecil"><Version>0.11.5</Version></PackageReference>
</ItemGroup>
</Project>
4 changes: 2 additions & 2 deletions Cecilifier.Core.Tests/Cecilifier.Core.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="NUnit" Version="4.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
</ItemGroup>
<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion Cecilifier.Core.Tests/Framework/ResourceTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ private void CompareAssemblies(string expectedAssemblyPath, string actualAssembl
var comparer = new AssemblyComparer(expectedAssemblyPath, actualAssemblyPath);
if (!comparer.Compare(visitor, instructionComparer))
{
Assert.Fail("Expected and generated assemblies differs:\r\n\tExpected: {0}\r\n\tGenerated: {1}\r\n\r\n{2}\r\n\r\nCecilified Code:\r\n{3}", comparer.First, comparer.Second, visitor.Reason, cecilifiedCode);
Assert.Fail($"Expected and generated assemblies differs:\r\n\tExpected: {comparer.First}\r\n\tGenerated: {comparer.Second}\r\n\r\n{visitor.Reason}\r\n\r\nCecilified Code:\r\n{cecilifiedCode}");
}
}

Expand Down
18 changes: 9 additions & 9 deletions Cecilifier.Core.Tests/Tests/Unit/ExternalMembersTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void TestPreserveSig([Values] bool preserveSig)
var result = RunCecilifier($"using System.Runtime.InteropServices; public class C {{ [DllImport(\"Foo\", PreserveSig = {preserveSig.ToString().ToLower()})] public static extern int M(); int Call() => M(); }}");
var cecilifiedCode = result.GeneratedCode.ReadToEnd();

Assert.AreEqual(preserveSig, cecilifiedCode.Contains("MethodImplAttributes.PreserveSig"));
Assert.That(cecilifiedCode.Contains("MethodImplAttributes.PreserveSig"), Is.EqualTo(preserveSig));
}

[Test]
Expand All @@ -40,7 +40,7 @@ public void TestCallingConvention([Values] CallingConvention callingConvention)
var result = RunCecilifier($"using System.Runtime.InteropServices; public class C {{ [DllImport(\"Foo\", CallingConvention = CallingConvention.{callingConvention})] public static extern int M(); int Call() => M(); }}");
var cecilifiedCode = result.GeneratedCode.ReadToEnd();

Assert.IsTrue(cecilifiedCode.Contains($"PInvokeAttributes.CallConv{callingConvention.ToString().ToLower()}", StringComparison.OrdinalIgnoreCase), cecilifiedCode);
Assert.That(cecilifiedCode.Contains($"PInvokeAttributes.CallConv{callingConvention.ToString().ToLower()}", StringComparison.OrdinalIgnoreCase), Is.True,cecilifiedCode);
}

[Test]
Expand All @@ -59,7 +59,7 @@ public void TestCharSet([Values(CharSet.Ansi, CharSet.Auto, CharSet.Unicode)] Ch
var result = RunCecilifier($"using System.Runtime.InteropServices; public class C {{ [DllImport(\"Foo\", CharSet = CharSet.{charSet})] public static extern int M(); }}");
var cecilifiedCode = result.GeneratedCode.ReadToEnd();

Assert.IsTrue(cecilifiedCode.Contains($"PInvokeAttributes.CharSet{charSet}"), cecilifiedCode);
Assert.That(cecilifiedCode.Contains($"PInvokeAttributes.CharSet{charSet}"), Is.True,cecilifiedCode);
}

[Test]
Expand All @@ -68,7 +68,7 @@ public void TestSetLastError([Values] bool setLastError)
var result = RunCecilifier($"using System.Runtime.InteropServices; public class C {{ [DllImport(\"Foo\", SetLastError = {setLastError.ToString().ToLower()})] public static extern int M(); }}");
var cecilifiedCode = result.GeneratedCode.ReadToEnd();

Assert.AreEqual(setLastError, cecilifiedCode.Contains($"PInvokeAttributes.SupportsLastError"), cecilifiedCode);
Assert.That(cecilifiedCode.Contains($"PInvokeAttributes.SupportsLastError"), Is.EqualTo(setLastError), cecilifiedCode);
}

[Test]
Expand All @@ -77,7 +77,7 @@ public void TestExactSpelling([Values] bool exactSpelling)
var result = RunCecilifier($"using System.Runtime.InteropServices; public class C {{ [DllImport(\"Foo\", ExactSpelling = {exactSpelling.ToString().ToLower()})] public static extern int M(); }}");
var cecilifiedCode = result.GeneratedCode.ReadToEnd();

Assert.AreEqual(exactSpelling, cecilifiedCode.Contains($"PInvokeAttributes.NoMangle"), cecilifiedCode);
Assert.That(cecilifiedCode.Contains($"PInvokeAttributes.NoMangle"), Is.EqualTo(exactSpelling), cecilifiedCode);
}

[Test]
Expand All @@ -86,8 +86,8 @@ public void TestBestFitMapping([Values] bool bestFitMapping)
var result = RunCecilifier($"using System.Runtime.InteropServices; public class C {{ [DllImport(\"Foo\", BestFitMapping = {bestFitMapping.ToString().ToLower()})] public static extern int M(); }}");
var cecilifiedCode = result.GeneratedCode.ReadToEnd();

Assert.AreEqual(bestFitMapping, cecilifiedCode.Contains("PInvokeAttributes.BestFitEnabled"), cecilifiedCode);
Assert.AreEqual(!bestFitMapping, cecilifiedCode.Contains("PInvokeAttributes.BestFitDisabled"), cecilifiedCode);
Assert.That(cecilifiedCode.Contains("PInvokeAttributes.BestFitEnabled"), Is.EqualTo(bestFitMapping), cecilifiedCode);
Assert.That(cecilifiedCode.Contains("PInvokeAttributes.BestFitDisabled"), Is.Not.EqualTo(bestFitMapping), cecilifiedCode);
}

[Test]
Expand All @@ -96,8 +96,8 @@ public void TestThrowOnUnmappableChar([Values] bool throwOnUnmappableChar)
var result = RunCecilifier($"using System.Runtime.InteropServices; public class C {{ [DllImport(\"Foo\", ThrowOnUnmappableChar = {throwOnUnmappableChar.ToString().ToLower()})] public static extern int M(); }}");
var cecilifiedCode = result.GeneratedCode.ReadToEnd();

Assert.AreEqual(throwOnUnmappableChar, cecilifiedCode.Contains("PInvokeAttributes.ThrowOnUnmappableCharEnabled"), cecilifiedCode);
Assert.AreEqual(!throwOnUnmappableChar, cecilifiedCode.Contains("PInvokeAttributes.ThrowOnUnmappableCharDisable"), cecilifiedCode);
Assert.That(cecilifiedCode.Contains("PInvokeAttributes.ThrowOnUnmappableCharEnabled"), Is.EqualTo(throwOnUnmappableChar), cecilifiedCode);
Assert.That(cecilifiedCode.Contains("PInvokeAttributes.ThrowOnUnmappableCharDisable"), Is.Not.EqualTo(throwOnUnmappableChar), cecilifiedCode);
}

[Test]
Expand Down
6 changes: 3 additions & 3 deletions Cecilifier.Core.Tests/Tests/Unit/ForEachStatementTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ public void EnumerableImplementingGenericAndNonGenericIEnumerator()
var listOfTEnumerator = typeof(List<>.Enumerator);

var expected= new[] { typeof(IEnumerator<>), typeof(IEnumerator), typeof(IDisposable) };
CollectionAssert.AreEquivalent(
expected,
listOfTEnumerator.GetInterfaces().Select(itf => itf.IsConstructedGenericType ? itf.GetGenericTypeDefinition() : itf));
Assert.That(
listOfTEnumerator.GetInterfaces().Select(itf => itf.IsConstructedGenericType ? itf.GetGenericTypeDefinition() : itf),
Is.EquivalentTo(expected));

var result = RunCecilifier("""
using System;
Expand Down
45 changes: 45 additions & 0 deletions Cecilifier.Core.Tests/Tests/Unit/Miscellaneous.Assingment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Collections.Generic;
using NUnit.Framework;

namespace Cecilifier.Core.Tests.Tests.Unit
{
[TestFixture]
public class MiscellaneousAssignmentsTests : CecilifierUnitTestBase
{
[TestCaseSource(nameof(TestScenarios))]
public void TestIndirectLoad_Issue259(string typeName, string expectedLoadOpcode, bool initializeVariable)
{
var code = $$"""
struct S {}
class Foo { {{typeName}} Bar(ref {{typeName}} p) { {{typeName}} local{{ (initializeVariable ? "" : "; local") }} = p; return local; } }
""";

var expectedSnippet = @".*(?<emit>.+\.Emit\(OpCodes\.)Ldarg_1\);\s"
+ $@"\1{expectedLoadOpcode}.+;\s"
+ @"\1Stloc, l_local_\d+\);\s";

var result = RunCecilifier(code);
Assert.That(result.GeneratedCode.ReadToEnd(), Does.Match(expectedSnippet));
}

static IEnumerable<TestCaseData> TestScenarios()
{
foreach(var initializeMode in new[] { true, false } )
{
yield return new TestCaseData("int", "Ldind_I4", initializeMode);
yield return new TestCaseData("long", "Ldind_I8", initializeMode);
yield return new TestCaseData("short", "Ldind_I2", initializeMode);
yield return new TestCaseData("byte", "Ldind_U1", initializeMode);
yield return new TestCaseData("float", "Ldind_R4", initializeMode);
yield return new TestCaseData("double", "Ldind_R8", initializeMode);
yield return new TestCaseData("bool", "Ldind_U1", initializeMode);
yield return new TestCaseData("char", "Ldind_U2", initializeMode);
yield return new TestCaseData("int[]", "Ldind_Ref", initializeMode);
yield return new TestCaseData("System.DateTime", "Ldobj", initializeMode);
yield return new TestCaseData("S", "Ldobj", initializeMode);
}
}

public record struct TestScenario(string TypeName, string ExpectedLoadOpcode, bool VariableInitializer);
}
}
7 changes: 3 additions & 4 deletions Cecilifier.Core.Tests/Tests/Unit/Miscellaneous.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using NUnit.Framework;

namespace Cecilifier.Core.Tests.Tests.Unit
Expand Down Expand Up @@ -74,9 +73,9 @@ class Foo
}");

var cecilifiedCode = result.GeneratedCode.ReadToEnd();
Assert.False(cecilifiedCode.Contains("FieldDefinition(\"file\", FieldAttributes.Public, st_fileStream_0);"), cecilifiedCode);
Assert.True(cecilifiedCode.Contains("FieldDefinition(\"definedInFooBar\", FieldAttributes.Public, st_fileStream_3);"), cecilifiedCode);
Assert.True(cecilifiedCode.Contains("FieldDefinition(\"file\", FieldAttributes.Public, assembly.MainModule.ImportReference(typeof(System.IO.FileStream)));"), cecilifiedCode);
Assert.That(cecilifiedCode.Contains("FieldDefinition(\"file\", FieldAttributes.Public, st_fileStream_0);"), Is.False, cecilifiedCode);
Assert.That(cecilifiedCode.Contains("FieldDefinition(\"definedInFooBar\", FieldAttributes.Public, st_fileStream_3);"), Is.True, cecilifiedCode);
Assert.That(cecilifiedCode.Contains("FieldDefinition(\"file\", FieldAttributes.Public, assembly.MainModule.ImportReference(typeof(System.IO.FileStream)));"), Is.True, cecilifiedCode);
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public void PrivateImplementationType_IsCached()
var context = new CecilifierContext(comp.GetSemanticModel(comp.SyntaxTrees[0]), new CecilifierOptions(), 1);

var found = context.DefinitionVariables.GetVariablesOf(VariableMemberKind.Type);
Assert.False(found.Any());
Assert.That(found.Any(), Is.False);

var _ = PrivateImplementationDetailsGenerator.GetOrCreateInitializationBackingFieldVariableName(context, 10, "int", "123");
found = context.DefinitionVariables.GetVariablesOf(VariableMemberKind.Type);
Expand All @@ -37,7 +37,7 @@ public void Int32AndInt64_AreUsedAsFieldBackingType_OfArraysOf4And8Bytes()
var context = new CecilifierContext(comp.GetSemanticModel(comp.SyntaxTrees[0]), new CecilifierOptions(), 1);

var found = context.DefinitionVariables.GetVariablesOf(VariableMemberKind.Type);
Assert.False(found.Any());
Assert.That(found.Any(), Is.False);

var _ = PrivateImplementationDetailsGenerator.GetOrCreateInitializationBackingFieldVariableName(context, 4, "int", "0123");
found = context.DefinitionVariables.GetVariablesOf(VariableMemberKind.Type);
Expand All @@ -59,7 +59,7 @@ public void BackingField_ForSameSize_IsCached()
var context = new CecilifierContext(comp.GetSemanticModel(comp.SyntaxTrees[0]), new CecilifierOptions(), 1);

var found = context.DefinitionVariables.GetVariablesOf(VariableMemberKind.Field);
Assert.False(found.Any());
Assert.That(found.Any(), Is.False);

var variableName = PrivateImplementationDetailsGenerator.GetOrCreateInitializationBackingFieldVariableName(context, 10, "int", "123");
found = context.DefinitionVariables.GetVariablesOf(VariableMemberKind.Field);
Expand All @@ -76,11 +76,11 @@ public void BackingField_ForSameSize_IsCached()
[Test]
public void BackingField_IsUniquePerDataSize()
{
var comp = CompilationFor("class Foo {}");
var comp = CompilationFor("class Foo {}");
var context = new CecilifierContext(comp.GetSemanticModel(comp.SyntaxTrees[0]), new CecilifierOptions(), 1);

var found = context.DefinitionVariables.GetVariablesOf(VariableMemberKind.Field);
Assert.False(found.Any());
Assert.That(found.Any(), Is.False);

var variableName = PrivateImplementationDetailsGenerator.GetOrCreateInitializationBackingFieldVariableName(context, 12, "int","{1, 2, 3, 4}");
found = context.DefinitionVariables.GetVariablesOf(VariableMemberKind.Field);
Expand Down
4 changes: 4 additions & 0 deletions Cecilifier.Core/Cecilifier.Core.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../Cecilifier.Common.props" />
<Import Project="../Cecilifier.CommonPackages.props" />

<ItemGroup>
<InternalsVisibleTo Include="$(AssemblyName).Tests"/>
</ItemGroup>
</Project>
17 changes: 10 additions & 7 deletions Cecilifier.Core/Cecilifier.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.Json;
using Cecilifier.Core.AST;
using Cecilifier.Core.Extensions;
using Cecilifier.Core.Mappings;
Expand All @@ -10,21 +11,20 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

[assembly: InternalsVisibleTo("Cecilifier.Core.Tests")]

namespace Cecilifier.Core
{
public sealed class Cecilifier
{
internal const int CecilifierProgramPreambleLength = 25; // The # of lines before the 1st cecilified line of code (see CecilifierExtensions.AsCecilApplication())

public static readonly int SupportedCSharpVersion = int.Parse(LanguageVersion.CSharp11.ToString().Substring("CSharp".Length));
private const LanguageVersion CurrentLanguageVersion = LanguageVersion .CSharp12;
public static readonly int SupportedCSharpVersion = int.Parse(CurrentLanguageVersion.ToString().Substring("CSharp".Length));

public static CecilifierResult Process(Stream content, CecilifierOptions options)
{
UsageVisitor.ResetInstance();
using var stream = new StreamReader(content);
var syntaxTree = CSharpSyntaxTree.ParseText(stream.ReadToEnd(), new CSharpParseOptions(LanguageVersion.CSharp11));
var syntaxTree = CSharpSyntaxTree.ParseText(stream.ReadToEnd(), new CSharpParseOptions(CurrentLanguageVersion));
var metadataReferences = options.References.Select(refPath => MetadataReference.CreateFromFile(refPath)).ToArray();

var comp = CSharpCompilation.Create(
Expand All @@ -33,10 +33,13 @@ public static CecilifierResult Process(Stream content, CecilifierOptions options
metadataReferences,
new CSharpCompilationOptions(OutputKindFor(syntaxTree), allowUnsafe: true));

var errors = comp.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error).Select(s => s.ToString()).ToArray();
var errors = comp.GetDiagnostics()
.Where(d => d.Severity == DiagnosticSeverity.Error)
.Select(d => (CompilationError) d)
.ToArray();
if (errors.Length > 0)
{
throw new SyntaxErrorException(string.Join("\n", errors));
throw new SyntaxErrorException(errors);
}

var semanticModel = comp.GetSemanticModel(syntaxTree);
Expand Down
5 changes: 2 additions & 3 deletions Cecilifier.Core/Extensions/ISymbolExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,8 @@ public static OpCode LoadIndirectOpCodeFor(this ITypeSymbol type)
SpecialType.System_Char => OpCodes.Ldind_U2,
SpecialType.System_Boolean => OpCodes.Ldind_U1,
SpecialType.System_Object => OpCodes.Ldind_Ref,
SpecialType.None => OpCodes.Ldind_Ref,

_ => throw new ArgumentException($"Literal type {type} not supported.", nameof(type))

_ => type.IsValueType ? OpCodes.Ldobj : OpCodes.Ldind_Ref
};
}

Expand Down
2 changes: 1 addition & 1 deletion Cecilifier.Core/Misc/CecilDefinitionsFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ public static string DefaultTypeAttributeFor(TypeKind typeKind, bool hasStaticCt
{
TypeKind.Struct => "TypeAttributes.Sealed |" + basicClassAttrs,
TypeKind.Class => basicClassAttrs,
TypeKind.Interface => "TypeAttributes.Interface | TypeAttributes.Abstract",
TypeKind.Interface => "TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit",
TypeKind.Delegate => "TypeAttributes.Sealed",
TypeKind.Enum => string.Empty,
_ => throw new Exception("Not supported type declaration: " + typeKind)
Expand Down
16 changes: 16 additions & 0 deletions Cecilifier.Core/Misc/CompilationError.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Microsoft.CodeAnalysis;

namespace Cecilifier.Core.Misc;

public record struct CompilationError(int StartLineNumber, int StartColumn, int EndLineNumber, int EndColumn, string Message)
{
public static implicit operator CompilationError(Diagnostic diagnostic)
{
var lineSpan = diagnostic.Location.GetLineSpan(); return new CompilationError(
lineSpan.Span.Start.Line + 1,
lineSpan.Span.Start.Character + 1,
lineSpan.Span.End.Line + 1,
lineSpan.Span.End.Character + 1,
diagnostic.GetMessage());
}
}
6 changes: 5 additions & 1 deletion Cecilifier.Core/SyntaxErrorException.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
using System;
using Cecilifier.Core.Misc;

namespace Cecilifier.Core
{
public class SyntaxErrorException : Exception
{
public SyntaxErrorException(string message) : base(message)
public CompilationError[] Errors { get; }

public SyntaxErrorException(CompilationError[] errors)
{
Errors = errors;
}
}
}
2 changes: 1 addition & 1 deletion Cecilifier.Runtime/Cecilifier.Runtime.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>11</LangVersion>
<AssemblyVersion>2.00.0</AssemblyVersion>
</PropertyGroup>
Expand Down
Loading

0 comments on commit c8fa196

Please sign in to comment.