LCOV - code coverage report
Current view: top level - as2js/lib - node_convert.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 147 147 100.0 %
Date: 2014-08-10 Functions: 15 15 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* node_convert.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             : namespace as2js
      42             : {
      43             : 
      44             : 
      45             : /**********************************************************************/
      46             : /**********************************************************************/
      47             : /***  DATA CONVERSION  ************************************************/
      48             : /**********************************************************************/
      49             : /**********************************************************************/
      50             : 
      51             : 
      52             : /** \brief Transform any node to NODE_UNKNOWN
      53             :  *
      54             :  * This function mark the node as unknown. Absolutely any node can be
      55             :  * marked as unknown. It is particularly used by the compiler and
      56             :  * optimizer to cancel nodes that they cannot otherwise delete at
      57             :  * the time they are working on the tree.
      58             :  *
      59             :  * All the children of an unknown node are ignored too.
      60             :  *
      61             :  * To remove all the unknown nodes once the compiler is finished,
      62             :  * one can call the clean_tree() function.
      63             :  */
      64         340 : void Node::to_unknown()
      65             : {
      66         340 :     modifying();
      67             : 
      68             :     // whatever the type of node we can always convert it to an unknown
      69             :     // node since that's similar to "deleting" the node
      70         170 :     f_type = node_t::NODE_UNKNOWN;
      71             :     // clear the node's data to avoid other problems?
      72         170 : }
      73             : 
      74             : 
      75             : /** \brief Transform a call in a NODE_AS node.
      76             :  *
      77             :  * This function transform a node defined as NODE_CALL into a NODE_AS.
      78             :  * The special casting syntax looks exactly like a function call. For
      79             :  * this reason the parser returns it as such. The compiler, however,
      80             :  * can determine whether the function name is really a function name
      81             :  * or if it is a type name. If it is a type, then the tree is changed
      82             :  * to represent an AS instruction instead:
      83             :  *
      84             :  * \code
      85             :  *     type ( expression )
      86             :  *     expression AS type
      87             :  * \endcode
      88             :  *
      89             :  * \todo
      90             :  * We will need to verify that this is correct and does not introduce
      91             :  * other problems. However, remember that we do not use prototypes in
      92             :  * our world. We have well defined classes so it should work just fine.
      93             :  *
      94             :  * \return true if the conversion happens.
      95             :  */
      96         338 : bool Node::to_as()
      97             : {
      98         338 :     modifying();
      99             : 
     100             :     // "a call to a getter" may be transformed from CALL to AS
     101             :     // because a getter can very much look like a cast (false positive)
     102         169 :     if(node_t::NODE_CALL == f_type)
     103             :     {
     104           1 :         f_type = node_t::NODE_AS;
     105           1 :         return true;
     106             :     }
     107             : 
     108         168 :     return false;
     109             : }
     110             : 
     111             : 
     112             : /** \brief Check whether a node can be converted to Boolean.
     113             :  *
     114             :  * This function is constant and can be used to see whether a node
     115             :  * represent true or false without actually converting the node.
     116             :  *
     117             :  * \li NODE_TRUE -- returned as is
     118             :  * \li NODE_FALSE -- returned as is
     119             :  * \li NODE_NULL -- returns NODE_FALSE
     120             :  * \li NODE_UNDEFINED -- returns NODE_FALSE
     121             :  * \li NODE_INT64 -- returns NODE_TRUE unless the interger is zero
     122             :  *                   in which case NODE_FALSE is returned
     123             :  * \li NODE_FLOAT64 -- returns NODE_TRUE unless the floating point is zero
     124             :  *                     in which case NODE_FALSE is returned
     125             :  * \li NODE_STRING -- returns NODE_TRUE unless the string is empty in
     126             :  *                    which case NODE_FALSE is returned
     127             :  * \li Any other node type -- returns NODE_UNDEFINED
     128             :  *
     129             :  * \return NODE_TRUE, NODE_FALSE, or NODE_UNDEFINED depending on 'this' node
     130             :  */
     131         538 : Node::node_t Node::to_boolean_type_only() const
     132             : {
     133         538 :     switch(f_type)
     134             :     {
     135             :     case node_t::NODE_TRUE:
     136             :     case node_t::NODE_FALSE:
     137             :         // already a boolean
     138           4 :         return f_type;
     139             : 
     140             :     case node_t::NODE_NULL:
     141             :     case node_t::NODE_UNDEFINED:
     142           4 :         return node_t::NODE_FALSE;
     143             : 
     144             :     case node_t::NODE_INT64:
     145         102 :         return f_int.get() != 0 ? node_t::NODE_TRUE : node_t::NODE_FALSE;
     146             : 
     147             :     case node_t::NODE_FLOAT64:
     148             : #pragma GCC diagnostic push
     149             : #pragma GCC diagnostic ignored "-Wfloat-equal"
     150         102 :         return f_float.get() != 0.0 && !f_float.is_NaN() ? node_t::NODE_TRUE : node_t::NODE_FALSE;
     151             : #pragma GCC diagnostic pop
     152             : 
     153             :     case node_t::NODE_STRING:
     154           2 :         return f_str.is_true() ? node_t::NODE_TRUE : node_t::NODE_FALSE;
     155             : 
     156             :     default:
     157             :         // failure (cannot convert)
     158         324 :         return node_t::NODE_UNDEFINED;
     159             : 
     160             :     }
     161             :     /*NOTREACHED*/
     162             : }
     163             : 
     164             : 
     165             : /** \brief Convert this node to a boolean node.
     166             :  *
     167             :  * This function converts 'this' node to a Boolean node:
     168             :  *
     169             :  * \li NODE_TRUE -- no conversion
     170             :  * \li NODE_FALSE -- no conversion
     171             :  * \li NODE_NULL -- converted to NODE_FALSE
     172             :  * \li NODE_UNDEFINED -- converted to NODE_FALSE
     173             :  * \li NODE_INT64 -- converted to NODE_TRUE unless it is 0
     174             :  *                   in which case it gets converted to NODE_FALSE
     175             :  * \li NODE_FLOAT64 -- converted to NODE_TRUE unless it is 0.0
     176             :  *                     in which case it gets converted to NODE_FALSE
     177             :  * \li NODE_STRING -- converted to NODE_TRUE unless the string is empty
     178             :  *                    in which case it gets converted to NODE_FALSE
     179             :  *
     180             :  * \return true if the conversion succeeds.
     181             :  */
     182         538 : bool Node::to_boolean()
     183             : {
     184         538 :     modifying();
     185             : 
     186         369 :     switch(f_type)
     187             :     {
     188             :     case node_t::NODE_TRUE:
     189             :     case node_t::NODE_FALSE:
     190             :         // already a boolean
     191           2 :         break;
     192             : 
     193             :     case node_t::NODE_NULL:
     194             :     case node_t::NODE_UNDEFINED:
     195           2 :         f_type = node_t::NODE_FALSE;
     196           2 :         break;
     197             : 
     198             :     case node_t::NODE_INT64:
     199         101 :         f_type = f_int.get() != 0 ? node_t::NODE_TRUE : node_t::NODE_FALSE;
     200         101 :         break;
     201             : 
     202             :     case node_t::NODE_FLOAT64:
     203             : #pragma GCC diagnostic push
     204             : #pragma GCC diagnostic ignored "-Wfloat-equal"
     205         101 :         f_type = f_float.get() != 0.0 && !f_float.is_NaN() ? node_t::NODE_TRUE : node_t::NODE_FALSE;
     206             : #pragma GCC diagnostic pop
     207         101 :         break;
     208             : 
     209             :     case node_t::NODE_STRING:
     210           1 :         f_type = f_str.is_true() ? node_t::NODE_TRUE : node_t::NODE_FALSE;
     211           1 :         break;
     212             : 
     213             :     default:
     214             :         // failure (cannot convert)
     215         162 :         return false;
     216             : 
     217             :     }
     218             : 
     219         207 :     return true;
     220             : }
     221             : 
     222             : 
     223             : /** \brief Convert a member or assignment to a function call.
     224             :  *
     225             :  * This function is used to convert a getter to a function call.
     226             :  *
     227             :  * \code
     228             :  *     // Convert a getter to a function call
     229             :  *     a = foo.field;
     230             :  *     a = foo.field_getter();
     231             :  *
     232             :  *     // Convert a setter to a function call
     233             :  *     foo.field = a;
     234             :  *     foo.field_setter(a);
     235             :  * \endcode
     236             :  *
     237             :  * The function returns false if 'this' node is not a NODE_MEMBER or
     238             :  * a NODE_ASSIGNMENT.
     239             :  *
     240             :  * \return true if the conversion succeeded.
     241             :  */
     242         338 : bool Node::to_call()
     243             : {
     244         338 :     modifying();
     245             : 
     246             :     // getters are transformed from MEMBER to CALL
     247             :     // setters are transformed from ASSIGNMENT to CALL
     248         338 :     if(node_t::NODE_MEMBER == f_type        // member getter
     249         169 :     || node_t::NODE_ASSIGNMENT == f_type)   // assignment setter
     250             :     {
     251           2 :         f_type = node_t::NODE_CALL;
     252           2 :         return true;
     253             :     }
     254             : 
     255         167 :     return false;
     256             : }
     257             : 
     258             : 
     259             : /** \brief Convert this node to a NODE_IDENTIFIER.
     260             :  *
     261             :  * This function converts the node to an identifier. This is used to
     262             :  * transform some keywords back to an identifier.
     263             :  *
     264             :  * \li NODE_PRIVATE -- "private"
     265             :  * \li NODE_PROTECTED -- "protected"
     266             :  * \li NODE_PUBLIC -- "public"
     267             :  *
     268             :  * At this point this is used to transform these keywords in labels.
     269             :  *
     270             :  * \return true if the conversion succeeded.
     271             :  */
     272       24579 : bool Node::to_identifier()
     273             : {
     274       24579 :     modifying();
     275             : 
     276       24579 :     switch(f_type)
     277             :     {
     278             :     case node_t::NODE_PRIVATE:
     279        8193 :         f_type = node_t::NODE_IDENTIFIER;
     280        8193 :         set_string("private");
     281        8193 :         return true;
     282             : 
     283             :     case node_t::NODE_PROTECTED:
     284        8193 :         f_type = node_t::NODE_IDENTIFIER;
     285        8193 :         set_string("protected");
     286        8193 :         return true;
     287             : 
     288             :     case node_t::NODE_PUBLIC:
     289        8193 :         f_type = node_t::NODE_IDENTIFIER;
     290        8193 :         set_string("public");
     291        8193 :         return true;
     292             : 
     293             :     default:
     294             :         // failure (cannot convert)
     295       24579 :         return false;
     296             : 
     297             :     }
     298             :     /*NOTREACHED*/
     299             : }
     300             : 
     301             : 
     302             : /** \brief Convert this node to a NODE_INT64.
     303             :  *
     304             :  * This function converts the node to an integer number,
     305             :  * just like JavaScript would do. This means converting the following
     306             :  * type of nodes:
     307             :  *
     308             :  * \li NODE_INT64 -- no conversion
     309             :  * \li NODE_FLOAT64 -- convert to integer
     310             :  * \li NODE_TRUE -- convert to 1
     311             :  * \li NODE_FALSE -- convert to 0
     312             :  * \li NODE_NULL -- convert to 0
     313             :  * \li NODE_UNDEFINED -- convert to 0 (NaN is not possible in an integer)
     314             :  *
     315             :  * This function does not convert strings. You may use the to_number()
     316             :  * to get NODE_STRING converted although it will convert it to a
     317             :  * floating pointer number instead. To still get an integer call both
     318             :  * functions in a row:
     319             :  *
     320             :  * \code
     321             :  *    node->to_number();
     322             :  *    node->to_int64();
     323             :  * \endcode
     324             :  *
     325             :  * \return true if the conversion succeeded.
     326             :  */
     327         538 : bool Node::to_int64()
     328             : {
     329         538 :     modifying();
     330             : 
     331         369 :     switch(f_type)
     332             :     {
     333             :     case node_t::NODE_INT64:
     334         101 :         return true;
     335             : 
     336             :     case node_t::NODE_FLOAT64:
     337         101 :         f_int.set(f_float.get());
     338         101 :         break;
     339             : 
     340             :     case node_t::NODE_TRUE:
     341           1 :         f_int.set(1);
     342           1 :         break;
     343             : 
     344             :     case node_t::NODE_NULL:
     345             :     case node_t::NODE_FALSE:
     346             :     case node_t::NODE_UNDEFINED: // should return NaN, not possible with an integer...
     347           3 :         f_int.set(0);
     348           3 :         break;
     349             : 
     350             :     default:
     351             :         // failure (cannot convert)
     352         163 :         return false;
     353             : 
     354             :     }
     355             : 
     356         105 :     f_type = node_t::NODE_INT64;
     357         105 :     return true;
     358             : }
     359             : 
     360             : 
     361             : /** \brief Convert this node to a NODE_FLOAT64.
     362             :  *
     363             :  * This function converts the node to a floatingp point number,
     364             :  * just like JavaScript would do. This means converting the following
     365             :  * type of nodes:
     366             :  *
     367             :  * \li NODE_INT64 -- convert to a float
     368             :  * \li NODE_FLOAT64 -- no conversion
     369             :  * \li NODE_TRUE -- convert to 1.0
     370             :  * \li NODE_FALSE -- convert to 0.0
     371             :  * \li NODE_NULL -- convert to 0.0
     372             :  * \li NODE_UNDEFINED -- convert to NaN
     373             :  *
     374             :  * This function does not convert strings. You may use the to_number()
     375             :  * to get NODE_STRING converted.
     376             :  *
     377             :  * \return true if the conversion succeeded.
     378             :  */
     379         538 : bool Node::to_float64()
     380             : {
     381         538 :     modifying();
     382             : 
     383         369 :     switch(f_type)
     384             :     {
     385             :     case node_t::NODE_INT64:
     386         101 :         f_float.set(f_int.get());
     387         101 :         break;
     388             : 
     389             :     case node_t::NODE_FLOAT64:
     390         101 :         return true;
     391             : 
     392             :     case node_t::NODE_TRUE:
     393           1 :         f_float.set(1.0);
     394           1 :         break;
     395             : 
     396             :     case node_t::NODE_NULL:
     397             :     case node_t::NODE_FALSE:
     398           2 :         f_float.set(0.0);
     399           2 :         break;
     400             : 
     401             :     case node_t::NODE_UNDEFINED:
     402           1 :         f_float.set_NaN();
     403           1 :         break;
     404             : 
     405             :     default:
     406             :         // failure (cannot convert)
     407         163 :         return false;
     408             : 
     409             :     }
     410             : 
     411         105 :     f_type = node_t::NODE_FLOAT64;
     412         105 :     return true;
     413             : }
     414             : 
     415             : 
     416             : /** \brief Convert this node to a label.
     417             :  *
     418             :  * This function converts a NODE_IDENTIFIER node to a NODE_LABEL node.
     419             :  *
     420             :  * \return true if the conversion succeeded.
     421             :  */
     422       41303 : bool Node::to_label()
     423             : {
     424       41303 :     modifying();
     425             : 
     426       41134 :     switch(f_type)
     427             :     {
     428             :     case node_t::NODE_IDENTIFIER:
     429       40966 :         f_type = node_t::NODE_LABEL;
     430       40966 :         break;
     431             : 
     432             :     default:
     433             :         // failure (cannot convert)
     434         168 :         return false;
     435             : 
     436             :     }
     437             : 
     438       40966 :     return true;
     439             : }
     440             : 
     441             : 
     442             : /** \brief Convert this node to a number.
     443             :  *
     444             :  * This function converts the node to a number just like JavaScript would do.
     445             :  * This means converting the following type of nodes:
     446             :  *
     447             :  * \li NODE_INT64 -- no conversion
     448             :  * \li NODE_FLOAT64 -- no conversion
     449             :  * \li NODE_TRUE -- convert to 1 (INT64)
     450             :  * \li NODE_FALSE -- convert to 0 (INT64)
     451             :  * \li NODE_NULL -- convert to 0 (INT64)
     452             :  * \li NODE_UNDEFINED -- convert to NaN (FLOAT64)
     453             :  * \li NODE_STRING -- converted to a float, NaN if not a valid float,
     454             :  *                    however, zero if empty.
     455             :  *
     456             :  * \return true if the conversion succeeded.
     457             :  */
     458         538 : bool Node::to_number()
     459             : {
     460         538 :     modifying();
     461             : 
     462         369 :     switch(f_type)
     463             :     {
     464             :     case node_t::NODE_INT64:
     465             :     case node_t::NODE_FLOAT64:
     466         202 :         break;
     467             : 
     468             :     case node_t::NODE_TRUE:
     469           1 :         f_type = node_t::NODE_INT64;
     470           1 :         f_int.set(1);
     471           1 :         break;
     472             : 
     473             :     case node_t::NODE_NULL:
     474             :     case node_t::NODE_FALSE:
     475           2 :         f_type = node_t::NODE_INT64;
     476           2 :         f_int.set(0);
     477           2 :         break;
     478             : 
     479             :     case node_t::NODE_UNDEFINED:
     480           1 :         f_type = node_t::NODE_FLOAT64;
     481           1 :         f_float.set_NaN();
     482           1 :         break;
     483             : 
     484             :     case node_t::NODE_STRING:
     485             :         // JavaScript tends to force conversions from stings to numbers
     486             :         // when possible (actually it always is, only strings often become
     487             :         // NaN as a result)
     488           1 :         f_type = node_t::NODE_FLOAT64;
     489           1 :         f_float.set(f_str.to_float64());
     490           1 :         break;
     491             : 
     492             :     default:
     493             :         // failure (cannot convert)
     494         162 :         return false;
     495             : 
     496             :     }
     497             : 
     498         207 :     return true;
     499             : }
     500             : 
     501             : 
     502             : /** \brief Transform a node to a string.
     503             :  *
     504             :  * This function transform a node from what it is to a string. If the
     505             :  * transformation is successful, the function returns true. Note that
     506             :  * the function does not throw if the type of 'this' cannot be
     507             :  * converted to a string.
     508             :  *
     509             :  * The nodes that can be converted to a string are:
     510             :  *
     511             :  * \li NODE_STRING -- unchanged
     512             :  * \li NODE_IDENTIFIER -- the identifier is now a string
     513             :  * \li NODE_UNDEFINED -- changed to "undefined"
     514             :  * \li NODE_NULL -- changed to "null"
     515             :  * \li NODE_TRUE -- changed to "true"
     516             :  * \li NODE_FALSE -- changed to "false"
     517             :  * \li NODE_INT64 -- changed to a string representation
     518             :  * \li NODE_FLOAT64 -- changed to a string representation
     519             :  *
     520             :  * \return true if the conversion succeeded, false otherwise.
     521             :  */
     522         541 : bool Node::to_string()
     523             : {
     524         541 :     modifying();
     525             : 
     526         372 :     switch(f_type)
     527             :     {
     528             :     case node_t::NODE_STRING:
     529           1 :         return true;
     530             : 
     531             :     case node_t::NODE_IDENTIFIER:
     532             :         // this happens with special identifiers that are strings in the end
     533           1 :         break;
     534             : 
     535             :     case node_t::NODE_UNDEFINED:
     536           1 :         f_str = "undefined";
     537           1 :         break;
     538             : 
     539             :     case node_t::NODE_NULL:
     540           1 :         f_str = "null";
     541           1 :         break;
     542             : 
     543             :     case node_t::NODE_TRUE:
     544           1 :         f_str = "true";
     545           1 :         break;
     546             : 
     547             :     case node_t::NODE_FALSE:
     548           1 :         f_str = "false";
     549           1 :         break;
     550             : 
     551             :     case node_t::NODE_INT64:
     552         101 :         f_str = std::to_string(f_int.get());
     553         101 :         break;
     554             : 
     555             :     case node_t::NODE_FLOAT64:
     556             : #pragma GCC diagnostic push
     557             : #pragma GCC diagnostic ignored "-Wfloat-equal"
     558             :     {
     559         104 :         Float64::float64_type const value(f_float.get());
     560         104 :         if(f_float.is_NaN())
     561             :         {
     562           1 :             f_str = "NaN";
     563             :         }
     564         103 :         else if(value == 0.0)
     565             :         {
     566             :             // make sure it does not become "0.0"
     567           1 :             f_str = "0";
     568             :         }
     569         102 :         else if(f_float.is_negative_infinity())
     570             :         {
     571           1 :             f_str = "-Infinity";
     572             :         }
     573         101 :         else if(f_float.is_positive_infinity())
     574             :         {
     575           1 :             f_str = "Infinity";
     576             :         }
     577             :         else
     578             :         {
     579         100 :             f_str = std::to_string(value);
     580             :         }
     581             :     }
     582             : #pragma GCC diagnostic pop
     583         104 :         break;
     584             : 
     585             :     default:
     586             :         // failure (cannot convert)
     587         161 :         return false;
     588             : 
     589             :     }
     590         210 :     f_type = node_t::NODE_STRING;
     591             : 
     592         372 :     return true;
     593             : }
     594             : 
     595             : 
     596             : /** \brief Transform an identifier into a NODE_VIDENTIFIER.
     597             :  *
     598             :  * This function is used to transform an identifier in a variable
     599             :  * identifier. By default identifiers may represent object names.
     600             :  * However, when written between parenthesis, they always represent
     601             :  * a variable. This can be important as certain syntax are not
     602             :  * at all equivalent:
     603             :  *
     604             :  * \code
     605             :  *    (a).field      // a becomes a NODE_VIDENTIFIER
     606             :  *    a.field
     607             :  * \code
     608             :  *
     609             :  * In the first case, (a) is transform with the content of variable
     610             :  * 'a' and that is used to access 'field'.
     611             :  *
     612             :  * In the second case, 'a' represents an object and we are access
     613             :  * that object's 'field' directly.
     614             :  *
     615             :  * \todo
     616             :  * Determine whether that really applies to JavaScript.
     617             :  *
     618             :  * \exception exception_internal_error
     619             :  * This exception is raised if the input node is not a NODE_IDENTIFIER.
     620             :  */
     621       24917 : void Node::to_videntifier()
     622             : {
     623       24917 :     modifying();
     624             : 
     625       24748 :     if(node_t::NODE_IDENTIFIER != f_type)
     626             :     {
     627         168 :         throw exception_internal_error("to_videntifier() called with a node other than a NODE_IDENTIFIER node");
     628             :     }
     629             : 
     630       24580 :     f_type = node_t::NODE_VIDENTIFIER;
     631       24580 : }
     632             : 
     633             : 
     634             : /** \brief Transform a variable into a variable of attributes.
     635             :  *
     636             :  * When compiling the tree, the code in compiler_variable.cpp may detect
     637             :  * that a variable is specifically used to represent a list of attributes.
     638             :  * When that happens, the compiler transforms the variable calling
     639             :  * this function.
     640             :  *
     641             :  * The distinction makes it a lot easier to deal with the variable later.
     642             :  *
     643             :  * \exception exception_internal_error
     644             :  * This exception is raised if 'this' node is not a NODE_VARIABLE.
     645             :  */
     646         338 : void Node::to_var_attributes()
     647             : {
     648         338 :     modifying();
     649             : 
     650         169 :     if(node_t::NODE_VARIABLE != f_type)
     651             :     {
     652         168 :         throw exception_internal_error("to_var_attribute() called with a node other than a NODE_VARIABLE node");
     653             :     }
     654             : 
     655           1 :     f_type = node_t::NODE_VAR_ATTRIBUTES;
     656           1 : }
     657             : 
     658             : 
     659          20 : }
     660             : // namespace as2js
     661             : 
     662             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.9