-
Notifications
You must be signed in to change notification settings - Fork 218
/
VisualBasicValue.cs
104 lines (91 loc) · 3.72 KB
/
VisualBasicValue.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// This file is part of Core WF which is licensed under the MIT license.
// See LICENSE file in the project root for full license information.
using System;
using System.Activities;
using System.Activities.ExpressionParser;
using System.Activities.Expressions;
using System.Activities.Internals;
using System.Activities.Runtime;
using System.Activities.Validation;
using System.Activities.XamlIntegration;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Windows.Markup;
using ActivityContext = System.Activities.ActivityContext;
namespace Microsoft.VisualBasic.Activities;
[DebuggerStepThrough]
public sealed class VisualBasicValue<TResult> : TextExpressionBase<TResult>, IValueSerializableExpression,
IExpressionContainer
{
private Func<ActivityContext, TResult> _compiledExpression;
private Expression<Func<ActivityContext, TResult>> _expressionTree;
private CompiledExpressionInvoker _invoker;
public VisualBasicValue() => UseOldFastPath = true;
public VisualBasicValue(string expressionText) : this() => ExpressionText = expressionText;
public override string ExpressionText { get; set; }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override string Language => VisualBasicHelper.Language;
public override Expression GetExpressionTree()
{
if (!IsMetadataCached)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.ActivityIsUncached));
}
if (_expressionTree == null)
{
if (_invoker != null)
{
return _invoker.GetExpressionTree();
}
// it's safe to create this CodeActivityMetadata here,
// because we know we are using it only as lookup purpose.
var metadata = new CodeActivityMetadata(this, GetParentEnvironment(), false);
var publicAccessor = CodeActivityPublicEnvironmentAccessor.CreateWithoutArgument(metadata);
try
{
_expressionTree = VisualBasicHelper.Compile<TResult>(ExpressionText, publicAccessor, false);
}
catch (SourceExpressionException e)
{
throw FxTrace.Exception.AsError(
new InvalidOperationException(SR.ExpressionTamperedSinceLastCompiled(e.Message)));
}
finally
{
metadata.Dispose();
}
}
Fx.Assert(_expressionTree.NodeType == ExpressionType.Lambda, "Lambda expression required");
return ExpressionUtilities.RewriteNonCompiledExpressionTree(_expressionTree);
}
public bool CanConvertToString(IValueSerializerContext context) => true;
public string ConvertToString(IValueSerializerContext context) => "[" + ExpressionText + "]";
protected override TResult Execute(CodeActivityContext context)
{
if (_expressionTree == null)
{
return (TResult)_invoker.InvokeExpression(context);
}
_compiledExpression ??= _expressionTree.Compile();
return _compiledExpression(context);
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
_expressionTree = null;
_invoker = new CompiledExpressionInvoker(this, false, metadata);
if (QueueForValidation<TResult>(metadata, false))
{
return;
}
try
{
var publicAccessor = CodeActivityPublicEnvironmentAccessor.Create(metadata);
_expressionTree = VisualBasicHelper.Compile<TResult>(ExpressionText, publicAccessor, false);
}
catch (SourceExpressionException e)
{
metadata.AddValidationError(e.Message);
}
}
}