as2js: /home/snapwebsites/snapcpp/contrib/as2js/lib/node_attribute.cpp Source File

as2js  0.1.14
AlexScript to JavaScript
node_attribute.cpp
Go to the documentation of this file.
1 /* lib/node_attribute.cpp
2 
3 Copyright (c) 2005-2019 Made to Order Software Corp. All Rights Reserved
4 
6 
7 Permission is hereby granted, free of charge, to any
8 person obtaining a copy of this software and
9 associated documentation files (the "Software"), to
10 deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify,
12 merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom
14 the Software is furnished to do so, subject to the
15 following conditions:
16 
17 The above copyright notice and this permission notice
18 shall be included in all copies or substantial
19 portions of the Software.
20 
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
22 ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
23 LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
24 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
25 EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28 ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 SOFTWARE.
31 
32 */
33 
34 #include "as2js/node.h"
35 
36 #include "as2js/exceptions.h"
37 #include "as2js/message.h"
38 
47 namespace as2js
48 {
49 
50 
51 
52 /**********************************************************************/
53 /**********************************************************************/
54 /*** NODE ATTRIBUTE *************************************************/
55 /**********************************************************************/
56 /**********************************************************************/
57 
70 namespace
71 {
72 
73 
79 char const *g_attribute_names[static_cast<int>(Node::attribute_t::NODE_ATTR_max)] =
80 {
81  "PUBLIC",
82  "PRIVATE",
83  "PROTECTED",
84  "INTERNAL",
85  "TRANSIENT",
86  "VOLATILE",
87  "STATIC",
88  "ABSTRACT",
89  "VIRTUAL",
90  "ARRAY",
91  "INLINE",
92  "REQUIRE_ELSE",
93  "ENSURE_THEN",
94  "NATIVE",
95  "DEPRECATED",
96  "UNSAFE",
97  "CONSTRUCTOR",
98  //"CONST", -- this is a flag, not needed here
99  "FINAL",
100  "ENUMERABLE",
101  "TRUE",
102  "FALSE",
103  "UNUSED",
104  "DYNAMIC",
105  "FOREACH",
106  "NOBREAK",
107  "AUTOBREAK",
108  "TYPE",
109  "DEFINED"
110 };
111 
112 
122 enum
123 {
131 
146 
156 
166 
181 };
182 
183 
192 #pragma GCC diagnostic push
193 #pragma GCC diagnostic ignored "-Wpedantic"
194 char const *g_attribute_groups[] =
195 {
196  [ATTRIBUTES_GROUP_CONDITIONAL_COMPILATION] = "true and false",
197  [ATTRIBUTES_GROUP_FUNCTION_TYPE] = "abstract, constructor, inline, native, static, and virtual",
198  [ATTRIBUTES_GROUP_FUNCTION_CONTRACT] = "require else and ensure then",
199  [ATTRIBUTES_GROUP_SWITCH_TYPE] = "foreach, nobreak, and autobreak",
200  [ATTRIBUTES_GROUP_MEMBER_VISIBILITY] = "public, private, and protected"
201 };
202 #pragma GCC diagnostic pop
203 
204 }
205 // no name namesoace
206 
207 
209 {
210  f_attribute_node = node;
211 }
212 
213 
215 {
216  return f_attribute_node;
217 }
218 
219 
240 bool Node::get_attribute(attribute_t const a) const
241 {
242  verify_attribute(a);
243  return f_attributes[static_cast<size_t>(a)];
244 }
245 
246 
263 void Node::set_attribute(attribute_t const a, bool const v)
264 {
265  verify_attribute(a);
266  if(v)
267  {
268  // exclusive attributes do not generate an exception, instead
269  // we test the return value and if two exclusive attribute flags
270  // were to be set simultaneously, we prevent the second one from
271  // being set
273  {
274  return;
275  }
276  }
277  f_attributes[static_cast<size_t>(a)] = v;
278 }
279 
280 
297 void Node::set_attribute_tree(attribute_t const a, bool const v)
298 {
299  verify_attribute(a);
300  if(v)
301  {
302  // exclusive attributes do not generate an exception, instead
303  // we test the return value and if two exclusive attribute flags
304  // were to be set simultaneously, we prevent the second one from
305  // being set
307  {
308  f_attributes[static_cast<size_t>(a)] = v;
309  }
310  }
311  else
312  {
313  f_attributes[static_cast<size_t>(a)] = v;
314  }
315 
316  // repeat on the children
317  for(size_t idx(0); idx < f_children.size(); ++idx)
318  {
319  f_children[idx]->set_attribute_tree(a, v);
320  }
321 }
322 
323 
344 {
345  switch(a)
346  {
347  // member visibility
354 
355  // function member type
361 
362  // function contracts
365 
366  // function/variable is defined in your system (execution env.)
368 
369  // function/variable will be removed in future releases, do not use
372 
373  // operator overload (function member)
375 
376  // function & member constrains
379 
380  // conditional compilation
383  case attribute_t::NODE_ATTR_UNUSED: // if definition is used, error!
384 
385  // class attribute (whether a class can be enlarged at run time)
387 
388  // switch attributes
392  // TBD -- we will need to see whether we want to limit the attributes
393  // on a per node type basis and how we can do that properly
395  {
396  return;
397  }
398  break;
399 
400  // attributes were defined
402  // all nodes can receive this flag
403  return;
404 
406  // the type attribute is limited to nodes that can appear in
407  // an expression so we limit to such nodes for now
408  switch(f_type)
409  {
410  case node_t::NODE_ADD:
411  case node_t::NODE_ARRAY:
413  case node_t::NODE_AS:
438  case node_t::NODE_CALL:
441  case node_t::NODE_DELETE:
442  case node_t::NODE_DIVIDE:
443  case node_t::NODE_EQUAL:
444  case node_t::NODE_FALSE:
450  case node_t::NODE_IN:
453  case node_t::NODE_INT64:
454  case node_t::NODE_IS:
455  case node_t::NODE_LESS:
457  case node_t::NODE_LIST:
462  case node_t::NODE_MATCH:
464  case node_t::NODE_MEMBER:
466  case node_t::NODE_MODULO:
468  case node_t::NODE_NAME:
469  case node_t::NODE_NEW:
471  case node_t::NODE_NULL:
475  case node_t::NODE_POWER:
477  case node_t::NODE_PUBLIC:
478  case node_t::NODE_RANGE:
481  case node_t::NODE_SCOPE:
487  case node_t::NODE_STRING:
489  case node_t::NODE_SUPER:
490  case node_t::NODE_THIS:
491  case node_t::NODE_TRUE:
492  case node_t::NODE_TYPEOF:
495  case node_t::NODE_VOID:
496  return;
497 
498  default:
499  // anything else is an error
500  break;
501 
502  }
503  break;
504 
506  break;
507 
508  // default: -- do not define so the compiler can tell us if
509  // an enumeration is missing in this case
510  }
511 
512  std::stringstream ss;
513  ss << "node " << get_type_name() << " does not like attribute " << attribute_to_string(a) << " in Node::verify_attribute()";
514  throw exception_internal_error(ss.str());
515 }
516 
517 
541 {
542  bool conflict(false);
543  char const *names;
544  switch(a)
545  {
558  // these attributes have no conflicts
559  return true;
560 
561  // function contract
563  conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_ENSURE_THEN)];
565  break;
566 
568  conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_REQUIRE_ELSE)];
570  break;
571 
572  // member visibility
574  conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_PRIVATE)]
575  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_PROTECTED)];
577  break;
578 
580  conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_PUBLIC)]
581  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_PROTECTED)];
583  break;
584 
586  conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_PUBLIC)]
587  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_PRIVATE)];
589  break;
590 
591  // function type group
593  conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_STATIC)]
594  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_CONSTRUCTOR)]
595  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_VIRTUAL)]
596  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_NATIVE)]
597  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_INLINE)];
599  break;
600 
602  conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_STATIC)]
603  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_VIRTUAL)]
604  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_INLINE)]
605  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_ABSTRACT)];
607  break;
608 
610  conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_ABSTRACT)]
611  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_CONSTRUCTOR)]
612  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_NATIVE)]
613  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_VIRTUAL)];
615  break;
616 
618  conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_ABSTRACT)]
619  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_INLINE)];
621  break;
622 
624  conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_ABSTRACT)]
625  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_CONSTRUCTOR)]
626  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_VIRTUAL)];
628  break;
629 
631  conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_STATIC)]
632  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_CONSTRUCTOR)]
633  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_ABSTRACT)]
634  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_INLINE)];
636  break;
637 
638  // switch type group
640  conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_NOBREAK)]
641  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_AUTOBREAK)];
643  break;
644 
646  conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_FOREACH)]
647  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_AUTOBREAK)];
649  break;
650 
652  conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_FOREACH)]
653  || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_NOBREAK)];
655  break;
656 
657  // conditional compilation group
659  conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_FALSE)];
661  break;
662 
664  conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_TRUE)];
666  break;
667 
669  // this should already have been caught in the verify_attribute() function
670  throw exception_internal_error("invalid attribute / flag in Node::verify_attribute()"); // LCOV_EXCL_LINE
671 
672  // default: -- do not define so the compiler can tell us if
673  // an enumeration is missing in this case
674  // note: verify_attribute(() is called before this function
675  // and it catches completely invalid attribute numbers
676  // (i.e. negative, larger than NODE_ATTR_max)
677  }
678 
679  if(conflict)
680  {
681  // this can be a user error so we emit an error instead of throwing
683  msg << "Attributes " << names << " are mutually exclusive. Only one of them can be used.";
684  return false;
685  }
686 
687  return true;
688 }
689 
690 
705 {
706  return f_attributes == s;
707 }
708 
709 
719 char const *Node::attribute_to_string(attribute_t const attr)
720 {
721  if(static_cast<int>(attr) < 0
722  || attr >= attribute_t::NODE_ATTR_max)
723  {
724  throw exception_internal_error("unknown attribute number in Node::attribute_to_string()");
725  }
726 
727  return g_attribute_names[static_cast<int>(attr)];
728 }
729 
730 
731 }
732 // namespace as2js
733 
734 // vim: ts=4 sw=4 et
pointer_t get_attribute_node() const
node_t f_type
Definition: node.h:594
void set_attribute_node(pointer_t node)
void set_attribute_tree(attribute_t const a, bool const v)
Set an attribute in a whole tree.
void verify_attribute(attribute_t const f) const
Verify that a corresponds to the Node type.
static char const * attribute_to_string(attribute_t const attr)
Convert an attribute to a string.
attribute_t
Definition: node.h:352
vector_of_pointers_t f_children
Definition: node.h:619
bool verify_exclusive_attributes(attribute_t f) const
Verify that we can indeed set an attribute.
std::shared_ptr< Node > pointer_t
Definition: node.h:67
char const * g_attribute_names[static_cast< int >(Node::attribute_t::NODE_ATTR_max)]
Array of attribute names.
attribute_set_t f_attributes
Definition: node.h:598
void set_attribute(attribute_t const a, bool const v)
Set an attribute.
std::bitset< static_cast< int >attribute_t::NODE_ATTR_max)> attribute_set_t
Definition: node.h:421
char const * g_attribute_groups[]
Table of group names.
Position f_position
Definition: node.h:605
The AlexScript to JavaScript namespace.
Definition: compiler.cpp:37
pointer_t f_attribute_node
Definition: node.h:597
bool get_attribute(attribute_t const a) const
Get the current status of an attribute.
bool compare_all_attributes(attribute_set_t const &s) const
Compare a set of attributes with the current attributes of this node.
char const * get_type_name() const
Retrieve the type of this node.
Definition: node_type.cpp:475

This document is part of the Snap! Websites Project.

Copyright by Made to Order Software Corp.

Syndicate content

Snap! Websites
An Open Source CMS System in C++

Contact Us Directly