/// <summary> /// Evaluates an R expresion in the specified environment, and returns an object describing the result. /// </summary> /// <param name="environmentExpression"> /// R expression designating the environment in which <paramref name="expression"/> will be evaluated. /// </param> /// <param name="expression">Expression to evaluate.</param> /// <param name="name"><see cref="IREvaluationResultInfo.Name"/> of the returned evaluation result.</param> /// <param name="properties">Specifies which <see cref="IREvaluationResultInfo"/> properties should be present in the result.</param> /// <param name="repr"> /// An R expression that must evaluate to a function that takes an R value as its sole argument, and returns the /// string representation of that argument as a single-element character vector. The representation is stored in /// <see cref="IRValueInfo.Representation"/> property of the produced result. If this argument is /// <see langword="null"/>, no representation is computed, and <see cref="IRValueInfo.Representation"/> /// will also be <see langword="null"/>. /// Use helper properties and methods in <see cref="RValueRepresentations"/> to obtain an appropriate expression /// for standard R functions such as <c>deparse()</c> or <c>str()</c>. /// </param> /// <remarks> /// <returns> /// If evaluation succeeded, an instance of <see cref="IRValueInfo"/> describing the resulting value. /// If evaluation failed with an error, an instance of <see cref="IRErrorInfo"/> describing the error. /// This method never returns <see cref="IRActiveBindingInfo"/> or <see cref="IRPromiseInfo"/>. /// </returns> public static async Task <IREvaluationResultInfo> TryEvaluateAndDescribeAsync( this IRExpressionEvaluator session, string environmentExpression, string expression, string name, REvaluationResultProperties properties, string repr, CancellationToken cancellationToken = default(CancellationToken) ) { if (environmentExpression == null) { throw new ArgumentNullException(nameof(environmentExpression)); } if (expression == null) { throw new ArgumentNullException(nameof(expression)); } await TaskUtilities.SwitchToBackgroundThread(); environmentExpression = environmentExpression ?? "NULL"; var code = Invariant($"rtvs:::eval_and_describe({expression.ToRStringLiteral()}, ({environmentExpression}),, {properties.ToRVector()},, {repr})"); var result = await session.EvaluateAsync <JObject>(code, REvaluationKind.Normal, cancellationToken); return(REvaluationResultInfo.Parse(session, environmentExpression, name, result)); }
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); }
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) { REvaluationResultProperties properties = ExpressionProperty | AccessorKindProperty | TypeNameProperty | ClassesProperty | LengthProperty | SlotCountProperty | AttributeCountProperty | DimProperty | FlagsProperty | (RToolsSettings.Current.EvaluateActiveBindings ? ComputedValueProperty : 0); var children = await valueEvaluation.DescribeChildrenAsync(properties, RValueRepresentations.Str(MaxReprLength), MaxChildrenCount); return(EvaluateChildren(children)); } } catch (REvaluationException) { } return(null); }
/// <summary> /// Like <see cref="TryEvaluateAndDescribeAsync(IRSession, string, REvaluationResultProperties, string, CancellationToken)"/>, /// but throws <see cref="RException"/> if result is an <see cref="IRErrorInfo"/>. /// </summary> public static Task<IRValueInfo> EvaluateAndDescribeAsync( this IRSession session, string expression, REvaluationResultProperties properties, string repr, CancellationToken cancellationToken = default(CancellationToken) ) => session.EvaluateAndDescribeAsync(REnvironments.GlobalEnv, expression, null, properties, repr, cancellationToken);
/// <summary> /// Like <see cref="RSessionExtensions.DescribeChildrenAsync"/>, but returns children of the object described /// by the provided evaluation info. /// </summary> public static Task <IReadOnlyList <IREvaluationResultInfo> > DescribeChildrenAsync( this IREvaluationResultInfo info, REvaluationResultProperties properties, string repr, int?maxCount = null, CancellationToken cancellationToken = default(CancellationToken) ) => info.Evaluator.DescribeChildrenAsync(info.EnvironmentExpression, info.Expression, properties, repr, maxCount, cancellationToken);
/// <summary> /// Like <see cref="RSessionExtensions.DescribeChildrenAsync"/>, but returns children of the object described /// by the provided evaluation info. /// </summary> public static Task<IReadOnlyList<IREvaluationResultInfo>> DescribeChildrenAsync( this IREvaluationResultInfo info, REvaluationResultProperties properties, string repr, int? maxCount = null, CancellationToken cancellationToken = default(CancellationToken) ) => info.Session.DescribeChildrenAsync(info.EnvironmentExpression, info.Expression, properties, repr, maxCount, cancellationToken);
/// <summary> /// Like <see cref="RSessionExtensions.DescribeChildrenAsync"/>, but returns children of this environment. /// </summary> /// <remarks> /// If this method is called on a stale frame (i.e if call stack has changed since the <see cref="RSessionExtensions.TracebackAsync"/> /// call that produced this frame), the result is undefined - the method can throw <see cref="RException"/>, or produce meaningless /// output. /// </remarks> public static Task <IReadOnlyList <IREvaluationResultInfo> > DescribeChildrenAsync( this IRStackFrame frame, REvaluationResultProperties properties, string repr, int?maxCount = null, CancellationToken cancellationToken = default(CancellationToken) ) => frame.Session.DescribeChildrenAsync(frame.EnvironmentExpression, "base::environment()", properties, repr, maxCount, cancellationToken);
/// <summary> /// Like <see cref="TryEvaluateAndDescribeAsync(IRSession, string, REvaluationResultProperties, string, CancellationToken)"/>, /// but throws <see cref="RException"/> if result is an <see cref="IRErrorInfo"/>. /// </summary> public static Task <IRValueInfo> EvaluateAndDescribeAsync( this IRExpressionEvaluator session, string expression, REvaluationResultProperties properties, string repr, CancellationToken cancellationToken = default(CancellationToken) ) => session.EvaluateAndDescribeAsync(REnvironments.GlobalEnv, expression, null, properties, repr, cancellationToken);
/// <summary> /// Same as <see cref="EvaluateAndDescribeAsync(IRStackFrame, string, string, REvaluationResultProperties, string, CancellationToken)"/>, /// but uses <see langword="null"/> for <c>name</c>. /// </summary> public static Task <IRValueInfo> EvaluateAndDescribeAsync( this IRStackFrame frame, string expression, REvaluationResultProperties properties, string repr, CancellationToken cancellationToken = default(CancellationToken) ) => frame.EvaluateAndDescribeAsync(expression, null, properties, repr, cancellationToken);
private async Task <IRValueInfo> EvaluateAndDescribeAsync(REnvironment env) { await TaskUtilities.SwitchToBackgroundThread(); const REvaluationResultProperties properties = ClassesProperty | ExpressionProperty | TypeNameProperty | DimProperty | LengthProperty; return(await _session.EvaluateAndDescribeAsync(env.EnvironmentExpression, properties, null)); }
/// <summary> /// Produces an object describing this frame's environment. <see cref="REvaluationResultInfoExtensions.DescribeChildrenAsync"/> /// method can then be used to retrieve the variables in the frame. /// </summary> /// <param name="properties"> /// Which properties of the returned object should be provided. Note that it should include at least the following flags /// argument value in order for <see cref="REvaluationResultInfoExtensions.DescribeChildrenAsync"/> to be working. /// </param> /// <remarks> /// <para> /// There is no guarantee that the returned evaluation result is <see cref="IRValueInfo"/>. Retrieving the frame environment involves /// evaluating <see cref="EnvironmentExpression"/>, and like any evaluation, it can fail. Caller should check for <see cref="IRErrorInfo"/> /// and handle it accordingly. However, it is never <see cref="IRPromiseInfo"/> or <see cref="IRActiveBindingInfo"/>. /// </para> /// <para> /// If this method is called on a stale frame (i.e if call stack has changed since the <see cref="RSessionExtensions.TracebackAsync"/> /// call that produced this frame), the result is undefined, and can be an error result, or contain unrelated data. /// </para> /// </remarks> public static Task <IRValueInfo> DescribeEnvironmentAsync( this IRStackFrame frame, REvaluationResultProperties properties, CancellationToken cancellationToken = default(CancellationToken) ) { properties |= ExpressionProperty | LengthProperty | AttributeCountProperty | FlagsProperty; return(frame.EvaluateAndDescribeAsync("base::environment()", properties, null, cancellationToken)); }
/// <summary> /// Same as <see cref="Microsoft.R.DataInspection.RSessionExtensions.TryEvaluateAndDescribeAsync(string, string, string, REvaluationResultProperties, int?, CancellationToken)"/>, /// but passes <see cref="EnvironmentExpression"/> of this frame as <c>environmentExpression</c> argument, /// </summary> public static Task <IREvaluationResultInfo> TryEvaluateAndDescribeAsync( this IRStackFrame frame, string expression, string name, REvaluationResultProperties properties, string repr, CancellationToken cancellationToken = default(CancellationToken) ) => frame.Session.TryEvaluateAndDescribeAsync(frame.EnvironmentExpression, expression, name, properties, repr, cancellationToken);
protected async Task<IRValueInfo> EvaluateAsync(string expression, REvaluationResultProperties fields, string repr, CancellationToken cancellationToken) { var result = await Evaluator.EvaluateAsync(expression, fields, repr, cancellationToken); var error = result as IRErrorInfo; if (error != null) { await VsAppShell.Current.SwitchToMainThreadAsync(cancellationToken); VsAppShell.Current.ShowErrorMessage(error.ErrorText); return null; } return result as IRValueInfo; }
protected async Task <IRValueInfo> EvaluateAsync(string expression, REvaluationResultProperties fields, string repr, CancellationToken cancellationToken) { var result = await Evaluator.EvaluateAsync(expression, fields, repr, cancellationToken); if (result is IRErrorInfo error) { await Services.MainThread().SwitchToAsync(cancellationToken); Services.UI().ShowErrorMessage(error.ErrorText); return(null); } return(result as IRValueInfo); }
private async Task UpdateList() { if (_updating) { return; } try { _updating = true; // May be null in tests var sessionProvider = EditorShell.Current.ExportProvider.GetExportedValueOrDefault <IRSessionProvider>(); var session = sessionProvider.GetOrCreate(GuidList.InteractiveWindowRSessionGuid); 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); // 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 } } } } } finally { _updating = false; } }
private async Task UpdateList() { if (_updating) { return; } try { _updating = true; // May be null in tests 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 settings = _services.GetService <IRSettings>(); var e = new RSessionDataObject(evaluation, settings.EvaluateActiveBindings); // 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; } }
public async Task<IREvaluationResultInfo> EvaluateAsync(string expression, REvaluationResultProperties fields, string repr, CancellationToken cancellationToken = default(CancellationToken)) { 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 = _workflow.RSession; var frames = await rSession.TracebackAsync(cancellationToken:cancellationToken); if (frames == null || frames.Count == 0) { throw new InvalidOperationException("Debugger frames stack is empty"); } return await frames.Last().TryEvaluateAndDescribeAsync(expression, fields, repr, cancellationToken) as IRValueInfo; }
private async Task EvaluateAsync() { try { await TaskUtilities.SwitchToBackgroundThread(); const REvaluationResultProperties properties = ClassesProperty | ExpressionProperty | TypeNameProperty | DimProperty | LengthProperty; var result = await _rSession.TryEvaluateAndDescribeAsync(_evaluation.Expression, properties, null); var wrapper = new VariableViewModel(result, _services); _services.MainThread().Post(() => SetEvaluation(wrapper)); } catch (Exception ex) { _services.MainThread().Post(() => SetError(ex.Message)); } }
protected async Task <IRValueInfo> EvaluateAsync(string expression, REvaluationResultProperties fields, string repr) { var result = await Evaluator.EvaluateAsync(expression, fields, repr); var error = result as IRErrorInfo; if (error != null) { await VsAppShell.Current.SwitchToMainThreadAsync(); VsAppShell.Current.ShowErrorMessage(error.ErrorText); return(null); } return(result as IRValueInfo); }
private async Task EvaluateAsync() { try { await TaskUtilities.SwitchToBackgroundThread(); const REvaluationResultProperties properties = ClassesProperty | ExpressionProperty | TypeNameProperty | DimProperty | LengthProperty; var result = await _rSession.TryEvaluateAndDescribeAsync(_evaluation.Expression, properties, null); var wrapper = new VariableViewModel(result, _aggregator); VsAppShell.Current.DispatchOnUIThread(() => SetEvaluation(wrapper)); } catch (Exception ex) { VsAppShell.Current.DispatchOnUIThread(() => SetError(ex.Message)); } }
protected override async Task <IReadOnlyList <IRSessionDataObject> > GetChildrenAsyncInternal() { List <IRSessionDataObject> result = null; var valueEvaluation = DebugEvaluation as IRValueInfo; if (valueEvaluation == null) { Debug.Assert(false, $"{nameof(VariableViewModel)} result type is not {typeof(IRValueInfo)}"); return(result); } if (valueEvaluation.HasChildren) { await TaskUtilities.SwitchToBackgroundThread(); REvaluationResultProperties properties = ExpressionProperty | AccessorKindProperty | TypeNameProperty | ClassesProperty | LengthProperty | SlotCountProperty | AttributeCountProperty | DimProperty | FlagsProperty | CanCoerceToDataFrameProperty | (Services.GetService <IRToolsSettings>().EvaluateActiveBindings ? ComputedValueProperty : 0); IReadOnlyList <IREvaluationResultInfo> children = await valueEvaluation.DescribeChildrenAsync(properties, Repr, MaxChildrenCount); result = new List <IRSessionDataObject>(); var aggregator = VsAppShell.Current.GetService <IObjectDetailsViewerAggregator>(); for (int i = 0; i < children.Count; i++) { result.Add(new VariableViewModel(children[i], Services, i, GetMaxChildrenCount(children[i]))); } // return children can be less than value's length in some cases e.g. missing parameter if (valueEvaluation.Length > result.Count && (valueEvaluation.Length > MaxChildrenCount)) { result.Add(VariableViewModel.Ellipsis); // insert dummy child to indicate truncation in UI } } return(result); }
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); }
private async Task SetRootModelAsync(REnvironment env) { await TaskUtilities.SwitchToBackgroundThread(); const REvaluationResultProperties properties = ClassesProperty | ExpressionProperty | TypeNameProperty | DimProperty | LengthProperty; IRValueInfo result; try { result = await _session.EvaluateAndDescribeAsync(env.EnvironmentExpression, properties, null); } catch (RException ex) { VsAppShell.Current.DispatchOnUIThread(() => SetRootNode(VariableViewModel.Error(ex.Message))); return; } var wrapper = new VariableViewModel(result, _aggregator); var rootNodeModel = new VariableNode(_settings, wrapper); VsAppShell.Current.DispatchOnUIThread(() => _rootNode.Model = rootNodeModel); }
private IReadOnlyList <IREvaluationResultInfo> CreateChildren() => TaskExtensions.RunSynchronouslyOnUIThread(async ct => { var valueResult = EvaluationResult as IRValueInfo; if (valueResult == null) { return(new IREvaluationResultInfo[0]); } REvaluationResultProperties properties = RToolsSettings.Current.EvaluateActiveBindings ? REvaluationResultProperties.ComputedValueProperty : 0; properties |= PrefetchedProperties; var children = await valueResult.DescribeChildrenAsync(properties, Repr, ChildrenMaxCount, ct); // Children of environments do not have any meaningful order, so sort them by name. if (valueResult.TypeName == "environment") { children = children.OrderBy(er => er.Name).ToArray(); } return(children); });
/// <summary> /// Like <see cref="TryEvaluateAndDescribeAsync(IRSession, string, string, string, REvaluationResultProperties, string, CancellationToken)"/>, /// but throws <see cref="RException"/> if result is an <see cref="IRErrorInfo"/>. /// </summary> public static async Task <IRValueInfo> EvaluateAndDescribeAsync( this IRExpressionEvaluator session, string environmentExpression, string expression, string name, REvaluationResultProperties properties, string repr, CancellationToken cancellationToken = default(CancellationToken) ) { var info = await session.TryEvaluateAndDescribeAsync(environmentExpression, expression, name, properties, repr, cancellationToken); var error = info as IRErrorInfo; if (error != null) { throw new RException(error.ErrorText); } Debug.Assert(info is IRValueInfo); return((IRValueInfo)info); }
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(); } }
/// <summary> /// Computes the children of the object represented by the given expression, and returns a collection of /// evaluation objects describing each child. /// See <see cref="RSessionExtensions.TryEvaluateAndDescribeAsync"/> for the meaning of other parameters. /// </summary> /// <param name="evaluateActiveBindings">Passes a flag to R to evalaute bindings based on RTools Settings.</param> /// <param name="maxCount">If not <see langword="null"/>, return at most that many children.</param> /// <remarks> /// <para> /// The resulting collection has an item for every child. If the child could be retrieved, and represents /// a value, the corresponding item is an <see cref="IRValueInfo"/> instance. If the child represents /// a promise, the promise is not forced, and the item is an <see cref="IRPromiseInfo"/> instance. If the /// child represents an active binding, the binding may be evaluated to retrieve the value, and the item is /// an <see cref="IRActiveBindingInfo"/> instance. If the child could not be retrieved, the item is an /// <see cref="IRErrorInfo"/> instance describing the error that prevented its retrieval. /// </para> /// <para> /// Where order matters (e.g. for children of atomic vectors and lists), children are returned in that order. /// Otherwise, the order is undefined. If an object has both ordered and unordered children (e.g. it is a vector /// with slots), then it is guaranteed that each group is reported as a contiguous sequence within the returned /// collection, and order is honored within each group; but groups themselves are not ordered relative to each other. /// </para> /// </remarks> /// <exception cref="RException"> /// Raised if the operation fails as a whole (note that if only specific children cannot be retrieved, those /// children are represented by <see cref="IRErrorInfo"/> instances in the returned collection instead). /// </exception> public static async Task <IReadOnlyList <IREvaluationResultInfo> > DescribeChildrenAsync( this IRExpressionEvaluator session, string environmentExpression, string expression, REvaluationResultProperties properties, string repr, int?maxCount = null, CancellationToken cancellationToken = default(CancellationToken) ) { await TaskUtilities.SwitchToBackgroundThread(); var call = Invariant($"rtvs:::describe_children({expression.ToRStringLiteral()}, {environmentExpression}, {properties.ToRVector()}, {maxCount}, {repr})"); var jChildren = await session.EvaluateAsync <JArray>(call, REvaluationKind.Normal, cancellationToken); Trace.Assert( jChildren.Children().All(t => t is JObject), Invariant($"rtvs:::describe_children(): object of objects expected.\n\n{jChildren}")); var children = new List <REvaluationResultInfo>(); foreach (var child in jChildren) { var childObject = (JObject)child; Trace.Assert( childObject.Count == 1, Invariant($"rtvs:::describe_children(): each object is expected contain one object\n\n")); foreach (var kv in childObject) { var name = kv.Key; var jEvalResult = (JObject)kv.Value; var evalResult = REvaluationResultInfo.Parse(session, environmentExpression, name, jEvalResult); children.Add(evalResult); } } return(children); }
/// <summary> /// Evaluates an R expresion in the specified environment, and returns an object describing the result. /// </summary> /// <param name="environmentExpression"> /// R expression designating the environment in which <paramref name="expression"/> will be evaluated. /// </param> /// <param name="expression">Expression to evaluate.</param> /// <param name="name"><see cref="IREvaluationResultInfo.Name"/> of the returned evaluation result.</param> /// <param name="properties">Specifies which <see cref="IREvaluationResultInfo"/> properties should be present in the result.</param> /// <param name="repr"> /// An R expression that must evaluate to a function that takes an R value as its sole argument, and returns the /// string representation of that argument as a single-element character vector. The representation is stored in /// <see cref="IRValueInfo.Representation"/> property of the produced result. If this argument is /// <see langword="null"/>, no representation is computed, and <see cref="IRValueInfo.Representation"/> /// will also be <see langword="null"/>. /// Use helper properties and methods in <see cref="RValueRepresentations"/> to obtain an appropriate expression /// for standard R functions such as <c>deparse()</c> or <c>str()</c>. /// </param> /// <remarks> /// <returns> /// If evaluation succeeded, an instance of <see cref="IRValueInfo"/> describing the resulting value. /// If evaluation failed with an error, an instance of <see cref="IRErrorInfo"/> describing the error. /// This method never returns <see cref="IRActiveBindingInfo"/> or <see cref="IRPromiseInfo"/>. /// </returns> public static async Task<IREvaluationResultInfo> TryEvaluateAndDescribeAsync( this IRSession session, string environmentExpression, string expression, string name, REvaluationResultProperties properties, string repr, CancellationToken cancellationToken = default(CancellationToken) ) { if (environmentExpression == null) { throw new ArgumentNullException(nameof(environmentExpression)); } if (expression == null) { throw new ArgumentNullException(nameof(expression)); } await TaskUtilities.SwitchToBackgroundThread(); environmentExpression = environmentExpression ?? "NULL"; var code = Invariant($"rtvs:::eval_and_describe({expression.ToRStringLiteral()}, ({environmentExpression}),, {properties.ToRVector()},, {repr})"); var result = await session.EvaluateAsync<JObject>(code, REvaluationKind.Normal, cancellationToken); return REvaluationResultInfo.Parse(session, environmentExpression, name, result); }
/// <summary> /// Like <see cref="TryEvaluateAndDescribeAsync(IRSession, string, string, string, REvaluationResultProperties, string, CancellationToken)"/>, /// but throws <see cref="RException"/> if result is an <see cref="IRErrorInfo"/>. /// </summary> public static async Task<IRValueInfo> EvaluateAndDescribeAsync( this IRSession session, string environmentExpression, string expression, string name, REvaluationResultProperties properties, string repr, CancellationToken cancellationToken = default(CancellationToken) ) { var info = await session.TryEvaluateAndDescribeAsync(environmentExpression, expression, name, properties, repr, cancellationToken); var error = info as IRErrorInfo; if (error != null) { throw new RException(error.ErrorText); } Debug.Assert(info is IRValueInfo); return (IRValueInfo)info; }
private Task <IRValueInfo> EvaluateAndDescribeAsync(string expression, REvaluationResultProperties properties, CancellationToken cancellationToken = default(CancellationToken)) => _session.EvaluateAndDescribeAsync(expression, properties, RValueRepresentations.Str(), cancellationToken);
/// <summary> /// Produces an object describing this frame's environment. <see cref="REvaluationResultInfoExtensions.DescribeChildrenAsync"/> /// method can then be used to retrieve the variables in the frame. /// </summary> /// <param name="properties"> /// Which properties of the returned object should be provided. Note that it should include at least the following flags /// argument value in order for <see cref="REvaluationResultInfoExtensions.DescribeChildrenAsync"/> to be working. /// </param> /// <remarks> /// <para> /// There is no guarantee that the returned evaluation result is <see cref="IRValueInfo"/>. Retrieving the frame environment involves /// evaluating <see cref="EnvironmentExpression"/>, and like any evaluation, it can fail. Caller should check for <see cref="IRErrorInfo"/> /// and handle it accordingly. However, it is never <see cref="IRPromiseInfo"/> or <see cref="IRActiveBindingInfo"/>. /// </para> /// <para> /// If this method is called on a stale frame (i.e if call stack has changed since the <see cref="RSessionExtensions.TracebackAsync"/> /// call that produced this frame), the result is undefined, and can be an error result, or contain unrelated data. /// </para> /// </remarks> public static Task<IRValueInfo> DescribeEnvironmentAsync( this IRStackFrame frame, REvaluationResultProperties properties, CancellationToken cancellationToken = default(CancellationToken) ) { properties |= ExpressionProperty | LengthProperty | AttributeCountProperty | FlagsProperty; return frame.EvaluateAndDescribeAsync("base::environment()", properties, null, cancellationToken); }
/// <summary> /// Same as <see cref="Microsoft.R.DataInspection.RSessionExtensions.TryEvaluateAndDescribeAsync(string, string, string, REvaluationResultProperties, int?, CancellationToken)"/>, /// but passes <see cref="EnvironmentExpression"/> of this frame as <c>environmentExpression</c> argument, /// </summary> public static Task<IREvaluationResultInfo> TryEvaluateAndDescribeAsync( this IRStackFrame frame, string expression, string name, REvaluationResultProperties properties, string repr, CancellationToken cancellationToken = default(CancellationToken) ) => frame.Session.TryEvaluateAndDescribeAsync(frame.EnvironmentExpression, expression, name, properties, repr, cancellationToken);
/// <summary> /// Same as <see cref="EvaluateAndDescribeAsync(IRStackFrame, string, string, REvaluationResultProperties, string, CancellationToken)"/>, /// but uses <see langword="null"/> for <c>name</c>. /// </summary> public static Task<IRValueInfo> EvaluateAndDescribeAsync( this IRStackFrame frame, string expression, REvaluationResultProperties properties, string repr, CancellationToken cancellationToken = default(CancellationToken) ) => frame.EvaluateAndDescribeAsync(expression, null, properties, repr, cancellationToken);
/// <summary> /// Like <see cref="RSessionExtensions.DescribeChildrenAsync"/>, but returns children of this environment. /// </summary> /// <remarks> /// If this method is called on a stale frame (i.e if call stack has changed since the <see cref="RSessionExtensions.TracebackAsync"/> /// call that produced this frame), the result is undefined - the method can throw <see cref="RException"/>, or produce meaningless /// output. /// </remarks> public static Task<IReadOnlyList<IREvaluationResultInfo>> DescribeChildrenAsync( this IRStackFrame frame, REvaluationResultProperties properties, string repr, int? maxCount = null, CancellationToken cancellationToken = default(CancellationToken) ) => frame.Session.DescribeChildrenAsync(frame.EnvironmentExpression, "base::environment()", properties, repr, maxCount, cancellationToken);
/// <summary> /// Computes the children of the object represented by the given expression, and returns a collection of /// evaluation objects describing each child. /// See <see cref="RSessionExtensions.TryEvaluateAndDescribeAsync"/> for the meaning of other parameters. /// </summary> /// <param name="evaluateActiveBindings">Passes a flag to R to evalaute bindings based on RTools Settings.</param> /// <param name="maxCount">If not <see langword="null"/>, return at most that many children.</param> /// <remarks> /// <para> /// The resulting collection has an item for every child. If the child could be retrieved, and represents /// a value, the corresponding item is an <see cref="IRValueInfo"/> instance. If the child represents /// a promise, the promise is not forced, and the item is an <see cref="IRPromiseInfo"/> instance. If the /// child represents an active binding, the binding may be evaluated to retrieve the value, and the item is /// an <see cref="IRActiveBindingInfo"/> instance. If the child could not be retrieved, the item is an /// <see cref="IRErrorInfo"/> instance describing the error that prevented its retrieval. /// </para> /// <para> /// Where order matters (e.g. for children of atomic vectors and lists), children are returned in that order. /// Otherwise, the order is undefined. If an object has both ordered and unordered children (e.g. it is a vector /// with slots), then it is guaranteed that each group is reported as a contiguous sequence within the returned /// collection, and order is honored within each group; but groups themselves are not ordered relative to each other. /// </para> /// </remarks> /// <exception cref="RException"> /// Raised if the operation fails as a whole (note that if only specific children cannot be retrieved, those /// children are represented by <see cref="IRErrorInfo"/> instances in the returned collection instead). /// </exception> public static async Task<IReadOnlyList<IREvaluationResultInfo>> DescribeChildrenAsync( this IRSession session, string environmentExpression, string expression, REvaluationResultProperties properties, string repr, int? maxCount = null, CancellationToken cancellationToken = default(CancellationToken) ) { await TaskUtilities.SwitchToBackgroundThread(); var call = Invariant($"rtvs:::describe_children({expression.ToRStringLiteral()}, {environmentExpression}, {properties.ToRVector()}, {maxCount}, {repr})"); var jChildren = await session.EvaluateAsync<JArray>(call, REvaluationKind.Normal, cancellationToken); Trace.Assert( jChildren.Children().All(t => t is JObject), Invariant($"rtvs:::describe_children(): object of objects expected.\n\n{jChildren}")); var children = new List<REvaluationResultInfo>(); foreach (var child in jChildren) { var childObject = (JObject)child; Trace.Assert( childObject.Count == 1, Invariant($"rtvs:::describe_children(): each object is expected contain one object\n\n")); foreach (var kv in childObject) { var name = kv.Key; var jEvalResult = (JObject)kv.Value; var evalResult = REvaluationResultInfo.Parse(session, environmentExpression, name, jEvalResult); children.Add(evalResult); } } return children; }
public static string ToRVector(this REvaluationResultProperties properties) { var fieldNames = _mapping.Where(kv => properties.HasFlag(kv.Key)).Select(kv => "'" + kv.Value + "'"); return(Invariant($"base::c({string.Join(", ", fieldNames)})")); }
/// <summary> /// Re-evaluates the expression that was used to create this evaluation object in its original context, /// but with a new representation function and properties. /// </summary> /// <remarks> /// Evaluating an expression always produces a regular value, never a promise or an active binding. Thus, /// this method can be used to compute the current value of an <see cref="IRActiveBindingInfo"/>, or force /// an <see cref="IRPromiseInfo"/>. /// </remarks> /// <exception cref="RException">Evaluation of the expression produced an error.</exception> public static Task <IRValueInfo> GetValueAsync(this IREvaluationResultInfo info, REvaluationResultProperties properties, string repr, CancellationToken cancellationToken = default(CancellationToken)) => info.Evaluator.EvaluateAndDescribeAsync(info.EnvironmentExpression, info.Expression, info.Name, properties, repr, cancellationToken);
/// <summary> /// Re-evaluates the expression that was used to create this evaluation object in its original context, /// but with a new representation function and properties. /// </summary> /// <remarks> /// Evaluating an expression always produces a regular value, never a promise or an active binding. Thus, /// this method can be used to compute the current value of an <see cref="IRActiveBindingInfo"/>, or force /// an <see cref="IRPromiseInfo"/>. /// </remarks> /// <exception cref="RException">Evaluation of the expression produced an error.</exception> public static Task<IRValueInfo> GetValueAsync(this IREvaluationResultInfo info, REvaluationResultProperties properties, string repr, CancellationToken cancellationToken = default(CancellationToken)) => info.Session.EvaluateAndDescribeAsync(info.EnvironmentExpression, info.Expression, info.Name, properties, repr, cancellationToken);