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

          Line data    Source code
       1             : /* node_flag.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             : 
      40             : 
      41             : /** \file
      42             :  * \brief Handle the node flags.
      43             :  *
      44             :  * Nodes accept a large set of flags (42 at time of writing).
      45             :  *
      46             :  * Flags are specific to node types. In an earlier implementation,
      47             :  * flags would overlap (i.e. the same bit would be used by different
      48             :  * flags, which flag was determine by the type of node being used.)
      49             :  * This was revamped to make use of unique flags in order to over
      50             :  * potential bugs.
      51             :  *
      52             :  * Flags being specific to a node type, the various functions below
      53             :  * make sure that the flags modified on a node are compatible with
      54             :  * that node.
      55             :  *
      56             :  * \todo
      57             :  * The conversion functions do not take flags in account. As far as
      58             :  * I know, at this point we cannot convert a node of a type that
      59             :  * accept a flag except with the to_unknown() function in which
      60             :  * case flags become irrelevant anyway. We should test that the
      61             :  * flags remain valid after a conversion.
      62             :  *
      63             :  * \todo
      64             :  * Mutually exclusive flags are not currently verified in this
      65             :  * code when it should be.
      66             :  */
      67             : 
      68             : 
      69             : namespace as2js
      70             : {
      71             : 
      72             : 
      73             : 
      74             : /**********************************************************************/
      75             : /**********************************************************************/
      76             : /***  NODE FLAG  ******************************************************/
      77             : /**********************************************************************/
      78             : /**********************************************************************/
      79             : 
      80             : 
      81             : /** \brief Get the current status of a flag.
      82             :  *
      83             :  * This function returns true or false depending on the current status
      84             :  * of the specified flag.
      85             :  *
      86             :  * The function verifies that the specified flag (\p f) corresponds to
      87             :  * the Node type we are dealing with.
      88             :  *
      89             :  * If the flag was never set, this function returns false.
      90             :  *
      91             :  * compare_all_flags() can be used to compare all the flags at once
      92             :  * without having to load each flag one at a time. This is particularly
      93             :  * useful in our unit tests.
      94             :  *
      95             :  * \param[in] f  The flag to retrieve.
      96             :  *
      97             :  * \return true if the flag was set to true, false otherwise.
      98             :  *
      99             :  * \sa set_flag()
     100             :  * \sa verify_flag()
     101             :  * \sa compare_all_flags()
     102             :  */
     103    37464768 : bool Node::get_flag(flag_t f) const
     104             : {
     105    37464768 :     verify_flag(f);
     106    37455815 :     return f_flags[static_cast<size_t>(f)];
     107             : }
     108             : 
     109             : 
     110             : /** \brief Set a flag.
     111             :  *
     112             :  * This function sets the specified flag \p f to the specified value \p v
     113             :  * in this Node object.
     114             :  *
     115             :  * The function verifies that the specified flag (\p f) corresponds to
     116             :  * the Node type we are dealing with.
     117             :  *
     118             :  * \param[in] f  The flag to set.
     119             :  * \param[in] v  The new value for the flag.
     120             :  *
     121             :  * \sa get_flag()
     122             :  * \sa verify_flag()
     123             :  */
     124     1983576 : void Node::set_flag(flag_t f, bool v)
     125             : {
     126     1983576 :     verify_flag(f);
     127     1965670 :     f_flags[static_cast<size_t>(f)] = v;
     128     1965670 : }
     129             : 
     130             : 
     131             : /** \brief Verify that f corresponds to the node type.
     132             :  *
     133             :  * This function verifies that \p f corresponds to a valid flag according
     134             :  * to the type of this Node object.
     135             :  *
     136             :  * \todo
     137             :  * Move some of the external tests (tests done by code in other
     138             :  * places like the parser) to here because some flags are
     139             :  * mutally exclusive and we should prevent such from being set
     140             :  * simultaneously.
     141             :  *
     142             :  * \exception exception_internal_error
     143             :  * This function checks that the flag is allowed in the type of node.
     144             :  * If not, this exception is raised because that represents a compiler
     145             :  * bug.
     146             :  *
     147             :  * \param[in] f  The flag to check.
     148             :  *
     149             :  * \sa set_flag()
     150             :  * \sa get_flag()
     151             :  */
     152    39448344 : void Node::verify_flag(flag_t f) const
     153             : {
     154    39448344 :     switch(f)
     155             :     {
     156             :     case flag_t::NODE_CATCH_FLAG_TYPED:
     157       90626 :         if(f_type == node_t::NODE_CATCH)
     158             :         {
     159       90119 :             return;
     160             :         }
     161         507 :         break;
     162             : 
     163             :     case flag_t::NODE_DIRECTIVE_LIST_FLAG_NEW_VARIABLES:
     164     2557298 :         if(f_type == node_t::NODE_DIRECTIVE_LIST)
     165             :         {
     166     2556791 :             return;
     167             :         }
     168         507 :         break;
     169             : 
     170             :     case flag_t::NODE_ENUM_FLAG_CLASS:
     171      156162 :         if(f_type == node_t::NODE_ENUM)
     172             :         {
     173      155655 :             return;
     174             :         }
     175         507 :         break;
     176             : 
     177             :     case flag_t::NODE_FOR_FLAG_CONST:
     178             :     case flag_t::NODE_FOR_FLAG_FOREACH:
     179             :     case flag_t::NODE_FOR_FLAG_IN:
     180      476709 :         if(f_type == node_t::NODE_FOR)
     181             :         {
     182      475188 :             return;
     183             :         }
     184        1521 :         break;
     185             : 
     186             :     case flag_t::NODE_FUNCTION_FLAG_GETTER:
     187             :     case flag_t::NODE_FUNCTION_FLAG_NEVER:
     188             :     case flag_t::NODE_FUNCTION_FLAG_NOPARAMS:
     189             :     case flag_t::NODE_FUNCTION_FLAG_OPERATOR:
     190             :     case flag_t::NODE_FUNCTION_FLAG_OUT:
     191             :     case flag_t::NODE_FUNCTION_FLAG_SETTER:
     192             :     case flag_t::NODE_FUNCTION_FLAG_VOID:
     193     7475763 :         if(f_type == node_t::NODE_FUNCTION)
     194             :         {
     195     7472214 :             return;
     196             :         }
     197        3549 :         break;
     198             : 
     199             :     case flag_t::NODE_IDENTIFIER_FLAG_WITH:
     200             :     case flag_t::NODE_IDENTIFIER_FLAG_TYPED:
     201    19369566 :         if(f_type == node_t::NODE_IDENTIFIER
     202      853382 :         || f_type == node_t::NODE_VIDENTIFIER
     203    10488995 :         || f_type == node_t::NODE_STRING)
     204             :         {
     205     9683781 :             return;
     206             :         }
     207        1002 :         break;
     208             : 
     209             :     case flag_t::NODE_IMPORT_FLAG_IMPLEMENTS:
     210      172546 :         if(f_type == node_t::NODE_IMPORT)
     211             :         {
     212      172039 :             return;
     213             :         }
     214         507 :         break;
     215             : 
     216             :     case flag_t::NODE_PACKAGE_FLAG_FOUND_LABELS:
     217             :     case flag_t::NODE_PACKAGE_FLAG_REFERENCED:
     218      263176 :         if(f_type == node_t::NODE_PACKAGE)
     219             :         {
     220      262162 :             return;
     221             :         }
     222        1014 :         break;
     223             : 
     224             :     case flag_t::NODE_PARAM_MATCH_FLAG_UNPROTOTYPED:
     225         514 :         if(f_type == node_t::NODE_PARAM_MATCH)
     226             :         {
     227           7 :             return;
     228             :         }
     229         507 :         break;
     230             : 
     231             :     case flag_t::NODE_PARAM_FLAG_CATCH:         // a parameter defined in a catch()
     232             :     case flag_t::NODE_PARAM_FLAG_CONST:
     233             :     case flag_t::NODE_PARAM_FLAG_IN:
     234             :     case flag_t::NODE_PARAM_FLAG_OUT:
     235             :     case flag_t::NODE_PARAM_FLAG_NAMED:
     236             :     case flag_t::NODE_PARAM_FLAG_PARAMREF:      // referenced from another parameter
     237             :     case flag_t::NODE_PARAM_FLAG_REFERENCED:    // referenced from a parameter or a variable
     238             :     case flag_t::NODE_PARAM_FLAG_REST:
     239             :     case flag_t::NODE_PARAM_FLAG_UNCHECKED:
     240             :     case flag_t::NODE_PARAM_FLAG_UNPROTOTYPED:
     241    11238901 :         if(f_type == node_t::NODE_PARAM)
     242             :         {
     243    11233831 :             return;
     244             :         }
     245        5070 :         break;
     246             : 
     247             :     case flag_t::NODE_SWITCH_FLAG_DEFAULT:           // we found a 'default:' label in that switch
     248       82434 :         if(f_type == node_t::NODE_SWITCH)
     249             :         {
     250       81927 :             return;
     251             :         }
     252         507 :         break;
     253             : 
     254             :     case flag_t::NODE_TYPE_FLAG_MODULO:             // type ... as mod ...;
     255      696834 :         if(f_type == node_t::NODE_TYPE)
     256             :         {
     257      696327 :             return;
     258             :         }
     259         507 :         break;
     260             : 
     261             :     case flag_t::NODE_VARIABLE_FLAG_CONST:
     262             :     case flag_t::NODE_VARIABLE_FLAG_LOCAL:
     263             :     case flag_t::NODE_VARIABLE_FLAG_MEMBER:
     264             :     case flag_t::NODE_VARIABLE_FLAG_ATTRIBUTES:
     265             :     case flag_t::NODE_VARIABLE_FLAG_ENUM:                 // there is a NODE_SET and it somehow needs to be copied
     266             :     case flag_t::NODE_VARIABLE_FLAG_COMPILED:             // Expression() was called on the NODE_SET
     267             :     case flag_t::NODE_VARIABLE_FLAG_INUSE:                // this variable was referenced
     268             :     case flag_t::NODE_VARIABLE_FLAG_ATTRS:                // currently being read for attributes (to avoid loops)
     269             :     case flag_t::NODE_VARIABLE_FLAG_DEFINED:              // was already parsed
     270             :     case flag_t::NODE_VARIABLE_FLAG_DEFINING:             // currently defining, can't read
     271             :     case flag_t::NODE_VARIABLE_FLAG_TOADD:                // to be added in the directive list
     272    13093976 :         if(f_type == node_t::NODE_VARIABLE
     273     6546988 :         || f_type == node_t::NODE_VAR_ATTRIBUTES)
     274             :         {
     275     6541444 :             return;
     276             :         }
     277        5544 :         break;
     278             : 
     279             :     case flag_t::NODE_FLAG_max:
     280         510 :         break;
     281             : 
     282             :     // default: -- do not define so the compiler can tell us if
     283             :     //             an enumeration is missing in this case
     284             :     }
     285             : 
     286             :     // since we do not use 'default' completely invalid values are not caught
     287             :     // in the switch...
     288       26859 :     throw exception_internal_error("flag / type missmatch in Node::verify_flag()");
     289             : }
     290             : 
     291             : 
     292             : /** \brief Compare a set of flags with the current flags of this node.
     293             :  *
     294             :  * This function compares the specified set of flags with the node's
     295             :  * flags. If the sets are equal, then the function returns true.
     296             :  * Otherwise the function returns false.
     297             :  *
     298             :  * This function compares all the flags, whether or not they are
     299             :  * valid for the current node type.
     300             :  *
     301             :  * \param[in] s  The set of flags to compare with.
     302             :  *
     303             :  * \return true if \p s is equal to the node flags.
     304             :  *
     305             :  * \sa get_flag()
     306             :  */
     307         171 : bool Node::compare_all_flags(flag_set_t const& s) const
     308             : {
     309         171 :     return f_flags == s;
     310             : }
     311             : 
     312             : 
     313          63 : }
     314             : // namespace as2js
     315             : 
     316             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.10