private static async Task EmitCompilationAsync(Compilation compilation, Package package) { if (package == null) { throw new ArgumentNullException(nameof(package)); } { var numberOfAttempts = 100; for (var attempt = 1; attempt < numberOfAttempts; attempt++) { try { compilation.Emit(package.EntryPointAssemblyPath.FullName); break; } catch (IOException) { if (attempt == numberOfAttempts - 1) { throw; } await Task.Delay(10); } } } }
public static async Task <(Compilation compilation, IReadOnlyCollection <Document> documents)> GetCompilation( this Package package, IReadOnlyCollection <SourceFile> sources, SourceCodeKind sourceCodeKind, IEnumerable <string> defaultUsings, Func <Task <Microsoft.CodeAnalysis.Workspace> > workspaceFactory, Budget budget) { var workspace = await workspaceFactory(); var currentSolution = workspace.CurrentSolution; var project = currentSolution.Projects.First(); var projectId = project.Id; foreach (var source in sources) { if (currentSolution.Projects .SelectMany(p => p.Documents) .FirstOrDefault(d => d.IsMatch(source)) is Document document) { // there's a pre-existing document, so overwrite its contents document = document.WithText(source.Text); document = document.WithSourceCodeKind(sourceCodeKind); currentSolution = document.Project.Solution; } else { var docId = DocumentId.CreateNewId(projectId, $"{package.Name}.Document"); currentSolution = currentSolution.AddDocument(docId, source.Name, source.Text); currentSolution = currentSolution.WithDocumentSourceCodeKind(docId, sourceCodeKind); } } project = currentSolution.GetProject(projectId); var usings = defaultUsings?.ToArray() ?? Array.Empty <string>(); if (usings.Length > 0) { var options = (CSharpCompilationOptions)project.CompilationOptions; project = project.WithCompilationOptions(options.WithUsings(usings)); } var compilation = await project.GetCompilationAsync().CancelIfExceeds(budget); return(compilation, project.Documents.ToArray()); }
private static async Task <RunResult> RunUnitTestsAsync( Package package, IEnumerable <SerializableDiagnostic> diagnostics, Budget budget, string requestId) { var dotnet = new Dotnet(package.Directory); var commandLineResult = await dotnet.VSTest( $@"--logger:trx ""{package.EntryPointAssemblyPath}"""); budget.RecordEntry(UserCodeCompleted); if (commandLineResult.ExitCode == 124) { throw new BudgetExceededException(budget); } var trex = new FileInfo( Path.Combine( Paths.DotnetToolsPath, "t-rex".ExecutableName())); if (!trex.Exists) { throw new InvalidOperationException($"t-rex not found in at location {trex}"); } var tRexResult = await CommandLine.Execute( trex, "", workingDir : package.Directory); var result = new RunResult( commandLineResult.ExitCode == 0, tRexResult.Output, diagnostics: diagnostics, requestId: requestId); result.AddFeature(new UnitTestRun(new[] { new UnitTestResult() })); return(result); }
internal static async Task <RunResult> RunConsoleAsync( Package package, IEnumerable <SerializableDiagnostic> diagnostics, Budget budget, string requestId, bool includeInstrumentation, string commandLineArgs) { var dotnet = new Dotnet(package.Directory); var commandName = $@"""{package.EntryPointAssemblyPath.FullName}"""; var commandLineResult = await dotnet.Execute( commandName.AppendArgs(commandLineArgs)); budget.RecordEntry(UserCodeCompleted); var output = InstrumentedOutputExtractor.ExtractOutput(commandLineResult.Output); if (commandLineResult.ExitCode == 124) { throw new BudgetExceededException(budget); } string exceptionMessage = null; if (commandLineResult.Error.Count > 0) { exceptionMessage = string.Join(Environment.NewLine, commandLineResult.Error); } var runResult = new RunResult( succeeded: true, output: output.StdOut, exception: exceptionMessage, diagnostics: diagnostics, requestId: requestId); if (includeInstrumentation) { runResult.AddFeature(output.ProgramStatesArray); runResult.AddFeature(output.ProgramDescriptor); } return(runResult); }
public static async Task <Compilation> Compile( this Package package, Workspace workspace, Budget budget, BufferId activeBufferId) { var sourceFiles = workspace.GetSourceFiles().ToArray(); var(compilation, documents) = await package.GetCompilationForRun(sourceFiles, SourceCodeKind.Regular, workspace.Usings, budget); var viewports = workspace.ExtractViewPorts(); var diagnostics = compilation.GetDiagnostics(); if (workspace.IncludeInstrumentation && !diagnostics.ContainsError()) { var activeDocument = GetActiveDocument(documents, activeBufferId); compilation = await AugmentCompilationAsync(viewports, compilation, activeDocument, activeBufferId, package); } return(compilation); }
private static RunResult RunWebRequest(Package package, string requestId) { var runResult = new RunResult(succeeded: true, requestId: requestId); return(runResult); }
private static async Task <Compilation> AugmentCompilationAsync( IEnumerable <Viewport> viewports, Compilation compilation, Document document, BufferId activeBufferId, Package build) { var regions = InstrumentationLineMapper.FilterActiveViewport(viewports, activeBufferId) .Where(v => v.Destination?.Name != null) .GroupBy(v => v.Destination.Name, v => v.Region, (name, region) => new InstrumentationMap(name, region)) .ToArray(); var solution = document.Project.Solution; var newCompilation = compilation; foreach (var tree in newCompilation.SyntaxTrees) { var replacementRegions = regions.FirstOrDefault(r => tree.FilePath.EndsWith(r.FileToInstrument))?.InstrumentationRegions; var subdocument = solution.GetDocument(tree); var visitor = new InstrumentationSyntaxVisitor(subdocument, await subdocument.GetSemanticModelAsync(), replacementRegions); var linesWithInstrumentation = visitor.Augmentations.Data.Keys; var activeViewport = viewports.DefaultIfEmpty(null).First(); var(augmentationMap, variableLocationMap) = await InstrumentationLineMapper.MapLineLocationsRelativeToViewportAsync( visitor.Augmentations, visitor.VariableLocations, document, activeViewport); var rewrite = new InstrumentationSyntaxRewriter( linesWithInstrumentation, variableLocationMap, augmentationMap); var newRoot = rewrite.Visit(tree.GetRoot()); var newTree = tree.WithRootAndOptions(newRoot, tree.Options); newCompilation = newCompilation.ReplaceSyntaxTree(tree, newTree); } var instrumentationSyntaxTree = build.GetInstrumentationEmitterSyntaxTree(); newCompilation = newCompilation.AddSyntaxTrees(instrumentationSyntaxTree); var augmentedDiagnostics = newCompilation.GetDiagnostics(); if (augmentedDiagnostics.ContainsError()) { throw new InvalidOperationException( $@"Augmented source failed to compile Diagnostics ----------- {string.Join(NewLine, augmentedDiagnostics)} Source ------ {newCompilation.SyntaxTrees.Select(s => $"// {s.FilePath ?? "(anonymous)"}{NewLine}//---------------------------------{NewLine}{NewLine}{s}").Join(NewLine + NewLine)}"); } return(newCompilation); }
public static Task <(Compilation compilation, IReadOnlyCollection <Document> documents)> GetCompilationForRun( this Package package, IReadOnlyCollection <SourceFile> sources, SourceCodeKind sourceCodeKind, IEnumerable <string> defaultUsings, Budget budget) =>