1
2
3
4
5
6 package dev.metaschema.core.metapath.cst;
7
8 import java.util.List;
9
10 import dev.metaschema.core.metapath.DynamicContext;
11 import dev.metaschema.core.metapath.IExpression;
12 import dev.metaschema.core.metapath.item.ISequence;
13 import dev.metaschema.core.qname.IEnhancedQName;
14 import dev.metaschema.core.util.ObjectUtils;
15 import edu.umd.cs.findbugs.annotations.NonNull;
16
17
18
19
20
21
22 public class Let
23 extends AbstractExpression {
24 @NonNull
25 private final VariableDeclaration variable;
26 @NonNull
27 private final IExpression returnExpression;
28
29
30
31
32
33
34
35
36
37
38
39
40
41 public Let(
42 @NonNull String text,
43 @NonNull IEnhancedQName name,
44 @NonNull IExpression boundExpression,
45 @NonNull IExpression returnExpression) {
46 super(text);
47 this.variable = new VariableDeclaration(name, boundExpression);
48 this.returnExpression = returnExpression;
49 }
50
51
52
53
54
55
56 @NonNull
57 public VariableDeclaration getVariable() {
58 return variable;
59 }
60
61
62
63
64
65
66 @NonNull
67 public IExpression getReturnExpression() {
68 return returnExpression;
69 }
70
71 @Override
72 public List<? extends IExpression> getChildren() {
73 return ObjectUtils.notNull(
74 List.of(returnExpression));
75 }
76
77 @Override
78 public <RESULT, CONTEXT> RESULT accept(IExpressionVisitor<RESULT, CONTEXT> visitor, CONTEXT context) {
79 return visitor.visitLet(this, context);
80 }
81
82 @Override
83 protected ISequence<?> evaluate(DynamicContext dynamicContext, ISequence<?> focus) {
84 DynamicContext subDynamicContext = dynamicContext.subContext();
85
86 getVariable().bind(dynamicContext, focus, subDynamicContext);
87
88 return getReturnExpression().accept(subDynamicContext, focus);
89 }
90
91
92
93
94 public static class VariableDeclaration {
95 @NonNull
96 private final IEnhancedQName name;
97 @NonNull
98 private final IExpression boundExpression;
99
100
101
102
103
104
105
106
107
108
109 public VariableDeclaration(@NonNull IEnhancedQName name, @NonNull IExpression boundExpression) {
110 this.name = name;
111 this.boundExpression = boundExpression;
112 }
113
114
115
116
117
118
119 @NonNull
120 public IEnhancedQName getName() {
121 return name;
122 }
123
124
125
126
127
128
129 @NonNull
130 public IExpression getBoundExpression() {
131 return boundExpression;
132 }
133
134
135
136
137
138
139
140
141
142
143
144 public void bind(
145 @NonNull DynamicContext evaluationDynamicContext,
146 @NonNull ISequence<?> focus,
147 @NonNull DynamicContext boundDynamicContext) {
148
149 ISequence<?> result = getBoundExpression().accept(evaluationDynamicContext, focus)
150
151 .reusable();
152 boundDynamicContext.bindVariableValue(getName(), result);
153 }
154 }
155 }