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

          Line data    Source code
       1             : /* node_display.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    <controlled_vars/controlled_vars_auto_enum_init.h>
      39             : 
      40             : #include    <iomanip>
      41             : 
      42             : 
      43             : namespace as2js
      44             : {
      45             : 
      46             : 
      47             : /**********************************************************************/
      48             : /**********************************************************************/
      49             : /***  NODE DISPLAY  ***************************************************/
      50             : /**********************************************************************/
      51             : /**********************************************************************/
      52             : 
      53             : 
      54             : /** \brief Display a node.
      55             :  *
      56             :  * This function prints a node in the \p out stream.
      57             :  *
      58             :  * The function is smart enough to recognize the different type of nodes
      59             :  * and thus know what is saved in them and knows how to display all of
      60             :  * that information.
      61             :  *
      62             :  * This is only to display a node in a technical way. It does not attempt
      63             :  * to display things in JavaScript or any other language.
      64             :  *
      65             :  * \param[in] out  The output stream where the node is displayed.
      66             :  */
      67       12038 : void Node::display_data(std::ostream& out) const
      68             : {
      69             :     struct sub_function
      70             :     {
      71        7626 :         static void display_str(std::ostream& out, String str)
      72             :         {
      73        7626 :             out << ": '";
      74      867045 :             for(as_char_t const *s(str.c_str()); *s != '\0'; ++s)
      75             :             {
      76      859419 :                 if(*s < 0x20)
      77             :                 {
      78             :                     // show controls as ^<letter>
      79          21 :                     out << '^' << static_cast<char>(*s + '@');
      80             :                 }
      81      859398 :                 else if(*s < 0x7f)
      82             :                 {
      83          92 :                     if(*s == '\'')
      84             :                     {
      85           1 :                         out << "\\'";
      86             :                     }
      87             :                     else
      88             :                     {
      89          92 :                         out << static_cast<char>(*s);
      90             :                     }
      91             :                 }
      92      859306 :                 else if(*s < 0x100)
      93             :                 {
      94         104 :                     out << "\\x" << std::hex << *s << std::dec;
      95             :                 }
      96      859202 :                 else if(*s < 0x10000)
      97             :                 {
      98       48979 :                     out << "\\u" << std::hex << std::setfill('0') << std::setw(4) << *s << std::dec;
      99             :                 }
     100             :                 else
     101             :                 {
     102      810223 :                     out << "\\U" << std::hex << std::setfill('0') << std::setw(8) << *s << std::dec;
     103             :                 }
     104             :             }
     105        7626 :             out << "'";
     106        7626 :         }
     107             :     };
     108             : 
     109             :     // WARNING: somehow g++ views the node_t type as a Node type and thus
     110             :     //          it recursively calls this function until the stack is full
     111       12038 :     out << std::setw(4) << std::setfill('0') << static_cast<int>(static_cast<node_t>(f_type))
     112       24076 :         << std::setfill('\0') << ": " << get_type_name();
     113       12038 :     if(static_cast<int>(static_cast<node_t>(f_type)) > ' ' && static_cast<int>(static_cast<node_t>(f_type)) < 0x7F)
     114             :     {
     115         668 :         out << " = '" << static_cast<char>(static_cast<node_t>(f_type)) << "'";
     116             :     }
     117             : 
     118       12038 :     switch(f_type)
     119             :     {
     120             :     case node_t::NODE_BREAK:
     121             :     case node_t::NODE_CLASS:
     122             :     case node_t::NODE_CONTINUE:
     123             :     case node_t::NODE_GOTO:
     124             :     case node_t::NODE_INTERFACE:
     125             :     case node_t::NODE_LABEL:
     126             :     case node_t::NODE_NAMESPACE:
     127             :     case node_t::NODE_REGULAR_EXPRESSION:
     128          10 :         sub_function::display_str(out, f_str);
     129          10 :         break;
     130             : 
     131             :     case node_t::NODE_CATCH:
     132           3 :         out << ":";
     133           3 :         if(f_flags[static_cast<size_t>(flag_t::NODE_CATCH_FLAG_TYPED)])
     134             :         {
     135           1 :             out << " TYPED";
     136             :         }
     137           3 :         break;
     138             : 
     139             :     case node_t::NODE_DIRECTIVE_LIST:
     140           5 :         out << ":";
     141           5 :         if(f_flags[static_cast<size_t>(flag_t::NODE_DIRECTIVE_LIST_FLAG_NEW_VARIABLES)])
     142             :         {
     143           2 :             out << " NEW-VARIABLES";
     144             :         }
     145           5 :         break;
     146             : 
     147             :     case node_t::NODE_ENUM:
     148           3 :         sub_function::display_str(out, f_str);
     149           3 :         if(f_flags[static_cast<size_t>(flag_t::NODE_ENUM_FLAG_CLASS)])
     150             :         {
     151           1 :             out << " CLASS";
     152             :         }
     153           3 :         break;
     154             : 
     155             :     case node_t::NODE_FOR:
     156           9 :         out << ":";
     157           9 :         if(f_flags[static_cast<size_t>(flag_t::NODE_FOR_FLAG_CONST)])
     158             :         {
     159           4 :             out << " CONST";
     160             :         }
     161           9 :         if(f_flags[static_cast<size_t>(flag_t::NODE_FOR_FLAG_FOREACH)])
     162             :         {
     163           4 :             out << " FOREACH";
     164             :         }
     165           9 :         if(f_flags[static_cast<size_t>(flag_t::NODE_FOR_FLAG_IN)])
     166             :         {
     167           4 :             out << " IN";
     168             :         }
     169           9 :         break;
     170             : 
     171             :     case node_t::NODE_IDENTIFIER:
     172             :     case node_t::NODE_STRING:
     173             :     case node_t::NODE_VIDENTIFIER:
     174        3375 :         sub_function::display_str(out, f_str);
     175        3375 :         if(f_flags[static_cast<size_t>(flag_t::NODE_IDENTIFIER_FLAG_WITH)])
     176             :         {
     177           6 :             out << " WITH";
     178             :         }
     179        3375 :         if(f_flags[static_cast<size_t>(flag_t::NODE_IDENTIFIER_FLAG_TYPED)])
     180             :         {
     181           7 :             out << " TYPED";
     182             :         }
     183        3375 :         break;
     184             : 
     185             :     case node_t::NODE_IMPORT:
     186           3 :         sub_function::display_str(out, f_str);
     187           3 :         if(f_flags[static_cast<size_t>(flag_t::NODE_IMPORT_FLAG_IMPLEMENTS)])
     188             :         {
     189           1 :             out << " IMPLEMENTS";
     190             :         }
     191           3 :         break;
     192             : 
     193             :     case node_t::NODE_PACKAGE:
     194           5 :         sub_function::display_str(out, f_str);
     195           5 :         if(f_flags[static_cast<size_t>(flag_t::NODE_PACKAGE_FLAG_FOUND_LABELS)])
     196             :         {
     197           2 :             out << " FOUND-LABELS";
     198             :         }
     199           5 :         if(f_flags[static_cast<size_t>(flag_t::NODE_PACKAGE_FLAG_REFERENCED)])
     200             :         {
     201           2 :             out << " REFERENCED";
     202             :         }
     203           5 :         break;
     204             : 
     205             :     case node_t::NODE_INT64:
     206           1 :         out << ": " << f_int.get() << ", 0x" << std::hex << std::setw(16) << std::setfill('0') << f_int.get() << std::dec << std::setw(0) << std::setfill('\0');
     207           1 :         break;
     208             : 
     209             :     case node_t::NODE_FLOAT64:
     210           2 :         out << ": " << f_float.get();
     211           2 :         break;
     212             : 
     213             :     case node_t::NODE_FUNCTION:
     214         130 :         sub_function::display_str(out, f_str);
     215         130 :         if(f_flags[static_cast<size_t>(flag_t::NODE_FUNCTION_FLAG_GETTER)])
     216             :         {
     217          64 :             out << " GETTER";
     218             :         }
     219         130 :         if(f_flags[static_cast<size_t>(flag_t::NODE_FUNCTION_FLAG_SETTER)])
     220             :         {
     221          64 :             out << " SETTER";
     222             :         }
     223         130 :         if(f_flags[static_cast<size_t>(flag_t::NODE_FUNCTION_FLAG_OUT)])
     224             :         {
     225          64 :             out << " OUT";
     226             :         }
     227         130 :         if(f_flags[static_cast<size_t>(flag_t::NODE_FUNCTION_FLAG_VOID)])
     228             :         {
     229          64 :             out << " VOID";
     230             :         }
     231         130 :         if(f_flags[static_cast<size_t>(flag_t::NODE_FUNCTION_FLAG_NEVER)])
     232             :         {
     233          64 :             out << " NEVER";
     234             :         }
     235         130 :         if(f_flags[static_cast<size_t>(flag_t::NODE_FUNCTION_FLAG_NOPARAMS)])
     236             :         {
     237          64 :             out << " NOPARAMS";
     238             :         }
     239         130 :         if(f_flags[static_cast<size_t>(flag_t::NODE_FUNCTION_FLAG_OPERATOR)])
     240             :         {
     241          64 :             out << " OPERATOR";
     242             :         }
     243         130 :         break;
     244             : 
     245             :     case node_t::NODE_PARAM:
     246             :         // THIS SEEMS WRONG, We do not save a string in
     247             :         // the NODE_PARAM; so either it is wrong here or
     248             :         // we miss the necessary call(s) when parsing the
     249             :         // function list of parameters
     250             :         //sub_function::display_str(out, f_str);
     251        1025 :         out << ":";
     252        1025 :         if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_CONST)])
     253             :         {
     254         512 :             out << " CONST";
     255             :         }
     256        1025 :         if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_IN)])
     257             :         {
     258         512 :             out << " IN";
     259             :         }
     260        1025 :         if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_OUT)])
     261             :         {
     262         512 :             out << " OUT";
     263             :         }
     264        1025 :         if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_NAMED)])
     265             :         {
     266         512 :             out << " NAMED";
     267             :         }
     268        1025 :         if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_REST)])
     269             :         {
     270         512 :             out << " REST";
     271             :         }
     272        1025 :         if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_UNCHECKED)])
     273             :         {
     274         512 :             out << " UNCHECKED";
     275             :         }
     276        1025 :         if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_UNPROTOTYPED)])
     277             :         {
     278         512 :             out << " UNPROTOTYPED";
     279             :         }
     280        1025 :         if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_REFERENCED)])
     281             :         {
     282         512 :             out << " REFERENCED";
     283             :         }
     284        1025 :         if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_PARAMREF)])
     285             :         {
     286         512 :             out << " PARAMREF";
     287             :         }
     288        1025 :         if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_CATCH)])
     289             :         {
     290         512 :             out << " CATCH";
     291             :         }
     292        1025 :         break;
     293             : 
     294             :     case node_t::NODE_PARAM_MATCH:
     295           3 :         out << ":";
     296           3 :         if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_MATCH_FLAG_UNPROTOTYPED)])
     297             :         {
     298           1 :             out << " UNPROTOTYPED";
     299             :         }
     300           3 :         break;
     301             : 
     302             :     case node_t::NODE_SWITCH:
     303           3 :         out << ":";
     304           3 :         if(f_flags[static_cast<size_t>(flag_t::NODE_SWITCH_FLAG_DEFAULT)])
     305             :         {
     306           1 :             out << " DEFAULT";
     307             :         }
     308           3 :         break;
     309             : 
     310             :     case node_t::NODE_TYPE:
     311           3 :         out << ":";
     312           3 :         if(f_flags[static_cast<size_t>(flag_t::NODE_TYPE_FLAG_MODULO)])
     313             :         {
     314           1 :             out << " MODULO";
     315             :         }
     316           3 :         break;
     317             : 
     318             :     case node_t::NODE_VARIABLE:
     319             :     case node_t::NODE_VAR_ATTRIBUTES:
     320        4100 :         sub_function::display_str(out, f_str);
     321        4100 :         if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_CONST)])
     322             :         {
     323        2048 :             out << " CONST";
     324             :         }
     325        4100 :         if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_LOCAL)])
     326             :         {
     327        2048 :             out << " LOCAL";
     328             :         }
     329        4100 :         if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_MEMBER)])
     330             :         {
     331        2048 :             out << " MEMBER";
     332             :         }
     333        4100 :         if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_ATTRIBUTES)])
     334             :         {
     335        2048 :             out << " ATTRIBUTES";
     336             :         }
     337        4100 :         if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_ENUM)])
     338             :         {
     339        2048 :             out << " ENUM";
     340             :         }
     341        4100 :         if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_COMPILED)])
     342             :         {
     343        2048 :             out << " COMPILED";
     344             :         }
     345        4100 :         if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_INUSE)])
     346             :         {
     347        2048 :             out << " INUSE";
     348             :         }
     349        4100 :         if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_ATTRS)])
     350             :         {
     351        2048 :             out << " ATTRS";
     352             :         }
     353        4100 :         if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_DEFINED)])
     354             :         {
     355        2048 :             out << " DEFINED";
     356             :         }
     357        4100 :         if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_DEFINING)])
     358             :         {
     359        2048 :             out << " DEFINING";
     360             :         }
     361        4100 :         if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_TOADD)])
     362             :         {
     363        2048 :             out << " TOADD";
     364             :         }
     365        4100 :         break;
     366             : 
     367             :     default:
     368        3358 :         break;
     369             : 
     370             :     }
     371       12038 : }
     372             : 
     373             : 
     374             : /** \brief Display a node tree.
     375             :  *
     376             :  * This function displays this node, its children, its children's children,
     377             :  * etc. until all the nodes in the tree were displayed.
     378             :  *
     379             :  * Note that the function knows about the node links, variables, and labels
     380             :  * which also get displayed.
     381             :  *
     382             :  * Because the tree cannot generate loops (the set_parent() function
     383             :  * prevents such), we do not have anything that would break the
     384             :  * recursivity of the function.
     385             :  *
     386             :  * The character used to start the string (\p c) changes depending on what
     387             :  * we are showing to the user. That way we know whether it is the root (.),
     388             :  * a child (-), a variable (=), or a label (:).
     389             :  *
     390             :  * \todo
     391             :  * We probably want to remove the \p parent parameter. I had it here because
     392             :  * I wanted to verify it as the old code had many problems with the tree
     393             :  * which would break while we were optimizing or compiling the code. The
     394             :  * set_parent() function is now working fine so the parent is not useful.
     395             :  *
     396             :  * \param[in,out] out  The output stream.
     397             :  * \param[in] indent  The current indentation. We start with 2.
     398             :  * \param[in] c  A character to start each line of output.
     399             :  */
     400       12038 : void Node::display(std::ostream& out, int indent, char c) const
     401             : {
     402             :     // this pointer
     403       12038 :     out << this << ": " << std::setfill('0') << std::setw(2) << indent << std::setfill(' ') << c << std::setw(indent) << "";
     404             : 
     405             :     // display node data (integer, string, float, etc.)
     406       12038 :     display_data(out);
     407             : 
     408             :     // display information about the links
     409       12038 :     bool first = true;
     410       12048 :     for(size_t lnk(0); lnk < f_link.size(); ++lnk)
     411             :     {
     412          10 :         if(f_link[lnk])
     413             :         {
     414           3 :             if(first)
     415             :             {
     416           2 :                 first = false;
     417           2 :                 out << " Lnk:";
     418             :             }
     419           3 :             out << " [" << lnk << "]=" << f_link[lnk].get();
     420             :         }
     421             :     }
     422             : 
     423             :     // display the different attributes if any
     424             :     struct display_attributes
     425             :     {
     426       12038 :         display_attributes(std::ostream& out, attribute_set_t attrs)
     427             :             : f_out(out)
     428       12038 :             , f_attributes(attrs)
     429             :         {
     430       12038 :             display_attribute(attribute_t::NODE_ATTR_PUBLIC,         "PUBLIC"        );
     431       12038 :             display_attribute(attribute_t::NODE_ATTR_PRIVATE,        "PRIVATE"       );
     432       12038 :             display_attribute(attribute_t::NODE_ATTR_PROTECTED,      "PROTECTED"     );
     433       12038 :             display_attribute(attribute_t::NODE_ATTR_INTERNAL,       "INTERNAL"      );
     434       12038 :             display_attribute(attribute_t::NODE_ATTR_TRANSIENT,      "TRANSIENT"     );
     435       12038 :             display_attribute(attribute_t::NODE_ATTR_VOLATILE,       "VOLATILE"      );
     436             : 
     437       12038 :             display_attribute(attribute_t::NODE_ATTR_STATIC,         "STATIC"        );
     438       12038 :             display_attribute(attribute_t::NODE_ATTR_ABSTRACT,       "ABSTRACT"      );
     439       12038 :             display_attribute(attribute_t::NODE_ATTR_VIRTUAL,        "VIRTUAL"       );
     440       12038 :             display_attribute(attribute_t::NODE_ATTR_ARRAY,          "ARRAY"         );
     441             : 
     442       12038 :             display_attribute(attribute_t::NODE_ATTR_REQUIRE_ELSE,   "REQUIRE_ELSE"  );
     443       12038 :             display_attribute(attribute_t::NODE_ATTR_ENSURE_THEN,    "ENSURE_THEN"   );
     444             : 
     445       12038 :             display_attribute(attribute_t::NODE_ATTR_NATIVE,         "NATIVE"        );
     446             : 
     447       12038 :             display_attribute(attribute_t::NODE_ATTR_DEPRECATED,     "DEPRECATED"    );
     448       12038 :             display_attribute(attribute_t::NODE_ATTR_UNSAFE,         "UNSAFE"        );
     449             : 
     450       12038 :             display_attribute(attribute_t::NODE_ATTR_CONSTRUCTOR,    "CONSTRUCTOR"   );
     451             : 
     452             :             //display_attribute(attribute_t::NODE_ATTR_CONST,          "CONST"         ); -- this is a flag, not needed here
     453       12038 :             display_attribute(attribute_t::NODE_ATTR_FINAL,          "FINAL"         );
     454       12038 :             display_attribute(attribute_t::NODE_ATTR_ENUMERABLE,     "ENUMERABLE"    );
     455             : 
     456       12038 :             display_attribute(attribute_t::NODE_ATTR_TRUE,           "TRUE"          );
     457       12038 :             display_attribute(attribute_t::NODE_ATTR_FALSE,          "FALSE"         );
     458       12038 :             display_attribute(attribute_t::NODE_ATTR_UNUSED,         "UNUSED"        );
     459             : 
     460       12038 :             display_attribute(attribute_t::NODE_ATTR_DYNAMIC,        "DYNAMIC"       );
     461             : 
     462       12038 :             display_attribute(attribute_t::NODE_ATTR_FOREACH,        "FOREACH"       );
     463       12038 :             display_attribute(attribute_t::NODE_ATTR_NOBREAK,        "NOBREAK"       );
     464       12038 :             display_attribute(attribute_t::NODE_ATTR_AUTOBREAK,      "AUTOBREAK"     );
     465             : 
     466       12038 :             display_attribute(attribute_t::NODE_ATTR_DEFINED,        "DEFINED"       );
     467       12038 :         }
     468             : 
     469      312988 :         void display_attribute(attribute_t a, char const *n)
     470             :         {
     471      312988 :             if(f_attributes[static_cast<size_t>(a)])
     472             :             {
     473        6422 :                 if(f_first)
     474             :                 {
     475        3212 :                     f_first = false;
     476        3212 :                     f_out << " attrs:";
     477             :                 }
     478        6422 :                 f_out << " " << n;
     479             :             }
     480      312988 :         }
     481             : 
     482             :         std::ostream&               f_out;
     483             :         controlled_vars::tbool_t    f_first;
     484             :         attribute_set_t             f_attributes;
     485       12038 :     } display_attr(out, f_attributes);
     486             : 
     487             :     // end the line with our position
     488       12038 :     out << " (" << f_position << ")" << std::endl;
     489             : 
     490             :     // now print children
     491       12051 :     for(size_t idx(0); idx < f_children.size(); ++idx)
     492             :     {
     493          13 :         f_children[idx]->display(out, indent + 1, '-');
     494             :     }
     495             : 
     496             :     // now print variables
     497       12039 :     for(size_t idx(0); idx < f_variables.size(); ++idx)
     498             :     {
     499           1 :         f_variables[idx]->display(out, indent + 1, '=');
     500             :     }
     501             : 
     502             :     // now print labels
     503       24078 :     for(map_of_pointers_t::const_iterator it(f_labels.begin());
     504       12039 :                                           it != f_labels.end();
     505             :                                           ++it)
     506             :     {
     507           1 :         it->second->display(out, indent + 1, ':');
     508             :     }
     509       12038 : }
     510             : 
     511             : 
     512             : /** \brief Send a node to the specified output stream.
     513             :  *
     514             :  * This function prints a node to the output stream. The printing is very
     515             :  * technical and mainly used to debug the node tree while parsing,
     516             :  * compiling, optimizing, and generating the final output.
     517             :  *
     518             :  * \param[in,out] out  The output stream.
     519             :  * \param[in] node  The node to print in the output stream.
     520             :  *
     521             :  * \return A reference to the output stream.
     522             :  */
     523       12023 : std::ostream& operator << (std::ostream& out, Node const& node)
     524             : {
     525       12023 :     node.display(out, 2, '.');
     526       12023 :     return out;
     527             : }
     528             : 
     529             : 
     530          20 : }
     531             : // namespace as2js
     532             : 
     533             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.9