alielie
2026-09-10 9ec80cafc23f5ee3278cacce3c9f86f4087b435a
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
using AddInEnums;
using DynamicExpresso;
using OpenTap;
using OpenTap.Addin;
using OpenTap.Addin.Util;
using System;
 
namespace AddInPlugin.Util
{
    public class DefaultVariableResolverFactory : IVariableResolverCreator
    {
        public IVariableResolver CreateResolver()
        {
            return new DefaultVariableResolver();
        }
    }
 
    public class DefaultVariableResolver : IVariableResolver
    {
        public event EventHandler<string> DataChanged;
 
        public static Interpreter GetInterpreter(TestPlanRun run, ITestStep step)
        {
            var target = new Interpreter();
            target.SetVariable("this", MethodUtil.Instance);
            target.SetVariable("Enums", Enums.Instance);
            target.SetVariable(ConstNames.LocalsName, run?.LocalsRuntime);
            target.SetVariable(ConstNames.ParametersName, run?.ParametersRuntime);
            target.SetVariable(ConstNames.FileGlobalsName, run?.FileGlobalsRuntime);
            target.SetVariable(ConstNames.StationGlobalsName, run?.StationGlobalsRuntime);
            target.SetVariable(ConstNames.ThisContextName, run);
            target.SetVariable("Step", step);
            target.SetVariable("RunState", step?.StepRun);
 
            target.SetVariable("True", true);
            target.SetVariable("TRUE", true);
            target.SetVariable("False", false);
            target.SetVariable("FALSE", false);
 
            target.SetFunction("Val", MethodUtil.GetValImpl());
 
 
            var context = step?.GetParent<ContextStep>();
            if (context != null)
            {
                target.SetVariable("Context", context.GetContextVariables());
            }
            return target;
        }
 
        public dynamic Resolve(TestPlanRun run, ITestStep step, string expr)
        {
            return Resolve(run, step, expr, typeof(void));
        }
 
        public T Resolve<T>(TestPlanRun run, ITestStep step, string expr)
        {
            return Resolve(run, step, expr, typeof(T));
        }
 
        public dynamic Resolve(TestPlanRun run, ITestStep step, string expr, Type targetType)
        {
            if (string.IsNullOrEmpty(expr)) return null;
            var target = GetInterpreter(run, step);
            object obj = target.Eval(expr);
            if (obj is NullVariable || obj == null)
            {
                return null;
            }
            if (targetType == typeof(string))
            {
                return obj.ToString();
            }
 
            var result = obj;
            if (obj is RuntimeVariable rv)
            {
                if (targetType == typeof(RuntimeVariable))
                {
                    return rv;
                }
                result = rv.__data___;
            }
 
            //if (targetType != typeof(void) && !targetType.IsAssignableFrom(result.GetType()))
            //{
            //    throw new ArgumentException($"{result.GetType()} can't convert to {targetType}");
            //}
            return result;
        }
 
        public void Update(TestPlanRun run, ITestStep step, string expr)
        {
            var target = GetInterpreter(run, step);
            string[] arr = ExpressUtil.SplitIgnoringQuotes(expr);
            {
                foreach (var data in arr)
                {
                    target.Eval(data);
                }
            }
            DataChanged?.Invoke(this, expr);
        }
 
        public void Update(TestPlanRun run, ITestStep step, string name, object value)
        {
            if (string.Equals(name, "true", StringComparison.OrdinalIgnoreCase)
                || string.Equals(name, "false", StringComparison.OrdinalIgnoreCase)
                || name.StartsWith("\"")
                || name.EndsWith("\"")
                || name.StartsWith("'")
                || name.EndsWith("'")
                || double.TryParse(name, out _))
            {
                /// 基础数据直接返回
                return;
            }
 
            var target = GetInterpreter(run, step);
            var expr = $"{name} = __temp";
            target.Eval(expr, new Parameter("__temp", value));
            DataChanged?.Invoke(this, name);
        }
    }
}