public async Task ViewAsync(string expression, string title, CancellationToken cancellationToken = default(CancellationToken)) { var evaluation = await EvaluateAsync(expression, _properties, RValueRepresentations.Str(), cancellationToken); if (evaluation != null) { await VsAppShell.Current.SwitchToMainThreadAsync(cancellationToken); var id = Math.Abs(_toolWindowIdBase + expression.GetHashCode() % (Int32.MaxValue - _toolWindowIdBase)); var pane = ToolWindowUtilities.FindWindowPane <VariableGridWindowPane>(id); if (pane == null) { pane = ToolWindowUtilities.ShowWindowPane <VariableGridWindowPane>(id, true); } else { var frame = pane.Frame as IVsWindowFrame; Debug.Assert(frame != null); frame?.Show(); } title = !string.IsNullOrEmpty(title) ? title : evaluation.Expression; pane.SetEvaluation(new VariableViewModel(evaluation, _aggregator), title); } }
public async Task ViewAsync(string expression, string title) { var evaluation = await EvaluateAsync(expression, _properties, RValueRepresentations.Str()) as IRValueInfo; if (evaluation != null) { await VsAppShell.Current.SwitchToMainThreadAsync(); var id = Math.Abs(_toolWindowIdBase + expression.GetHashCode() % (Int32.MaxValue - _toolWindowIdBase)); var existingPane = ToolWindowUtilities.FindWindowPane <VariableGridWindowPane>(id); var frame = existingPane?.Frame as IVsWindowFrame; if (frame != null) { frame.Show(); } else { VariableGridWindowPane pane = ToolWindowUtilities.ShowWindowPane <VariableGridWindowPane>(id, true); frame = (IVsWindowFrame)pane.Frame; frame.SetProperty((int)__VSFPROPID.VSFPROPID_IsWindowTabbed, true); frame.SetFramePos(VSSETFRAMEPOS.SFP_fDock, typeof(VariableGridWindowPane).GUID, 0, 0, 0, 0); title = !string.IsNullOrEmpty(title) ? title : evaluation.Expression; pane.SetEvaluation(new VariableViewModel(evaluation, _aggregator), title); } } }
public async Task StrLimit() { string expr = "as.double(1:100)"; string fullRepr = (await _session.EvaluateAndDescribeAsync(expr, None, RValueRepresentations.Str())).Representation; string expectedRepr = fullRepr.Substring(0, 7) + "!!!"; (await _session.EvaluateAndDescribeAsync(expr, None, RValueRepresentations.Str(10, null, "!!!"))) .Representation.Should().Be(expectedRepr); }
public async Task DeparseLimit() { string expr = "as.double(1:100)"; string fullRepr = (await _session.EvaluateAndDescribeAsync(expr, None, RValueRepresentations.Deparse())).Representation; string expectedRepr = fullRepr.Substring(0, 53); (await _session.EvaluateAndDescribeAsync(expr, None, RValueRepresentations.Deparse(50))) .Representation.Should().Be(expectedRepr); }
public async Task <IREvaluationResultInfo> EvaluateAsync(string expression, REvaluationResultProperties fields, string repr = null) { await TaskUtilities.SwitchToBackgroundThread(); repr = repr ?? RValueRepresentations.Str(); // Don't cache sessions since they can be disposed, expecially the debug session // when host is restarts or gets re-created in tests var rSession = _rSessionProvider.GetInteractiveWindowRSession(); var frames = await rSession.TracebackAsync(); if (frames == null || frames.Count == 0) { throw new InvalidOperationException("Debugger frames stack is empty"); } return(await frames.Last().TryEvaluateAndDescribeAsync(expression, fields, repr) as IRValueInfo); }
public async Task Children(ChildrenDataRow row) { var children = row.Children.Select(childRow => { var child = Substitute.For <IRValueInfo>(); child.Name.Returns((string)childRow[0]); child.Expression.Returns((string)childRow[1]); child.Representation.Returns((string)childRow[2]); return(child); }).ToArray(); var frame = (await _session.TracebackAsync()).Single(); await _session.ExecuteAsync("PARENT <- {" + row.Expression + "}"); var res = (await frame.TryEvaluateAndDescribeAsync("PARENT", AllFields, null)) .Should().BeAssignableTo <IRValueInfo>().Which; res.Length.Should().Be(row.Length); res.NameCount.Should().Be(row.NameCount); res.AttributeCount.Should().Be(row.AttrCount); res.SlotCount.Should().Be(row.SlotCount); var actualChildren = (await res.DescribeChildrenAsync(AllFields, RValueRepresentations.Deparse())) .Cast <IRValueInfo>() .ToArray(); res.HasChildren.Should().Be(children.Any()); if (row.Sorted) { actualChildren = actualChildren.OrderBy(er => er.Name).ToArray(); } actualChildren.ShouldAllBeEquivalentTo(children, options => options .Including(child => child.Name) .Including(child => child.Expression) .Including(child => child.Representation) .WithStrictOrdering()); }
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`"); }
public async Task Promise() { const string code = @"f <- function(p) { browser() force(p) browser() } f(1 + 2)"; var tracer = await _session.TraceExecutionAsync(); using (var sf = new SourceFile(code)) { await tracer.EnableBreakpointsAsync(true); await sf.Source(_session); await _session.NextPromptShouldBeBrowseAsync(); var stackFrames = (await _session.TracebackAsync()).ToArray(); stackFrames.Should().NotBeEmpty(); var frame = stackFrames.Last(); var children = await frame.DescribeChildrenAsync(REvaluationResultProperties.None, RValueRepresentations.Deparse()); children.Should().ContainSingle(er => er.Name == "p") .Which.Should().BeAssignableTo <IRPromiseInfo>() .Which.Code.Should().Be("1 + 2"); await tracer.ContinueAsync(); await _session.NextPromptShouldBeBrowseAsync(); children = await frame.DescribeChildrenAsync(REvaluationResultProperties.None, RValueRepresentations.Deparse()); children.Should().ContainSingle(er => er.Name == "p") .Which.Should().BeAssignableTo <IRValueInfo>() .Which.Representation.Should().Be("3"); } }
public async Task Representation(string expr, string deparse, string str, string toString) { string actualDeparse = (await _session.EvaluateAndDescribeAsync(expr, None, RValueRepresentations.Deparse())).Representation; string actualStr = (await _session.EvaluateAndDescribeAsync(expr, None, RValueRepresentations.Str())).Representation; string actualToString = (await _session.EvaluateAndDescribeAsync(expr, None, RValueRepresentations.ToString)).Representation; actualDeparse.Should().Be(deparse); actualStr.Should().Be(str); actualToString.Should().Be(toString); }
public async Task ActiveBindingEvaluate() { const string code = @"makeActiveBinding('x', function() 42, environment()) browser(); "; var tracer = await _session.TraceExecutionAsync(); using (var sf = new SourceFile(code)) { await tracer.EnableBreakpointsAsync(true); await sf.Source(_session); await _session.NextPromptShouldBeBrowseAsync(); var stackFrames = (await _session.TracebackAsync()).ToArray(); stackFrames.Should().NotBeEmpty(); var children = await stackFrames.Last().DescribeChildrenAsync(ComputedValueProperty, RValueRepresentations.Deparse()); children.Should().ContainSingle(er => er.Name == "x") .Which.Should().BeAssignableTo <IRActiveBindingInfo>() .Which.ComputedValue.Representation.Should().Be("42"); } }
public async Task EnvironmentIndependentResult() { const string code = @"(function(p) { v <- 42 makeActiveBinding('a', function() 42, environment()) browser() })(42)"; var tracer = await _session.TraceExecutionAsync(); using (var sf = new SourceFile(code)) { await tracer.EnableBreakpointsAsync(true); await sf.Source(_session); await _session.NextPromptShouldBeBrowseAsync(); var stackFrames = (await _session.TracebackAsync()).ToArray(); stackFrames.Should().NotBeEmpty(); var env = stackFrames.Last(); var children = (await env.DescribeChildrenAsync(ExpressionProperty | ComputedValueProperty, RValueRepresentations.Deparse())); var v = children.Should().ContainSingle(er => er.Name == "v") .Which.Should().BeAssignableTo <IRValueInfo>() .Which; var p = children.Should().ContainSingle(er => er.Name == "p") .Which.Should().BeAssignableTo <IRPromiseInfo>() .Which; var a = children.Should().ContainSingle(er => er.Name == "a") .Which.Should().BeAssignableTo <IRActiveBindingInfo>() .Which; var e = (await env.TryEvaluateAndDescribeAsync("non_existing_variable", None, null)) .Should().BeAssignableTo <IRErrorInfo>() .Which; var iv = v.ToEnvironmentIndependentResult().Should().BeAssignableTo <IRValueInfo>().Which; (await _session.EvaluateAndDescribeAsync(iv.Expression, ExpressionProperty, RValueRepresentations.Deparse())) .Should().BeAssignableTo <IRValueInfo>().Which.Representation.Should().Be(v.Representation); // When a promise expression is evaluated directly, rather than via children, the promise is forced // and becomes a value. To have something to compare it against, evaluate the original promise in // its original environment as well. var pv = await v.GetValueAsync(ExpressionProperty, RValueRepresentations.Deparse()); var ipv = p.ToEnvironmentIndependentResult().Should().BeAssignableTo <IRPromiseInfo>().Which; (await _session.EvaluateAndDescribeAsync(ipv.Expression, ExpressionProperty, RValueRepresentations.Deparse())) .Should().BeAssignableTo <IRValueInfo>() .Which.Representation.Should().Be(pv.Representation); // When an active binding expression is evaluated directly, rather than via children, its active // binding nature is not discoverable, and it produces a value result. var iav = a.ToEnvironmentIndependentResult().Should().BeAssignableTo <IRActiveBindingInfo>().Which; (await _session.EvaluateAndDescribeAsync(iav.Expression, ExpressionProperty | ComputedValueProperty, RValueRepresentations.Deparse())) .Should().BeAssignableTo <IRValueInfo>().Which.Representation.Should().Be(a.ComputedValue.Representation); var ie = e.ToEnvironmentIndependentResult().Should().BeAssignableTo <IRErrorInfo>().Which; (await _session.TryEvaluateAndDescribeAsync(ie.Expression, ExpressionProperty, RValueRepresentations.Deparse())) .Should().BeAssignableTo <IRErrorInfo>(); } }
public async Task <IREvaluationResultInfo> EvaluateAsync(string rScript) { // One eval at a time await _sem.WaitAsync(); try { var frames = await Session.TracebackAsync(); var frame = frames.FirstOrDefault(f => f.Index == 0); const REvaluationResultProperties properties = ClassesProperty | ExpressionProperty | TypeNameProperty | DimProperty | LengthProperty; var result = await frame.TryEvaluateAndDescribeAsync(rScript, properties, RValueRepresentations.Str()); var globalResult = await frame.TryEvaluateAndDescribeAsync("base::environment()", properties, RValueRepresentations.Str()); _globalEnv = new VariableViewModel(globalResult, VsAppShell.Current.ExportProvider.GetExportedValue <IObjectDetailsViewerAggregator>()); return(result); } finally { _sem.Release(); } }
protected virtual async Task <IReadOnlyList <IRSessionDataObject> > GetChildrenAsyncInternal() { var valueEvaluation = DebugEvaluation as IRValueInfo; if (valueEvaluation == null) { // Failed to fetch children - for example, because the object is already gone. return(null); } await TaskUtilities.SwitchToBackgroundThread(); try { if (valueEvaluation.HasChildren) { var properties = ExpressionProperty | AccessorKindProperty | TypeNameProperty | ClassesProperty | LengthProperty | SlotCountProperty | AttributeCountProperty | DimProperty | FlagsProperty | (_evaluateActiveBindings ? ComputedValueProperty : 0); var children = await valueEvaluation.DescribeChildrenAsync(properties, RValueRepresentations.Str(MaxReprLength), MaxChildrenCount); return(EvaluateChildren(children)); } } catch (REvaluationException) { } return(null); }
protected virtual async Task <IReadOnlyList <IRSessionDataObject> > GetChildrenAsyncInternal() { List <IRSessionDataObject> result = null; var valueEvaluation = DebugEvaluation as IRValueInfo; if (valueEvaluation == null) { Debug.Assert(false, $"{nameof(RSessionDataObject)} result type is not {nameof(IRValueInfo)}"); return(result); } if (valueEvaluation.HasChildren) { await TaskUtilities.SwitchToBackgroundThread(); const REvaluationResultProperties properties = ExpressionProperty | AccessorKindProperty | TypeNameProperty | ClassesProperty | LengthProperty | SlotCountProperty | AttributeCountProperty | DimProperty | FlagsProperty; var children = await valueEvaluation.DescribeChildrenAsync(properties, RValueRepresentations.Str(MaxReprLength), MaxChildrenCount); result = EvaluateChildren(children); } return(result); }
private async Task UpdateList() { if (_updating) { return; } try { _updating = true; // May be null in tests IRSession session = Workflow.RSession; if (session.IsHostRunning) { var stackFrames = await session.TracebackAsync(); var globalStackFrame = stackFrames.FirstOrDefault(s => s.IsGlobal); if (globalStackFrame != null) { const REvaluationResultProperties properties = ExpressionProperty | AccessorKindProperty | TypeNameProperty | ClassesProperty | LengthProperty | SlotCountProperty | AttributeCountProperty | DimProperty | FlagsProperty; var evaluation = await globalStackFrame.TryEvaluateAndDescribeAsync("base::environment()", "Global Environment", properties, RValueRepresentations.Str()); var e = new RSessionDataObject(evaluation, _coreShell.Services); // root level doesn't truncate children and return every variables _topLevelVariables.Clear(); var children = await e.GetChildrenAsync(); if (children != null) { foreach (var x in children) { _topLevelVariables[x.Name] = x; // TODO: BUGBUG: this doesn't address removed variables } } } } } catch (REvaluationException) { } finally { _updating = false; } }
private Task <IRValueInfo> EvaluateAndDescribeAsync(string expression, REvaluationResultProperties properties, CancellationToken cancellationToken = default(CancellationToken)) => _session.EvaluateAndDescribeAsync(expression, properties, RValueRepresentations.Str(), cancellationToken);
public async Task MultilinePromise() { const string code = @"f <- function(p, d) { force(d) browser() } x <- quote({{{}}}) eval(substitute(f(P, x), list(P = x)))"; var tracer = await _session.TraceExecutionAsync(); using (var sf = new SourceFile(code)) { await tracer.EnableBreakpointsAsync(true); await sf.Source(_session); await _session.NextPromptShouldBeBrowseAsync(); var stackFrames = (await _session.TracebackAsync()).ToArray(); stackFrames.Should().NotBeEmpty(); var children = (await stackFrames.Last().DescribeChildrenAsync(REvaluationResultProperties.None, RValueRepresentations.Deparse())); var d = children.Should().ContainSingle(er => er.Name == "d") .Which.Should().BeAssignableTo <IRValueInfo>() .Which; var p = children.Should().ContainSingle(er => er.Name == "p") .Which.Should().BeAssignableTo <IRPromiseInfo>() .Which.Code.Should().Be(d.Representation); } }