1 /*
2  * Copyright 2006-2008 The FLWOR Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 #ifndef ZORBA_COMPILER_EXPR_BASE
18 #define ZORBA_COMPILER_EXPR_BASE
19 
20 #include <zorba/config.h>
21 
22 #include "common/shared_types.h"
23 
24 #include "compiler/parser/query_loc.h"
25 #include "compiler/parser/parse_constants.h"
26 #include "compiler/expression/expr_consts.h"
27 
28 #include "functions/function_consts.h"
29 
30 #include "types/typeimpl.h"
31 
32 #include "context/static_context_consts.h"
33 
34 
35 namespace zorba
36 {
37 
38 class static_context;
39 
40 class expr;
41 
42 class wrapper_expr;
43 
44 class expr_visitor;
45 
46 class CompilerCB;
47 
48 enum expr_kind_t
49 {
50   const_expr_kind,
51 
52   var_expr_kind,
53 
54   doc_expr_kind,
55   elem_expr_kind,
56   attr_expr_kind,
57   text_expr_kind,
58   pi_expr_kind,
59 
60   relpath_expr_kind,
61   axis_step_expr_kind,
62   match_expr_kind,
63 
64   flwor_expr_kind,
65   gflwor_expr_kind,
66   if_expr_kind,
67   trycatch_expr_kind,
68 
69   fo_expr_kind,
70   dynamic_function_invocation_expr_kind,
71   function_item_expr_kind,
72 
73   castable_expr_kind,
74   cast_expr_kind,
75   instanceof_expr_kind,
76   treat_expr_kind,
77   promote_expr_kind,
78   name_cast_expr_kind,
79 
80   validate_expr_kind,
81 
82   extension_expr_kind,
83 
84   order_expr_kind,
85 
86 #ifndef ZORBA_NO_FULL_TEXT
87   ft_expr_kind,
88 #endif /* ZORBA_NO_FULL_TEXT */
89 
90   delete_expr_kind,
91   insert_expr_kind,
92   rename_expr_kind,
93   replace_expr_kind,
94   transform_expr_kind,
95 
96   block_expr_kind,
97   var_decl_expr_kind,
98   var_set_expr_kind,
99   apply_expr_kind,
100   exit_expr_kind,
101   exit_catcher_expr_kind,
102   flowctl_expr_kind,
103   while_expr_kind,
104 
105   eval_expr_kind,
106   debugger_expr_kind,
107   wrapper_expr_kind,
108   function_trace_expr_kind,
109 
110 #ifdef ZORBA_WITH_JSON
111   json_direct_object_expr_kind,
112   json_object_expr_kind,
113   json_array_expr_kind,
114 #endif
115 
116   unknown_expr_kind
117 };
118 
119 
120 /*******************************************************************************
121   Base class for the expression tree node hierarchy
122 ********************************************************************************/
123 class expr
124 {
125   friend class expr_iterator_data;
126   friend class ExprIterator;
127   friend class forletwin_clause;
128   friend class for_clause;
129   friend class let_clause;
130   friend class where_clause;
131   friend class function_trace_expr;
132 
133 public:
134   typedef std::map<const expr *, expr*> substitution_t;
135 
136   typedef substitution_t::iterator subst_iter_t;
137 
138   typedef std::set<const var_expr *> FreeVars;
139 
140   typedef enum
141   {
142     PRODUCES_SORTED_NODES   = 0,
143     PRODUCES_DISTINCT_NODES = 2,
144     IGNORES_SORTED_NODES    = 4,
145     IGNORES_DUPLICATE_NODES = 6,
146     NON_DISCARDABLE         = 8,
147     UNFOLDABLE              = 10,
148     CONTAINS_RECURSIVE_CALL = 12,
149     PROPAGATES_INPUT_NODES  = 14,
150     IN_UNSAFE_CONTEXT       = 16,
151     MUST_COPY_NODES         = 18,
152     CONTAINS_PRAGMA         = 20
153   } Annotationkey;
154 
155   typedef enum
156   {
157     PRODUCES_SORTED_NODES_MASK    = 0x003,
158     PRODUCES_DISTINCT_NODES_MASK  = 0x00C,
159     IGNORES_SORTED_NODES_MASK     = 0x030,
160     IGNORES_DUPLICATE_NODES_MASK  = 0x0C0,
161     NON_DISCARDABLE_MASK          = 0x300,
162     UNFOLDABLE_MASK               = 0xC00,
163     CONTAINS_RECURSIVE_CALL_MASK  = 0x3000,
164     PROPAGATES_INPUT_NODES_MASK   = 0xC000,
165     IN_UNSAFE_CONTEXT_MASK        = 0x30000,
166     MUST_COPY_NODES_MASK          = 0xC0000,
167     CONTAINS_PRAGMA_MASK          = 0x300000
168   } AnnotationMask;
169 
170 
171 protected:
172   static expr*      iter_end_expr;
173   static expr*    * iter_done;
174 
175 protected:
176   static_context   * theSctx;
177 
178   QueryLoc           theLoc;
179 
180   unsigned short     theKind;
181   unsigned short     theScriptingKind;
182 
183   xqtref_t           theType;
184 
185   uint32_t           theFlags1;
186 
187   FreeVars           theFreeVars;
188 
189   CompilerCB  *const theCCB;
190 
191 public:
192   static bool is_sequential(unsigned short theScriptingKind);
193 
194   static void checkSimpleExpr(const expr* e);
195 
196   static void checkNonUpdating(const expr* e);
197 
198 protected:
199   expr(CompilerCB*, static_context*, const QueryLoc&, expr_kind_t);
200 
expr()201   expr() : theSctx(NULL), theFlags1(0), theCCB(NULL) {}
202 
203 public:
204   virtual ~expr();
205 
get_ccb()206   CompilerCB* get_ccb() {return theCCB;}
207 
get_expr_kind()208   expr_kind_t get_expr_kind() const { return static_cast<expr_kind_t>(theKind); }
209 
get_loc()210   const QueryLoc& get_loc() const { return theLoc; }
211 
set_loc(const QueryLoc & loc)212   void set_loc(const QueryLoc& loc) { theLoc = loc; }
213 
get_sctx()214   static_context* get_sctx() const { return theSctx; }
215 
216   TypeManager* get_type_manager() const;
217 
getFlags()218   uint32_t getFlags() const { return theFlags1; }
219 
setFlags(uint32_t flags)220   void setFlags(uint32_t flags) { theFlags1 = flags; }
221 
get_scripting_detail()222   unsigned short get_scripting_detail() const { return theScriptingKind; }
223 
224   bool is_updating() const;
225 
226   bool is_sequential() const;
227 
228   bool is_vacuous() const;
229 
230   bool is_simple() const;
231 
232   bool is_updating_or_vacuous() const;
233 
234   void set_not_exiting();
235 
236   void adjustSequential();
237 
238   void checkScriptingKind() const;
239 
240   void compute_return_type(bool deep, bool* modified);
241 
242   xqtref_t get_return_type();
243 
244   expr* clone() const;
245 
246   expr* clone(substitution_t&) const;
247 
248   virtual expr* cloneImpl(substitution_t& substitution) const;
249 
250   virtual void accept(expr_visitor& v) = 0;
251 
252   void accept_children(expr_visitor& v);
253 
254   virtual std::ostream& put(std::ostream&) const = 0;
255 
256   std::string toString() const;
257 
258 public:
259   // Annotation : produces-sorted-nodes
260   BoolAnnotationValue getProducesSortedNodes() const;
261 
262   void setProducesSortedNodes(BoolAnnotationValue v);
263 
264   bool producesSortedNodes() const;
265 
266   // Annotation : produces-distinct-nodes
267   BoolAnnotationValue getProducesDistinctNodes() const;
268 
269   void setProducesDistinctNodes(BoolAnnotationValue v);
270 
271   bool producesDistinctNodes() const;
272 
273   // Annotation : propagatesInputNodes
274   BoolAnnotationValue getPropagatesInputNodes() const;
275 
276   void setPropagatesInputNodes(BoolAnnotationValue v);
277 
278   // Annotation : ignores-sorted-nodes
279   BoolAnnotationValue getIgnoresSortedNodes() const;
280 
281   void setIgnoresSortedNodes(BoolAnnotationValue v);
282 
283   bool ignoresSortedNodes() const;
284 
285   // Annotation : ignores-duplicated-nodes
286   BoolAnnotationValue getIgnoresDuplicateNodes() const;
287 
288   void setIgnoresDuplicateNodes(BoolAnnotationValue v);
289 
290   bool ignoresDuplicateNodes() const;
291 
292   // Annotation : non-discardable
293   BoolAnnotationValue getNonDiscardable() const;
294 
295   bool isNonDiscardable() const;
296 
297   void setNonDiscardable(BoolAnnotationValue v);
298 
299   // Annotation : unfoldable
300   BoolAnnotationValue getUnfoldable() const;
301 
302   void setUnfoldable(BoolAnnotationValue v);
303 
304   bool isUnfoldable() const;
305 
306   // Annotation : contains-recursive-call
307   BoolAnnotationValue getContainsRecursiveCall() const;
308 
309   void setContainsRecursiveCall(BoolAnnotationValue v);
310 
311   bool containsRecursiveCall() const;
312 
313   // Annotation : mustCopyNodes
314   BoolAnnotationValue getMustCopyNodes() const;
315 
316   void setMustCopyNodes(BoolAnnotationValue v);
317 
318   // Annotation : inUnsafeContext
319   BoolAnnotationValue getInUnsafeContext() const;
320 
321   void setInUnsafeContext(BoolAnnotationValue v);
322 
323   bool inUnsafeContext() const;
324 
325   // Annotation : containsPragma
326   BoolAnnotationValue getContainsPragma() const;
327 
328   void setContainsPragma(BoolAnnotationValue v);
329 
330   bool containsPragma() const;
331 
332   // Annotation : free vars
getFreeVars()333   const FreeVars& getFreeVars() const { return theFreeVars; }
334 
getFreeVars()335   FreeVars& getFreeVars() { return theFreeVars; }
336 
337   void setFreeVars(FreeVars& s);
338 
339   bool is_constant() const;
340 
341   bool is_nondeterministic() const;
342 
343   void replace_expr(expr* oldExpr, expr* newExpr);
344 
345   bool contains_expr(const expr* e) const;
346 
347   bool contains_node_construction() const;
348 
349   void get_exprs_of_kind(
350       expr_kind_t kind,
351       bool deep,
352       std::vector<expr*>& exprs) const;
353 
354   void get_fo_exprs_of_kind(
355       FunctionConsts::FunctionKind kind,
356       bool deep,
357       std::vector<expr*>& exprs) const;
358 
359   bool is_map(expr* e, static_context* sctx) const;
360 
361   FunctionConsts::FunctionKind get_function_kind() const;
362 
363   const var_expr* get_var() const;
364 
365   const store::Item* getQName(static_context* sctx) const;
366 
367   void clear_annotations();
368 
369   xqtref_t get_return_type_with_empty_input(const expr* input) const;
370 
371 protected:
372   virtual void compute_scripting_kind() = 0;
373 
374   bool is_map_internal(const expr* e, bool& found) const;
375 };
376 
377 
378 /*******************************************************************************
379 
380 ********************************************************************************/
381 #define DEF_EXPR_ACCEPT( type )             \
382 void type::accept(expr_visitor& v)          \
383 {                                           \
384   if (v.begin_visit(*this))                 \
385     accept_children(v);                     \
386                                             \
387   v.end_visit(*this);                       \
388 }
389 
390 
391 }
392 #endif
393 
394 /*
395  * Local variables:
396  * mode: c++
397  * End:
398  */
399 /* vim:set et sw=2 ts=2: */
400