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

A bunch of random improvements #58

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
33 changes: 12 additions & 21 deletions CSharpRepl.Tests/EvalTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public EvalTests(ITestOutputHelper outputHelper)
[Theory]
[InlineData("1+1", 2L, "int")]
[InlineData("return 1+1;", 2L, "int")]
[InlineData("return Random.Next(1,2);", 1L, "int")]
[InlineData("return Random.Shared.Next(1,2);", 1L, "int")]
[InlineData(@"var a = ""thing""; return a;", "thing", "string")]
[InlineData("Math.Pow(1,2)", 1D, "double")]
[InlineData(@"Enumerable.Range(0,1).Select(a=>""@"");", null, null)]
Expand All @@ -79,7 +79,7 @@ public async Task Eval_WellFormattedCodeExecutes(string expr, object expected, s
var (result, statusCode) = await Execute(expr);
var res = result.ReturnValue as JsonElement?;
object convertedValue;
if (res.Value.ValueKind == JsonValueKind.Array)
if (res?.ValueKind == JsonValueKind.Array)
{
convertedValue = res.Value.GetRawText();
}
Expand Down Expand Up @@ -150,9 +150,9 @@ public async Task Eval_JsonNetSerializationFailureHandled(string expr, string me
}

[Theory]
[InlineData(@"Enumerable.Range(0,1).Select(a=>""@"")", "@", 1, "SelectRangeIterator<string>")]
[InlineData(@"return Enumerable.Range(0,1).Select(a=>""@"");", "@", 1, "SelectRangeIterator<string>")]
public async Task Eval_EnumerablesReturnArraysOf(string expr, object expected, int count, string type)
[InlineData(@"Enumerable.Range(0,1).Select(a=>""@"")", "@", 1)]
[InlineData(@"return Enumerable.Range(0,1).Select(a=>""@"");", "@", 1)]
public async Task Eval_EnumerablesReturnArraysOf(string expr, object expected, int count)
{
var (result, statusCode) = await Execute(expr);

Expand All @@ -162,13 +162,11 @@ public async Task Eval_EnumerablesReturnArraysOf(string expr, object expected, i
Assert.Equal(expr, result.Code);
Assert.Equal(expected, res.Value[0].GetString());
Assert.Equal(count, res.Value.GetArrayLength());
Assert.Equal(type, result.ReturnTypeName);
}

[Theory]
[InlineData("return 1+1", "CompilationErrorException", "; expected")]
[InlineData(@"throw new Exception(""test"");", "Exception", "test")]
[InlineData("return System.Environment.MachineName;", "CompilationErrorException", "Usage of this API is prohibited\nUsage of this API is prohibited")]
[InlineData("return DoesNotCompile()", "CompilationErrorException", "; expected\nThe name 'DoesNotCompile' does not exist in the current context")]
public async Task Eval_FaultyCodeThrowsExpectedException(string expr, string exception, string message)
{
Expand All @@ -193,15 +191,6 @@ public async Task Eval_ConsoleOutputIsCaptured(string expr, string consoleOut, o
Assert.Equal(returnValue, result.ReturnValue);
}

[Fact]
public async Task Eval_LoadDLLThatExposesTypeOfADependency()
{
var expr = "#nuget CK.ActivityMonitor\nvar m = new CK.Core.ActivityMonitor();";
var (result, statusCode) = await Execute(expr);

Assert.Equal(HttpStatusCode.OK, statusCode);
}

[Fact]
public async Task Eval_FaultyDirectiveFailsGracefully()
{
Expand Down Expand Up @@ -233,15 +222,17 @@ public async void Eval_ValidateGenericMathSupport()
Assert.Equal(HttpStatusCode.OK, statusCode);
}

[Fact(Skip = "Test is failing presumably because of a bug in ByteSize")]
[Fact]
public async Task Eval_SupportsNugetDirectiveWithActualUsage()
{
var expr = @"#nuget ByteSize
var input = ""80527998976 B"";
if (ByteSize.TryParse(input, NumberStyles.Any, new CultureInfo(""en-us""), out var output))
var expr = """
#nuget ByteSize
var input = "80527998976 B";
if (ByteSize.TryParse(input, NumberStyles.Any, new CultureInfo("en-us"), out var output))
{
Console.WriteLine(output);
}";
}
""";

var (result, statusCode) = await Execute(expr);

Expand Down
9 changes: 6 additions & 3 deletions CSharpRepl/CSharpRepl.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<LangVersion>preview</LangVersion>
<TargetFramework>net9.0</TargetFramework>
<OutputType>Exe</OutputType>
Expand All @@ -15,8 +15,11 @@
<ItemGroup>
<PackageReference Include="AngouriMath" Version="1.3.0" />
<PackageReference Include="ICSharpCode.Decompiler" Version="8.2.0.7535" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.11.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Basic.Reference.Assemblies.Net90" Version="1.7.9" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.12.0-3.final" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3">
<ExcludeAssets>compile</ExcludeAssets>
</PackageReference>
<PackageReference Include="NuGet.Resolver" Version="6.11.1" />
<PackageReference Include="Seq.Extensions.Logging" Version="6.1.0" />
</ItemGroup>
Expand Down
56 changes: 0 additions & 56 deletions CSharpRepl/Eval/BlacklistedTypesAnalyzer.cs

This file was deleted.

19 changes: 5 additions & 14 deletions CSharpRepl/Eval/CSharpEval.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using CSDiscordService.Eval.ResultModels;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Scripting;
using System;
using System.Collections.Immutable;
Expand All @@ -17,10 +16,6 @@ namespace CSDiscordService.Eval
{
public class CSharpEval
{
private static readonly ImmutableArray<DiagnosticAnalyzer> Analyzers =
ImmutableArray.Create<DiagnosticAnalyzer>(new BlacklistedTypesAnalyzer());

private static readonly Random random = new Random();
private readonly JsonSerializerOptions _serializerOptions;
private readonly IPreProcessorService _preProcessor;
private readonly ILogger<CSharpEval> _logger;
Expand All @@ -31,12 +26,10 @@ public CSharpEval(JsonSerializerOptions serializerOptons, IPreProcessorService p
_preProcessor = preProcessor;
_logger = logger;
}

public async Task<EvalResult> RunEvalAsync(string code)
{
var sb = new StringBuilder();
using var textWr = new ConsoleLikeStringWriter(sb);
var env = new BasicEnvironment();

var sw = Stopwatch.StartNew();

Expand All @@ -47,16 +40,16 @@ public async Task<EvalResult> RunEvalAsync(string code)
}
catch(Exception ex)
{
var diagnostics = Diagnostic.Create(new DiagnosticDescriptor("REPL01", ex.Message, ex.Message, "Code", DiagnosticSeverity.Error, true),
var diagnostic = Diagnostic.Create(new DiagnosticDescriptor("REPL01", ex.Message, ex.Message, "Code", DiagnosticSeverity.Error, true),
Location.Create("", TextSpan.FromBounds(0,0), new LinePositionSpan(LinePosition.Zero, LinePosition.Zero)));
_logger.LogCritical(ex, "{message}", ex.Message);
return EvalResult.CreateErrorResult(code, sb.ToString(), sw.Elapsed, new[] { diagnostics }.ToImmutableArray());
return EvalResult.CreateErrorResult(code, sb.ToString(), sw.Elapsed, [diagnostic]);
}
var eval = CSharpScript.Create(context.Code, context.Options, typeof(Globals));

var compilation = eval.GetCompilation().WithAnalyzers(Analyzers);
var compilation = eval.GetCompilation();

var compileResult = await compilation.GetAllDiagnosticsAsync();
var compileResult = compilation.GetDiagnostics();
var compileErrors = compileResult.Where(a => a.Severity == DiagnosticSeverity.Error).ToImmutableArray();
sw.Stop();

Expand All @@ -67,16 +60,14 @@ public async Task<EvalResult> RunEvalAsync(string code)
}

var globals = new Globals();
Globals.Random = random;
Globals.Console = textWr;
Globals.Environment = env;

sw.Restart();
ScriptState<object> result;

try
{
result = await eval.RunAsync(globals, ex => true);
result = await eval.RunAsync(globals, _ => true);
}
catch (CompilationErrorException ex)
{
Expand Down
29 changes: 4 additions & 25 deletions CSharpRepl/Eval/DisassemblyService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,20 @@
using ICSharpCode.Decompiler.Disassembler;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using ICSharpCode.Decompiler.Metadata;

namespace CSDiscordService.Eval
{
public class DisassemblyService
{
private static readonly IReadOnlyCollection<MetadataReference> References = ImmutableArray.Create(
MetadataReference.CreateFromFile(typeof(Binder).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(typeof(ValueTuple<>).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(typeof(Enumerable).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(typeof(List<>).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(typeof(JsonConvert).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(typeof(string).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(typeof(HttpClient).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(typeof(Regex).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(typeof(BinaryExpression).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(typeof(Console).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(Assembly.Load("System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a").Location)
);

private static readonly ImmutableArray<string> Imports = ImmutableArray.Create(
private static readonly ImmutableArray<string> Imports =
[
"System",
"System.IO",
"System.Linq",
Expand All @@ -46,11 +27,9 @@ public class DisassemblyService
"System.Threading",
"System.Threading.Tasks",
"System.Net.Http",
"Newtonsoft.Json",
"Newtonsoft.Json.Linq",
"System.Reflection",
"System.Reflection.Emit"
);
];

public string GetIl(string code)
{
Expand Down Expand Up @@ -85,7 +64,7 @@ public object Main()
.WithAllowUnsafe(true)
.WithPlatform(Platform.AnyCpu);

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

var sb = new StringBuilder();
Expand Down
28 changes: 0 additions & 28 deletions CSharpRepl/Eval/Globals.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,8 @@ namespace CSDiscordService.Eval
{
public class Globals
{
public static Random Random { get; set; }
public static ConsoleLikeStringWriter Console { get; internal set; }
public static BasicEnvironment Environment { get; internal set; }
patrickklaeren marked this conversation as resolved.
Show resolved Hide resolved

public void ResetButton()
{
System.Environment.Exit(0);
}

public void PowerButton()
{
System.Environment.Exit(1);
}
patrickklaeren marked this conversation as resolved.
Show resolved Hide resolved
public void Cmd(string name, string args = "")
{
var psi = new ProcessStartInfo(name)
Expand All @@ -33,22 +22,5 @@ public void Cmd(string name, string args = "")
Console.WriteLine(p.StandardOutput.ReadToEnd());
Console.WriteLine(p.StandardError.ReadToEnd());
}

}

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
public class ʘ‿ʘAttribute : Attribute { }

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
public class ʘ_ʘAttribute : Attribute { }

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
public class ಠ_ಠAttribute : Attribute { }

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
public class ಠ‿ಠAttribute : Attribute { }

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
public class 눈ᆺ눈Attribute : Attribute { }

}
Loading
Loading