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

Update to .NET 8 and fix float serialization #56

Merged
merged 3 commits into from
Dec 18, 2023
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
12 changes: 6 additions & 6 deletions CSharpRepl.Tests/CSharpRepl.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
<PropertyGroup>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<LangVersion>preview</LangVersion>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>CSDiscordService.Tests</RootNamespace>
</PropertyGroup>

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="7.0.0-rc.2.22476.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0-preview-20221003-04" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.reporters" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="xunit" Version="2.6.2" />
<PackageReference Include="xunit.runner.reporters" Version="2.6.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
Expand Down
19 changes: 15 additions & 4 deletions CSharpRepl.Tests/EvalTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,33 @@ public EvalTests(ITestOutputHelper outputHelper)
[InlineData(@"var a = ""thing""; return a;", "thing", "string")]
[InlineData("Math.Pow(1,2)", 1D, "double")]
[InlineData(@"Enumerable.Range(0,1).Select(a=>""@"");", null, null)]
[InlineData("typeof(int)", "System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", "RuntimeType")]
[InlineData("typeof(int)", "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", "RuntimeType")]
[InlineData("Assembly.GetExecutingAssembly()", true, "RuntimeAssembly")]
[InlineData("TimeSpan.FromSeconds(2310293892)", "26739.12:18:12", "TimeSpan")]
[InlineData("float.PositiveInfinity", "Infinity", "float")]
[InlineData("List<int> l = [1, 2, 3]; l", "[1,2,3]", "List<int>")]
public async Task Eval_WellFormattedCodeExecutes(string expr, object expected, string type)
{
var (result, statusCode) = await Execute(expr);
var res = result.ReturnValue as JsonElement?;
object convertedValue;
if (expected is string || expected is null)
if (res.Value.ValueKind == JsonValueKind.Array)
{
convertedValue = res.Value.GetRawText();
}
else if (expected is string || expected is null)
{
convertedValue = res?.GetString();
}
else if (res.Value.ValueKind == JsonValueKind.Object)
{
convertedValue = res.HasValue;
}
else if (result.ReturnTypeName == "RuntimeAssembly")
{
// nothing to do here, value is random for this test
convertedValue = expected;
}
else
{
var value = res.Value.GetRawText();
Expand Down Expand Up @@ -185,8 +196,8 @@ public async Task Eval_ConsoleOutputIsCaptured(string expr, string consoleOut, o
[Fact]
public async Task Eval_LoadDLLThatExposesTypeOfADependency()
{
var expr = "#nuget CK.ActivityMonitor\nvar m = new ActivityMonitor();";
var (_, statusCode) = await Execute(expr);
var expr = "#nuget CK.ActivityMonitor\nvar m = new CK.Core.ActivityMonitor();";
var (result, statusCode) = await Execute(expr);

Assert.Equal(HttpStatusCode.OK, statusCode);
}
Expand Down
12 changes: 5 additions & 7 deletions CSharpRepl/CSharpRepl.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<LangVersion>preview</LangVersion>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
<UserSecretsId>03629088-8bb9-4faf-8162-debf93066bc4</UserSecretsId>
</PropertyGroup>
Expand All @@ -14,12 +14,10 @@

<ItemGroup>
<PackageReference Include="AngouriMath" Version="1.3.0" />
<PackageReference Include="ICSharpCode.Decompiler" Version="3.2.0.3856" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.5.0-1.22524.5" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2-beta2" />
<PackageReference Include="NuGet.Packaging" Version="6.5.0-preview.1.35" />
<PackageReference Include="NuGet.Protocol" Version="6.5.0-preview.1.35" />
<PackageReference Include="NuGet.Resolver" Version="6.5.0-preview.1.35" />
<PackageReference Include="ICSharpCode.Decompiler" Version="8.2.0.7535" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.8.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NuGet.Resolver" Version="6.8.0" />
<PackageReference Include="Seq.Extensions.Logging" Version="6.1.0" />
</ItemGroup>
<ItemGroup>
Expand Down
30 changes: 19 additions & 11 deletions CSharpRepl/Eval/DisassemblyService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using ICSharpCode.Decompiler.Disassembler;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Mono.Cecil;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
Expand All @@ -15,6 +14,7 @@
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using ICSharpCode.Decompiler.Metadata;

namespace CSDiscordService.Eval
{
Expand Down Expand Up @@ -65,7 +65,7 @@ public string GetIl(string code)

namespace Eval
{{
public class Code
public unsafe class Code
{{
public object Main()
{{
Expand All @@ -75,17 +75,22 @@ public object Main()
}}
";

var opts = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview).WithKind(SourceCodeKind.Regular);
var opts = CSharpParseOptions.Default
.WithLanguageVersion(LanguageVersion.Preview)
.WithKind(SourceCodeKind.Regular);

var scriptSyntaxTree = CSharpSyntaxTree.ParseText(toExecute, opts);
var compOpts = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary).WithOptimizationLevel(OptimizationLevel.Debug).WithAllowUnsafe(true).WithPlatform(Platform.AnyCpu);
var compOpts = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
.WithOptimizationLevel(OptimizationLevel.Debug)
.WithAllowUnsafe(true)
.WithPlatform(Platform.AnyCpu);

var compilation = CSharpCompilation.Create(Guid.NewGuid().ToString(), options: compOpts, references: References).AddSyntaxTrees(scriptSyntaxTree);
var compilation = CSharpCompilation.Create(Guid.NewGuid().ToString(), options: compOpts, references: References)
.AddSyntaxTrees(scriptSyntaxTree);

var sb = new StringBuilder();
using var pdb = new MemoryStream();
using var dll = new MemoryStream();
var result = compilation.Emit(dll, pdb);
var result = compilation.Emit(dll);
if (!result.Success)
{
sb.AppendLine("Emit Failed");
Expand All @@ -94,19 +99,22 @@ public object Main()
else
{
dll.Seek(0, SeekOrigin.Begin);
using var module = ModuleDefinition.ReadModule(dll);
using var file = new PEFile(compilation.AssemblyName!, dll);
using var writer = new StringWriter(sb);
module.Name = compilation.AssemblyName;
var plainOutput = new PlainTextOutput(writer);
var rd = new ReflectionDisassembler(plainOutput, CancellationToken.None)
{
DetectControlStructure = true
};
var ignoredMethods = new[] { ".ctor" };
var methods = module.Types.SelectMany(a => a.Methods).Where(a => !ignoredMethods.Contains(a.Name));
var methods = file.Metadata.MethodDefinitions.Where(a =>
{
var methodName = file.Metadata.GetString(file.Metadata.GetMethodDefinition(a).Name);
return !ignoredMethods.Contains(methodName);
});
foreach (var method in methods)
{
rd.DisassembleMethod(method);
rd.DisassembleMethod(file, method);
plainOutput.WriteLine();
}
}
Expand Down
2 changes: 1 addition & 1 deletion CSharpRepl/Eval/NugetDirectiveProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public async Task PreProcess(string directive, ScriptExecutionContext context, A
{
var actionLogger = new NugetLogger(logger);
var nugetDirective = NugetPreProcessorDirective.Parse(directive);
string frameworkName = Assembly.GetEntryAssembly()!.GetCustomAttributes(true)
string frameworkName = typeof(NugetDirectiveProcessor).Assembly.GetCustomAttributes(true)
.OfType<System.Runtime.Versioning.TargetFrameworkAttribute>()
.Select(x => x.FrameworkName)
.FirstOrDefault()!;
Expand Down
1 change: 1 addition & 0 deletions CSharpRepl/Eval/ResultModels/EvalResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public override string ToString()
IncludeFields = true,
PropertyNameCaseInsensitive = true,
ReferenceHandler = ReferenceHandler.IgnoreCycles,
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
Converters = {
new TypeJsonConverter(), new TypeInfoJsonConverter(),
new RuntimeTypeHandleJsonConverter(), new TypeJsonConverterFactory(), new AssemblyJsonConverter(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializer

public class AssemblyJsonConverterFactory : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert) => typeToConvert == Type.GetType("System.RuntimeAssembly");
public override bool CanConvert(Type typeToConvert) => typeToConvert == Type.GetType("System.Reflection.RuntimeAssembly");
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
return new RuntimeAssemblyJsonConverter();
Expand Down
2 changes: 2 additions & 0 deletions CSharpRepl/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public void ConfigureServices(IServiceCollection services)
IncludeFields = true,
PropertyNameCaseInsensitive = true,
ReferenceHandler = ReferenceHandler.IgnoreCycles,
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
Converters = {
new TypeJsonConverter(), new TypeInfoJsonConverter(),
new RuntimeTypeHandleJsonConverter(), new TypeJsonConverterFactory(), new AssemblyJsonConverter(),
Expand All @@ -57,6 +58,7 @@ public void ConfigureServices(IServiceCollection services)
o.JsonSerializerOptions.IncludeFields = true;
o.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
o.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
o.JsonSerializerOptions.NumberHandling |= JsonNumberHandling.AllowNamedFloatingPointLiterals;
o.JsonSerializerOptions.Converters.Add(new TypeJsonConverter());
o.JsonSerializerOptions.Converters.Add(new TypeInfoJsonConverter());
o.JsonSerializerOptions.Converters.Add(new RuntimeTypeHandleJsonConverter());
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:7.0 as dotnet-build
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 as dotnet-build
ARG TARGETPLATFORM
ARG BUILDPLATFORM
WORKDIR /src
Expand All @@ -10,7 +10,7 @@ RUN dotnet build --configuration Release --no-restore
#RUN dotnet test --configuration Release CSharpRepl.Tests/CSharpRepl.Tests.csproj --no-build --no-restore
RUN dotnet publish --configuration Release CSharpRepl/CSharpRepl.csproj --no-build --no-restore -o /app

FROM --platform=$TARGETPLATFORM mcr.microsoft.com/dotnet/aspnet:7.0
FROM --platform=$TARGETPLATFORM mcr.microsoft.com/dotnet/aspnet:8.0
ARG TARGETPLATFORM
ARG BUILDPLATFORM
WORKDIR /app
Expand Down
Loading