LCOV - code coverage report
Current view: top level - lib - node_attribute.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 106 106 100.0 %
Date: 2014-11-22 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* node_attribute.cpp -- written by Alexis WILKE for Made to Order Software Corp. (c) 2005-2014 */
       2             : 
       3             : /*
       4             : 
       5             : Copyright (c) 2005-2014 Made to Order Software Corp.
       6             : 
       7             : http://snapwebsites.org/project/as2js
       8             : 
       9             : Permission is hereby granted, free of charge, to any
      10             : person obtaining a copy of this software and
      11             : associated documentation files (the "Software"), to
      12             : deal in the Software without restriction, including
      13             : without limitation the rights to use, copy, modify,
      14             : merge, publish, distribute, sublicense, and/or sell
      15             : copies of the Software, and to permit persons to whom
      16             : the Software is furnished to do so, subject to the
      17             : following conditions:
      18             : 
      19             : The above copyright notice and this permission notice
      20             : shall be included in all copies or substantial
      21             : portions of the Software.
      22             : 
      23             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
      24             : ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
      25             : LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
      26             : FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
      27             : EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
      28             : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
      29             : WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      30             : ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      31             : SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      32             : SOFTWARE.
      33             : 
      34             : */
      35             : 
      36             : #include    "as2js/node.h"
      37             : 
      38             : #include    "as2js/exceptions.h"
      39             : #include    "as2js/message.h"
      40             : 
      41             : /** \file
      42             :  * \brief Implementation of the Node class attributes.
      43             :  *
      44             :  * Node objects support a large set of attributes. Attributes can be added
      45             :  * and removed from a Node. Some attributes are mutually exclusive.
      46             :  */
      47             : 
      48             : 
      49             : namespace as2js
      50             : {
      51             : 
      52             : 
      53             : 
      54             : /**********************************************************************/
      55             : /**********************************************************************/
      56             : /***  NODE ATTRIBUTE  *************************************************/
      57             : /**********************************************************************/
      58             : /**********************************************************************/
      59             : 
      60             : /** \brief Anonymous namespace for attribute internal definitions.
      61             :  *
      62             :  * The Node attributes are organized in groups. In most cases, only one
      63             :  * attribute from the same group can be set at a time. Trying to set
      64             :  * another attribute from the same group generates an error.
      65             :  *
      66             :  * The tables defined here are used to determine whether attributes are
      67             :  * mutually exclusive.
      68             :  *
      69             :  * Note that such errors are considered to be bugs in the compiler. The
      70             :  * implementation needs to be fixed if such errors are detected.
      71             :  */
      72             : namespace
      73             : {
      74             : 
      75             : 
      76             : /** \brief Array of attribute names.
      77             :  *
      78             :  * This array is used to convert an attribute to a string. It can also
      79             :  * be used to convert a string to an attribute.
      80             :  */
      81             : char const *g_attribute_names[static_cast<int>(Node::attribute_t::NODE_ATTR_max)] =
      82             : {
      83             :     "PUBLIC",
      84             :     "PRIVATE",
      85             :     "PROTECTED",
      86             :     "INTERNAL",
      87             :     "TRANSIENT",
      88             :     "VOLATILE",
      89             :     "STATIC",
      90             :     "ABSTRACT",
      91             :     "VIRTUAL",
      92             :     "ARRAY",
      93             :     "INLINE",
      94             :     "REQUIRE_ELSE",
      95             :     "ENSURE_THEN",
      96             :     "NATIVE",
      97             :     "DEPRECATED",
      98             :     "UNSAFE",
      99             :     "CONSTRUCTOR",
     100             :     //  "CONST"         ); -- this is a flag, not needed here
     101             :     "FINAL",
     102             :     "ENUMERABLE",
     103             :     "TRUE",
     104             :     "FALSE",
     105             :     "UNUSED",
     106             :     "DYNAMIC",
     107             :     "FOREACH",
     108             :     "NOBREAK",
     109             :     "AUTOBREAK",
     110             :     "DEFINED"
     111             : };
     112             : 
     113             : 
     114             : /** \brief List of attribute groups.
     115             :  *
     116             :  * The following enumeration defines a set of group attributes. These
     117             :  * are used internally to declare the list of attribute groups.
     118             :  *
     119             :  * \todo
     120             :  * Add a class name to this enumeration, even if private, it still
     121             :  * makes it a lot safer.
     122             :  */
     123             : enum
     124             : {
     125             :     /** \brief Conditional Compilation Group.
     126             :      *
     127             :      * This group includes the TRUE and FALSE attributes. A statement
     128             :      * can be marked as TRUE (compiled in) or FALSE (left out). A
     129             :      * statement cannot at the same time be TRUE and FALSE.
     130             :      */
     131             :     ATTRIBUTES_GROUP_CONDITIONAL_COMPILATION,
     132             : 
     133             :     /** \brief Function Type Group.
     134             :      *
     135             :      * Functions can be marked as ABSTRACT, CONSTRUCTOR, INLINE, NATIVE,
     136             :      * STATIC, and VIRTUAL. This group is used to detect whether a function
     137             :      * is marked by more than one of these attributes.
     138             :      *
     139             :      * Note that this group has exceptions:
     140             :      *
     141             :      * \li A NATIVE CONSTRUCTOR is considered valid.
     142             :      * \li A NATIVE VIRTUAL is considered valid.
     143             :      * \li A NATIVE STATIC is considered valid.
     144             :      * \li A STATIC INLINE is considered valid.
     145             :      */
     146             :     ATTRIBUTES_GROUP_FUNCTION_TYPE,
     147             : 
     148             :     /** \brief Function Contract Group.
     149             :      *
     150             :      * The function contract includes the REQUIRE ELSE and the
     151             :      * ENSURE THEN, both of which cannot be assigned to one
     152             :      * function simultaneously.
     153             :      *
     154             :      * Contracts are taken from the Effel language.
     155             :      */
     156             :     ATTRIBUTES_GROUP_FUNCTION_CONTRACT,
     157             : 
     158             :     /** \brief Switch Type Group.
     159             :      *
     160             :      * A 'switch' statement can be given a type: FOREACH, NOBREAK,
     161             :      * or AUTOBREAK. Only one type can be specified.
     162             :      *
     163             :      * The AUTOBREAK idea comes from languages such as Ada and
     164             :      * Visual BASIC which always break at the end of a case.
     165             :      */
     166             :     ATTRIBUTES_GROUP_SWITCH_TYPE,
     167             : 
     168             :     /** \brief Member Visibility Group.
     169             :      *
     170             :      * Variable and function members defined in a class can be given a
     171             :      * specific visibility of PUBLIC, PRIVATE, or PROTECTED.
     172             :      *
     173             :      * All the visibilities are mutually exclusive.
     174             :      *
     175             :      * Note that the visibility capability can either use a direct
     176             :      * attribute definition or a 'label' definition (as in C++).
     177             :      * The 'label' definition is ignored when a direct attribute is
     178             :      * used, in other words, the visibility can be contradictory in
     179             :      * that case and the compiler still accepts the entry (TBD.)
     180             :      */
     181             :     ATTRIBUTES_GROUP_MEMBER_VISIBILITY
     182             : };
     183             : 
     184             : 
     185             : /** \brief Table of group names.
     186             :  *
     187             :  * This table defines a set of names for the attribute groups. These
     188             :  * are used whenever an error is generated in link with that given
     189             :  * group.
     190             :  *
     191             :  * The index makes use of the group enumeration values.
     192             :  */
     193             : char const *g_attribute_groups[] =
     194             : {
     195             :     [ATTRIBUTES_GROUP_CONDITIONAL_COMPILATION] = "true and false",
     196             :     [ATTRIBUTES_GROUP_FUNCTION_TYPE] = "abstract, constructor, inline, native, static, and virtual",
     197             :     [ATTRIBUTES_GROUP_FUNCTION_CONTRACT] = "require else and ensure then",
     198             :     [ATTRIBUTES_GROUP_SWITCH_TYPE] = "foreach, nobreak, and autobreak",
     199             :     [ATTRIBUTES_GROUP_MEMBER_VISIBILITY] = "public, private, and protected"
     200             : };
     201             : 
     202             : }
     203             : // no name namesoace
     204             : 
     205             : 
     206             : /** \brief Get the current status of an attribute.
     207             :  *
     208             :  * This function returns true or false depending on the current status
     209             :  * of the specified attribute.
     210             :  *
     211             :  * The function verifies that the specified attribute (\p a) corresponds to
     212             :  * the type of data you are dealing with. If not, an exception is raised.
     213             :  *
     214             :  * If the attribute was never set, this function returns false.
     215             :  *
     216             :  * \note
     217             :  * All attributes are always considered false by default.
     218             :  *
     219             :  * \param[in] a  The attribute to retrieve.
     220             :  *
     221             :  * \return true if the attribute was set, false otherwise.
     222             :  *
     223             :  * \sa set_attribute()
     224             :  * \sa verify_attribute()
     225             :  */
     226   590702676 : bool Node::get_attribute(attribute_t a) const
     227             : {
     228   590702676 :     verify_attribute(a);
     229   590700780 :     return f_attributes[static_cast<size_t>(a)];
     230             : }
     231             : 
     232             : 
     233             : /** \brief Set an attribute.
     234             :  *
     235             :  * This function sets the specified attribute \p a to the specified value
     236             :  * \p v in this Node object.
     237             :  *
     238             :  * The function verifies that the specified attribute (\p a) corresponds to
     239             :  * the type of data you are dealing with.
     240             :  *
     241             :  * \param[in] a  The flag to set.
     242             :  * \param[in] v  The new value for the flag.
     243             :  *
     244             :  * \sa get_attribute()
     245             :  * \sa verify_attribute()
     246             :  * \sa verify_exclusive_attributes()
     247             :  */
     248      141979 : void Node::set_attribute(attribute_t a, bool v)
     249             : {
     250      141979 :     verify_attribute(a);
     251      138187 :     if(v)
     252             :     {
     253             :         // exclusive attributes do not generate an exception, instead
     254             :         // we test the return value and if two exclusive attribute flags
     255             :         // were to be set simultaneously, we prevent the second one from
     256             :         // being set
     257       44603 :         if(!verify_exclusive_attributes(a))
     258             :         {
     259      138507 :             return;
     260             :         }
     261             :     }
     262      137867 :     f_attributes[static_cast<size_t>(a)] = v;
     263             : }
     264             : 
     265             : 
     266             : /** \brief Verify that \p a corresponds to the Node type.
     267             :  *
     268             :  * This function verifies that \p a corresponds to a valid attribute
     269             :  * according to the type of this Node object.
     270             :  *
     271             :  * \note
     272             :  * At this point attributes can be assigned to any type of node
     273             :  * exception a NODE_PROGRAM which only accepts the NODE_ATTR_DEFINED
     274             :  * attribute.
     275             :  *
     276             :  * \exception exception_internal_error
     277             :  * If the attribute is not valid for this node type,
     278             :  * then this exception is raised.
     279             :  *
     280             :  * \param[in] a  The attribute to check.
     281             :  *
     282             :  * \sa set_attribute()
     283             :  * \sa get_attribute()
     284             :  */
     285   590844655 : void Node::verify_attribute(attribute_t a) const
     286             : {
     287   590844655 :     switch(a)
     288             :     {
     289             :     // member visibility
     290             :     case attribute_t::NODE_ATTR_PUBLIC:
     291             :     case attribute_t::NODE_ATTR_PRIVATE:
     292             :     case attribute_t::NODE_ATTR_PROTECTED:
     293             :     case attribute_t::NODE_ATTR_INTERNAL:
     294             :     case attribute_t::NODE_ATTR_TRANSIENT:
     295             :     case attribute_t::NODE_ATTR_VOLATILE:
     296             : 
     297             :     // function member type
     298             :     case attribute_t::NODE_ATTR_STATIC:
     299             :     case attribute_t::NODE_ATTR_ABSTRACT:
     300             :     case attribute_t::NODE_ATTR_VIRTUAL:
     301             :     case attribute_t::NODE_ATTR_ARRAY:
     302             :     case attribute_t::NODE_ATTR_INLINE:
     303             : 
     304             :     // function contracts
     305             :     case attribute_t::NODE_ATTR_REQUIRE_ELSE:
     306             :     case attribute_t::NODE_ATTR_ENSURE_THEN:
     307             : 
     308             :     // function/variable is defined in your system (execution env.)
     309             :     case attribute_t::NODE_ATTR_NATIVE:
     310             : 
     311             :     // function/variable will be removed in future releases, do not use
     312             :     case attribute_t::NODE_ATTR_DEPRECATED:
     313             :     case attribute_t::NODE_ATTR_UNSAFE:
     314             : 
     315             :     // operator overload (function member)
     316             :     case attribute_t::NODE_ATTR_CONSTRUCTOR:
     317             : 
     318             :     // function & member constrains
     319             :     case attribute_t::NODE_ATTR_FINAL:
     320             :     case attribute_t::NODE_ATTR_ENUMERABLE:
     321             : 
     322             :     // conditional compilation
     323             :     case attribute_t::NODE_ATTR_TRUE:
     324             :     case attribute_t::NODE_ATTR_FALSE:
     325             :     case attribute_t::NODE_ATTR_UNUSED:                      // if definition is used, error!
     326             : 
     327             :     // class attribute (whether a class can be enlarged at run time)
     328             :     case attribute_t::NODE_ATTR_DYNAMIC:
     329             : 
     330             :     // switch attributes
     331             :     case attribute_t::NODE_ATTR_FOREACH:
     332             :     case attribute_t::NODE_ATTR_NOBREAK:
     333             :     case attribute_t::NODE_ATTR_AUTOBREAK:
     334             :         // TBD -- we'll need to see whether we want to limit the attributes
     335             :         //        on a per node type basis and how we can do that properly
     336   568113308 :         if(f_type != node_t::NODE_PROGRAM)
     337             :         {
     338   568113230 :             return;
     339             :         }
     340          78 :         break;
     341             : 
     342             :     // attributes were defined
     343             :     case attribute_t::NODE_ATTR_DEFINED:
     344             :         // all nodes can receive this flag
     345    22725737 :         return;
     346             : 
     347             :     case attribute_t::NODE_ATTR_max:
     348         510 :         break;
     349             : 
     350             :     // default: -- do not define so the compiler can tell us if
     351             :     //             an enumeration is missing in this case
     352             :     }
     353             : 
     354        5688 :     std::stringstream ss;
     355        5688 :     ss << "node " << get_type_name() << " does not like attribute " << attribute_to_string(a) << " in Node::verify_attribute()";
     356          78 :     throw exception_internal_error(ss.str());
     357             : }
     358             : 
     359             : 
     360             : /** \brief Verify that we can indeed set an attribute.
     361             :  *
     362             :  * Many attributes are mutually exclusive. This function checks that
     363             :  * only one of a group of attributes gets set.
     364             :  *
     365             :  * This function is not called if you clear an attribute since in that
     366             :  * case the default applies.
     367             :  *
     368             :  * When attributes are found to be in conflict, it is not an internal
     369             :  * error, so instead the function generates an error message and the
     370             :  * function returns false. This means the compiler may end up generating
     371             :  * more errors than one might want to get.
     372             :  *
     373             :  * \exception exception_internal_error
     374             :  * This exception is raised whenever the parameter \p a is invalid.
     375             :  *
     376             :  * \param[in] a  The attribute being set.
     377             :  *
     378             :  * \return true if the attributes are not in conflict.
     379             :  *
     380             :  * \sa set_attribute()
     381             :  */
     382       44603 : bool Node::verify_exclusive_attributes(attribute_t a) const
     383             : {
     384       44603 :     bool conflict(false);
     385             :     char const *names;
     386       44603 :     switch(a)
     387             :     {
     388             :     case attribute_t::NODE_ATTR_ARRAY:
     389             :     case attribute_t::NODE_ATTR_DEFINED:
     390             :     case attribute_t::NODE_ATTR_DEPRECATED:
     391             :     case attribute_t::NODE_ATTR_DYNAMIC:
     392             :     case attribute_t::NODE_ATTR_ENUMERABLE:
     393             :     case attribute_t::NODE_ATTR_FINAL:
     394             :     case attribute_t::NODE_ATTR_INTERNAL:
     395             :     case attribute_t::NODE_ATTR_TRANSIENT:
     396             :     case attribute_t::NODE_ATTR_UNSAFE:
     397             :     case attribute_t::NODE_ATTR_UNUSED:
     398             :     case attribute_t::NODE_ATTR_VOLATILE:
     399             :         // these attributes have no conflicts
     400       21353 :         return true;
     401             : 
     402             :     // function contract
     403             :     case attribute_t::NODE_ATTR_REQUIRE_ELSE:
     404        8631 :         conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_ENSURE_THEN)];
     405        8631 :         names = g_attribute_groups[ATTRIBUTES_GROUP_FUNCTION_CONTRACT];
     406        8631 :         break;
     407             : 
     408             :     case attribute_t::NODE_ATTR_ENSURE_THEN:
     409        8631 :         conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_REQUIRE_ELSE)];
     410        8631 :         names = g_attribute_groups[ATTRIBUTES_GROUP_FUNCTION_CONTRACT];
     411        8631 :         break;
     412             : 
     413             :     // member visibility
     414             :     case attribute_t::NODE_ATTR_PUBLIC:
     415         429 :         conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_PRIVATE)]
     416         429 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_PROTECTED)];
     417         429 :         names = g_attribute_groups[ATTRIBUTES_GROUP_MEMBER_VISIBILITY];
     418         429 :         break;
     419             : 
     420             :     case attribute_t::NODE_ATTR_PRIVATE:
     421         429 :         conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_PUBLIC)]
     422         429 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_PROTECTED)];
     423         429 :         names = g_attribute_groups[ATTRIBUTES_GROUP_MEMBER_VISIBILITY];
     424         429 :         break;
     425             : 
     426             :     case attribute_t::NODE_ATTR_PROTECTED:
     427         429 :         conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_PUBLIC)]
     428         429 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_PRIVATE)];
     429         429 :         names = g_attribute_groups[ATTRIBUTES_GROUP_MEMBER_VISIBILITY];
     430         429 :         break;
     431             : 
     432             :     // function type group
     433             :     case attribute_t::NODE_ATTR_ABSTRACT:
     434         419 :         conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_STATIC)]
     435         409 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_CONSTRUCTOR)]
     436         399 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_VIRTUAL)]
     437         389 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_NATIVE)]
     438         808 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_INLINE)];
     439         419 :         names = g_attribute_groups[ATTRIBUTES_GROUP_FUNCTION_TYPE];
     440         419 :         break;
     441             : 
     442             :     case attribute_t::NODE_ATTR_CONSTRUCTOR:
     443         419 :         conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_STATIC)]
     444         409 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_VIRTUAL)]
     445         399 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_INLINE)]
     446         818 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_ABSTRACT)];
     447         419 :         names = g_attribute_groups[ATTRIBUTES_GROUP_FUNCTION_TYPE];
     448         419 :         break;
     449             : 
     450             :     case attribute_t::NODE_ATTR_INLINE:
     451         419 :         conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_ABSTRACT)]
     452         409 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_CONSTRUCTOR)]
     453         399 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_NATIVE)]
     454         818 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_VIRTUAL)];
     455         419 :         names = g_attribute_groups[ATTRIBUTES_GROUP_FUNCTION_TYPE];
     456         419 :         break;
     457             : 
     458             :     case attribute_t::NODE_ATTR_NATIVE:
     459         440 :         conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_ABSTRACT)]
     460         440 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_INLINE)];
     461         440 :         names = g_attribute_groups[ATTRIBUTES_GROUP_FUNCTION_TYPE];
     462         440 :         break;
     463             : 
     464             :     case attribute_t::NODE_ATTR_STATIC:
     465         419 :         conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_ABSTRACT)]
     466         409 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_CONSTRUCTOR)]
     467         818 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_VIRTUAL)];
     468         419 :         names = g_attribute_groups[ATTRIBUTES_GROUP_FUNCTION_TYPE];
     469         419 :         break;
     470             : 
     471             :     case attribute_t::NODE_ATTR_VIRTUAL:
     472         419 :         conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_STATIC)]
     473         409 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_CONSTRUCTOR)]
     474         399 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_ABSTRACT)]
     475         808 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_INLINE)];
     476         419 :         names = g_attribute_groups[ATTRIBUTES_GROUP_FUNCTION_TYPE];
     477         419 :         break;
     478             : 
     479             :     // switch type group
     480             :     case attribute_t::NODE_ATTR_FOREACH:
     481         429 :         conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_NOBREAK)]
     482         429 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_AUTOBREAK)];
     483         429 :         names = g_attribute_groups[ATTRIBUTES_GROUP_SWITCH_TYPE];
     484         429 :         break;
     485             : 
     486             :     case attribute_t::NODE_ATTR_NOBREAK:
     487         429 :         conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_FOREACH)]
     488         429 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_AUTOBREAK)];
     489         429 :         names = g_attribute_groups[ATTRIBUTES_GROUP_SWITCH_TYPE];
     490         429 :         break;
     491             : 
     492             :     case attribute_t::NODE_ATTR_AUTOBREAK:
     493         429 :         conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_FOREACH)]
     494         429 :                 || f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_NOBREAK)];
     495         429 :         names = g_attribute_groups[ATTRIBUTES_GROUP_SWITCH_TYPE];
     496         429 :         break;
     497             : 
     498             :     // conditional compilation group
     499             :     case attribute_t::NODE_ATTR_TRUE:
     500         440 :         conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_FALSE)];
     501         440 :         names = g_attribute_groups[ATTRIBUTES_GROUP_CONDITIONAL_COMPILATION];
     502         440 :         break;
     503             : 
     504             :     case attribute_t::NODE_ATTR_FALSE:
     505         439 :         conflict = f_attributes[static_cast<size_t>(attribute_t::NODE_ATTR_TRUE)];
     506         439 :         names = g_attribute_groups[ATTRIBUTES_GROUP_CONDITIONAL_COMPILATION];
     507         439 :         break;
     508             : 
     509             :     case attribute_t::NODE_ATTR_max:
     510             :         // this should already have been caught in the verify_attribute() function
     511             :         throw exception_internal_error("invalid attribute / flag in Node::verify_attribute()"); // LCOV_EXCL_LINE
     512             : 
     513             :     // default: -- do not define so the compiler can tell us if
     514             :     //             an enumeration is missing in this case
     515             :     // note: verify_attribute(() is called before this function
     516             :     //       and it catches completely invalid attribute numbers
     517             :     //       (i.e. negative, larger than NODE_ATTR_max)
     518             :     }
     519             : 
     520       23250 :     if(conflict)
     521             :     {
     522             :         // this can be a user error so we emit an error instead of throwing
     523         320 :         Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_INVALID_ATTRIBUTES, f_position);
     524         320 :         msg << "Attributes " << names << " are mutually exclusive. Only one of them can be used.";
     525         320 :         return false;
     526             :     }
     527             : 
     528       22930 :     return true;
     529             : }
     530             : 
     531             : 
     532             : /** \brief Compare a set of attributes with the current attributes of this node.
     533             :  *
     534             :  * This function compares the specified set of attributes with the node's
     535             :  * attributes. If the sets are equal, then the function returns true.
     536             :  * Otherwise the function returns false.
     537             :  *
     538             :  * This function compares all the attributes, whether or not they are
     539             :  * valid for the current node type.
     540             :  *
     541             :  * \param[in] s  The set of attributes to compare with.
     542             :  *
     543             :  * \return true if \p s is equal to the node attributes.
     544             :  */
     545         420 : bool Node::compare_all_attributes(attribute_set_t const& s) const
     546             : {
     547         420 :     return f_attributes == s;
     548             : }
     549             : 
     550             : 
     551             : /** \brief Convert an attribute to a string.
     552             :  *
     553             :  * This function converts an attribute to a string. This is most often used
     554             :  * to print out an error about an attribute.
     555             :  *
     556             :  * \param[in] attr  The attribute to convert to a string.
     557             :  *
     558             :  * \return A static string pointer representing the attribute.
     559             :  */
     560       25250 : char const *Node::attribute_to_string(attribute_t const attr)
     561             : {
     562       25250 :     if(static_cast<int>(attr) < 0
     563       21000 :     || attr >= attribute_t::NODE_ATTR_max)
     564             :     {
     565        9350 :         throw exception_internal_error("unknown attribute number in Node::attribute_to_string()");
     566             :     }
     567             : 
     568       15900 :     return g_attribute_names[static_cast<int>(attr)];
     569             : }
     570             : 
     571             : 
     572          63 : }
     573             : // namespace as2js
     574             : 
     575             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.10