private async Task <IReadOnlyList <RPackage> > GetPackagesAsync(Func <Task <JArray> > queryFunc, CancellationToken cancellationToken) { // Fetching of installed and available packages is done in a // separate package query session to avoid freezing the REPL. try { await _session.EnsureHostStartedAsync(new RHostStartupInfo(), null, cancellationToken : cancellationToken); await _session.SetVsCranSelectionAsync(CranMirrorList.UrlFromName(_settings.CranMirror), cancellationToken); await _session.SetCodePageAsync(_settings.RCodePage, cancellationToken); // Get the repos and libpaths from the REPL session and set them // in the package query session var repositories = (await DeparseRepositoriesAsync()); if (repositories != null) { await WrapRException(_session.ExecuteAsync($"options(repos=eval(parse(text={repositories.ToRStringLiteral()})))", cancellationToken)); } var libraries = (await DeparseLibrariesAsync()); if (libraries != null) { await WrapRException(_session.ExecuteAsync($".libPaths(eval(parse(text={libraries.ToRStringLiteral()})))", cancellationToken)); } var result = await WrapRException(queryFunc()); return(result.Select(p => p.ToObject <RPackage>()).ToList().AsReadOnly()); } catch (RHostDisconnectedException ex) { throw new RPackageManagerException(Resources.PackageManager_TransportError, ex); } }
public async Task RCreateGetDestroyBlobs() { var createResult = await _session.EvaluateAsync("rtvs:::create_blob(as.raw(1:10))", REvaluationKind.Normal); createResult.Result.Should().NotBeNull(); var blobId = ((JValue)createResult.Result).Value <ulong>(); var actualData = await _session.EvaluateAsync <byte[]>($"rtvs:::get_blob({blobId})", REvaluationKind.Normal); byte[] expectedData = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; actualData.Should().Equal(expectedData); await _session.ExecuteAsync($"rtvs:::destroy_blob({blobId})"); }
public async Task BacktickNames() { var tracer = await _session.TraceExecutionAsync(); await _session.ExecuteAsync("`123` <- list(`name with spaces` = 42)"); var stackFrames = (await _session.TracebackAsync()).ToArray(); stackFrames.Should().NotBeEmpty(); var children = await stackFrames.Last().DescribeChildrenAsync(ExpressionProperty | LengthProperty, RValueRepresentations.Deparse()); var parent = children.Should().Contain(er => er.Name == "`123`") .Which.Should().BeAssignableTo <IRValueInfo>().Which; parent.Expression.Should().Be("`123`"); children = await parent.DescribeChildrenAsync(ExpressionProperty, RValueRepresentations.Deparse()); children.Should().Contain(er => er.Name == "$`name with spaces`") .Which.Should().BeAssignableTo <IRValueInfo>() .Which.Expression.Should().Be("`123`$`name with spaces`"); }
private async Task SaveStateAsync() { try { if (_settings.ShowSaveOnResetConfirmationDialog == YesNo.Yes) { if (MessageButtons.Yes == await _services.ShowMessageAsync(Resources.Warning_SaveOnReset, MessageButtons.YesNo)) { await Session.ExecuteAsync("rtvs:::save_state()"); } } } catch (RHostDisconnectedException rhdex) { WriteRHostDisconnectedError(rhdex); WriteErrorLine(Resources.Error_FailedToSaveState); } }
private void DeleteCachedVariable() { if (_evaluation != null && _evaluation.Expression.StartsWithOrdinal(ViewEnvName)) { if (_rSession.IsHostRunning) { var varName = _evaluation.Expression.Substring(ViewEnvName.Length + 1); try { _rSession.ExecuteAsync(Invariant($"rm('{varName}', envir = {ViewEnvName})")).DoNotWait(); } catch (Exception ex) when(!ex.IsCriticalException()) { } } } _evaluation = null; }
public async Task RemoveBreakpointWhileRunning() { const string code = @"browser() f <- function() { NULL browser() } b <- FALSE; while (TRUE) if (b) f()"; var tracer = await _session.TraceExecutionAsync(); using (var sf = new SourceFile(code)) { await tracer.EnableBreakpointsAsync(true); await sf.Source(_session); await _session.NextPromptShouldBeBrowseAsync(); var bp = await tracer.CreateBreakpointAsync(sf, 3); int hitCount = 0; bp.BreakpointHit += delegate { ++hitCount; }; await tracer.ContinueAsync(); await Task.Delay(100); await bp.DeleteAsync(); await _session.ExecuteAsync("b <- TRUE"); await _session.NextPromptShouldBeBrowseAsync(); await _session.ShouldBeAtAsync(sf.FilePath, 4); hitCount.Should().Be(0); } }
public async Task BreakContinue() { const string code = @"x <- 0 browser() while (x >= 0) { x <- x + 1 } browser()"; var tracer = await _session.TraceExecutionAsync(); using (var sf = new SourceFile(code)) { await sf.Source(_session); await _session.NextPromptShouldBeBrowseAsync(); await tracer.ContinueAsync(); await Task.Delay(100); await tracer.BreakAsync(); await _session.NextPromptShouldBeBrowseAsync(); var frame = (await _session.TracebackAsync()).Single(); frame.FileName.Should().Be(sf.FilePath); frame.LineNumber.Should().BeInRange(3, 5); await _session.ExecuteAsync("x <- -42"); await tracer.ContinueAsync(); await _session.NextPromptShouldBeBrowseAsync(); await _session.ShouldHaveTracebackAsync(new TracebackBuilder { { sf, 6 } }); } }
private async Task Environments(string script, params IREnvironment[] expectedEnvs) { // Detach all packages that can be detached before doing anything else. The only two that // cannot be detached are .GlobalEnv, which is the first in the list, and package:base, // which is the last. So, just keep detaching the 2nd item until the list only has 2 left. await _session.ExecuteAsync("while (length(search()) > 2) detach(2)"); // Wait for prompt to appear. using (var eval = await _session.BeginInteractionAsync()) { } var envProvider = new REnvironmentProvider(_session); var envTcs = new TaskCompletionSource <IREnvironment[]>(); envProvider.Environments.CollectionChanged += (sender, args) => { envTcs.TrySetResult(envProvider.Environments.ToArray()); }; using (var inter = await _session.BeginInteractionAsync()) { inter.RespondAsync(script + "\n").DoNotWait(); } // Wait until we hit the Browse> prompt. using (var inter = await _session.BeginInteractionAsync()) { inter.Contexts.IsBrowser().Should().BeTrue(); } var actualEnvs = await envTcs.Task; actualEnvs.ShouldAllBeEquivalentTo(expectedEnvs, options => options .Including(env => env.Name) .Including(env => env.Kind) .WithStrictOrdering()); // Validating EnvironmentExpression: // For environments that are on the search list, we can validate it by retrieving environment by name, // and verifying that it is indeed the same. format() generates comparable string values - it returns strings // that are unique for any given environment (using its name if it has one, and its memory address otherwise). // For all other environments, we validate by looking at a variable named 'tag' in that environment, and // comparing its value to the name of the function extracted from the call (i.e. environment name). var expectedObjects = new List <string>(); var actualObjects = new List <string>(); foreach (var env in actualEnvs) { if (env == null) { expectedObjects.Add(null); actualObjects.Add(null); } else if (env.Kind == REnvironmentKind.Function) { int tagEnd = env.Name.IndexOf("("); tagEnd.Should().BePositive(); string tag = env.Name.Substring(0, tagEnd); expectedObjects.Add(tag); actualObjects.Add(await _session.EvaluateAsync <string>( $"({env.EnvironmentExpression})$tag", REvaluationKind.Normal)); } else { expectedObjects.Add(await _session.EvaluateAsync <string>( $"format(as.environment({env.Name.ToRStringLiteral()}))", REvaluationKind.Normal)); actualObjects.Add(await _session.EvaluateAsync <string>( $"format({env.EnvironmentExpression})", REvaluationKind.Normal)); } } actualObjects.Should().Equal(expectedObjects); }