Line data Source code
1 : // Copyright (c) 2011-2023 Made to Order Software Corp. All Rights Reserved 2 : // 3 : // https://snapwebsites.org/project/as2js 4 : // contact@m2osw.com 5 : // 6 : // This program is free software: you can redistribute it and/or modify 7 : // it under the terms of the GNU General Public License as published by 8 : // the Free Software Foundation, either version 3 of the License, or 9 : // (at your option) any later version. 10 : // 11 : // This program is distributed in the hope that it will be useful, 12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : // GNU General Public License for more details. 15 : // 16 : // You should have received a copy of the GNU General Public License 17 : // along with this program. If not, see <https://www.gnu.org/licenses/>. 18 : 19 : // self 20 : // 21 : #include "catch_main.h" 22 : 23 : #include "tests/compiler_data/attr_native_class.h" 24 : 25 : 26 : // as2js 27 : // 28 : #include <as2js/compiler.h> 29 : #include <as2js/exception.h> 30 : #include <as2js/json.h> 31 : #include <as2js/message.h> 32 : #include <as2js/parser.h> 33 : 34 : 35 : // snapdev 36 : // 37 : #include <snapdev/string_replace_many.h> 38 : 39 : 40 : // C++ 41 : // 42 : #include <algorithm> 43 : #include <climits> 44 : #include <cstring> 45 : #include <iomanip> 46 : 47 : 48 : // C 49 : // 50 : #include <unistd.h> 51 : #include <sys/stat.h> 52 : 53 : 54 : // last include 55 : // 56 : #include <snapdev/poison.h> 57 : 58 : 59 : 60 : namespace 61 : { 62 : 63 : bool g_created_files = false; 64 : 65 : 66 : 67 : 68 : class input_retriever 69 : : public as2js::input_retriever 70 : { 71 : public: 72 0 : virtual as2js::base_stream::pointer_t retrieve(std::string const & filename) override 73 : { 74 0 : if(filename == "") 75 : { 76 : } 77 : 78 0 : return as2js::base_stream::pointer_t(); 79 : } 80 : 81 : }; 82 : 83 : 84 : std::string g_current_working_directory; 85 : 86 : 87 0 : void init_compiler(as2js::compiler & compiler) 88 : { 89 : // The .rc file cannot be captured by the input retriever 90 : // so instead we create a file in the current directory 91 : 92 : // setup an input retriever which in most cases just returns nullptr 93 : // 94 0 : compiler.set_input_retriever(std::make_shared<input_retriever>()); 95 0 : } 96 : 97 : 98 1 : void init_rc() 99 : { 100 1 : g_created_files = true; 101 : 102 : // we recreate because in the clean up we may end up deleting that 103 : // folder (even though it's already created by the catch_db_init() 104 : // function which happens before this call) 105 : // 106 1 : if(mkdir("as2js", 0700) != 0) 107 : { 108 1 : if(errno != EEXIST) 109 : { 110 0 : CATCH_REQUIRE(!"could not create directory as2js"); 111 : } 112 : // else -- we already created it, that's fine 113 : } 114 : 115 : // The .rc file cannot be captured by the input retriever 116 : // so instead we create a file in the current directory 117 : // 118 3 : std::string const safe_cwd(snapdev::string_replace_many( 119 : g_current_working_directory 120 4 : , { { "'", "\\'" } })); 121 1 : std::ofstream out("as2js/as2js.rc"); 122 : out << "// rc test file\n" 123 : "{\n" 124 1 : " 'scripts': '" << SNAP_CATCH2_NAMESPACE::g_source_dir() << "/scripts',\n" 125 : " 'db': '" << safe_cwd << "/test.db',\n" 126 : " 'temporary_variable_name': '@temp$'\n" 127 1 : "}\n"; 128 : 129 1 : CATCH_REQUIRE(!!out); 130 2 : } 131 : 132 : 133 : 134 : 135 : } 136 : // no name namespace 137 : 138 : 139 : namespace SNAP_CATCH2_NAMESPACE 140 : { 141 : 142 : 143 : 144 : } // namespace SNAP_CATCH2_NAMESPACE 145 : 146 : 147 : 148 : 149 : 150 1 : CATCH_TEST_CASE("compiler_attributes_inherited", "[compiler][valid]") 151 : { 152 1 : CATCH_START_SECTION("compiler_attributes_inherited: simple native class with a function operator") 153 : { 154 : // get source code 155 : // 156 2 : std::string const program_source(as2js_tests::attr_native_class, as2js_tests::attr_native_class_size); 157 : 158 : // prepare input stream 159 : // 160 1 : as2js::input_stream<std::stringstream>::pointer_t prog_text(std::make_shared<as2js::input_stream<std::stringstream>>()); 161 1 : prog_text->get_position().set_filename("tests/compiler_data/attr_native_class.ajs"); 162 1 : *prog_text << program_source; 163 : 164 : // parse the input 165 : // 166 1 : as2js::options::pointer_t options(std::make_shared<as2js::options>()); 167 1 : as2js::parser::pointer_t parser(std::make_shared<as2js::parser>(prog_text, options)); 168 1 : init_rc(); 169 1 : as2js::node::pointer_t root(parser->parse()); 170 : 171 : // run the compiler 172 : // 173 2 : as2js::compiler compiler(options); 174 1 : CATCH_REQUIRE(compiler.compile(root) == 0); 175 : 176 : // find nodes of interest and verify they are or not marked with the 177 : // "native" flag as expected 178 : // 179 : //std::cerr << "--- resulting node tree is:\n" << *root << "\n"; 180 1 : as2js::node::pointer_t func(root->find_descendent( 181 : as2js::node_t::NODE_FUNCTION 182 1 : , [](as2js::node::pointer_t n) 183 : { 184 1 : return n->get_string() == "+"; 185 2 : })); 186 1 : CATCH_REQUIRE(func != nullptr); 187 : 188 2 : as2js::node::pointer_t add(root->find_descendent(as2js::node_t::NODE_ADD, nullptr)); 189 1 : CATCH_REQUIRE(add->get_attribute(as2js::attribute_t::NODE_ATTR_NATIVE)); 190 : 191 1 : as2js::node::pointer_t product(root->find_descendent(as2js::node_t::NODE_IDENTIFIER, 192 15 : [](as2js::node::pointer_t n) 193 : { 194 15 : return n->get_string() == "*"; 195 2 : })); 196 1 : CATCH_REQUIRE(!product->get_attribute(as2js::attribute_t::NODE_ATTR_NATIVE)); 197 : 198 1 : as2js::node::pointer_t member(product->get_parent()); 199 1 : CATCH_REQUIRE(member->get_type() == as2js::node_t::NODE_MEMBER); 200 1 : CATCH_REQUIRE(!member->get_attribute(as2js::attribute_t::NODE_ATTR_NATIVE)); 201 : 202 1 : as2js::node::pointer_t call(member->get_parent()); 203 1 : CATCH_REQUIRE(call->get_type() == as2js::node_t::NODE_CALL); 204 1 : CATCH_REQUIRE_FALSE(call->get_attribute(as2js::attribute_t::NODE_ATTR_NATIVE)); 205 : 206 1 : as2js::node::pointer_t assignment(call->get_parent()); 207 3 : as2js::node::pointer_t optimized_assignment(assignment->get_parent()->find_next_child(assignment, as2js::node_t::NODE_ASSIGNMENT)); 208 1 : as2js::node::pointer_t identifier(optimized_assignment->get_child(0)); 209 1 : CATCH_REQUIRE(identifier->get_type() == as2js::node_t::NODE_IDENTIFIER); 210 1 : CATCH_REQUIRE(identifier->get_string() == "e"); 211 1 : as2js::node::pointer_t integer(optimized_assignment->get_child(1)); 212 1 : CATCH_REQUIRE(integer->get_type() == as2js::node_t::NODE_INTEGER); 213 1 : CATCH_REQUIRE(integer->get_integer().get() == 76 * 12); 214 1 : } 215 1 : CATCH_END_SECTION() 216 1 : } 217 : 218 : 219 : 220 : // vim: ts=4 sw=4 et