public async virtual Task <MemoryStream> CreateAssembly(string code) { _mscorlib = _mscorlib ?? MetadataReference.CreateFromStream(new MemoryStream(await _mscorlibProvider.Get())); CSharpCompilation previousCompilation = null; var scriptCompilation = CSharpCompilation.CreateScriptCompilation(Guid.NewGuid().ToString(), CSharpSyntaxTree.ParseText(code, CSharpParseOptions.Default.WithKind(SourceCodeKind.Script).WithLanguageVersion(LanguageVersion.Latest)), references: new[] { _mscorlib }, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, optimizationLevel: OptimizationLevel.Release, concurrentBuild: false, usings: new[] { "System", "System.Threading.Tasks" }), previousCompilation); var errorDiagnostics = scriptCompilation.GetDiagnostics().Where(x => x.Severity == DiagnosticSeverity.Error); if (errorDiagnostics.Any()) { Console.WriteLine(string.Join(",\r\n", errorDiagnostics.Select(e => e.GetMessage()))); return(null); } var stream = new MemoryStream(); if (scriptCompilation.Emit(stream).Success) { return(await Task.FromResult(stream)); } return(null); }
private IEnumerable <Diagnostic> CompileSourceCode(SourceText sourceCode) { currentScriptAssembly = null; currentScriptType = null; currentDrawMethod = null; var syntaxTree = SyntaxFactory.ParseSyntaxTree(sourceCode, parseOptions); var compilation = CSharpCompilation.CreateScriptCompilation( "SkiaSharpDrawing", syntaxTree, metadataReferences, compilationOptions, lastSuccessfulCompilation); using (var ms = new MemoryStream()) { var result = compilation.Emit(ms); if (result.Success) { lastSuccessfulCompilation = compilation; currentScriptAssembly = Assembly.Load(ms.ToArray()); currentScriptType = currentScriptAssembly.GetType("Script"); currentDrawMethod = currentScriptType.GetMethod("Draw"); } return(result.Diagnostics); } }
public void UnusedUsingInteractive() { var tree = Parse("using System;", options: TestOptions.Script); var comp = CSharpCompilation.CreateScriptCompilation("sub1", tree, new[] { MscorlibRef_v4_0_30316_17626 }); comp.VerifyDiagnostics(); }
private CompilationResult CompileSourceCode(SourceText sourceCode, CancellationToken cancellationToken = default) { var syntaxTree = SyntaxFactory.ParseSyntaxTree( sourceCode, parseOptions, cancellationToken: cancellationToken); var compilation = CSharpCompilation.CreateScriptCompilation( "SkiaSharpDrawing", syntaxTree, metadataReferences, compilationOptions); using (var ms = new MemoryStream()) { var result = compilation.Emit(ms, cancellationToken: cancellationToken); Type scriptType = null; if (result.Success) { var assembly = Assembly.Load(ms.ToArray()); scriptType = assembly.GetType("Script"); } return(new CompilationResult { CompilationMessages = GetCompilationMessages(result.Diagnostics), ScriptType = scriptType, }); } }
public void AcrossSubmissions() { var references = new[] { MscorlibRef_v4_0_30316_17626, SystemCoreRef }; var source0 = @"bool b = false; L: ; if (b) { goto L; }"; var source1 = @"goto L;"; var s0 = CSharpCompilation.CreateScriptCompilation( "s0.dll", SyntaxFactory.ParseSyntaxTree(source0, options: TestOptions.Script), references ); s0.VerifyDiagnostics(); var s1 = CSharpCompilation.CreateScriptCompilation( "s1.dll", SyntaxFactory.ParseSyntaxTree(source1, options: TestOptions.Script), references, previousScriptCompilation: s0 ); s1.VerifyDiagnostics( // (1,6): error CS0159: No such label 'L' within the scope of the goto statement // goto L; Diagnostic(ErrorCode.ERR_LabelNotFound, "L").WithArguments("L").WithLocation(1, 6) ); }
private Compilation GetCompilationFromCode(string code) { var tree = SyntaxFactory.ParseSyntaxTree(code, ParseOptions, FilePath); var references = GetReferences(); var compilation = CSharpCompilation.CreateScriptCompilation( _globalAssemblyNamePrefix, tree, references, new CSharpCompilationOptions( outputKind: OutputKind.DynamicallyLinkedLibrary, mainTypeName: null, scriptClassName: "Program", usings: Usings, optimizationLevel: OptimizationLevel.Debug, // TODO checkOverflow: false, // TODO allowUnsafe: true, // TODO platform: Platform.AnyCpu, warningLevel: 4, xmlReferenceResolver: null, sourceReferenceResolver: null, metadataReferenceResolver: MetadataResolver, assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default ), //.WithTopLevelBinderFlags(BinderFlags.IgnoreCorLibraryDuplicatedTypes), null, typeof(object)); return(compilation); }
public bool RewriteFile(string path, string dstDir) { string source = File.ReadAllText(path); var isScript = Path.GetExtension(path).Equals(".csx"); var syntaxTree = CSharpSyntaxTree.ParseText(source, new CSharpParseOptions(kind: isScript ? SourceCodeKind.Script : SourceCodeKind.Regular)); var references = new[] { MetadataReference.CreateFromFile(typeof(int).GetTypeInfo().Assembly.Location), // mscorlib MetadataReference.CreateFromFile(typeof(Uri).GetTypeInfo().Assembly.Location), // System MetadataReference.CreateFromFile(typeof(Enumerable).GetTypeInfo().Assembly.Location) // System.Core }; var compilation = isScript ? CSharpCompilation.CreateScriptCompilation("LinqRewriteExample", syntaxTree, references) : CSharpCompilation.Create("LinqRewriteExample", new[] { syntaxTree }, references, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); if (PrintDiagnostics(compilation)) { return(false); } var rewriter = new LinqRewriter(compilation.GetSemanticModel(syntaxTree)); var rewrittenNode = rewriter.Visit(syntaxTree.GetRoot()); Directory.Delete(dstDir, true); Directory.CreateDirectory(dstDir); File.WriteAllText(rewrittenNode.ToString(), Path.Combine(dstDir, Path.GetFileName(path))); return(true); }
public void CompilationChain_SystemObject_NotEquals() { // As in VS/ETA, make a new list of references for each submission. var options = new CSharpParseOptions(kind: SourceCodeKind.Script, documentationMode: DocumentationMode.None); var corLib = AssemblyMetadata.CreateFromImage(TestResources.NetFX.v4_0_30319.mscorlib); var s1 = CSharpCompilation.CreateScriptCompilation("s1.dll", syntaxTree: SyntaxFactory.ParseSyntaxTree("struct S { }", options), references: new[] { corLib.GetReference(documentation: new TestDocumentationProviderNoEquals()) }, returnType: typeof(object)); s1.VerifyDiagnostics(); var s2 = CSharpCompilation.CreateScriptCompilation("s2.dll", syntaxTree: SyntaxFactory.ParseSyntaxTree("System.Collections.IEnumerable Iterator() { yield return new S(); }", options), previousScriptCompilation: s1, references: new[] { corLib.GetReference(documentation: new TestDocumentationProviderNoEquals()) }, returnType: typeof(object)); Assert.NotEqual(s1.GetSpecialType(SpecialType.System_Object), s2.GetSpecialType(SpecialType.System_Object)); s2.VerifyDiagnostics( // (1,58): error CS0029: Cannot implicitly convert type 'S' to 'object' // System.Collections.IEnumerable Iterator() { yield return new S(); } Diagnostic(ErrorCode.ERR_NoImplicitConv, "new S()").WithArguments("S", "object")); }
public void DuplicateLabelInSeparateSubmissions() { var references = new[] { MscorlibRef_v4_0_30316_17626, SystemCoreRef }; var source0 = @"bool b = false; L: ; if (b) { goto L; }"; var source1 = @"if (!b) { b = !b; if (b) goto L; L: ; }"; var s0 = CSharpCompilation.CreateScriptCompilation( "s0.dll", SyntaxFactory.ParseSyntaxTree(source0, options: TestOptions.Script), references ); s0.VerifyDiagnostics(); var s1 = CSharpCompilation.CreateScriptCompilation( "s1.dll", SyntaxFactory.ParseSyntaxTree(source1, options: TestOptions.Script), references, previousScriptCompilation: s0 ); s1.VerifyDiagnostics(); }
public void SubmissionEntryPoint() { var references = new[] { MscorlibRef_v4_0_30316_17626, SystemCoreRef }; var source0 = @"{ await System.Threading.Tasks.Task.Delay(100); System.Console.Write(""complete""); }"; var s0 = CSharpCompilation.CreateScriptCompilation( "s0.dll", SyntaxFactory.ParseSyntaxTree(source0, options: TestOptions.Script), references); var verifier = CompileAndVerify(s0, verify: Verification.Fails); var methodData = verifier.TestData.GetMethodData("<Initialize>"); Assert.Equal("System.Threading.Tasks.Task<object>", methodData.Method.ReturnType.ToDisplayString()); methodData.VerifyIL( @"{ // Code size 60 (0x3c) .maxstack 2 .locals init (<<Initialize>>d__0 V_0, System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object> V_1) IL_0000: newobj ""<<Initialize>>d__0..ctor()"" IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: ldarg.0 IL_0008: stfld ""Script <<Initialize>>d__0.<>4__this"" IL_000d: ldloc.0 IL_000e: call ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object> System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object>.Create()"" IL_0013: stfld ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object> <<Initialize>>d__0.<>t__builder"" IL_0018: ldloc.0 IL_0019: ldc.i4.m1 IL_001a: stfld ""int <<Initialize>>d__0.<>1__state"" IL_001f: ldloc.0 IL_0020: ldfld ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object> <<Initialize>>d__0.<>t__builder"" IL_0025: stloc.1 IL_0026: ldloca.s V_1 IL_0028: ldloca.s V_0 IL_002a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object>.Start<<<Initialize>>d__0>(ref <<Initialize>>d__0)"" IL_002f: nop IL_0030: ldloc.0 IL_0031: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object> <<Initialize>>d__0.<>t__builder"" IL_0036: call ""System.Threading.Tasks.Task<object> System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object>.Task.get"" IL_003b: ret }"); methodData = verifier.TestData.GetMethodData("<Factory>"); Assert.Equal("System.Threading.Tasks.Task<object>", methodData.Method.ReturnType.ToDisplayString()); methodData.VerifyIL( @"{ // Code size 12 (0xc) .maxstack 1 IL_0000: ldarg.0 IL_0001: newobj "".ctor(object[])"" IL_0006: callvirt ""System.Threading.Tasks.Task<object> <Initialize>()"" IL_000b: ret }"); }
public void CompilationDoesNotAcceptArbitrarilyRootedTree() { var arbitraryTree = SyntaxFactory.SyntaxTree(SyntaxFactory.Attribute(SyntaxFactory.IdentifierName("Wooh"))); var parsedTree = SyntaxFactory.ParseSyntaxTree(""); Assert.Throws<ArgumentException>(() => CSharpCompilation.Create("Grrr", syntaxTrees: new[] { arbitraryTree })); Assert.Throws<ArgumentException>(() => CSharpCompilation.CreateScriptCompilation("Wah").AddSyntaxTrees(arbitraryTree)); Assert.Throws<ArgumentException>(() => CSharpCompilation.Create("Bahh", syntaxTrees: new[] { parsedTree }).ReplaceSyntaxTree(parsedTree, arbitraryTree)); Assert.Throws<ArgumentException>(() => CSharpCompilation.Create("Woo").GetSemanticModel(arbitraryTree)); }
public override Compilation CreateSubmission(Script script) { CSharpCompilation previousSubmission = null; if (script.Previous != null) { previousSubmission = (CSharpCompilation)script.Previous.GetCompilation(); } var diagnostics = DiagnosticBag.GetInstance(); var references = script.GetReferencesForCompilation( MessageProvider.Instance, diagnostics ); // TODO: report diagnostics diagnostics.Free(); var tree = SyntaxFactory.ParseSyntaxTree( script.SourceText, script.Options.ParseOptions ?? DefaultParseOptions, script.Options.FilePath ); string assemblyName, submissionTypeName; script.Builder.GenerateSubmissionId(out assemblyName, out submissionTypeName); var compilation = CSharpCompilation.CreateScriptCompilation( assemblyName, tree, references, WithTopLevelBinderFlags( new CSharpCompilationOptions( outputKind: OutputKind.DynamicallyLinkedLibrary, mainTypeName: null, scriptClassName: submissionTypeName, usings: script.Options.Imports, optimizationLevel: script.Options.OptimizationLevel, checkOverflow: script.Options.CheckOverflow, allowUnsafe: script.Options.AllowUnsafe, platform: Platform.AnyCpu, warningLevel: script.Options.WarningLevel, xmlReferenceResolver: null, // don't support XML file references in interactive (permissions & doc comment includes) sourceReferenceResolver: script.Options.SourceResolver, metadataReferenceResolver: script.Options.MetadataResolver, assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default ) ), previousSubmission, script.ReturnType, script.GlobalsType ); return(compilation); }
private void CompileExample(string path, bool devPath = true) { var source = File.ReadAllText(devPath ? Path.Combine("../../Samples/", path) : path); var isScript = Path.GetExtension(path).Equals(".csx"); var syntaxTree = CSharpSyntaxTree.ParseText(source, new CSharpParseOptions(kind: isScript ? SourceCodeKind.Script : SourceCodeKind.Regular)); var references = new[] { MetadataReference.CreateFromFile(typeof(int).GetTypeInfo().Assembly.Location), // mscorlib MetadataReference.CreateFromFile(typeof(Uri).GetTypeInfo().Assembly.Location), // System MetadataReference.CreateFromFile(typeof(System.Linq.Enumerable).GetTypeInfo().Assembly.Location), // System.Core }; var compilation = isScript ? CSharpCompilation.CreateScriptCompilation("LinqRewriteExample", syntaxTree, references) : CSharpCompilation.Create("LinqRewriteExample", new[] { syntaxTree }, references, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); var hasErrs = false; foreach (var item in compilation.GetDiagnostics()) { if (item.Severity == DiagnosticSeverity.Error) { hasErrs = true; } PrintDiagnostic(item); } if (hasErrs) { return; } var rewriter = new LinqRewriter(compilation.GetSemanticModel(syntaxTree)); var rewritten = rewriter.Visit(syntaxTree.GetRoot()); hasErrs = false; foreach (var item in compilation.GetDiagnostics()) { if (item.Severity == DiagnosticSeverity.Error) { hasErrs = true; } if (item.Severity == DiagnosticSeverity.Warning) { continue; } PrintDiagnostic(item); } if (hasErrs) { return; } Console.WriteLine(rewritten.ToString()); }
public static Type?CompileCommand(string code) { Match m = _cbRegex.Match(code); if (!m.Success) { return(null); } code = $@" [ModuleLifespan(ModuleLifespan.Transient)] public sealed class DynamicCommands : TheGodfatherModule {{ {m.Groups["code"]} }}"; string type = $"DynamicCommands{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"; Type? moduleType = null; IEnumerable <PortableExecutableReference> refs = AppDomain.CurrentDomain.GetAssemblies() .Where(xa => !xa.IsDynamic && !string.IsNullOrWhiteSpace(xa.Location)) .Select(x => MetadataReference.CreateFromFile(x.Location)); SyntaxTree ast = SyntaxFactory.ParseSyntaxTree(code, new CSharpParseOptions() .WithKind(SourceCodeKind.Script) .WithLanguageVersion(LanguageVersion.Latest)); var opts = new CSharpCompilationOptions( OutputKind.DynamicallyLinkedLibrary, scriptClassName: type, usings: _usings, optimizationLevel: OptimizationLevel.Release, allowUnsafe: true, platform: Platform.AnyCpu ); var compilation = CSharpCompilation.CreateScriptCompilation(type, ast, refs, opts, returnType: typeof(object)); Assembly?assembly = null; using (var ms = new MemoryStream()) { compilation.Emit(ms); ms.Position = 0; assembly = Assembly.Load(ms.ToArray()); } Type?outerType = assembly.ExportedTypes.FirstOrDefault(x => x.Name == type); moduleType = outerType?.GetNestedTypes().FirstOrDefault(x => x.BaseType == typeof(TheGodfatherModule)); return(moduleType); }
public void ExternAliasInInteractive_Error() { var src = "extern alias Bar;"; var comp = CSharpCompilation.CreateScriptCompilation( GetUniqueName(), syntaxTree: SyntaxFactory.ParseSyntaxTree(src, options: TestOptions.Script), references: new MetadataReference[] { MscorlibRef, ExternAliasTests.Goo1, ExternAliasTests.Goo2 }); comp.VerifyDiagnostics( // (1,1): error CS7015: 'extern alias' is not valid in this context // extern alias Bar; Diagnostic(ErrorCode.ERR_ExternAliasNotAllowed, "extern alias Bar;")); }
// private async Task<List<MetadataReference>> LoadMetadataReferencesAsync() // { // if (_loadMetadataReferencesTask is null) // { // _loadMetadataReferencesTask = Task.Run<List<MetadataReference>>( // async () => // { // List<MetadataReference> references = new(); // var httpClient = _httpClientFactory.CreateClient("Default"); // foreach (var assembly in AssemblyLoadContext.Default.Assemblies) // { // if (!assembly.IsDynamic) // { // var response = await httpClient.GetAsync( // $"_framework/{assembly.GetName().Name!}.dll"); // using var stream = await response.Content.ReadAsStreamAsync(); // references.Add(MetadataReference.CreateFromStream( // stream)); // } // } // return references; // }); // } // return _loadMetadataReferencesTask; // } private static CSharpCompilation Compile( IEnumerable <ScriptFile> sources, IEnumerable <MetadataReference> references) { var mergedContent = string.Join( Environment.NewLine, sources.Select(source => source.Content)); var syntaxTree = CSharpSyntaxTree.ParseText( mergedContent, CSharpParseOptions.Default .WithKind(SourceCodeKind.Script) .WithLanguageVersion(LanguageVersion.Preview)); var compilationOptions = new CSharpCompilationOptions( OutputKind.DynamicallyLinkedLibrary, concurrentBuild: false, usings: new[] { "Amolenk.GameATron4000.Graphics", "Amolenk.GameATron4000.Graphics.Geometry", "Amolenk.GameATron4000.Model", "Amolenk.GameATron4000.Model.Builders", "System", "System.Linq" }); var compilation = CSharpCompilation.CreateScriptCompilation( Guid.NewGuid().ToString("N"), globalsType: typeof(Game)) .WithOptions(compilationOptions) .AddReferences(references) .AddSyntaxTrees(syntaxTree); if (compilation.GetDiagnostics().Any( diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)) { throw new ScriptException( "Failed to compile script.", compilation.GetDiagnostics().Select(diagnostic => CSharpScriptError.FromDiagnostic(diagnostic, sources))); } return(compilation); }
private async Task <object> MsRun(IAssemblyLoader loader, int i) { var name = "test" + i; var code = "public class test : roslyn_assemblyunload_lib.HostBase { public int Thing() { return (int)(12.0 * new System.Random().NextDouble()); } }"; var metadataReferences = refs.Select(x => MetadataReference.CreateFromFile(x.Location)) .Cast <MetadataReference>() .ToArray(); var libCompilation = CSharpCompilation.Create(name + "Host", new[] { SyntaxFactory.ParseSyntaxTree(code) }, metadataReferences, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); var libReference = libCompilation.ToMetadataReference(); var scriptReferences = metadataReferences.Append(libReference).ToList(); var libStream = EmitToStream(libCompilation); var libAssembly = loader.LoadFromStream(libStream); var hostType = libAssembly.GetType("test"); var hostObject = Activator.CreateInstance(hostType); var scriptCompilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary); var scriptCode = "Thing();"; var scriptCompilation = CSharpCompilation.CreateScriptCompilation(name + "Script", SyntaxFactory.ParseSyntaxTree(scriptCode, new CSharpParseOptions(kind: SourceCodeKind.Script)), scriptReferences, scriptCompilationOptions, null, null, hostType); var scriptStream = EmitToStream(scriptCompilation); var scriptAssembly = loader.LoadFromStream(scriptStream); var scriptEntryPoint = scriptCompilation.GetEntryPoint(CancellationToken.None); var scriptEntryPointType = scriptAssembly.GetType(scriptEntryPoint.ContainingType.MetadataName); var scriptEntryPointMethod = scriptEntryPointType.GetMethod(scriptEntryPoint.Name); var scriptDelegate = (Func <object[], Task <object> >)scriptEntryPointMethod.CreateDelegate(typeof(Func <object[], Task <object> >)); return(await scriptDelegate(new object[] { hostObject, null })); }
public static CSharpCompilation CreateSubmission( string code, IEnumerable <MetadataReference> references = null, CSharpCompilationOptions options = null, CSharpParseOptions parseOptions = null, CSharpCompilation previous = null, Type returnType = null, Type hostObjectType = null) { return(CSharpCompilation.CreateScriptCompilation( GetUniqueName(), references: (references != null) ? s_scriptRefs.Concat(references) : s_scriptRefs, options: options, syntaxTree: Parse(code, options: parseOptions ?? TestOptions.Script), previousScriptCompilation: previous, returnType: returnType, globalsType: hostObjectType)); }
public void NoReferences() { var submission = CSharpCompilation.CreateScriptCompilation("test", syntaxTree: SyntaxFactory.ParseSyntaxTree("1", options: TestOptions.Script), returnType: typeof(int)); submission.VerifyDiagnostics( // (1,1): error CS0518: Predefined type 'System.Object' is not defined or imported // 1 Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "1").WithArguments("System.Object").WithLocation(1, 1), // error CS0518: Predefined type 'System.Object' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Object").WithLocation(1, 1), // error CS0518: Predefined type 'System.Threading.Tasks.Task`1' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Threading.Tasks.Task`1").WithLocation(1, 1), // error CS0400: The type or namespace name 'System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' could not be found in the global namespace (are you missing an assembly reference?) Diagnostic(ErrorCode.ERR_GlobalSingleTypeNameNotFound).WithArguments("System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089").WithLocation(1, 1), // (1,1): error CS0518: Predefined type 'System.Int32' is not defined or imported // 1 Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "1").WithArguments("System.Int32").WithLocation(1, 1), // error CS0518: Predefined type 'System.Object' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Object").WithLocation(1, 1)); }
private Compilation GetCompilationFromCode(string code) { var tree = SyntaxFactory.ParseSyntaxTree(code, ParseOptions, FilePath); var references = GetReferences(); var compilationOptions = new CSharpCompilationOptions( OutputKind, mainTypeName: null, scriptClassName: "Program", usings: Usings, optimizationLevel: _optimizationLevel, checkOverflow: _checkOverflow, allowUnsafe: _allowUnsafe, platform: Platform, warningLevel: 4, xmlReferenceResolver: null, sourceReferenceResolver: SourceResolver, metadataReferenceResolver: MetadataResolver, assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default ); //.WithTopLevelBinderFlags(BinderFlags.IgnoreCorLibraryDuplicatedTypes), var assemblyNumber = Interlocked.Increment(ref _assemblyNumber); if (OutputKind == OutputKind.ConsoleApplication || OutputKind == OutputKind.WindowsApplication) { return(CSharpCompilation.Create( _globalAssemblyNamePrefix + assemblyNumber, new[] { tree }, references, compilationOptions)); } return(CSharpCompilation.CreateScriptCompilation( _globalAssemblyNamePrefix + assemblyNumber, tree, references, compilationOptions, returnType: typeof(object))); }
private static PreparedCompilation PrepareScriptCompilation(SyntaxTree compilationSource, AsmDetail detailsToUseForTarget, IEnumerable <string> additionalUsings = null, IEnumerable <MetadataReference> additionalReferences = null) { var commonDetails = BuildCommonCompilationDetails(additionalUsings, additionalReferences); var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) .WithUsings(commonDetails.ListOfUsings); var compilation = CSharpCompilation.CreateScriptCompilation(detailsToUseForTarget.AsmName) //.WithReferences(commonDetails.MetadataReferences) .AddReferences(commonDetails.MetadataReferences) .WithOptions(options) .AddSyntaxTrees(compilationSource); return(new PreparedCompilation { Options = options, Compilation = compilation, MetadataReferences = commonDetails.MetadataReferences, Usings = commonDetails.ListOfUsings }); }
protected override Compilation CreateScriptCompilation(string assemblyName, SyntaxTree syntaxTree, IEnumerable <MetadataReference> references, CompilationOptions options, Compilation previousScriptCompilation, Type returnType, Type globalsType) => CSharpCompilation.CreateScriptCompilation(assemblyName, syntaxTree, references, (CSharpCompilationOptions)options, (CSharpCompilation)previousScriptCompilation, returnType, globalsType);
public static void CreateEditorInstance() { lock (instanceCreateLocked) { if (instance == null) { instance = new ScriptEditor(); instance.FormClosing += (form, e) => { e.Cancel = true; ((Form)form).Visible = false; //if (editor.DialogResult == DialogResult.OK) //{ // try // { // string code = editor.Code; // //string code = editor.roslynHost.GetDocument(editor.docId).GetTextAsync().Result.ToString(); // //ret = codeFunc(code); // //var scrOpt = scriptOptions // // //.WithReferences(typeof(ScriptEditor).Assembly, typeof(MainController).Assembly) // // .WithReferences( // // editor.roslynHost.DefaultReferences // // .Concat(scriptOptions.MetadataReferences)) // // //.Concat( // // // scriptOptions.MetadataResolver)) // // //typeof(Enumerable).Assembly.GetReferencedAssemblies())) // // .WithImports(editor.roslynHost.DefaultImports); // var script = CSharpScript.Create( // code, // scriptOptions.WithImports(roslynHost.DefaultImports), // globalContext.GetType()); // var task = script.RunAsync(globalContext); // task.Wait(); // var ret = task.Result; // task.Dispose(); // File.WriteAllText("Code\\_last", editor.Code); // GC.Collect(); // } // catch (Exception ex) // { // if (exceptionHandler != null) // { // exceptionHandler(ex); // e.Cancel = true; // } // else throw; // } //} }; instance.button1.Click += (_, __) => { instance.button1.Enabled = false; cancellationTokenSource = new CancellationTokenSource(); Context.Reset(cancellationTokenSource); new Thread(() => { try { Guid guid = Guid.NewGuid(); string code = Code; File.WriteAllText("Code\\_last", code); //var script = CSharpScript.Create( // code, // scriptOptions // .WithImports(roslynHost.DefaultImports) // .WithEmitDebugInformation(true), // typeof(GlobalContext)); //var task = script.RunAsync(Context, Context.CancellationToken); //task.Wait(); //ScriptState scriptState = task.Result; //task.Dispose(); //GC.Collect(); //ScriptFinished?.Invoke(scriptState); //System.Diagnostics.Debug.WriteLine(scriptState.ReturnValue); InteractiveAssemblyLoader ial = new InteractiveAssemblyLoader(); //RoslynPad.Roslyn.Scripting.ScriptRunner scriptRunner = new RoslynPad.Roslyn.Scripting.ScriptRunner( // Code, // references: roslynHost.DefaultReferences, // usings: roslynHost.DefaultImports, // workingDirectory: $"{Environment.CurrentDirectory}\\Plugins", // assemblyLoader: ial // ); CSharpParseOptions parseOptions = CSharpParseOptions.Default .WithKind(SourceCodeKind.Script); //CSharpParseOptions parseOptions = new CSharpParseOptions( // documentationMode: DocumentationMode.Diagnose, // kind: SourceCodeKind.Script); string path = $"{Environment.CurrentDirectory}\\AsmTmp\\{guid.ToString().Substring(0, 8)}-{guid.GetHashCode()}"; string plugins = $"{Environment.CurrentDirectory}\\Plugins"; string className = "Submission"; string codePath = $"{path}\\{guid}.csx"; Directory.CreateDirectory(path); File.WriteAllText(codePath, Code); CSharpCompilationOptions compilationOptions = new CSharpCompilationOptions( OutputKind.DynamicallyLinkedLibrary, mainTypeName: null, scriptClassName: className, usings: roslynHost.DefaultImports, allowUnsafe: true, sourceReferenceResolver: new SourceFileResolver(new[] { Environment.CurrentDirectory, plugins, path }, Environment.CurrentDirectory), metadataReferenceResolver: ScriptMetadataResolver .Default .WithBaseDirectory(Environment.CurrentDirectory) .WithSearchPaths(plugins, Environment.CurrentDirectory, path), assemblyIdentityComparer: AssemblyIdentityComparer.Default ); SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText( Code, options: parseOptions, path: codePath, encoding: Encoding.Unicode, cancellationToken: cancellationTokenSource.Token); CSharpCompilation compilation = CSharpCompilation.CreateScriptCompilation( guid.ToString(), syntaxTree, roslynHost.DefaultReferences, options: compilationOptions, //previousScriptCompilation: previous, globalsType: typeof(GlobalContext)); //compilation = compilation.AddReferences(compilation.DirectiveReferences); foreach (MetadataReference item in compilation.DirectiveReferences) { string asmName = item.Display.Substring(item.Display.LastIndexOf('\\') + 1); asmName = asmName.Substring(0, asmName.Length - 4); //var asmid = // new AssemblyIdentity(asmName); //ial.RegisterDependency(asmid, item.Display); //Assembly.LoadFrom(item.Display); } Microsoft.CodeAnalysis.Emit.EmitResult emit = compilation.Emit($"{path}\\{guid}.dll", $"{path}\\{guid}.pdb", $"{path}\\{guid}.xml", cancellationToken: cancellationTokenSource.Token); previous = compilation; IMethodSymbol entryPoint = compilation.GetEntryPoint(cancellationTokenSource.Token); assemblyLoadContext?.Unload(); assemblyLoadContext = new AssemblyLoadContext(guid.ToString(), true); using FileStream fs = new FileStream($"{path}\\{guid}.dll", FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); assemblyLoadContext.LoadFromStream(fs); Assembly asm = assemblyLoadContext.LoadFromAssemblyPath($"{path}\\{guid}.dll"); assemblyLoadContext.Resolving += AssemblyLoadContext_Resolving; //Assembly asm = Assembly.LoadFrom($"{path}\\{guid}.dll"); //ial.RegisterDependency(asm); string BuildQualifiedName( string qualifier, string name) => !string.IsNullOrEmpty(qualifier) ? string.Concat(qualifier, ".", name) : name; var entryPointTypeName = BuildQualifiedName( entryPoint.ContainingNamespace.MetadataName, entryPoint.ContainingType.MetadataName); var entryPointMethodName = entryPoint.MetadataName; var entryPointType = asm.GetType(entryPointTypeName, throwOnError: true, ignoreCase: false); var runtimeEntryPoint = entryPointType.GetTypeInfo().GetDeclaredMethod(entryPointMethodName); var executor = (Func <object[], Task <object> >)runtimeEntryPoint.CreateDelegate(typeof(Func <object[], Task <object> >)); object[] vs = new object[3]; vs[0] = Context; var result = executor.Invoke(vs); if (result.IsFaulted) { SctiptException?.Invoke(result.Exception.InnerException); instance.Invoke((Action)(() => instance.propertyGrid.SelectedObject = new ScriptResult(Context, vs[1], result.Exception))); } else { System.Diagnostics.Debug.WriteLine(result.Result); instance.Invoke((Action)(() => instance.propertyGrid.SelectedObject = new ScriptResult(Context, vs[1], result.Result))); } //var compilation = script.GetCompilation() // .WithAssemblyName(guid.ToString()) // .WithOptions(compilation.Options.); //compilation.Options. //Directory.CreateDirectory("AsmTmp"); ////compilation.WithAssemblyName(); //var emit = compilation.Emit($"AsmTmp\\{guid}.dll", $"AsmTmp\\{guid}.pdb", $"AsmTmp\\{guid}.xml", cancellationToken: cancellationTokenSource.Token); } catch (Exception ex) { SctiptException?.Invoke(ex); } finally { // Выполнение в UI потоке instance.Invoke((Action)(() => instance.button1.Enabled = true)); GC.Collect(); } }) { Name = "ScriptThread" }.Start(); }; instance.button2.Click += (_, __) => { cancellationTokenSource?.Cancel(true); }; } }
public static (bool success, Assembly asm, Compilation compilation) LoadSource(string source) { // Use ConcurrentBuild to avoid the issue in // TODO: https://github.com/dotnet/runtime/issues/43411 var compilation = CSharpCompilation.CreateScriptCompilation( Path.GetRandomFileName(), CSharpSyntaxTree.ParseText(source, CSharpParseOptions.Default.WithKind(SourceCodeKind.Script).WithLanguageVersion(LanguageVersion.Preview)), References, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, usings: new[] { "System", "System.Collections.Generic", "System.Console", "System.Linq", "Elements", "Elements.Geometry", "Elements.Geometry.Profiles", "Elements.Validators" }, concurrentBuild: false)); ImmutableArray <Diagnostic> diagnostics = compilation.GetDiagnostics(); bool error = false; foreach (Diagnostic diag in diagnostics) { switch (diag.Severity) { case DiagnosticSeverity.Info: Console.WriteLine(diag.ToString()); break; case DiagnosticSeverity.Warning: Console.WriteLine(diag.ToString()); break; case DiagnosticSeverity.Error: error = true; Console.WriteLine(diag.ToString()); break; } } if (error) { return(false, null, null); } Assembly assembly; using (var outputAssembly = new MemoryStream()) { var result = compilation.Emit(outputAssembly); if (!result.Success) { foreach (var resultD in result.Diagnostics) { Console.WriteLine(resultD.ToString()); } } assembly = Assembly.Load(outputAssembly.ToArray()); } return(true, assembly, compilation); }
public static CompilationResult Create(string sourcePath, bool watch = false, OnRecompiledHandler callback = null) { var result = new CompilationResult() { Error = null, AssemblyLocation = null, Assembly = null }; try { if (!File.Exists(sourcePath)) { result.Error = $"File ${sourcePath} not found"; return(result); } if (watch) { Watch(sourcePath, callback); } var directory = Path.GetDirectoryName(sourcePath); var assemblyName = Path.GetFileNameWithoutExtension(sourcePath); var dllPath = Path.Combine(directory, assemblyName + ".dll"); var finfo = new FileInfo(dllPath); if (finfo.Exists && finfo.Length > 0 && File.GetLastWriteTime(sourcePath) <= finfo.LastWriteTime) { if (!s_assemblies.ContainsKey(sourcePath)) { s_assemblies.Add(sourcePath, Assembly.Load(File.ReadAllBytes(dllPath))); VerifyMemoryUsage(); } result.Assembly = s_assemblies[sourcePath]; result.AssemblyLocation = dllPath; return(result); } // // ParseSyntaxTree // var code = File.ReadAllText(sourcePath); var ParseOptions = new CSharpParseOptions() .WithKind(SourceCodeKind.Script) .WithDocumentationMode(DocumentationMode.Parse) .WithPreprocessorSymbols(new[] { "__DEMO__", "__DEMO_EXPERIMENTAL__", "TRACE", "DEBUG" }); var tree = SyntaxFactory.ParseSyntaxTree(code, ParseOptions, sourcePath, Encoding.UTF8); if (tree.GetDiagnostics().Count() != 0) { result.Error = String.Join("\n", from d in tree.GetDiagnostics() select $"{d.GetMessage()} ({d.Location.GetLineSpan ()})"); return(result); } // // CreateScriptCompilation // if (!Environment.Is64BitProcess) { result.Error = "Not x64 platform"; return(result); } var compilationOptions = new CSharpCompilationOptions( outputKind: OutputKind.DynamicallyLinkedLibrary, scriptClassName: Pascalize(assemblyName) + ".Program", usings: null, optimizationLevel: OptimizationLevel.Debug, platform: Platform.X64, sourceReferenceResolver: SourceFileResolver.Default, metadataReferenceResolver: ScriptMetadataResolver.Default, assemblyIdentityComparer: AssemblyIdentityComparer.Default, allowUnsafe: false ); var compilation = CSharpCompilation.CreateScriptCompilation( assemblyName, options: compilationOptions, references: GetInitialReferences() ); if (compilation.GetDiagnostics().Count() != 0) { result.Error = String.Join("\n", from d in tree.GetDiagnostics() select $"{d.GetMessage()} ({d.Location.GetLineSpan()})"); return(result); } compilation = compilation.AddSyntaxTrees(tree); IEnumerable <MetadataReference> GetInitialReferences() { var assemblies = new[] { typeof(Input).Assembly, typeof(RhinoApp).Assembly, typeof(GH_Document).Assembly }; var refs = from a in assemblies select MetadataReference.CreateFromFile(a.Location); var stdPath = Path.GetDirectoryName(typeof(object).Assembly.Location); return(new List <MetadataReference>() { MetadataReference.CreateFromFile(Path.Combine(stdPath, "mscorlib.dll")), MetadataReference.CreateFromFile(Path.Combine(stdPath, "System.dll")), MetadataReference.CreateFromFile(Path.Combine(stdPath, "System.Core.dll")), MetadataReference.CreateFromFile(Path.Combine(stdPath, "System.Runtime.dll")) }); } // // EmitAssembly // var pdbPath = Path.Combine(directory, assemblyName + ".pdb"); var xmlPath = Path.Combine(directory, assemblyName + ".xml"); var options = new EmitOptions( debugInformationFormat: DebugInformationFormat.PortablePdb ); using (var modFs = new FileStream(dllPath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.Asynchronous)) using (var pdbFs = new FileStream(pdbPath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.Asynchronous)) { // Can be changed with MemoryStream // And save the assembly files with the GH_Document in same directory EmitResult r = compilation.Emit(modFs, pdbFs, options: options); if (!r.Success) { result.Error = String.Join("\n", from d in r.Diagnostics select $"{d.GetMessage()} ({d.Location.GetLineSpan()})"); return(result); } } result.Assembly = Assembly.Load(File.ReadAllBytes(dllPath)); if (!s_assemblies.ContainsKey(sourcePath)) { s_assemblies.Add(sourcePath, result.Assembly); } else { s_assemblies[sourcePath] = result.Assembly; } result.AssemblyLocation = dllPath; VerifyMemoryUsage(); return(result); void VerifyMemoryUsage() { var size = Process.GetCurrentProcess().WorkingSet64; if (size > s_target_process_size) { //TODO: Alert user to reload Rhino } } string Pascalize(string str) { var r = new StringBuilder(str.Length); var i = 0; var chars = str.ToCharArray(); for (; i != chars.Length; ++i) { var c = chars[i]; if (!Char.IsLetter(c)) { continue; } if (Char.IsUpper(c)) { r.Append(c); } else { r.Append(Char.ToUpper(c)); } break; } var needupper = false; for (++i; i != chars.Length; ++i) { var c = chars[i]; if (!Char.IsLetterOrDigit(c)) { needupper = true; } else if (Char.IsUpper(c)) { needupper = false; r.Append(c); } else if (needupper) { needupper = false; r.Append(Char.ToUpper(c)); } else { r.Append(c); } } return(r.ToString()); } } catch (Exception e) { result.Error = e.Message; return(result); } }
public async Task AddAsync(CommandContext ctx, [RemainingText, Description("Code to evaluate.")] string code) { if (string.IsNullOrWhiteSpace(code)) { throw new InvalidCommandUsageException("Code missing."); } int cs1 = code.IndexOf("```") + 3; int cs2 = code.LastIndexOf("```"); if (cs1 == -1 || cs2 == -1) { throw new InvalidCommandUsageException("You need to wrap the code into a code block."); } code = $@" [ModuleLifespan(ModuleLifespan.Transient)] public sealed class DynamicCommands : BaseCommandModule {{ {code.Substring(cs1, cs2 - cs1)} }}"; await this.InformAsync(ctx, StaticDiscordEmoji.Information, "Compiling..."); string type = $"DynamicCommands{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}"; Type moduleType = null; try { IEnumerable <PortableExecutableReference> refs = AppDomain.CurrentDomain.GetAssemblies() .Where(xa => !xa.IsDynamic && !string.IsNullOrWhiteSpace(xa.Location)) .Select(x => MetadataReference.CreateFromFile(x.Location)); SyntaxTree ast = SyntaxFactory.ParseSyntaxTree(code, new CSharpParseOptions().WithKind(SourceCodeKind.Script).WithLanguageVersion(LanguageVersion.Latest)); var opts = new CSharpCompilationOptions( OutputKind.DynamicallyLinkedLibrary, scriptClassName: type, usings: new[] { "System", "System.Collections.Generic", "System.Linq", "System.Text", "System.Threading.Tasks", "DSharpPlus", "DSharpPlus.Entities", "DSharpPlus.CommandsNext", "DSharpPlus.CommandsNext.Attributes", "DSharpPlus.Interactivity" }, optimizationLevel: OptimizationLevel.Release, allowUnsafe: true, platform: Platform.X64 ); var compilation = CSharpCompilation.CreateScriptCompilation(type, ast, refs, opts, returnType: typeof(object)); Assembly assembly = null; using (var ms = new MemoryStream()) { var er = compilation.Emit(ms); ms.Position = 0; assembly = Assembly.Load(ms.ToArray()); } Type outerType = assembly.ExportedTypes.FirstOrDefault(x => x.Name == type); moduleType = outerType.GetNestedTypes().FirstOrDefault(x => x.BaseType == typeof(BaseCommandModule)); ctx.CommandsNext.RegisterCommands(moduleType); TheGodfatherShard.UpdateCommandList(ctx.CommandsNext); await this.InformAsync(ctx, StaticDiscordEmoji.Information, "Compilation successful! Commands successfully added!"); } catch (Exception ex) { await this.InformFailureAsync(ctx, $"Compilation failed!\n\n{Formatter.Bold(ex.GetType().ToString())}: {ex.Message}"); } }