diff --git a/CMake/CMakeLists.txt b/CMake/CMakeLists.txt deleted file mode 100644 index ccb14fc..0000000 --- a/CMake/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -## -# CMakeLists.txt -# -# Copyright (C) 2016-2018 srcML, LLC. (www.srcML.org) -# -# This file is part of the srcSAXEventDispatch. -# -# The srcSAXEventDispatch is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# The srcSAXEventDispatch is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with the srcSAXEventDispatch; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -# add this directory -list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) - -include(srcsax_event_dispatch_build) -if(CMAKE_PROJECT_NAME STREQUAL "srcSAXEventDispatch") - include(srcsax_event_dispatch_install) -endif() diff --git a/CMake/srcsax_event_dispatch_build.cmake b/CMake/srcsax_event_dispatch_build.cmake deleted file mode 100644 index 1259926..0000000 --- a/CMake/srcsax_event_dispatch_build.cmake +++ /dev/null @@ -1,38 +0,0 @@ -## -# srcsax_event_dispatch.cmake -# -# Copyright (C) 2016-2018 srcML, LLC. (www.srcML.org) -# -# This file is part of the srcSAXEventDispatch. -# -# The srcSAXEventDispatch is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# The srcSAXEventDispatch is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with the srcSAXEventDispatch; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -get_filename_component(DISPATCH_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) -get_filename_component(DISPATCH_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) - -add_subdirectory(${DISPATCH_SOURCE_DIR}/srcSAX/CMake ${DISPATCH_BINARY_DIR}/srcSAX/CMake) - -set(DISPATCH_INCLUDE_DIR ${SRCSAX_INCLUDE_DIR} - ${DISPATCH_SOURCE_DIR}/src/dispatcher - ${DISPATCH_SOURCE_DIR}/src/policy_classes - CACHE INTERNAL "Include directories for srcSAXEventDispatch") - -set(DISPATCH_LIBRARIES ${SRCSAX_LIBRARIES} CACHE INTERNAL "Libraries for srcSAXEventDispatch") - -# include needed includes -include_directories(${DISPATCH_INCLUDE_DIR}) - -# Continue to build directory -add_subdirectory(${DISPATCH_SOURCE_DIR}/src ${DISPATCH_BINARY_DIR}/src) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d4d430..91aba02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,34 +1,54 @@ ## # CMakeLists.txt # -# Copyright (C) 2016-2024 srcML, LLC. (www.srcML.org) +# Copyright (C) 2025-2025 srcML, LLC. (www.srcML.org) # -# This file is part of the srcSAXEventDispatch. +# This file is part of the srcDispatch. # -# The srcSAXEventDispatch is free software; you can redistribute it and/or modify +# The srcDispatch is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # -# The srcSAXEventDispatch is distributed in the hope that it will be useful, +# The srcDispatch is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with the srcSAXEventDispatch; if not, write to the Free Software +# along with the srcDispatch; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA cmake_minimum_required(VERSION 3.14) -project(srcSAXEventDispatch) +project(srcDispatch) + +include(CTest) + +if(NOT WIN32) + set(CMAKE_INSTALL_PREFIX "/usr/local/") +endif() set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) +add_definitions("-Wall") + +add_subdirectory(srcSAX/CMake) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -add_subdirectory(CMake) -add_subdirectory(tests) +set(SRCDISPATCH_INCLUDE_DIR ${SRCSAX_INCLUDE_DIR} + src/policy_classes + src/dispatcher + CACHE INTERNAL "Include directories for srcDispatch") + +set(SRCDISPATCH_LIBRARIES ${SRCSAX_LIBRARIES} CACHE INTERNAL "Libraries for srcDispatch") + +# include needed includes +include_directories(${SRCDISPATCH_INCLUDE_DIR}) + +# Continue to src/test +add_subdirectory(src) +add_subdirectory(test) diff --git a/dispatch.nlp.str.xml b/dispatch.nlp.str.xml deleted file mode 100644 index 26b44e6..0000000 --- a/dispatch.nlp.str.xml +++ /dev/null @@ -1,16540 +0,0 @@ - - -#include <srcSAXEventDispatcher.hpp> -#include <srcSAXHandler.hpp> -#include <unordered_map> -#include <unordered_set> -#include <srcSAXHandler.hpp> -#include <FunctionCallPolicy.hpp> -#include <cassert> -#include <srcml.h> -std::string StringToSrcMLStringToSrcML(std::string str){ - struct srcml_archive* archive; - struct srcml_unit* unit; - size_t size = 0; - - char * ch = new char[str.size()]; - - archive = srcml_archive_create(); - srcml_archive_enable_option(archive, SRCML_OPTION_POSITION); - srcml_archive_write_open_memory(archive, &ch, &size); - - unit = srcml_unit_create(archive); - srcml_unit_set_language(unit, SRCML_LANGUAGE_CXX); - srcml_unit_set_filename(unit, "testsrcType.cpp"); - - srcml_unit_parse_memory(unit, str.c_str(), str.size()); - srcml_archive_write_unit(archive, unit); - - srcml_unit_free(unit); - srcml_archive_close(archive); - srcml_archive_free(archive); - //TrimFromEnd(ch, size); - return std::string(ch); -} - -class TestCalls : public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - ~TestCalls(){} - TestCalls(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners ){} - /**command collaborator */ - void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - calldata = *policy->Data<CallPolicy::CallData>(); - datatotest.push_back(calldata); - } - /**unclassified */ - void RunTest(){ - assert(datatotest[0].fnName == "bin"); //TODO: Fix, figure out way to test. - } - protected: - /**voidaccessor */ - void * DataInnerDataInner() const override { - return (void*)0; //To silence the warning - } - private: - CallPolicy callpolicy; - CallPolicy::CallData calldata; - std::vector<CallPolicy::CallData> datatotest; - -}; - -int main(int argc, char** filename){ - std::string codestr = "void foo(){foo(bar, baz, bin(), beep);}"; - std::string srcmlstr = StringToSrcML(codestr); - - TestCalls calldata; - srcSAXController control(srcmlstr); - srcSAXEventDispatch::srcSAXEventDispatcher<CallPolicy> handler{&calldata}; - control.parseparse(&handler); //Start parsing - calldata.RunTestRunTest(); -} - - -#include <srcSAXEventDispatcher.hpp> -#include <srcSAXHandler.hpp> -#include <unordered_map> -#include <unordered_set> -#include <srcSAXHandler.hpp> -#include <ExprPolicy.hpp> -#include <cassert> -#include <srcml.h> -std::string StringToSrcML(std::string str){ - struct srcml_archive* archive; - struct srcml_unit* unit; - size_t size = 0; - - char * ch = new char[str.size()]; - - archive = srcml_archive_create(); - srcml_archive_enable_option(archive, SRCML_OPTION_POSITION); - srcml_archive_write_open_memory(archive, &ch, &size); - - unit = srcml_unit_create(archive); - srcml_unit_set_language(unit, SRCML_LANGUAGE_CXX); - srcml_unit_set_filename(unit, "testsrcType.cpp"); - - srcml_unit_parse_memory(unit, str.c_str(), str.size()); - srcml_archive_write_unit(archive, unit); - - srcml_unit_free(unit); - srcml_archive_close(archive); - srcml_archive_free(archive); - //TrimFromEnd(ch, size); - return std::string(ch); -} - -class TestExpr : public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - ~TestExpr(){} - TestExpr(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners ){} - /**command collaborator */ - void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - exprdata = *policy->Data<ExprPolicy::ExprData>(); - datatotest.push_back(exprdata); - } - /**unclassified */ - void RunTest(){ - - } - protected: - /**voidaccessor */ - void * DataInnerDataInner() const override { - return (void*)0; //To silence the warning - } - private: - ExprPolicy::ExprData exprdata; - std::vector<ExprPolicy::ExprData> datatotest; -}; - -int main(int argc, char** filename){ - std::string codestr = "void foo(){j = 0; \nk = 1; \ndoreme = 5; \nabc = abc + 0;\n i = j + k;\n foo(abc+doreme);}"; - std::string srcmlstr = StringToSrcML(codestr); - std::cerr<<srcmlstr<<std::endl; - TestExpr exprdata; - srcSAXController control(srcmlstr); - srcSAXEventDispatch::srcSAXEventDispatcher<ExprPolicy> handler {&exprdata}; - control.parseparse(&handler); //Start parsing - exprdata.RunTestRunTest(); -} - -#include <srcSAXEventDispatcher.hpp> -#include <srcSAXHandler.hpp> -#include <unordered_map> -#include <unordered_set> -#include <srcSAXHandler.hpp> -#include <DeclTypePolicy.hpp> -#include <cassert> -#include <srcml.h> -std::string StringToSrcML(std::string str){ - struct srcml_archive* archive; - struct srcml_unit* unit; - size_t size = 0; - - char * ch = new char[str.size()]; - - archive = srcml_archive_create(); - srcml_archive_enable_option(archive, SRCML_OPTION_POSITION); - srcml_archive_write_open_memory(archive, &ch, &size); - - unit = srcml_unit_create(archive); - srcml_unit_set_language(unit, SRCML_LANGUAGE_CXX); - srcml_unit_set_filename(unit, "testsrcType.cpp"); - - srcml_unit_parse_memory(unit, str.c_str(), str.size()); - srcml_archive_write_unit(archive, unit); - - srcml_unit_free(unit); - srcml_archive_close(archive); - srcml_archive_free(archive); - //TrimFromEnd(ch, size); - return std::string(ch); -} - -class TestDeclType : public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - ~TestDeclType(){} - TestDeclType(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners ){} - /**command collaborator */ - void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - decltypedata = *policy->Data<DeclTypePolicy::DeclTypeData>(); - datatotest.push_back(decltypedata); - } - /**command */ - void RunTest(){ - assert(datatotest.size() == 5); - assert(datatotest[0].nameoftype == "int"); - assert(datatotest[0].nameofidentifier == "abc"); - assert(datatotest[0].linenumber == 1); - assert(datatotest[0].isConst == false); - assert(datatotest[0].isReference == true); - assert(datatotest[0].isPointer == false); - assert(datatotest[0].isStatic == false); - assert(datatotest[0].namespaces.empty()); - - assert(datatotest[1].nameoftype == "Object"); - assert(datatotest[1].nameofidentifier == "onetwothree"); - assert(datatotest[1].linenumber == 1); - assert(datatotest[1].isConst == false); - assert(datatotest[1].isReference == false); - assert(datatotest[1].isPointer == false); - assert(datatotest[1].isStatic == false); - assert(datatotest[1].namespaces.empty()); - - assert(datatotest[2].nameoftype == "Object"); - assert(datatotest[2].nameofidentifier == "DoReiMe"); - assert(datatotest[2].linenumber == 1); - assert(datatotest[2].isConst == false); - assert(datatotest[2].isReference == false); - assert(datatotest[2].isPointer == true); - assert(datatotest[2].isStatic == true); - assert(datatotest[2].namespaces.empty()); - - assert(datatotest[3].nameoftype == "Object"); - assert(datatotest[3].nameofidentifier == "aybeecee"); - assert(datatotest[3].linenumber == 1); - assert(datatotest[3].isConst == true); - assert(datatotest[3].isReference == false); - assert(datatotest[3].isPointer == true); - assert(datatotest[3].isStatic == false); - assert(datatotest[3].namespaces.empty()); - - assert(datatotest[4].nameoftype == "vector"); - assert(datatotest[4].nameofidentifier == "spaces"); - assert(datatotest[4].linenumber == 2); - assert(datatotest[4].isConst == false); - assert(datatotest[4].isReference == false); - assert(datatotest[4].isPointer == false); - assert(datatotest[4].isStatic == false); - assert(datatotest[4].namespaces.size() == 2); - } - protected: - /**voidaccessor */ - void * DataInnerDataInner() const override { - return (void*)0; //To silence the warning - } - private: - - DeclTypePolicy declpolicy; - DeclTypePolicy::DeclTypeData decltypedata; - std::vector<DeclTypePolicy::DeclTypeData> datatotest; -}; - -int main(int argc, char** filename){ - std::string codestr = "void foo(){int& abc; Object<int> onetwothree; static Object* DoReiMe; const Object* aybeecee;\n nlp::std::vector<std::string> spaces;}"; - std::string srcmlstr = StringToSrcML(codestr); - std::cerr<<"out"<<std::endl; - TestDeclType decltypedata; - srcSAXController control(srcmlstr); - srcSAXEventDispatch::srcSAXEventDispatcher<DeclTypePolicy> handler {&decltypedata}; - control.parseparse(&handler); //Start parsing - decltypedata.RunTestRunTest(); -} - -#include <srcSAXEventDispatcher.hpp> -#include <srcSAXHandler.hpp> -#include <unordered_map> -#include <unordered_set> -#include <srcSAXHandler.hpp> -#include <CollectNLContext.hpp> -#include <cassert> -#include <srcml.h> -#include <string> -#include <fstream> -#include <streambuf> - -std::string filetostring (const std::string file){ - std::ifstream t(file); - std::string str; - - t.seekg(0, std::ios::end); - str.reserve(t.tellg()); - t.seekg(0, std::ios::beg); - - str.assign((std::istreambuf_iterator<char>(t)), - std::istreambuf_iterator<char>()); - return str; -} -std::string StringToSrcML(std::string str){ - struct srcml_archive* archive; - struct srcml_unit* unit; - size_t size = 0; - - char * ch = new char[str.size()]; - - archive = srcml_archive_create(); - srcml_archive_enable_option(archive, SRCML_OPTION_POSITION); - srcml_archive_write_open_memory(archive, &ch, &size); - - unit = srcml_unit_create(archive); - srcml_unit_set_language(unit, SRCML_LANGUAGE_CXX); - srcml_unit_set_filename(unit, "testsrcType.cpp"); - - srcml_unit_parse_memory(unit, str.c_str(), str.size()); - srcml_archive_write_unit(archive, unit); - - srcml_unit_free(unit); - srcml_archive_close(archive); - srcml_archive_free(archive); - //TrimFromEnd(ch, size); - return std::string(ch); -} - -class TestSNLPolicy : public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - ~TestSNLPolicy(){} - TestSNLPolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners ){} - /**set collaborator */ - void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - sourcenlpdata = *policy->Data<NLContextPolicy::NLContextData>(); - std::cerr<<"Output: "<<sourcenlpdata.identifiername<<" "<<sourcenlpdata.category<<std::endl; - //datatotest.push_back(NLContextData); - } - /**unclassified */ - void RunTest(){ - } - protected: - /**voidaccessor */ - void * DataInnerDataInner() const override { - return (void*)0; //To silence the warning - } - private: - - NLContextPolicy::NLContextData sourcenlpdata; -}; - -int main(int argc, char** filename){ - std::string srcmlstr = filetostring(filename[1]); - - TestSNLPolicy decltypedata; - srcSAXController control(srcmlstr); - srcSAXEventDispatch::srcSAXEventDispatcher<NLContextPolicy> handler {&decltypedata}; - control.parseparse(&handler); //Start parsing -} - -#include <srcSAXEventDispatcher.hpp> -#include <srcSAXHandler.hpp> -#include <unordered_map> -#include <unordered_set> -#include <srcSAXHandler.hpp> -#include <FunctionSignaturePolicy.hpp> -#include <cassert> -#include <srcml.h> -std::string StringToSrcML(std::string str){ - struct srcml_archive* archive; - struct srcml_unit* unit; - size_t size = 0; - - char * ch = new char[str.size()]; - - archive = srcml_archive_create(); - srcml_archive_enable_option(archive, SRCML_OPTION_POSITION); - srcml_archive_write_open_memory(archive, &ch, &size); - - unit = srcml_unit_create(archive); - srcml_unit_set_language(unit, SRCML_LANGUAGE_CXX); - srcml_unit_set_filename(unit, "testsrcType.cpp"); - - srcml_unit_parse_memory(unit, str.c_str(), str.size()); - srcml_archive_write_unit(archive, unit); - - srcml_unit_free(unit); - srcml_archive_close(archive); - srcml_archive_free(archive); - //TrimFromEnd(ch, size); - return std::string(ch); -} - -class TestFunctionSignature : public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - ~TestFunctionSignature(){} - TestFunctionSignature(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners ){} - /**command collaborator */ - void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - signaturedata = *policy->Data<FunctionSignaturePolicy::SignatureData>(); - datatotest.push_back(signaturedata); - } - /**command */ - void RunTest(){ - - assert(datatotest.size() == 5); - assert(datatotest[0].returnType == "void"); - assert(datatotest[0].functionName == "foo"); - assert(datatotest[0].returnTypeModifier == std::string()); - assert(datatotest[0].linenumber == 1); - assert(datatotest[0].isConst == false); - assert(datatotest[0].isMethod == false); - assert(datatotest[0].isStatic == false); - assert(datatotest[0].parameters.size() == 4); - assert(datatotest[0].returnTypeNamespaces.size() == 0); - assert(datatotest[0].functionNamespaces.size() == 0); - assert(datatotest[0].pointerToConstReturn == false); - assert(datatotest[0].constPointerReturn == false); - assert(datatotest[0].hasAliasedReturn == false); - - assert(datatotest[1].returnType == "void"); - assert(datatotest[1].functionName == "bar"); - assert(datatotest[1].returnTypeModifier == std::string()); - assert(datatotest[1].linenumber == 2); - assert(datatotest[1].isConst == false); - assert(datatotest[1].isMethod == false); - assert(datatotest[1].isStatic == true); - assert(datatotest[1].parameters.size() == 4); - assert(datatotest[1].returnTypeNamespaces.size() == 0); - assert(datatotest[1].functionNamespaces.size() == 0); - assert(datatotest[1].pointerToConstReturn == false); - assert(datatotest[1].constPointerReturn == false); - assert(datatotest[1].hasAliasedReturn == false); - - assert(datatotest[2].returnType == "int"); - assert(datatotest[2].functionName == "bloo"); - assert(datatotest[2].returnTypeModifier == "*"); - assert(datatotest[2].linenumber == 3); - assert(datatotest[2].isConst == false); - assert(datatotest[2].isMethod == false); - assert(datatotest[2].isStatic == false); - assert(datatotest[2].parameters.size() == 4); - assert(datatotest[2].returnTypeNamespaces.size() == 0); - assert(datatotest[2].functionNamespaces.size() == 0); - assert(datatotest[2].pointerToConstReturn == false); - assert(datatotest[2].constPointerReturn == false); - assert(datatotest[2].hasAliasedReturn == true); - - assert(datatotest[3].returnType == "void"); - assert(datatotest[3].functionName == "bleep"); - assert(datatotest[3].returnTypeModifier == std::string()); - assert(datatotest[3].linenumber == 4); - assert(datatotest[3].isConst == true); - assert(datatotest[3].isMethod == true); - assert(datatotest[3].isStatic == false); - assert(datatotest[3].parameters.size() == 4); - assert(datatotest[3].returnTypeNamespaces.size() == 0); - assert(datatotest[3].functionNamespaces.size() == 0); - assert(datatotest[3].pointerToConstReturn == false); - assert(datatotest[3].constPointerReturn == false); - assert(datatotest[3].hasAliasedReturn == false); - - assert(datatotest[4].returnType == "object"); - assert(datatotest[4].functionName == "bloo"); - assert(datatotest[4].returnTypeModifier == "*"); - assert(datatotest[4].linenumber == 5); - assert(datatotest[4].isConst == false); - assert(datatotest[4].isMethod == false); - assert(datatotest[4].isStatic == true); - assert(datatotest[4].parameters.size() == 3); - assert(datatotest[4].returnTypeNamespaces.size() == 2); - assert(datatotest[4].functionNamespaces.size() == 1); - assert(datatotest[4].pointerToConstReturn == true); - assert(datatotest[4].constPointerReturn == true); - assert(datatotest[4].hasAliasedReturn == true); - - } - protected: - /**voidaccessor */ - void * DataInnerDataInner() const override { - return (void*)0; //To silence the warning - } - private: - FunctionSignaturePolicy::SignatureData signaturedata; - std::vector<FunctionSignaturePolicy::SignatureData> datatotest; -}; - -int main(int argc, char** filename){ - std::string codestr = "void foo(int abc, Object<int> onetwothree, Object* DoReiMe, const Object* aybeecee){}\n" - "static void bar(int abc, Object<int> onetwothree, Object* DoReiMe, const Object* aybeecee){}\n" - "int* bloo(int abc, Object<int> onetwothree, Object* DoReiMe, const Object* aybeecee){}\n" - "class{void bleep(int abc, Object<int> onetwothree, Object* DoReiMe, const Object* aybeecee)const{}};\n" - "static const GameDes::std::object* const std::bloo(Object<int> onetwothree, Object* DoReiMe, const Object* aybeecee){}"; - std::string srcmlstr = StringToSrcML(codestr); - - TestFunctionSignature sigData; - srcSAXController control(srcmlstr); - srcSAXEventDispatch::srcSAXEventDispatcher<FunctionSignaturePolicy> handler {&sigData}; - control.parseparse(&handler); //Start parsing - sigData.RunTestRunTest(); -} - -#include <cassert> -#include <srcSAXEventDispatcher.hpp> -#include <srcSAXHandler.hpp> -#include <unordered_map> -#include <unordered_set> -#include <srcSAXHandler.hpp> -#include <ParamTypePolicy.hpp> -#include <srcml.h> -std::string StringToSrcML(std::string str){ - struct srcml_archive* archive; - struct srcml_unit* unit; - size_t size = 0; - - char * ch = new char[str.size()]; - - archive = srcml_archive_create(); - srcml_archive_enable_option(archive, SRCML_OPTION_POSITION); - srcml_archive_write_open_memory(archive, &ch, &size); - - unit = srcml_unit_create(archive); - srcml_unit_set_language(unit, SRCML_LANGUAGE_CXX); - srcml_unit_set_filename(unit, "testsrcType.cpp"); - - srcml_unit_parse_memory(unit, str.c_str(), str.size()); - srcml_archive_write_unit(archive, unit); - - srcml_unit_free(unit); - srcml_archive_close(archive); - srcml_archive_free(archive); - //TrimFromEnd(ch, size); - return std::string(ch); -} - -class TestParamType : public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - ~TestParamType(){} - TestParamType(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners ){} - /**command collaborator */ - void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - paramdata = *policy->Data<ParamTypePolicy::ParamData>(); - datatotest.push_back(paramdata); - } - /**command */ - void RunTest(){ - assert(datatotest.size() == 5); - assert(datatotest[0].nameoftype == "int"); - assert(datatotest[0].nameofidentifier == "abc"); - assert(datatotest[0].linenumber == 1); - assert(datatotest[0].isConst == false); - assert(datatotest[0].isReference == true); - assert(datatotest[0].isPointer == false); - assert(datatotest[0].isStatic == false); - assert(datatotest[0].namespaces.empty()); - - assert(datatotest[1].nameoftype == "Object"); - assert(datatotest[1].nameofidentifier == "onetwothree"); - assert(datatotest[1].linenumber == 1); - assert(datatotest[1].isConst == false); - assert(datatotest[1].isReference == false); - assert(datatotest[1].isPointer == false); - assert(datatotest[1].isStatic == false); - assert(datatotest[1].namespaces.empty()); - - assert(datatotest[2].nameoftype == "Object"); - assert(datatotest[2].nameofidentifier == "DoReiMe"); - assert(datatotest[2].linenumber == 1); - assert(datatotest[2].isConst == false); - assert(datatotest[2].isReference == false); - assert(datatotest[2].isPointer == true); - assert(datatotest[2].isStatic == true); - assert(datatotest[2].namespaces.empty()); - - assert(datatotest[3].nameoftype == "Object"); - assert(datatotest[3].nameofidentifier == "aybeecee"); - assert(datatotest[3].linenumber == 1); - assert(datatotest[3].isConst == true); - assert(datatotest[3].isReference == false); - assert(datatotest[3].isPointer == true); - assert(datatotest[3].isStatic == false); - assert(datatotest[3].namespaces.empty()); - - assert(datatotest[4].nameoftype == "vector"); - assert(datatotest[4].nameofidentifier == "spaces"); - assert(datatotest[4].linenumber == 1); - assert(datatotest[4].isConst == false); - assert(datatotest[4].isReference == false); - assert(datatotest[4].isPointer == false); - assert(datatotest[4].isStatic == false); - assert(datatotest[4].namespaces.size() == 1); - } - protected: - /**voidaccessor */ - void * DataInnerDataInner() const override { - return (void*)0; //To silence the warning - } - private: - - ParamTypePolicy parampolicy; - ParamTypePolicy::ParamData paramdata; - std::vector<ParamTypePolicy::ParamData> datatotest; -}; - -int main(int argc, char** filename){ - std::string codestr = "void foo(int& abc, Object<int> onetwothree, static Object* DoReiMe, const Object* aybeecee, std::vector<std::string> spaces){}"; - std::string srcmlstr = StringToSrcML(codestr); - - TestParamType paramData; - srcSAXController control(srcmlstr); - srcSAXEventDispatch::srcSAXEventDispatcher<ParamTypePolicy> handler {&paramData}; - control.parseparse(&handler); //Start parsing - paramData.RunTestRunTest(); -} - -#include <srcSAXEventDispatcher.hpp> -#include <srcSAXHandler.hpp> -#include <unordered_map> -#include <unordered_set> -#include <srcSAXHandler.hpp> -#include <srcSlicePolicy.hpp> -#include <cassert> -#include <srcml.h> -std::string StringToSrcML(std::string str){ - struct srcml_archive* archive; - struct srcml_unit* unit; - size_t size = 0; - - char * ch = new char[str.size()]; - - archive = srcml_archive_create(); - srcml_archive_enable_option(archive, SRCML_OPTION_POSITION); - srcml_archive_write_open_memory(archive, &ch, &size); - - unit = srcml_unit_create(archive); - srcml_unit_set_language(unit, SRCML_LANGUAGE_CXX); - srcml_unit_set_filename(unit, "testsrcType.cpp"); - - srcml_unit_parse_memory(unit, str.c_str(), str.size()); - srcml_archive_write_unit(archive, unit); - - srcml_unit_free(unit); - srcml_archive_close(archive); - srcml_archive_free(archive); - //TrimFromEnd(ch, size); - return std::string(ch); -} - -class TestSrcSlice : public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - ~TestSrcSlice(){} - TestSrcSlice(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners ){} - /**command collaborator */ - void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - decltypedata = *policy->Data<srcSlicePolicy::DeclTypeData>(); - datatotest.push_back(decltypedata); - } - /**command */ - void RunTest(){ - assert(datatotest.size() == 5); - assert(datatotest[0].nameoftype == "int"); - assert(datatotest[0].nameofidentifier == "abc"); - assert(datatotest[0].linenumber == 1); - assert(datatotest[0].isConst == false); - assert(datatotest[0].isReference == true); - assert(datatotest[0].isPointer == false); - assert(datatotest[0].isStatic == false); - assert(datatotest[0].namespaces.empty()); - - assert(datatotest[1].nameoftype == "Object"); - assert(datatotest[1].nameofidentifier == "onetwothree"); - assert(datatotest[1].linenumber == 1); - assert(datatotest[1].isConst == false); - assert(datatotest[1].isReference == false); - assert(datatotest[1].isPointer == false); - assert(datatotest[1].isStatic == false); - assert(datatotest[1].namespaces.empty()); - - assert(datatotest[2].nameoftype == "Object"); - assert(datatotest[2].nameofidentifier == "DoReiMe"); - assert(datatotest[2].linenumber == 1); - assert(datatotest[2].isConst == false); - assert(datatotest[2].isReference == false); - assert(datatotest[2].isPointer == true); - assert(datatotest[2].isStatic == true); - assert(datatotest[2].namespaces.empty()); - - assert(datatotest[3].nameoftype == "Object"); - assert(datatotest[3].nameofidentifier == "aybeecee"); - assert(datatotest[3].linenumber == 1); - assert(datatotest[3].isConst == true); - assert(datatotest[3].isReference == false); - assert(datatotest[3].isPointer == true); - assert(datatotest[3].isStatic == false); - assert(datatotest[3].namespaces.empty()); - - assert(datatotest[4].nameoftype == "vector"); - assert(datatotest[4].nameofidentifier == "spaces"); - assert(datatotest[4].linenumber == 2); - assert(datatotest[4].isConst == false); - assert(datatotest[4].isReference == false); - assert(datatotest[4].isPointer == false); - assert(datatotest[4].isStatic == false); - assert(datatotest[4].namespaces.size() == 2); - } - protected: - /**voidaccessor */ - void * DataInnerDataInner() const override { - return (void*)0; //To silence the warning - } - private: - - srcSlicePolicy declpolicy; - srcSlicePolicy::DeclTypeData decltypedata; - std::vector<srcSlicePolicy::DeclTypeData> datatotest; -}; - -int main(int argc, char** filename){ - std::string codestr = "void foo(){int& abc; Object<int> onetwothree; static Object* DoReiMe; const Object* aybeecee;\n nlp::std::vector<std::string> spaces;}"; - std::string srcmlstr = StringToSrcML(codestr); - - TestSrcSlice decltypedata; - srcSAXController control(srcmlstr); - srcSAXEventDispatch::srcSAXEventDispatcher<srcSlicePolicy> handler {&decltypedata}; - control.parseparse(&handler); //Start parsing - decltypedata.RunTestRunTest(); -} - -/** - * @file srcsax_handler_test.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef INCLUDED_SRCSAX_HANDLER_TEST_HPP -#define INCLUDED_SRCSAX_HANDLER_TEST_HPP - -#include <srcSAXHandler.hpp> - -#include <libxml/parser.h> - -#include <string.h> -#include <string> -#include <cassert> - -/** - * srcsax_handler_test - * - * Test class with callbacks for C API. - */ -class srcsax_handler_test { - -public : - - /** number which start_document callback was called */ - int start_document_call_number; - /** number which end_document callback was called */ - int end_document_call_number; - - /** number which start_root callback was called */ - int start_root_call_number; - /** number which start_unit callback was called */ - int start_unit_call_number; - /** number which start_element callback was called */ - int start_element_call_number; - - /** number which end_root callback was called */ - int end_root_call_number; - /** number which end_unit callback was called */ - int end_unit_call_number; - /** number which end_elemnt callback was called */ - int end_element_call_number; - - /** number which characters_root callback was called */ - int characters_root_call_number; - /** number which characters_unit callback was called */ - int characters_unit_call_number; - - /** number which meta_tag callback was called */ - int meta_tag_call_number; - /** number which comment callback was called */ - int comment_call_number; - /** number which cdata_block callback was called */ - int cdata_block_call_number; - /** number which processing_instruction callback was called */ - int processing_instruction_call_number; - - /** the number of calls made */ - int call_count; - - /** - * srcsax_handler_test - * - * Constructor. Initialize members for testing C API. - */ - srcsax_handler_test() - : start_document_call_number(0), end_document_call_number(0), start_root_call_number(0), start_unit_call_number(0), start_element_call_number(0), - end_root_call_number(0), end_unit_call_number(0), end_element_call_number(0), characters_root_call_number(0), characters_unit_call_number(0), - meta_tag_call_number(0), comment_call_number(0), cdata_block_call_number(0), processing_instruction_call_number(0), call_count(0) {} - - /** - * factory - * - * Factory method to generate the srcsax_handler containin this classes - * callbacks needed to test C API. - * - * @returns the generated srcsax_handler with the correct callbacks for C API. - */ - /**collaborator */ - static srcsax_handler factory() { - - srcsax_handler handler; - - handler.start_document = start_document; - handler.end_document = end_document; - handler.start_root = start_root; - handler.start_unit = start_unit; - handler.start_element = start_element; - handler.end_root = end_root; - handler.end_unit = end_unit; - handler.end_element = end_element; - handler.characters_root = characters_root; - handler.characters_unit = characters_unit; - handler.meta_tag = meta_tag; - handler.comment = comment; - handler.cdata_block = cdata_block; - handler.processing_instruction = processing_instruction; - - return handler; - - } - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" - - /** - * start_document - * @param context a srcSAX context - * - * SAX handler function for start of document. - * Overidden for testing. Count calls made and order. - */ - /**collaborational-command collaborator */ - static void start_documentstart_document(struct srcsax_context * context) { - - srcsax_handler_test * test_handler = (srcsax_handler_test *)context->data; - - assert(context->stack_size == 0); - assert(context->srcml_element_stack == 0); - - test_handler->start_document_call_number = ++test_handler->call_count; - - } - - /** - * end_document - * @param context a srcSAX context - * - * SAX handler function for end of document. - * Overidden for testing. Count calls made and order. - */ - /**collaborational-command collaborator */ - static void end_documentend_document(struct srcsax_context * context) { - - srcsax_handler_test * test_handler = (srcsax_handler_test *)context->data; - - assert(context->stack_size == 0); - assert(context->srcml_element_stack == 0); - - test_handler->end_document_call_number = ++test_handler->call_count; - - } - - /** - * start_root - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param nb_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for start of the root element. - * Overidden for testing. Count calls made and order. - */ - /**command collaborator */ - static void start_rootstart_root(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI, - int nb_namespaces, const struct srcsax_namespace * namespaces, int nb_attributes, - const struct srcsax_attribute * attributes) { - - srcsax_handler_test * test_handler = (srcsax_handler_test *)context->data; - - assert(context->stack_size == 1); - assert(strcmp(context->srcml_element_stack[context->stack_size - 1], "unit") == 0); - - test_handler->start_root_call_number = ++test_handler->call_count; - - } - - /** - * start_unit - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param nb_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for start of an unit. - * Overidden for testing. Count calls made and order. - */ - /**command collaborator */ - static void start_unit(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI, - int nb_namespaces, const struct srcsax_namespace * namespaces, int nb_attributes, - const struct srcsax_attribute * attributes) { - - srcsax_handler_test * test_handler = (srcsax_handler_test *)context->data; - - assert(strcmp(context->srcml_element_stack[context->stack_size - 1], "unit") == 0); - - test_handler->start_unit_call_number = ++test_handler->call_count; - - } - - /** - * start_element - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param nb_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for start of an element. - * Overidden for testing. Count calls made and order. - */ - /**command collaborational-command collaborator */ - static void start_element(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI, - int nb_namespaces, const struct srcsax_namespace * namespaces, int nb_attributes, - const struct srcsax_attribute * attributes) { - - srcsax_handler_test * test_handler = (srcsax_handler_test *)context->data; - - std::string element = ""; - if(prefix) { - - element += prefix; - element += ':'; - - } - - element += localname; - - assert(std::string(context->srcml_element_stack[context->stack_size - 1]) == element); - - test_handler->start_element_call_number = ++test_handler->call_count; - - } - - /** - * end_root - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * SAX handler function for end of the root element. - * Overidden for testing. Count calls made and order. - */ - /**collaborational-command collaborator */ - static void end_root(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI) { - - srcsax_handler_test * test_handler = (srcsax_handler_test *)context->data; - - test_handler->end_root_call_number = ++test_handler->call_count; - - } - - /** - * end_unit - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * SAX handler function for end of an unit. - * Overidden for testing. Count calls made and order. - */ - /**collaborational-command collaborator */ - static void end_unitend_unit(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI) { - - srcsax_handler_test * test_handler = (srcsax_handler_test *)context->data; - - test_handler->end_unit_call_number = ++test_handler->call_count; - - } - - /** - * end_element - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * SAX handler function for end of an element. - * Overidden for testing. Count calls made and order. - */ - /**collaborational-command collaborator */ - static void end_elementend_element(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI) { - - srcsax_handler_test * test_handler = (srcsax_handler_test *)context->data; - - test_handler->end_element_call_number = ++test_handler->call_count; - - } - - /** - * characters_root - * @param context a srcSAX context - * @param ch the characers - * @param len number of characters - * - * SAX handler function for character handling at the root level. - * Overidden for testing. Count calls made and order. - */ - /**collaborational-command collaborator */ - static void characters_rootcharacters_root(struct srcsax_context * context, const char * ch, int len) { - - srcsax_handler_test * test_handler = (srcsax_handler_test *)context->data; - - test_handler->characters_root_call_number = ++test_handler->call_count; - - } - - /** - * characters_unit - * @param context a srcSAX context - * @param ch the characers - * @param len number of characters - * - * SAX handler function for character handling within a unit. - * Overidden for testing. Count calls made and order. - */ - /**collaborational-command collaborator */ - static void characters_unitcharacters_unit(struct srcsax_context * context, const char * ch, int len) { - - srcsax_handler_test * test_handler = (srcsax_handler_test *)context->data; - - test_handler->characters_unit_call_number = ++test_handler->call_count; - - } - - /** - * meta_tag - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param nb_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for meta tags. - * Overidden for testing. Count calls made and order. - */ - /**command collaborator */ - static void meta_tagmeta_tag(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI, - int nb_namespaces, const struct srcsax_namespace * namespaces, int nb_attributes, - const struct srcsax_attribute * attributes) { - - srcsax_handler_test * test_handler = (srcsax_handler_test *)context->data; - - assert(strcmp(context->srcml_element_stack[context->stack_size - 1], localname) == 0); - - test_handler->meta_tag_call_number = ++test_handler->call_count; - - } - - - /** - * comment - * @param context a srcSAX context - * @param value the comment content - * - * A comment has been parsed. - * Overidden for testing. Count calls made and order. - */ - /**collaborational-command collaborator */ - static void comment(struct srcsax_context * context, const char * value) { - - srcsax_handler_test * test_handler = (srcsax_handler_test *)context->data; - - test_handler->comment_call_number = ++test_handler->call_count; - - } - - /** - * cdata_block - * @param context a srcSAX context - * @param value the pcdata content - * @param len the block length - * - * Called when a pcdata block has been parsed. - * Overidden for testing. Count calls made and order. - */ - /**collaborational-command collaborator */ - static void cdata_blockcdata_block(struct srcsax_context * context, const char * value, int len) { - - srcsax_handler_test * test_handler = (srcsax_handler_test *)context->data; - - test_handler->cdata_block_call_number = ++test_handler->call_count; - - } - - /** - * processing_instruction - * @param context a srcSAX context - * @param value the pcdata content - * @param len the block length - * - * Called when a pcdata block has been parsed. - * Overidden for testing. Count calls made and order. - */ - /**collaborational-command collaborator */ - static void processing_instructionprocessing_instruction(struct srcsax_context * context, const char * target, const char * data) { - - srcsax_handler_test * test_handler = (srcsax_handler_test *)context->data; - - test_handler->processing_instruction_call_number = ++test_handler->call_count; - - } - -#pragma GCC diagnostic pop - -}; - -#endif - - -/** - * @file test_srcsax.cpp - * - * @copyright Copyright (C) 2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <srcsax.h> -#include <srcsax_handler_test.hpp> - -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <cassert> - -/** - * read_callback - * @param context the context to read from - * @param buffer the buffer to read into - * @param len the number of bytes to read - * - * FILE read callback for testing io. - * - * @returns the number of bytes read. - */ -int read_callback(void * context, char * buffer, int len) { - - return (int)fread(buffer, 1, len, (FILE *)context); - -} - -/** - * close_callback - * @param context the context to read from - * - * FILE close callback for testing io. - * - * @returns 0 on success EOF otherwise. - */ -int close_callback(void * context) { - - return fclose((FILE *)context); - -} - -/** - * main - * - * Test the srcsax functions. - * - * @returns 0 on success. - */ -int main() { - - /* - srcsax_create_context_filename - */ - { - - srcsax_context * context = srcsax_create_context_filename(__FILE__, "UTF-8"); - - assert(context->data == 0); - assert(context->handler == 0); - assert(context->srcsax_error == 0); - assert(context->is_archive == 0); - assert(context->unit_count == 0); - assert(context->encoding == 0); - assert(context->input != 0); - assert(context->libxml2_context != 0); - - srcsax_free_context(context); - - } - - { - - srcsax_context * context = srcsax_create_context_filename(__FILE__, "ISO-8859-1"); - - assert(context->data == 0); - assert(context->handler == 0); - assert(context->srcsax_error == 0); - assert(context->is_archive == 0); - assert(context->unit_count == 0); - assert(context->encoding == 0); - assert(context->input != 0); - assert(context->libxml2_context != 0); - - srcsax_free_context(context); - - } - - { - - srcsax_context * context = srcsax_create_context_filename(__FILE__, 0); - - assert(context->data == 0); - assert(context->handler == 0); - assert(context->srcsax_error == 0); - assert(context->is_archive == 0); - assert(context->unit_count == 0); - assert(context->encoding == 0); - assert(context->input != 0); - assert(context->libxml2_context != 0); - - srcsax_free_context(context); - - } - - { - - srcsax_context * context = srcsax_create_context_filename(0, "UTF-8"); - - assert(context == 0); - - } - - { - - srcsax_context * context = srcsax_create_context_filename("foobar", "UTF-8"); - - assert(context == 0); - - } - - /* - srcsax_create_context_memory - */ - { - - const char * srcml_buffer = "<unit/>"; - - srcsax_context * context = srcsax_create_context_memory(srcml_buffer, strlen(srcml_buffer), "UTF-8"); - - assert(context->data == 0); - assert(context->handler == 0); - assert(context->srcsax_error == 0); - assert(context->is_archive == 0); - assert(context->unit_count == 0); - assert(context->encoding == 0); - assert(context->input != 0); - assert(context->libxml2_context != 0); - - srcsax_free_context(context); - - } - - { - - const char * srcml_buffer = "<unit/>"; - - srcsax_context * context = srcsax_create_context_memory(srcml_buffer, strlen(srcml_buffer), "ISO-8859-1"); - - assert(context->data == 0); - assert(context->handler == 0); - assert(context->srcsax_error == 0); - assert(context->is_archive == 0); - assert(context->unit_count == 0); - assert(context->encoding == 0); - assert(context->input != 0); - assert(context->libxml2_context != 0); - - srcsax_free_context(context); - - } - - { - - const char * srcml_buffer = "<unit/>"; - - srcsax_context * context = srcsax_create_context_memory(srcml_buffer, strlen(srcml_buffer), 0); - - assert(context->data == 0); - assert(context->handler == 0); - assert(context->srcsax_error == 0); - assert(context->is_archive == 0); - assert(context->unit_count == 0); - assert(context->encoding == 0); - assert(context->input != 0); - assert(context->libxml2_context != 0); - - srcsax_free_context(context); - - } - - { - - const char * srcml_buffer = "<unit/>"; - - srcsax_context * context = srcsax_create_context_memory(0, strlen(srcml_buffer), "UTF-8"); - - assert(context == 0); - - } - - { - - const char * srcml_buffer = "<unit/>"; - - srcsax_context * context = srcsax_create_context_memory(srcml_buffer, 0, "UTF-8"); - - assert(context == 0); - - } - - /* - srcsax_create_context_FILE - */ - { - - FILE * file = fopen(__FILE__, "r"); - srcsax_context * context = srcsax_create_context_FILE(file, "UTF-8"); - - assert(context->data == 0); - assert(context->handler == 0); - assert(context->srcsax_error == 0); - assert(context->is_archive == 0); - assert(context->unit_count == 0); - assert(context->encoding == 0); - assert(context->input != 0); - assert(context->libxml2_context != 0); - - srcsax_free_context(context); - fclose(file); - - } - - { - - FILE * file = fopen(__FILE__, "r"); - srcsax_context * context = srcsax_create_context_FILE(file, "ISO-8859-1"); - - assert(context->data == 0); - assert(context->handler == 0); - assert(context->srcsax_error == 0); - assert(context->is_archive == 0); - assert(context->unit_count == 0); - assert(context->encoding == 0); - assert(context->input != 0); - assert(context->libxml2_context != 0); - - srcsax_free_context(context); - fclose(file); - - } - - { - - FILE * file = fopen(__FILE__, "r"); - srcsax_context * context = srcsax_create_context_FILE(file, 0); - - assert(context->data == 0); - assert(context->handler == 0); - assert(context->srcsax_error == 0); - assert(context->is_archive == 0); - assert(context->unit_count == 0); - assert(context->encoding == 0); - assert(context->input != 0); - assert(context->libxml2_context != 0); - - srcsax_free_context(context); - fclose(file); - - } - - { - - srcsax_context * context = srcsax_create_context_FILE(0, "UTF-8"); - - assert(context == 0); - - } - - /* - srcsax_create_context_fd - */ - { - - int fd = open(__FILE__, O_RDONLY); - srcsax_context * context = srcsax_create_context_fd(fd, "UTF-8"); - - assert(context->data == 0); - assert(context->handler == 0); - assert(context->srcsax_error == 0); - assert(context->is_archive == 0); - assert(context->unit_count == 0); - assert(context->encoding == 0); - assert(context->input != 0); - assert(context->libxml2_context != 0); - - srcsax_free_context(context); - close(fd); - - } - - { - - int fd = open(__FILE__, O_RDONLY); - srcsax_context * context = srcsax_create_context_fd(fd, "ISO-8859-1"); - - assert(context->data == 0); - assert(context->handler == 0); - assert(context->srcsax_error == 0); - assert(context->is_archive == 0); - assert(context->unit_count == 0); - assert(context->encoding == 0); - assert(context->input != 0); - assert(context->libxml2_context != 0); - - srcsax_free_context(context); - close(fd); - - } - - { - - int fd = open(__FILE__, O_RDONLY); - srcsax_context * context = srcsax_create_context_fd(fd, 0); - - assert(context->data == 0); - assert(context->handler == 0); - assert(context->srcsax_error == 0); - assert(context->is_archive == 0); - assert(context->unit_count == 0); - assert(context->encoding == 0); - assert(context->input != 0); - assert(context->libxml2_context != 0); - - srcsax_free_context(context); - close(fd); - - } - - { - - srcsax_context * context = srcsax_create_context_fd(-1, "UTF-8"); - - assert(context == 0); - - } - - /* - srcsax_create_context_io - */ - { - - FILE * file = fopen(__FILE__, "r"); - srcsax_context * context = srcsax_create_context_io((void *)file, read_callback, close_callback, "UTF-8"); - - assert(context->data == 0); - assert(context->handler == 0); - assert(context->srcsax_error == 0); - assert(context->is_archive == 0); - assert(context->unit_count == 0); - assert(context->encoding == 0); - assert(context->input != 0); - assert(context->libxml2_context != 0); - - srcsax_free_context(context); - - } - - { - - FILE * file = fopen(__FILE__, "r"); - srcsax_context * context = srcsax_create_context_io((void *)file, read_callback, close_callback, "ISO-8859-1"); - - assert(context->data == 0); - assert(context->handler == 0); - assert(context->srcsax_error == 0); - assert(context->is_archive == 0); - assert(context->unit_count == 0); - assert(context->encoding == 0); - assert(context->input != 0); - assert(context->libxml2_context != 0); - - srcsax_free_context(context); - - } - - { - - FILE * file = fopen(__FILE__, "r"); - srcsax_context * context = srcsax_create_context_io((void *)file, read_callback, close_callback, 0); - - assert(context->data == 0); - assert(context->handler == 0); - assert(context->srcsax_error == 0); - assert(context->is_archive == 0); - assert(context->unit_count == 0); - assert(context->encoding == 0); - assert(context->input != 0); - assert(context->libxml2_context != 0); - - srcsax_free_context(context); - - } - - { - - FILE * file = fopen(__FILE__, "r"); - srcsax_context * context = srcsax_create_context_io((void *)file, 0, close_callback, "UTF-8"); - - assert(context == 0); - - } - - { - - srcsax_context * context = srcsax_create_context_io(0, read_callback, close_callback, "UTF-8"); - - assert(context == 0); - - } - - /* - srcsax_free_context - */ - - { - - srcsax_free_context(0); - - } - - /* - srcsax_parse - */ - { - - srcsax_handler_test data; - srcsax_handler handler = srcsax_handler_test::factory(); - - const char * srcml_buffer = "<unit/>"; - - srcsax_context * context = srcsax_create_context_memory(srcml_buffer, strlen(srcml_buffer), "UTF-8"); - context->data = &data; - context->handler = &handler; - - assert(srcsax_parse(context) == 0); - - srcsax_free_context(context); - - } - - { - - srcsax_handler_test data; - srcsax_handler handler = srcsax_handler_test::factory(); - - const char * srcml_buffer = "<unit>"; - - srcsax_context * context = srcsax_create_context_memory(srcml_buffer, strlen(srcml_buffer), "UTF-8"); - context->data = &data; - context->handler = &handler; - - assert(srcsax_parse(context) == -1); - - srcsax_free_context(context); - - } - - { - - srcsax_handler_test data; - srcsax_handler handler = srcsax_handler_test::factory(); - - const char * srcml_buffer = "<unit/>"; - - srcsax_context * context = srcsax_create_context_memory(srcml_buffer, strlen(srcml_buffer), "UTF-8"); - context->data = &data; - context->handler = &handler; - - assert(srcsax_parse(0) == -1); - - srcsax_free_context(context); - - } - - { - - srcsax_handler_test data; - - const char * srcml_buffer = "<unit/>"; - - srcsax_context * context = srcsax_create_context_memory(srcml_buffer, strlen(srcml_buffer), "UTF-8"); - context->data = &data; - - assert(srcsax_parse(context) == -1); - - srcsax_free_context(context); - - } - - { - - srcsax_handler_test data; - - const char * srcml_buffer = "<unit/>"; - - srcsax_context * context = srcsax_create_context_memory(srcml_buffer, strlen(srcml_buffer), "UTF-8"); - context->data = &data; - context->handler = 0; - - assert(srcsax_parse(context) == -1); - - srcsax_free_context(context); - - } - - /* - srcsax_parse_handler - */ - { - - srcsax_handler_test data; - srcsax_handler handler = srcsax_handler_test::factory(); - - const char * srcml_buffer = "<unit/>"; - - srcsax_context * context = srcsax_create_context_memory(srcml_buffer, strlen(srcml_buffer), "UTF-8"); - context->data = &data; - - assert(srcsax_parse_handler(context, &handler) == 0); - - srcsax_free_context(context); - - } - - { - - srcsax_handler_test data; - srcsax_handler handler = srcsax_handler_test::factory(); - - const char * srcml_buffer = "<unit>"; - - srcsax_context * context = srcsax_create_context_memory(srcml_buffer, strlen(srcml_buffer), "UTF-8"); - context->data = &data; - - assert(srcsax_parse_handler(context, &handler) == -1); - - srcsax_free_context(context); - - } - - { - - srcsax_handler_test data; - srcsax_handler handler = srcsax_handler_test::factory(); - - const char * srcml_buffer = "<unit/>"; - - srcsax_context * context = srcsax_create_context_memory(srcml_buffer, strlen(srcml_buffer), "UTF-8"); - context->data = &data; - - assert(srcsax_parse_handler(0, &handler) == -1); - - srcsax_free_context(context); - - } - - { - - srcsax_handler_test data; - - const char * srcml_buffer = "<unit/>"; - - srcsax_context * context = srcsax_create_context_memory(srcml_buffer, strlen(srcml_buffer), "UTF-8"); - context->data = &data; - - assert(srcsax_parse_handler(context, 0) == -1); - - srcsax_free_context(context); - - } - - /* - srcsax_stop_parse - */ - { - - srcsax_handler_test data; - srcsax_handler handler = srcsax_handler_test::factory(); - - const char * srcml_buffer = "<unit/>"; - - srcsax_context * context = srcsax_create_context_memory(srcml_buffer, strlen(srcml_buffer), "UTF-8"); - context->data = &data; - context->handler = &handler; - - srcsax_stop_parser(context); - - srcsax_free_context(context); - - } - - return 0; - -} - - -/** - * @file test_srcsax_control_handler.cpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <sax2_srcsax_handler.hpp> -#include <srcsax_handler_test.hpp> -#include <cppCallbackAdapter.hpp> - -#include <srcsax.h> - -#include <stdio.h> -#include <string.h> -#include <cassert> - -/** default initialization used throughout for testing */ -sax2_srcsax_handler sax2_handler_init; - -/** default initialization used throughout for testing */ -xmlParserCtxt ctxt_init; - -/** - * main - * - * Test the srcsax functions. - * - * @returns 0 on success. - */ -int main() { - - - /** - srcml_element_stack - */ - { - - srcSAXHandler handler; - cppCallbackAdapter cpp_adapter(&handler); - srcsax_handler srcsax_sax = cppCallbackAdapter::factory(); - - srcsax_context context; - context.data = &cpp_adapter; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - - start_document(&ctxt); - assert(handler.get_stack().size() == 0); - - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(handler.get_stack().size() == 0); - - start_element_ns_first(&ctxt, (const xmlChar *)"expr_stmt", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(handler.get_stack().size() == 2); - assert(handler.get_stack().front() == "unit"); - assert(handler.get_stack().back() == "expr_stmt"); - - start_unit(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(handler.get_stack().size() == 3); - assert(handler.get_stack().back() == "unit"); - - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(handler.get_stack().size() == 2); - assert(handler.get_stack().back() == "expr_stmt"); - - start_unit(&ctxt, (const xmlChar *)"decl_stmt", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(handler.get_stack().size() == 3); - assert(handler.get_stack().back() == "decl_stmt"); - - start_unit(&ctxt, (const xmlChar *)"if", (const xmlChar *)"cpp", - (const xmlChar *)"http://www.sdml.info/srcML/cpp", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(handler.get_stack().size() == 4); - assert(handler.get_stack().back() == "cpp:if"); - - end_element_ns(&ctxt, (const xmlChar *)"if", (const xmlChar *)"cpp", - (const xmlChar *)"http://www.sdml.info/srcML/cpp"); - - assert(handler.get_stack().size() == 3); - assert(handler.get_stack().back() == "decl_stmt"); - - end_element_ns(&ctxt, (const xmlChar *)"decl_stmt", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(handler.get_stack().size() == 2); - assert(handler.get_stack().back() == "expr_stmt"); - - end_element_ns(&ctxt, (const xmlChar *)"expr_stmt", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(handler.get_stack().size() == 1); - assert(handler.get_stack().back() == "unit"); - - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(handler.get_stack().size() == 0); - - end_document(&ctxt); - - assert(handler.get_stack().size() == 0); - - } - - { - - srcSAXHandler handler; - cppCallbackAdapter cpp_adapter(&handler); - srcsax_handler srcsax_sax = cppCallbackAdapter::factory(); - - srcsax_context context; - context.data = &cpp_adapter; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - - start_document(&ctxt); - assert(handler.get_stack().size() == 0); - - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(handler.get_stack().size() == 0); - - start_element_ns_first(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(handler.get_stack().size() == 2); - assert(handler.get_stack().front() == "unit"); - assert(handler.get_stack().back() == "unit"); - - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(handler.get_stack().size() == 1); - assert(handler.get_stack().back() == "unit"); - - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(handler.get_stack().size() == 0); - - end_document(&ctxt); - - assert(handler.get_stack().size() == 0); - - } - - { - - srcSAXHandler handler; - cppCallbackAdapter cpp_adapter(&handler); - srcsax_handler srcsax_sax = cppCallbackAdapter::factory(); - - srcsax_context context; - context.data = &cpp_adapter; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - - start_document(&ctxt); - assert(handler.get_stack().size() == 0); - - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(handler.get_stack().size() == 0); - - start_element_ns_first(&ctxt, (const xmlChar *)"macro-list", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(handler.get_stack().size() == 0); - - end_element_ns(&ctxt, (const xmlChar *)"macro-list", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(handler.get_stack().size() == 0); - - start_element_ns_first(&ctxt, (const xmlChar *)"expr_stmt", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(handler.get_stack().size() == 2); - assert(handler.get_stack().front() == "unit"); - assert(handler.get_stack().back() == "expr_stmt"); - - end_element_ns(&ctxt, (const xmlChar *)"expr_stmt", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(handler.get_stack().size() == 1); - assert(handler.get_stack().back() == "unit"); - - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(handler.get_stack().size() == 0); - - end_document(&ctxt); - - assert(handler.get_stack().size() == 0); - - } - - { - - srcSAXHandler handler; - cppCallbackAdapter cpp_adapter(&handler); - srcsax_handler srcsax_sax = cppCallbackAdapter::factory(); - - srcsax_context context; - context.data = &cpp_adapter; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - - start_document(&ctxt); - assert(handler.get_stack().size() == 0); - - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(handler.get_stack().size() == 0); - - start_element_ns_first(&ctxt, (const xmlChar *)"macro-list", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(handler.get_stack().size() == 0); - - end_element_ns(&ctxt, (const xmlChar *)"macro-list", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(handler.get_stack().size() == 0); - - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(handler.get_stack().size() == 0); - - end_document(&ctxt); - - assert(handler.get_stack().size() == 0); - - } - - return 0; -} - - -/** - * @file windows_utils.cpp - * - * @copyright Copyright (C) 2013-2014 srcML, LLC. (www.srcML.org) - * - * srcSAX are free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * srcSAX are distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <windows_utils.hpp> - -#include <cstdlib> -#include <cstring> - -#ifdef _MSC_BUILD - -char * strndup(const char * source, size_t n) { - - if(source == 0) return 0; - - char * dup = (char *)malloc((n + 1) * sizeof(char)); - strncpy(dup, source, n); - dup[n] = 0; - - return dup; - -} - -#endif - - -/** - * @file windows_utils.hpp - * - * @copyright Copyright (C) 2014 srcML, LLC. (www.srcML.org) - * - * srcSAX are free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * srcSAX are distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef INCLUDED_SRCTOOLS_WINDOWS_HPP -#define INCLUDED_SRCTOOLS_WINDOWS_HPP - -#ifdef _MSC_BUILD - -#ifdef WIN32 -#include <cstdlib> -#endif - -char * strndup(const char * source, size_t n); - -#endif - -#endif - - -/** - * @file test_sax2_srcsax_handler.cpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <sax2_srcsax_handler.hpp> -#include <srcsax_handler_test.hpp> - -#include <srcsax.h> - -#include <stdio.h> -#include <string.h> -#include <cassert> - -/** default initialization used throughout for testing */ -sax2_srcsax_handler sax2_handler_init; - -/** default initialization used throughout for testing */ -xmlParserCtxt ctxt_init; - -/** - * main - * - * Test the sax2_srcsax_handler. - * - * @returns 0 on success. - */ -int main() { - - /* - start_document - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - start_document(&ctxt); - - } - - { - - start_document(NULL); - - } - - /* - end_document - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - end_document(&ctxt); - - } - - { - - end_document(NULL); - - } - - /* - start_root - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert((const char *)sax2_handler.root.localname == std::string("unit")); - assert((const char *)sax2_handler.root.prefix == 0); - assert((const char *)sax2_handler.root.URI == std::string("http://www.sdml.info/srcML/src")); - assert(sax2_handler.root.nb_namespaces == 2); - assert((const char *)sax2_handler.root.namespaces[0] == 0); - assert((const char *)sax2_handler.root.namespaces[1] == std::string("http://www.sdml.info/srcML/src")); - assert((const char *)sax2_handler.root.namespaces[2] == std::string("cpp")); - assert((const char *)sax2_handler.root.namespaces[3] == std::string("http://www.sdml.info/srcML/cpp")); - assert(sax2_handler.root.nb_attributes == 3); - assert(sax2_handler.root.nb_defaulted == 0); - assert((const char *)sax2_handler.root.attributes[0] == std::string("filename")); - assert((const char *)sax2_handler.root.attributes[1] == 0); - assert((const char *)sax2_handler.root.attributes[2] == std::string("http://www.sdml.info/srcML/src")); - assert(sax2_handler.root.attributes[4] - sax2_handler.root.attributes[3] == 1); - assert((char)sax2_handler.root.attributes[3][0] == 'a'); - assert((const char *)sax2_handler.root.attributes[5] == std::string("dir")); - assert((const char *)sax2_handler.root.attributes[6] == 0); - assert((const char *)sax2_handler.root.attributes[7] == std::string("http://www.sdml.info/srcML/src")); - assert(sax2_handler.root.attributes[9] - sax2_handler.root.attributes[8] == 1); - assert((char)sax2_handler.root.attributes[8][0] == 'b'); - assert((const char *)sax2_handler.root.attributes[10] == std::string("language")); - assert((const char *)sax2_handler.root.attributes[11] == 0); - assert((const char *)sax2_handler.root.attributes[12] == std::string("http://www.sdml.info/srcML/src")); - assert(sax2_handler.root.attributes[14] - sax2_handler.root.attributes[13] == 1); - assert((char)sax2_handler.root.attributes[13][0] == 'c'); - assert(ctxt.sax->startDocument == start_document); - assert(ctxt.sax->endDocument == end_document); - assert(ctxt.sax->startElementNs == start_element_ns_first); - assert(ctxt.sax->endElementNs == end_element_ns); - assert(ctxt.sax->characters == characters_first); - assert(ctxt.sax->comment == comment); - assert(ctxt.sax->cdataBlock == cdata_block); - assert(ctxt.sax->processingInstruction == processing_instruction); - end_document(&ctxt); - - } - - { - - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - start_root(NULL, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - } - - /* - start_element_ns_first - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - start_element_ns_first(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(ctxt.sax->startDocument == start_document); - assert(ctxt.sax->endDocument == end_document); - assert(ctxt.sax->startElementNs == start_element_ns); - assert(ctxt.sax->endElementNs == end_element_ns); - assert(ctxt.sax->characters == characters_unit); - assert(ctxt.sax->comment == comment); - assert(ctxt.sax->cdataBlock == cdata_block); - assert(ctxt.sax->processingInstruction == processing_instruction); - - } - - { - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - start_root(NULL, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - start_element_ns_first(NULL, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - } - - /* - start_unit - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - - start_unit(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(ctxt.sax->startDocument == start_document); - assert(ctxt.sax->endDocument == end_document); - assert(ctxt.sax->startElementNs == start_element_ns); - assert(ctxt.sax->endElementNs == end_element_ns); - assert(ctxt.sax->characters == characters_unit); - assert(ctxt.sax->comment == comment); - assert(ctxt.sax->cdataBlock == cdata_block); - assert(ctxt.sax->processingInstruction == processing_instruction); - - } - - { - - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - start_unit(NULL, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - } - - /* - start_element_ns - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - - start_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(ctxt.sax->startDocument == start_document); - assert(ctxt.sax->endDocument == end_document); - assert(ctxt.sax->startElementNs == start_root); - assert(ctxt.sax->endElementNs == end_element_ns); - assert(ctxt.sax->characters == characters_first); - assert(ctxt.sax->comment == comment); - assert(ctxt.sax->cdataBlock == cdata_block); - assert(ctxt.sax->processingInstruction == processing_instruction); - - } - - { - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - start_element_ns(NULL, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - } - - /* - end_element_ns - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - assert(ctxt.sax->startDocument == start_document); - assert(ctxt.sax->endDocument == end_document); - assert(ctxt.sax->startElementNs == start_unit); - assert(ctxt.sax->endElementNs == end_element_ns); - assert(ctxt.sax->characters == characters_root); - assert(ctxt.sax->comment == comment); - assert(ctxt.sax->cdataBlock == cdata_block); - assert(ctxt.sax->processingInstruction == processing_instruction); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - sax.startElementNs = &start_unit; - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - assert(ctxt.sax->startDocument == start_document); - assert(ctxt.sax->endDocument == end_document); - assert(ctxt.sax->startElementNs == start_unit); - assert(ctxt.sax->endElementNs == end_element_ns); - assert(ctxt.sax->characters == characters_first); - assert(ctxt.sax->comment == comment); - assert(ctxt.sax->cdataBlock == cdata_block); - assert(ctxt.sax->processingInstruction == processing_instruction); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - end_element_ns(&ctxt, (const xmlChar *)"name", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - assert(ctxt.sax->startDocument == start_document); - assert(ctxt.sax->endDocument == end_document); - assert(ctxt.sax->startElementNs == start_root); - assert(ctxt.sax->endElementNs == end_element_ns); - assert(ctxt.sax->characters == characters_first); - assert(ctxt.sax->comment == comment); - assert(ctxt.sax->cdataBlock == cdata_block); - assert(ctxt.sax->processingInstruction == processing_instruction); - - } - - { - - end_element_ns(NULL, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - } - - /* - characters_first - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - characters_first(&ctxt, (const xmlChar *)"unit", 4); - assert(sax2_handler.characters == "unit"); - assert(ctxt.sax->startDocument == start_document); - assert(ctxt.sax->endDocument == end_document); - assert(ctxt.sax->startElementNs == start_root); - assert(ctxt.sax->endElementNs == end_element_ns); - assert(ctxt.sax->characters == characters_first); - assert(ctxt.sax->comment == comment); - assert(ctxt.sax->cdataBlock == cdata_block); - assert(ctxt.sax->processingInstruction == processing_instruction); - - } - - { - - characters_first(NULL, (const xmlChar *)"unit", 4); - - } - - /* - characters_root - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - characters_root(&ctxt, (const xmlChar *)"unit", 4); - assert(ctxt.sax->startDocument == start_document); - assert(ctxt.sax->endDocument == end_document); - assert(ctxt.sax->startElementNs == start_root); - assert(ctxt.sax->endElementNs == end_element_ns); - assert(ctxt.sax->characters == characters_first); - assert(ctxt.sax->comment == comment); - assert(ctxt.sax->cdataBlock == cdata_block); - assert(ctxt.sax->processingInstruction == processing_instruction); - } - - { - - characters_root(NULL, (const xmlChar *)"unit", 4); - - } - - /* - characters_unit - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - characters_unit(&ctxt, (const xmlChar *)"unit", 4); - assert(ctxt.sax->startDocument == start_document); - assert(ctxt.sax->endDocument == end_document); - assert(ctxt.sax->startElementNs == start_root); - assert(ctxt.sax->endElementNs == end_element_ns); - assert(ctxt.sax->characters == characters_first); - assert(ctxt.sax->comment == comment); - assert(ctxt.sax->cdataBlock == cdata_block); - assert(ctxt.sax->processingInstruction == processing_instruction); - } - - { - - characters_unit(NULL, (const xmlChar *)"unit", 4); - - } - - /* - meta_tag - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - sax.startElementNs = start_element_ns_first; - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char ** namespaces = 0; - const char * values = "ab"; - const char * attributes[10] = { "token", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "type", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2 }; - - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 0, (const xmlChar **)namespaces, 2, 0, - (const xmlChar **) attributes); - - start_element_ns_first(&ctxt, (const xmlChar *)"macro-list", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 0, (const xmlChar **)namespaces, 2, 0, - (const xmlChar **) attributes); - assert(ctxt.sax->startDocument == start_document); - assert(ctxt.sax->endDocument == end_document); - assert(ctxt.sax->startElementNs == start_element_ns_first); - assert(ctxt.sax->endElementNs == end_element_ns); - assert(ctxt.sax->characters == characters_first); - assert(ctxt.sax->comment == comment); - assert(ctxt.sax->cdataBlock == cdata_block); - assert(ctxt.sax->processingInstruction == processing_instruction); - - } - - /* - comment - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - comment(&ctxt, (const xmlChar *)"unit"); - assert(ctxt.sax->startDocument == start_document); - assert(ctxt.sax->endDocument == end_document); - assert(ctxt.sax->startElementNs == start_root); - assert(ctxt.sax->endElementNs == end_element_ns); - assert(ctxt.sax->characters == characters_first); - assert(ctxt.sax->comment == comment); - assert(ctxt.sax->cdataBlock == cdata_block); - assert(ctxt.sax->processingInstruction == processing_instruction); - } - - { - - comment(NULL, (const xmlChar *)"unit"); - - } - - /* - cdata_block - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - cdata_block(&ctxt, (const xmlChar *)"unit", 4); - assert(ctxt.sax->startDocument == start_document); - assert(ctxt.sax->endDocument == end_document); - assert(ctxt.sax->startElementNs == start_root); - assert(ctxt.sax->endElementNs == end_element_ns); - assert(ctxt.sax->characters == characters_first); - assert(ctxt.sax->comment == comment); - assert(ctxt.sax->cdataBlock == cdata_block); - assert(ctxt.sax->processingInstruction == processing_instruction); - } - - { - - cdata_block(NULL, (const xmlChar *)"unit", 4); - - } - - /* - processing_instruction - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - processing_instruction(&ctxt, (const xmlChar *)"target", (const xmlChar *)"data"); - assert(ctxt.sax->startDocument == start_document); - assert(ctxt.sax->endDocument == end_document); - assert(ctxt.sax->startElementNs == start_root); - assert(ctxt.sax->endElementNs == end_element_ns); - assert(ctxt.sax->characters == characters_first); - assert(ctxt.sax->comment == comment); - assert(ctxt.sax->cdataBlock == cdata_block); - assert(ctxt.sax->processingInstruction == processing_instruction); - } - - { - - processing_instruction(NULL, (const xmlChar *)"target", (const xmlChar *)"data"); - - } - - /** - srcml_element_stack - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - - start_document(&ctxt); - assert(context.stack_size == 0); - assert(context.srcml_element_stack == 0); - - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(context.stack_size == 1); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - start_element_ns_first(&ctxt, (const xmlChar *)"expr_stmt", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(context.stack_size == 2); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "expr_stmt") == 0); - - start_unit(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(context.stack_size == 3); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(context.stack_size == 2); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "expr_stmt") == 0); - - start_element_ns(&ctxt, (const xmlChar *)"decl_stmt", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(context.stack_size == 3); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "decl_stmt") == 0); - - start_element_ns(&ctxt, (const xmlChar *)"if", (const xmlChar *)"cpp", - (const xmlChar *)"http://www.sdml.info/srcML/cpp", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(context.stack_size == 4); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "cpp:if") == 0); - - end_element_ns(&ctxt, (const xmlChar *)"if", (const xmlChar *)"cpp", - (const xmlChar *)"http://www.sdml.info/srcML/cpp"); - - assert(context.stack_size == 3); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "decl_stmt") == 0); - - end_element_ns(&ctxt, (const xmlChar *)"decl_stmt", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(context.stack_size == 2); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "expr_stmt") == 0); - - end_element_ns(&ctxt, (const xmlChar *)"expr_stmt", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(context.stack_size == 1); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(context.stack_size == 0); - assert(context.srcml_element_stack == 0); - - end_document(&ctxt); - - assert(context.stack_size == 0); - assert(context.srcml_element_stack == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - - start_document(&ctxt); - assert(context.stack_size == 0); - assert(context.srcml_element_stack == 0); - - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(context.stack_size == 1); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - start_element_ns_first(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(context.stack_size == 2); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(context.stack_size == 1); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(context.stack_size == 0); - assert(context.srcml_element_stack == 0); - - end_document(&ctxt); - - assert(context.stack_size == 0); - assert(context.srcml_element_stack == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - - start_document(&ctxt); - assert(context.stack_size == 0); - assert(context.srcml_element_stack == 0); - - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(context.stack_size == 1); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - start_element_ns_first(&ctxt, (const xmlChar *)"macro-list", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(context.stack_size == 1); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - end_element_ns(&ctxt, (const xmlChar *)"macro-list", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(context.stack_size == 1); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - - start_element_ns_first(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(context.stack_size == 2); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(context.stack_size == 1); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(context.stack_size == 0); - assert(context.srcml_element_stack == 0); - - end_document(&ctxt); - - assert(context.stack_size == 0); - assert(context.srcml_element_stack == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - - start_document(&ctxt); - assert(context.stack_size == 0); - assert(context.srcml_element_stack == 0); - - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(context.stack_size == 1); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - start_element_ns_first(&ctxt, (const xmlChar *)"macro-list", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(context.stack_size == 1); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - end_element_ns(&ctxt, (const xmlChar *)"macro-list", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(context.stack_size == 1); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - - start_element_ns_first(&ctxt, (const xmlChar *)"expr_stmt", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(context.stack_size == 2); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "expr_stmt") == 0); - - end_element_ns(&ctxt, (const xmlChar *)"expr_stmt", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(context.stack_size == 1); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(context.stack_size == 0); - assert(context.srcml_element_stack == 0); - - end_document(&ctxt); - - assert(context.stack_size == 0); - assert(context.srcml_element_stack == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - - start_document(&ctxt); - assert(context.stack_size == 0); - assert(context.srcml_element_stack == 0); - - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(context.stack_size == 1); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - start_element_ns_first(&ctxt, (const xmlChar *)"macro-list", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - - assert(context.stack_size == 1); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - end_element_ns(&ctxt, (const xmlChar *)"macro-list", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(context.stack_size == 1); - assert(context.srcml_element_stack != 0); - assert(strcmp(context.srcml_element_stack[context.stack_size - 1], "unit") == 0); - - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - - assert(context.stack_size == 0); - assert(context.srcml_element_stack == 0); - - end_document(&ctxt); - - assert(context.stack_size == 0); - assert(context.srcml_element_stack == 0); - - } - - return 0; -} - - -/** - * @file sax2_srcsax_handler.hpp - * - * @copyright Copyright (C) 2013-2014 srcML, LLC. (www.srcML.org) - * - * This file is part of the srcML SAX2 Framework. - * - * The srcML SAX2 Framework is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML SAX2 Framework is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML SAX2 Framework; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef INCLUDED_SAX2_SRCSAX_HANDLER_HPP -#define INCLUDED_SAX2_SRCSAX_HANDLER_HPP - -#include <srcml_element.hpp> -#include <srcsax.h> - -#include <libxml/parser.h> - -#include <string> -#include <vector> - -/** - * srcMLMode - * - * Enum of srcML parsing modes. - */ -enum srcMLMode { - - START, - ROOT, - UNIT, - END_UNIT, - END_ROOT - -}; - -/** - * declaration - * - * Data structure to hold a declaration. - */ -struct declaration { - - /** default constructor */ - declaration() : type(), name(), mode(TYPE) {} - - /** declaration type */ - std::string type; - - /** declaration name */ - std::string name; - - /** declaration parsing modes */ - enum { TYPE, NAME, INIT } mode; - -}; - -/** - * function_prototype - * - * Data structure to hold a function prototype. - */ -struct function_prototype { - - /**constructor */ - function_prototype(bool is_decl = false) : name(), return_type(), parameter_list(), mode(RETURN_TYPE), is_decl(is_decl) {} - - /** function name */ - std::string name; - - /** function return type */ - std::string return_type; - - /** function parameter list */ - std::vector<declaration> parameter_list; - - /** function prototype parsing modes */ - enum { RETURN_TYPE, NAME, PARAMETER_LIST, PARAMETER } mode; - - /** bool to indicate if function_decl or function */ - bool is_decl; - -}; - -/** - * sax2_srcsax_handler - * - * Data structure to hold process during - * sax parsing. - */ -struct sax2_srcsax_handler { - - /** default constructor */ - sax2_srcsax_handler() : context(0), root(), meta_tags(), characters(), is_archive(false), mode(START), parse_function(false), in_function_header(false), current_function() {} - - /** hooks for processing */ - srcsax_context * context; - - /** temporary storage for root unit */ - srcml_element root; - - /** temporary storage of meta-tags */ - std::vector<srcml_element> meta_tags; - - /** temporary storate of root characters */ - std::string characters; - - /** used to detect root unit */ - bool is_archive; - - /** open srcMLElement stack */ - std::vector<const char *> srcml_element_stack; - - /** the current parsing mode */ - srcMLMode mode; - - /** bool to indicate if should do special function parsing */ - bool parse_function; - - /** bool to indicate if in funciton for special function parsing */ - bool in_function_header; - - /** store data for special function parsing */ - function_prototype current_function; - -}; - -/** - * srcsax_sax2_factory - * - * Create SAX handler. - */ -xmlSAXHandler srcsax_sax2_factory(); - -/** - * start_document - * @param ctx an xmlParserCtxtPtr - * - * SAX handler function for start of document. - * Immediately calls supplied handlers function. - */ -void start_document(void * ctx); - -/** - * end_document - * @param ctx an xmlParserCtxtPtr - * - * SAX handler function for end of document. - * Calls endRoot if needed then - * immediately calls supplied handlers function. - */ -void end_document(void * ctx); - -/** - * start_root - * @param ctx an xmlParserCtxtPtr - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param nb_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param nb_defaulted the number of defaulted attributes - * @param attributes list of attribute name value pairs (localname/prefix/URI/value/end) - * - * SAX handler function for start of root element. - * Caches root info and immediately calls supplied handlers function. - */ -void start_root(void * ctx, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI, - int nb_namespaces, const xmlChar ** namespaces, int nb_attributes, int nb_defaulted, - const xmlChar ** attributes); - - -/** - * start_element_ns_first - * @param ctx an xmlParserCtxtPtr - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param nb_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param nb_defaulted the number of defaulted attributes - * @param attributes list of attribute name value pairs (localname/prefix/URI/value/end) - * - * SAX handler function for start of first element after root - * Detects archive and acts accordingly. - */ -void start_element_ns_first(void * ctx, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI, - int nb_namespaces, const xmlChar ** namespaces, int nb_attributes, int nb_defaulted, - const xmlChar ** attributes); -/** - * start_unit - * @param ctx an xmlParserCtxtPtr - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param nb_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param nb_defaulted the number of defaulted attributes - * @param attributes list of attribute name value pairs (localname/prefix/URI/value/end) - * - * SAX handler function for start of an unit. - * Immediately calls supplied handlers function. - */ -void start_unit(void * ctx, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI, - int nb_namespaces, const xmlChar ** namespaces, int nb_attributes, int nb_defaulted, - const xmlChar ** attributes); - -/** - * start_element_ns - * @param ctx an xmlParserCtxtPtr - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param nb_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param nb_defaulted the number of defaulted attributes - * @param attributes list of attribute name value pairs (localname/prefix/URI/value/end) - * - * SAX handler function for start of an element. - * Immediately calls supplied handlers function. - */ -void start_element_ns(void * ctx, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI, - int nb_namespaces, const xmlChar ** namespaces, int nb_attributes, int nb_defaulted, - const xmlChar ** attributes); - -/** - * end_element_ns - * @param ctx an xmlParserCtxtPtr - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * SAX handler function for end of an element. - * Detects end of unit and calls correct functions - * for either end_root end_unit or end_element_ns. - */ -void end_element_ns(void * ctx, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI); - -/** - * characters_first - * @param ctx an xmlParserCtxtPtr - * @param ch the characers - * @param len number of characters - * - * SAX handler function for character handling before we - * know if we have an archive or not. - * Immediately calls supplied handlers function. - */ -void characters_first(void * ctx, const xmlChar * ch, int len); - -/** - * characters_root - * @param ctx an xmlParserCtxtPtr - * @param ch the characers - * @param len number of characters - * - * SAX handler function for character handling at the root level. - * Immediately calls supplied handlers function. - */ -void characters_root(void * ctx, const xmlChar * ch, int len); - -/** - * characters_unit - * @param ctx an xmlParserCtxtPtr - * @param ch the characers - * @param len number of characters - * - * SAX handler function for character handling within a unit. - * Immediately calls supplied handlers function. - */ -void characters_unit(void * ctx, const xmlChar * ch, int len); - -/** - * comment - * @param ctx an xmlParserCtxtPtr - * @param value the comment content - * - * A comment has been parsed. - * Immediately calls supplied handlers function. - */ -void comment(void * ctx, const xmlChar * value); - -/** - * cdata_block - * @param ctx an xmlParserCtxtPtr - * @param value the pcdata content - * @param len the block length - * - * Called when a pcdata block has been parsed. - * Immediately calls supplied handlers function. - */ -void cdata_block(void * ctx, const xmlChar * value, int len); - -/** - * processing_instruction - * @param ctx an xmlParserCtxtPtr - * @param target the processing instruction target. - * @param data the processing instruction data. - * - * Called when a processing instruction has been parsed. - * Immediately calls supplied handlers function. - */ -void processing_instruction(void * ctx, const xmlChar * target, const xmlChar * data); - -#endif - - -/** - * @file srcml_element.hpp - * - * @copyright Copyright (C) 2013-2014 srcML, LLC. (www.srcML.org) - * - * srcSAX is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * srcSAX is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef INCLUDED_SRCML_ELEMENT_HPP -#define INCLUDED_SRCML_ELEMENT_HPP - -#ifndef _MSC_BUILD -/** Macro to define the correct name of strdup on unix/windows */ -#define STRDUP strdup -#else -#define STRDUP _strdup -#endif - -#include <srcsax.h> - -#include <libxml/parser.h> - -#include <string.h> -#include <string> - -/** Check if a copy was actually allocated */ -#define CHECK_COPY(ORIGINAL , COPY ) if(ORIGINAL && !COPY) { fprintf(stderr, "ERROR allocating memory"); srcsax_stop_parser(context); return; } - -/** - * srcml_element - * - * Data structure to hold an element - * mainly root element - */ -struct srcml_element { - - /** Default constructor to Zero out srcml_element */ - srcml_element() : context(0), localname(0), prefix(0), URI(0), - nb_namespaces(0), namespaces(0), - nb_attributes(0), nb_defaulted(0), - attributes(0) - {} - - /** Constructor to initialize using start element items */ - srcml_element(srcsax_context * context, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI, - int nb_namespaces, const xmlChar ** namespaces, int nb_attributes, int nb_defaulted, - const xmlChar ** attributes) - : context(context), localname(0), prefix(0), URI(0), - nb_namespaces(0), namespaces(0), - nb_attributes(0), nb_defaulted(0), - attributes(0) { - - // save all the info in case this is not a srcML archive - this->localname = localname ? (xmlChar*) STRDUP((const char*) localname) : 0; - CHECK_COPY(localname, this->localname); - - this->prefix = prefix ? (xmlChar*) STRDUP((const char*) prefix) : 0; - CHECK_COPY(prefix, this->prefix); - - this->URI = URI ? (xmlChar*) STRDUP((const char*) URI) : 0; - CHECK_COPY(URI, this->URI); - - this->nb_namespaces = nb_namespaces; - int ns_length = nb_namespaces * 2; - this->namespaces = (const xmlChar**) malloc(ns_length * sizeof(namespaces[0])); - CHECK_COPY(namespaces, this->namespaces); - memset(this->namespaces, 0, ns_length * sizeof(namespaces[0])); - - for (int i = 0; i < ns_length; ++i) { - - if(prefix && namespaces[i] && strcmp((const char *)prefix, (const char *)namespaces[i]) == 0) - this->namespaces[i] = this->prefix; - else if(URI && namespaces[i] && strcmp((const char *)URI, (const char *)namespaces[i]) == 0) - this->namespaces[i] = this->URI; - else { - - this->namespaces[i] = namespaces[i] ? (xmlChar*) STRDUP((const char*) namespaces[i]) : 0; - CHECK_COPY(namespaces[i], this->namespaces[i]); - } - - } - - this->nb_attributes = nb_attributes; - this->nb_defaulted = nb_defaulted; - - int nb_length = nb_attributes * 5; - this->attributes = (const xmlChar**) malloc(nb_length * sizeof(attributes[0])); - CHECK_COPY(attributes, this->attributes); - - memset(this->attributes, 0, nb_length * sizeof(attributes[0])); - - for (int i = 0, index = 0; i < nb_attributes; ++i, index += 5) { - this->attributes[index] = attributes[index] ? (xmlChar*) STRDUP((const char*) attributes[index]) : 0; - CHECK_COPY(attributes[index], this->attributes[index]); - this->attributes[index + 1] = attributes[index + 1] ? (xmlChar*) STRDUP((const char*) attributes[index + 1]) : 0; - CHECK_COPY(attributes[index + 1], this->attributes[index + 1]); - this->attributes[index + 2] = attributes[index + 2] ? (xmlChar*) STRDUP((const char*) attributes[index + 2]) : 0; - CHECK_COPY(attributes[index + 2], this->attributes[index + 2]); - - int vallength = (int)(attributes[index + 4] - attributes[index + 3]); - this->attributes[index + 3] = (const xmlChar*) malloc(vallength + 1); - CHECK_COPY(attributes[index + 3], this->attributes[index + 3]); - - strncpy((char *) this->attributes[index + 3], (const char*) attributes[index + 3], vallength); - ((char *)this->attributes[index + 3])[vallength] = 0; - this->attributes[index + 4] = this->attributes[index + 3] + vallength; - - } - - } - - /** Copy constructor */ - srcml_element(const srcml_element & element) - : context(element.context), localname(0), prefix(0), URI(0), - nb_namespaces(0), namespaces(0), - nb_attributes(0), nb_defaulted(0), - attributes(0) { - - // save all the info in case this is not a srcML archive - this->localname = element.localname ? (xmlChar*) STRDUP((const char*) element.localname) : 0; - CHECK_COPY(element.localname, this->localname); - - this->prefix = element.prefix ? (xmlChar*) STRDUP((const char*) element.prefix) : 0; - CHECK_COPY(element.prefix, this->prefix); - - this->URI = element.URI ? (xmlChar*) STRDUP((const char*) element.URI) : 0; - CHECK_COPY(element.URI, this->URI); - - this->nb_namespaces = element.nb_namespaces; - int ns_length = element.nb_namespaces * 2; - this->namespaces = (const xmlChar**) malloc(ns_length * sizeof(element.namespaces[0])); - CHECK_COPY(element.namespaces, this->namespaces); - memset(this->namespaces, 0, ns_length * sizeof(element.namespaces[0])); - - for (int i = 0; i < ns_length; ++i) { - this->namespaces[i] = element.namespaces[i] ? (xmlChar*) STRDUP((const char*) element.namespaces[i]) : 0; - CHECK_COPY(element.namespaces[i], this->namespaces[i]); - } - - this->nb_attributes = element.nb_attributes; - this->nb_defaulted = element.nb_defaulted; - - int nb_length = element.nb_attributes * 5; - this->attributes = (const xmlChar**) malloc(nb_length * sizeof(element.attributes[0])); - CHECK_COPY(element.attributes, this->attributes); - - memset(this->attributes, 0, nb_length * sizeof(element.attributes[0])); - - for (int i = 0, index = 0; i < element.nb_attributes; ++i, index += 5) { - this->attributes[index] = element.attributes[index] ? (xmlChar*) STRDUP((const char*) element.attributes[index]) : 0; - CHECK_COPY(element.attributes[index], this->attributes[index]); - this->attributes[index + 1] = element.attributes[index + 1] ? (xmlChar*) STRDUP((const char*) element.attributes[index + 1]) : 0; - CHECK_COPY(element.attributes[index + 1], this->attributes[index + 1]); - this->attributes[index + 2] = element.attributes[index + 2] ? (xmlChar*) STRDUP((const char*) element.attributes[index + 2]) : 0; - CHECK_COPY(element.attributes[index + 2], this->attributes[index + 2]); - - int vallength = (int)(element.attributes[index + 4] - element.attributes[index + 3]); - this->attributes[index + 3] = (const xmlChar*) malloc(vallength + 1); - CHECK_COPY(element.attributes[index + 3], this->attributes[index + 3]); - - strncpy((char *) this->attributes[index + 3], (const char*) element.attributes[index + 3], vallength); - ((char *)this->attributes[index + 3])[vallength] = 0; - this->attributes[index + 4] = this->attributes[index + 3] + vallength; - - } - - } - - /** Overloaded assignment operator */ - /**non-void-command collaborator stateless */ - srcml_element & operator=operator=operator=(srcml_element element) { - - swap(element); - return *this; - - } - - /** swap operator */ - /**command collaborational-command collaborator */ - void swapswap(srcml_element & element) { - - std::swap(localname, element.localname); - std::swap(prefix, element.prefix); - std::swap(URI, element.URI); - std::swap(nb_namespaces, element.nb_namespaces); - std::swap(namespaces, element.namespaces); - std::swap(nb_attributes, element.nb_attributes); - std::swap(nb_defaulted, element.nb_defaulted); - std::swap(attributes, element.attributes); - - } - - /** destructor */ - ~srcml_element() { - - if(namespaces) { - - for(int i = 0; i < nb_namespaces * 2; ++i) - if(namespaces[i] && namespaces[i] != prefix && namespaces[i] != URI) - free((void *)namespaces[i]); - - free((void *)namespaces); - } - - if(localname) free((void *)localname); - if(prefix) free((void *)prefix); - if(URI) free((void *)URI); - - if(attributes) { - - for (int i = 0, index = 0; i < nb_attributes; ++i, index += 5) { - if(attributes[index]) - free((void *)attributes[index]); - if(attributes[index + 1]) - free((void *)attributes[index + 1]); - if(attributes[index + 2]) - free((void *)attributes[index + 2]); - free((void *)attributes[index + 3]); - } - - free((void *)attributes); - - } - - } - - /** parser context */ - srcsax_context * context; - - /** local name of an element*/ - const xmlChar* localname; - - /** prefix of an element*/ - const xmlChar* prefix; - - /** URI of an element*/ - const xmlChar* URI; - - /** number of namespaces on an element*/ - int nb_namespaces; - - /** namespaces on an element*/ - const xmlChar** namespaces; - - /** number of attributes on an element*/ - int nb_attributes; - - /** number of defaulted on an element*/ - int nb_defaulted; - - /** attributes of an element*/ - const xmlChar** attributes; - -}; - -#endif - - -/** - * @file sax2_srcsax_handler.cpp - * - * @copyright Copyright (C) 2013-2014 srcML, LLC. (www.srcML.org) - * - * This file is part of the srcML SAX2 Framework. - * - * The srcML SAX2 Framework is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML SAX2 Framework is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with the srcML SAX2 Framework; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <sax2_srcsax_handler.hpp> -#include <windows_utils.hpp> - -#include <cstring> - -/** Static sax handler for zero initializing in factory */ -xmlSAXHandler sax2_srcml_handler_init; - -/** - * factory - * - * Create SAX handler. - */ -xmlSAXHandler srcsax_sax2_factory() { - - xmlSAXHandler sax = sax2_srcml_handler_init; - - sax.initialized = XML_SAX2_MAGIC; - - sax.startDocumentstartDocumentstartDocument = &start_documentstart_document; - sax.endDocumentendDocumentendDocument = &end_documentend_document; - - sax.startElementNs = &start_rootstart_root; - sax.endElementNs = &end_element_nsend_element_ns; - - sax.characters = &characters_firstcharacters_first; - sax.ignorableWhitespace = &characters_firstcharacters_first; - - sax.commentcommentcomment = &commentcomment; - sax.cdataBlockcdataBlockcdataBlock = &cdata_blockcdata_block; - sax.processingInstructionprocessingInstructionprocessingInstruction = &processing_instructionprocessing_instruction; - - return sax; -} - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" - -/** - * libxml2_namespaces2srcsax_namespaces - * @param number_namespaces the number of namespaces - * @param libxml2_namespaces - * - * Helper function to convert the libxml2 namespaces to srcsax namespaces - * returning a dynamically allocated struct containing the namespaces. - * - * @returns the converted namespaces as srcsax_namespace. - */ -static inline srcsax_namespace * libxml2_namespaces2srcsax_namespaces(int number_namespaces, const xmlChar ** libxml2_namespaces) { - - struct srcsax_namespace * srcsax_namespaces = (srcsax_namespace *)calloc(number_namespaces, sizeof(srcsax_namespace)); - - for(int pos = 0, index = 0; pos < number_namespaces; ++pos, index += 2) { - - srcsax_namespaces[pos].prefix = (const char *)libxml2_namespaces[index]; - srcsax_namespaces[pos].uri = (const char *)libxml2_namespaces[index + 1]; - - } - - return srcsax_namespaces; -} - -/** - * free_srcsax_namespaces - * @param number_namespaces the number of namespaces (not currently used) - * @param libxml2_namespaces - * - * Helper function to free srcsax_namespace * struct allocated by libxml2_namespaces2srcsax_namespaces. - */ -static inline void free_srcsax_namespaces(int /*number_namespaces*/, srcsax_namespace * namespaces) { - - free((void *)namespaces); - -} - -/** - * libxml2_attributes2srcsax_attributes - * @param number_attributes the number of attributes - * @param libxml2_attributes - * - * Helper function to convert the libxml2 attributes to srcsax attributes - * returning a dynamically allocated struct containing the attributes. - * - * @returns the converted attributes as srcsax_attribute. - */ -static inline srcsax_attribute * libxml2_attributes2srcsax_attributes(int number_attributes, const xmlChar ** libxml2_attributes) { - - struct srcsax_attribute * srcsax_attributes = (srcsax_attribute *)calloc(number_attributes, sizeof(srcsax_attribute)); - - for(int pos = 0, index = 0; pos < number_attributes; ++pos, index += 5) { - - srcsax_attributes[pos].localname = (const char *)libxml2_attributes[index]; - srcsax_attributes[pos].prefix = (const char *)libxml2_attributes[index + 1]; - srcsax_attributes[pos].uri = (const char *)libxml2_attributes[index + 2]; - srcsax_attributes[pos].value = strndup((const char *)libxml2_attributes[index + 3], libxml2_attributes[index + 4] - libxml2_attributes[index + 3]); - - } - - return srcsax_attributes; -} - -/** - * free_srcsax_attributes - * @param number_attributes the number of attributes - * @param libxml2_attributes - * - * Helper function to free srcsax_attribute * struct allocated by libxml2_attributes2srcsax_attributes. - */ -static inline void free_srcsax_attributes(int number_attributes, srcsax_attribute * attributes) { - - for(int pos = 0; pos < number_attributes; ++pos) - free((void *)attributes[pos].value); - - free((void *)attributes); - -} - -/** - * srcml_element_stack_push - * @param context the srcsax_context - * @param srcml_element_stack the stack - * @param prefix the prefix of the element to push - * @param localname the name of the element to push - * - * Push the element on to the stack. - */ - void srcml_element_stack_push(srcsax_context * context, std::vector<const char *> & srcml_element_stack, const char * prefix, const char * localname) { - - size_t prefix_length = prefix ? strlen(prefix) : 0; - size_t name_length = strlen(localname); - size_t srcml_element_length = prefix ? prefix_length + name_length + 1 : name_length; - char * srcml_element_string = (char *)calloc(srcml_element_length + 1, sizeof(char)); - - size_t offset = 0; - if(prefix) { - - strncat(srcml_element_string, prefix, prefix_length); - srcml_element_string[prefix_length] = ':'; - offset = prefix_length + 1; - - } - - strncat(srcml_element_string + offset, localname, name_length); - - srcml_element_stack.push_back(srcml_element_string); - - context->stack_size = srcml_element_stack.size(); - context->srcml_element_stack = &srcml_element_stack.front(); - - } - -/** - * srcml_element_stack_pop - * @param context the srcsax_context - * @param srcml_element_stack the stack - * - * Pop an element off the stack. - */ - void srcml_element_stack_pop(srcsax_context * context, std::vector<const char *> & srcml_element_stack) { - - if(srcml_element_stack.size() == 0) return; - - const char * srcml_element = srcml_element_stack.back(); - - srcml_element_stack.pop_back(); - - free((void *)srcml_element); - - context->stack_size = srcml_element_stack.size(); - if(context->stack_size == 0) - context->srcml_element_stack = 0; - else - context->srcml_element_stack = &srcml_element_stack.front(); - - } - -/** - * start_document - * @param ctx an xmlParserCtxtPtr - * - * SAX handler function for start of document. - * Immediately calls supplied handlers function. - */ -void start_document(void * ctx) { - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); -#endif - - if(ctx == NULL) return; - - xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; - sax2_srcsax_handler * state = (sax2_srcsax_handler *) ctxt->_private; - - state->context->stack_size = 0; - state->context->srcml_element_stack = 0; - - state->context->encoding = "UTF-8"; - if(ctxt->encoding && ctxt->encoding[0]!= '\0') - state->context->encoding = (const char *)ctxt->encoding; - else if(ctxt->input) - state->context->encoding = (const char *)ctxt->input->encoding; - - if(state->context->terminate) return; - - if(state->context->handler->start_documentstart_documentstart_document) - state->context->handler->start_document(state->context); - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); -#endif - -} - -/** - * end_document - * @param ctx an xmlParserCtxtPtr - * - * SAX handler function for end of document. - * Calls end_root if needed then - * immediately calls supplied handlers function. - */ -void end_document(void * ctx) { - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); -#endif - - if(ctx == NULL) return; - - xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; - sax2_srcsax_handler * state = (sax2_srcsax_handler *) ctxt->_private; - - state->context->stack_size = 0; - state->context->srcml_element_stack = 0; - - if(state->context->terminate) return; - - if(state->mode != END_ROOT && state->mode != START && state->context->handler->end_rootend_rootend_root) - state->context->handler->end_root(state->context, (const char *)state->root.localname, (const char *)state->root.prefix, (const char *)state->root.URI); - - if(state->context->terminate) return; - - if(state->context->handler->end_documentend_documentend_document) - state->context->handler->end_document(state->context); - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); -#endif - -} - -/** - * start_root - * @param ctx an xmlParserCtxtPtr - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param nb_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param nb_defaulted the number of defaulted attributes - * @param attributes list of attribute name value pairs (localname/prefix/URI/value/end) - * - * SAX handler function for start of root element. - * Caches root info and immediately calls supplied handlers function. - */ -void start_root(void * ctx, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI, - int nb_namespaces, const xmlChar ** namespaces, int nb_attributes, int nb_defaulted, - const xmlChar ** attributes) { - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d '%s'\n", __FILE__, __FUNCTION__, __LINE__, (const char *)localname); -#endif - - if(ctx == NULL) return; - - xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; - sax2_srcsax_handler * state = (sax2_srcsax_handler *) ctxt->_private; - - srcml_element_stack_push(state->context, state->srcml_element_stack, (const char *)prefix, (const char *)localname); - - state->root = srcml_element(state->context, localname, prefix, URI, nb_namespaces, namespaces, nb_attributes, nb_defaulted, attributes); - - state->mode = ROOT; - - // handle nested units - ctxt->sax->startElementNs = &start_element_ns_firststart_element_ns_first; - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d '%s'\n", __FILE__, __FUNCTION__, __LINE__, (const char *)localname); -#endif - -} - -/** - * start_element_ns_first - * @param ctx an xmlParserCtxtPtr - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param nb_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param nb_defaulted the number of defaulted attributes - * @param attributes list of attribute name value pairs (localname/prefix/URI/value/end) - * - * SAX handler function for start of first element after root - * Detects archive and acts accordingly. - */ -void start_element_ns_first(void * ctx, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI, - int nb_namespaces, const xmlChar ** namespaces, int nb_attributes, int nb_defaulted, - const xmlChar ** attributes) { - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d '%s'\n", __FILE__, __FUNCTION__, __LINE__, (const char *)localname); -#endif - - if(ctx == NULL) return; - - xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; - sax2_srcsax_handler * state = (sax2_srcsax_handler *) ctxt->_private; - - int ns_length = state->root.nb_namespaces * 2; - for (int i = 0; i < ns_length; i += 2) - if(prefix && state->root.namespaces[i] && strcmp((const char *)state->root.namespaces[i], (const char *)prefix) == 0) - prefix = state->root.namespaces[i]; - - for (int i = 1; i < ns_length; i += 2) - if(URI && state->root.namespaces[i] && strcmp((const char *)state->root.namespaces[i], (const char *)URI) == 0) - URI = state->root.namespaces[i]; - - if(strcmp((const char *)localname, "macro-list") == 0) { - - if(state->context->handler->meta_tag) - state->meta_tags.push_back(srcml_element(state->context, localname, prefix, URI, nb_namespaces, namespaces, nb_attributes, nb_defaulted, attributes)); - - return; - - } - - srcsax_namespace * srcsax_namespaces = (srcsax_namespace *)libxml2_namespaces2srcsax_namespaceslibxml2_namespaces2srcsax_namespaces(nb_namespaceslibxml2_namespaces2srcsax_namespaces, namespaceslibxml2_namespaces2srcsax_namespaces); - srcsax_attribute * srcsax_attributes = (srcsax_attribute *)libxml2_attributes2srcsax_attributeslibxml2_attributes2srcsax_attributes(nb_attributeslibxml2_attributes2srcsax_attributes, attributeslibxml2_attributes2srcsax_attributes); - - state->is_archive = strcmp((const char *)localname, "unit") == 0; - state->context->is_archive = state->is_archive; - - if(state->context->terminate) return; - - if(state->context->handler->start_rootstart_rootstart_root) { - - srcsax_namespace * srcsax_namespaces_root = (srcsax_namespace *)libxml2_namespaces2srcsax_namespaces(state->root.nb_namespaces, state->root.namespaces); - srcsax_attribute * srcsax_attributes_root = (srcsax_attribute *)libxml2_attributes2srcsax_attributes(state->root.nb_attributes, state->root.attributes); - state->context->handler->start_root(state->context, (const char *)state->root.localname, (const char *)state->root.prefix, (const char *)state->root.URI, - state->root.nb_namespaces, srcsax_namespaces_root, state->root.nb_attributes, - srcsax_attributes_root); - - free_srcsax_namespaces(state->root.nb_namespaces, srcsax_namespaces_root); - free_srcsax_attributes(state->root.nb_attributes, srcsax_attributes_root); - - } - - if(state->context->terminate) return; - - if(state->context->handler->meta_tagmeta_tagmeta_tag && !state->meta_tags.empty()) { - - for(std::vector<srcml_element>::const_iterator citr = state->meta_tags.begin(); citr < state->meta_tags.end(); ++citr) { - - if(state->context->terminate) return; - - srcml_element_stack_push(state->context, state->srcml_element_stack, (const char *)citr->prefix, (const char *)citr->localname); - - srcsax_namespace * srcsax_namespaces_meta_tag = (srcsax_namespace *)libxml2_namespaces2srcsax_namespaces(citr->nb_namespaces, citr->namespaces); - srcsax_attribute * srcsax_attributes_meta_tag = (srcsax_attribute *)libxml2_attributes2srcsax_attributes(citr->nb_attributes, citr->attributes); - - state->context->handler->meta_tag(state->context, (const char *)citr->localname, (const char *)citr->prefix, (const char *)citr->URI, - citr->nb_namespaces, srcsax_namespaces_meta_tag, citr->nb_attributes, - srcsax_attributes_meta_tag); - - free_srcsax_namespaces(citr->nb_namespaces, srcsax_namespaces_meta_tag); - free_srcsax_attributes(citr->nb_attributes, srcsax_attributes_meta_tag); - - srcml_element_stack_pop(state->context, state->srcml_element_stack); - - } - - } - - if(state->context->terminate) return; - - if(!state->is_archive) { - - ++state->context->unit_count; - - if(state->context->terminate) return; - - state->mode = UNIT; - - if(state->context->handler->start_unit) { - - srcsax_namespace * srcsax_namespaces_root = (srcsax_namespace *)libxml2_namespaces2srcsax_namespaces(state->root.nb_namespaces, state->root.namespaces); - srcsax_attribute * srcsax_attributes_root = (srcsax_attribute *)libxml2_attributes2srcsax_attributes(state->root.nb_attributes, state->root.attributes); - state->context->handler->start_unit(state->context, (const char *)state->root.localname, (const char *)state->root.prefix, (const char *)state->root.URI, - state->root.nb_namespaces, srcsax_namespaces_root, state->root.nb_attributes, - srcsax_attributes_root); - - free_srcsax_namespaces(state->root.nb_namespaces, srcsax_namespaces_root); - free_srcsax_attributes(state->root.nb_attributes, srcsax_attributes_root); - - } - - if(state->context->terminate) return; - - if(state->characters.size() != 0 && state->context->handler->characters_unit) - state->context->handler->characters_unit(state->context, state->characters.c_str(), (int)state->characters.size()); - - if(state->context->terminate) return; - - srcml_element_stack_push(state->context, state->srcml_element_stack, (const char *)prefix, (const char *)localname); - - if(state->context->handler->start_element) - state->context->handler->start_element(state->context, (const char *)localname, (const char *)prefix, (const char *)URI, - nb_namespaces, srcsax_namespaces, nb_attributes, srcsax_attributes); - } else { - - if(state->context->terminate) return; - - if(state->context->handler->characters_root) - state->context->handler->characters_root(state->context, state->characters.c_str(), (int)state->characters.size()); - - ++state->context->unit_count; - - srcml_element_stack_push(state->context, state->srcml_element_stack, (const char *)prefix, (const char *)localname); - - if(state->context->terminate) return; - - state->mode = UNIT; - if(state->context->handler->start_unit) - state->context->handler->start_unit(state->context, (const char *)localname, (const char *)prefix, (const char *)URI, - nb_namespaces, srcsax_namespaces, nb_attributes, srcsax_attributes); - - - } - - if(state->context->terminate) return; - - if(ctxt->sax->startElementNs) ctxt->sax->startElementNs = &start_element_ns; - if(ctxt->sax->characters) { - - ctxt->sax->characters = &characters_unit; - ctxt->sax->ignorableWhitespace = &characters_unit; - - } - - free_srcsax_namespaces(nb_namespaces, srcsax_namespaces); - free_srcsax_attributes(nb_attributes, srcsax_attributes); - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d '%s'\n", __FILE__, __FUNCTION__, __LINE__, (const char *)localname); -#endif - -} - -/** - * start_unit - * @param ctx an xmlParserCtxtPtr - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param nb_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param nb_defaulted the number of defaulted attributes - * @param attributes list of attribute name value pairs (localname/prefix/URI/value/end) - * - * SAX handler function for start of an unit. - * Immediately calls supplied handlers function. - */ -void start_unit(void * ctx, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI, - int nb_namespaces, const xmlChar ** namespaces, int nb_attributes, int nb_defaulted, - const xmlChar ** attributes) { - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d '%s'\n", __FILE__, __FUNCTION__, __LINE__, (const char *)localname); -#endif - - if(ctx == NULL) return; - - xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; - sax2_srcsax_handler * state = (sax2_srcsax_handler *) ctxt->_private; - - if(state->context->terminate) return; - - srcsax_namespace * srcsax_namespaces = (srcsax_namespace *)libxml2_namespaces2srcsax_namespaceslibxml2_namespaces2srcsax_namespaces(nb_namespaceslibxml2_namespaces2srcsax_namespaces, namespaceslibxml2_namespaces2srcsax_namespaces); - srcsax_attribute * srcsax_attributes = (srcsax_attribute *)libxml2_attributes2srcsax_attributeslibxml2_attributes2srcsax_attributes(nb_attributeslibxml2_attributes2srcsax_attributes, attributeslibxml2_attributes2srcsax_attributes); - - srcml_element_stack_push(state->context, state->srcml_element_stack, (const char *)prefix, (const char *)localname); - - int ns_length = state->root.nb_namespaces * 2; - for (int i = 0; i < ns_length; i += 2) - if(prefix && state->root.namespaces[i] && strcmp((const char *)state->root.namespaces[i], (const char *)prefix) == 0) - prefix = state->root.namespaces[i]; - - for (int i = 1; i < ns_length; i += 2) - if(URI && state->root.namespaces[i] && strcmp((const char *)state->root.namespaces[i], (const char *)URI) == 0) - URI = state->root.namespaces[i]; - - ++state->context->unit_count; - - state->mode = UNIT; - - - - if(state->context->handler->start_unitstart_unitstart_unit) - state->context->handler->start_unit(state->context, (const char *)localname, (const char *)prefix, (const char *)URI, - nb_namespaces, srcsax_namespaces, nb_attributes, srcsax_attributes); - - if(ctxt->sax->startElementNs) ctxt->sax->startElementNs = &start_element_ns; - if(ctxt->sax->characters) { - - ctxt->sax->characters = &characters_unit; - ctxt->sax->ignorableWhitespace = &characters_unit; - - } - - free_srcsax_namespaces(nb_namespaces, srcsax_namespaces); - free_srcsax_attributes(nb_attributes, srcsax_attributes); - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d '%s'\n", __FILE__, __FUNCTION__, __LINE__, (const char *)localname); -#endif - -} - -/** - * start_element_ns - * @param ctx an xmlParserCtxtPtr - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param nb_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param nb_defaulted the number of defaulted attributes - * @param attributes list of attribute name value pairs (localname/prefix/URI/value/end) - * - * SAX handler function for start of an element. - * Immediately calls supplied handlers function. - */ -void start_element_ns(void * ctx, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI, - int nb_namespaces, const xmlChar ** namespaces, int nb_attributes, int nb_defaulted, - const xmlChar ** attributes) { - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d '%s'\n", __FILE__, __FUNCTION__, __LINE__, (const char *)localname); -#endif - - if(ctx == NULL) return; - - xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; - sax2_srcsax_handler * state = (sax2_srcsax_handler *) ctxt->_private; - - if(state->context->terminate) return; - - srcsax_namespace * srcsax_namespaces = (srcsax_namespace *)libxml2_namespaces2srcsax_namespaceslibxml2_namespaces2srcsax_namespaces(nb_namespaceslibxml2_namespaces2srcsax_namespaces, namespaceslibxml2_namespaces2srcsax_namespaces); - srcsax_attribute * srcsax_attributes = (srcsax_attribute *)libxml2_attributes2srcsax_attributeslibxml2_attributes2srcsax_attributes(nb_attributeslibxml2_attributes2srcsax_attributes, attributeslibxml2_attributes2srcsax_attributes); - - srcml_element_stack_push(state->context, state->srcml_element_stack, (const char *)prefix, (const char *)localname); - - int ns_length = state->root.nb_namespaces * 2; - for (int i = 0; i < ns_length; i += 2) - if(prefix && state->root.namespaces[i] && strcmp((const char *)state->root.namespaces[i], (const char *)prefix) == 0) - prefix = state->root.namespaces[i]; - - for (int i = 1; i < ns_length; i += 2) - if(URI && state->root.namespaces[i] && strcmp((const char *)state->root.namespaces[i], (const char *)URI) == 0) - URI = state->root.namespaces[i]; - - if(state->parse_function && (strcmp((const char *)localname, "function_decl") == 0 || strcmp((const char *)localname, "function") == 0)) { - - state->in_function_header = true; - state->current_function = function_prototype(strcmp((const char *)localname, "function_decl") == 0); - - } else if(!state->in_function_header) { - - if(state->context->handler->start_element) - state->context->handler->start_element(state->context, (const char *)localname, (const char *)prefix, (const char *)URI, - nb_namespaces, srcsax_namespaces, nb_attributes, srcsax_attributes); - - } else { - - if(state->current_function.mode == function_prototype::NAME && strcmp((const char *)localname, "parameter_list") == 0) { - - state->current_function.mode = function_prototype::PARAMETER_LIST; - - } else if(state->current_function.mode == function_prototype::PARAMETER_LIST && strcmp((const char *)localname, "param") == 0) { - - state->current_function.parameter_list.push_back(declaration()); - state->current_function.mode = function_prototype::PARAMETER; - - } else if(state->current_function.mode == function_prototype::PARAMETER && strcmp((const char *)localname, "init") == 0) { - - state->current_function.parameter_list.back().mode = declaration::INIT; - - state->current_function.mode = function_prototype::PARAMETER_LIST; - - } - - } - - free_srcsax_namespaces(nb_namespaces, srcsax_namespaces); - free_srcsax_attributes(nb_attributes, srcsax_attributes); - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d '%s'\n", __FILE__, __FUNCTION__, __LINE__, (const char *)localname); -#endif - -} - -/** - * end_element_ns - * @param ctx an xmlParserCtxtPtr - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * SAX handler function for end of an element. - * Detects end of unit and calls correct functions - * for either end_root end_unit or end_element_ns. - */ -void end_element_ns(void * ctx, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI) { - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d '%s'\n", __FILE__, __FUNCTION__, __LINE__, (const char *)localname); -#endif - - if(ctx == NULL) return; - - if(strcmp((const char *)localname, "macro-list") == 0) { - - return; - - } - - xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; - sax2_srcsax_handler * state = (sax2_srcsax_handler *) ctxt->_private; - - if(strcmp((const char *)localname, "unit") == 0) { - - if(state->mode == ROOT) { - - state->is_archive = false; - state->context->is_archive = state->is_archive; - - if(state->context->terminate) return; - - srcsax_namespace * srcsax_namespaces_root = (srcsax_namespace *)libxml2_namespaces2srcsax_namespaces(state->root.nb_namespaces, state->root.namespaces); - srcsax_attribute * srcsax_attributes_root = (srcsax_attribute *)libxml2_attributes2srcsax_attributes(state->root.nb_attributes, state->root.attributes); - - if(state->context->handler->start_root) - state->context->handler->start_root(state->context, (const char *)state->root.localname, (const char *)state->root.prefix, (const char *)state->root.URI, - state->root.nb_namespaces, srcsax_namespaces_root, state->root.nb_attributes, - srcsax_attributes_root); - - if(state->context->terminate) return; - - if(state->context->handler->meta_tag && !state->meta_tags.empty()) { - - for(std::vector<srcml_element>::const_iterator citr = state->meta_tags.begin(); citr < state->meta_tags.end(); ++citr) { - - srcml_element_stack_push(state->context, state->srcml_element_stack, (const char *)citr->prefix, (const char *)citr->localname); - - srcsax_namespace * srcsax_namespaces_meta_tag = (srcsax_namespace *)libxml2_namespaces2srcsax_namespaces(citr->nb_namespaces, citr->namespaces); - srcsax_attribute * srcsax_attributes_meta_tag = (srcsax_attribute *)libxml2_attributes2srcsax_attributes(citr->nb_attributes, citr->attributes); - - if(state->context->terminate) { - - free_srcsax_namespaces(state->root.nb_namespaces, srcsax_namespaces_root); - free_srcsax_attributes(state->root.nb_attributes, srcsax_attributes_root); - return; - - } - - state->context->handler->meta_tag(state->context, (const char *)citr->localname, (const char *)citr->prefix, (const char *)citr->URI, - citr->nb_namespaces, srcsax_namespaces_meta_tag, citr->nb_attributes, - srcsax_attributes_meta_tag); - - free_srcsax_namespaces(citr->nb_namespaces, srcsax_namespaces_meta_tag); - free_srcsax_attributes(citr->nb_attributes, srcsax_attributes_meta_tag); - - srcml_element_stack_pop(state->context, state->srcml_element_stack); - - } - - } - - if(state->context->terminate) { - - free_srcsax_namespaces(state->root.nb_namespaces, srcsax_namespaces_root); - free_srcsax_attributes(state->root.nb_attributes, srcsax_attributes_root); - return; - - } - - if(state->context->handler->start_unit) - state->context->handler->start_unit(state->context, (const char *)state->root.localname, (const char *)state->root.prefix, (const char *)state->root.URI, - state->root.nb_namespaces, srcsax_namespaces_root, state->root.nb_attributes, - srcsax_attributes_root); - - free_srcsax_namespaces(state->root.nb_namespaces, srcsax_namespaces_root); - free_srcsax_attributes(state->root.nb_attributes, srcsax_attributes_root); - - if(state->context->terminate) return; - - if(state->characters.size() != 0 && state->context->handler->characters_unit) - state->context->handler->characters_unit(state->context, state->characters.c_str(), (int)state->characters.size()); - - } - - srcml_element_stack_pop(state->context, state->srcml_element_stack); - - if(state->context->terminate) return; - - if(ctxt->sax->startElementNs == &start_unit) { - - state->mode = END_ROOT; - if(state->context->handler->end_root) - state->context->handler->end_root(state->context, (const char *)localname, (const char *)prefix, (const char *)URI); - - } else { - - state->mode = END_UNIT; - if(state->context->handler->end_unit) - state->context->handler->end_unit(state->context, (const char *)localname, (const char *)prefix, (const char *)URI); - if(ctxt->sax->startElementNs) ctxt->sax->startElementNs = &start_unit; - if(ctxt->sax->characters) { - - ctxt->sax->characters = &characters_root; - ctxt->sax->ignorableWhitespace = &characters_root; - - } - } - - if(state->context->terminate) return; - - } else { - - srcml_element_stack_pop(state->context, state->srcml_element_stack); - - if(state->in_function_header && (strcmp((const char *)localname, "function_decl") == 0 || strcmp((const char *)localname, "function") == 0)) { - - //state->context->handler->endFunction(); - - } else if(!state->in_function_header) { - - if(state->context->terminate) return; - - if(state->context->handler->end_element) - state->context->handler->end_element(state->context, (const char *)localname, (const char *)prefix, (const char *)URI); - - if(state->context->terminate) return; - - } else { - - if(state->current_function.mode == function_prototype::RETURN_TYPE && strcmp((const char *)localname, "type") == 0) { - - state->current_function.mode = function_prototype::NAME; - - } else if(state->current_function.mode == function_prototype::PARAMETER && state->current_function.parameter_list.back().mode == declaration::TYPE - && strcmp((const char *)localname, "type") == 0) { - - state->current_function.parameter_list.back().mode = declaration::NAME; - - } else if(state->current_function.mode == function_prototype::PARAMETER - && (strcmp((const char *)localname, "param") == 0 || strcmp((const char *)localname, "decl") == 0)) { - - state->current_function.mode = function_prototype::PARAMETER_LIST; - - } else if(state->current_function.mode == function_prototype::PARAMETER_LIST && strcmp((const char *)localname, "parameter_list") == 0) { - - state->in_function_header = false; - //state->context->handler->startFunction(state->current_function.name, state->current_function.return_type, state->current_function.parameter_list, state->current_function.is_decl); - - } - - } - - } - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d '%s'\n", __FILE__, __FUNCTION__, __LINE__, (const char *)localname); -#endif - -} - -/** - * characters_first - * @param ctx an xmlParserCtxtPtr - * @param ch the characers - * @param len number of characters - * - * SAX handler function for character handling before we - * know if we have an archive or not. - * Immediately calls supplied handlers function. - */ -void characters_first(void * ctx, const xmlChar * ch, int len) { - -#ifdef SRCSAX_DEBUG - std::string chars; - chars.append((const char *)ch, len); - fprintf(stderr, "HERE: %s %s %d '%s'\n", __FILE__, __FUNCTION__, __LINE__, chars.c_str()); -#endif - - if(ctx == NULL) return; - - xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; - sax2_srcsax_handler * state = (sax2_srcsax_handler *) ctxt->_private; - - state->characters.append((const char *)ch, len); - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d '%s'\n", __FILE__, __FUNCTION__, __LINE__, chars.c_str()); -#endif - -} - -/** - * characters_root - * @param ctx an xmlParserCtxtPtr - * @param ch the characers - * @param len number of characters - * - * SAX handler function for character handling at the root level. - * Immediately calls supplied handlers function. - */ -void characters_root(void * ctx, const xmlChar * ch, int len) { - -#ifdef SRCSAX_DEBUG - std::string chars; - chars.append((const char *)ch, len); - fprintf(stderr, "HERE: %s %s %d '%s'\n", __FILE__, __FUNCTION__, __LINE__, chars.c_str()); -#endif - - if(ctx == NULL) return; - - xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; - sax2_srcsax_handler * state = (sax2_srcsax_handler *) ctxt->_private; - - if(state->context->terminate) return; - - if(state->context->handler->characters_rootcharacters_rootcharacters_root) - state->context->handler->characters_root(state->context, (const char *)ch, len); - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d '%s'\n", __FILE__, __FUNCTION__, __LINE__, chars.c_str()); -#endif - -} - -/** - * characters_unit - * @param ctx an xmlParserCtxtPtr - * @param ch the characers - * @param len number of characters - * - * SAX handler function for character handling within a unit. - * Immediately calls supplied handlers function. - */ -void characters_unit(void * ctx, const xmlChar * ch, int len) { - -#ifdef SRCSAX_DEBUG - std::string chars; - chars.append((const char *)ch, len); - fprintf(stderr, "HERE: %s %s %d '%s'\n", __FILE__, __FUNCTION__, __LINE__, chars.c_str()); -#endif - - if(ctx == NULL) return; - - xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; - sax2_srcsax_handler * state = (sax2_srcsax_handler *) ctxt->_private; - - - if(!state->in_function_header) { - - if(state->context->terminate) return; - - if(state->context->handler->characters_unit) - state->context->handler->characters_unit(state->context, (const char *)ch, len); - - } else { - - if(state->current_function.mode == function_prototype::RETURN_TYPE) - state->current_function.return_type.append((const char *)ch, len); - else if(state->current_function.mode == function_prototype::NAME) - state->current_function.name.append((const char *)ch, len); - else if(state->current_function.mode == function_prototype::PARAMETER) { - - if(state->current_function.parameter_list.back().mode == declaration::TYPE) - state->current_function.parameter_list.back().type.append((const char *)ch, len); - else if(state->current_function.parameter_list.back().mode == declaration::NAME) - state->current_function.parameter_list.back().name.append((const char *)ch, len); - - } - - } - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d '%s'\n", __FILE__, __FUNCTION__, __LINE__, chars.c_str()); -#endif - -} - -/** - * comment - * @param ctx an xmlParserCtxtPtr - * @param value the comment content - * - * A comment has been parsed. - * Immediately calls supplied handlers function. - */ -void comment(void * ctx, const xmlChar * value) { - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); -#endif - - if(ctx == NULL) return; - - xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; - sax2_srcsax_handler * state = (sax2_srcsax_handler *) ctxt->_private; - - if(state->context->terminate) return; - - if(state->context->handler->commentcommentcomment) - state->context->handler->comment(state->context, (const char *)value); - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); -#endif - -} - -/** - * cdata_block - * @param ctx an xmlParserCtxtPtr - * @param value the pcdata content - * @param len the block length - * - * Called when a pcdata block has been parsed. - * Immediately calls supplied handlers function. - */ -void cdata_block(void * ctx, const xmlChar * value, int len) { - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); -#endif - - if(ctx == NULL) return; - - xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; - sax2_srcsax_handler * state = (sax2_srcsax_handler *) ctxt->_private; - - if(state->context->terminate) return; - - if(state->context->handler->cdata_blockcdata_blockcdata_block) - state->context->handler->cdata_block(state->context, (const char *)value, len); - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); -#endif - -} - -/** - * processing_instruction - * @param ctx an xmlParserCtxtPtr - * @param target the processing instruction target. - * @param data the processing instruction data. - * - * Called when a processing instruction has been parsed. - * Immediately calls supplied handlers function. - */ -void processing_instruction(void * ctx, const xmlChar * target, const xmlChar * data) { - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); -#endif - - if(ctx == NULL) return; - - xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; - sax2_srcsax_handler * state = (sax2_srcsax_handler *) ctxt->_private; - - if(state->context->terminate) return; - - if(state->context->handler->processing_instructionprocessing_instructionprocessing_instruction) - state->context->handler->processing_instruction(state->context, (const char *)target, (const char *)data); - -#ifdef SRCSAX_DEBUG - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); -#endif - -} - -#pragma GCC diagnostic pop - - -/** - * @file srcsax.h - * - * @copyright Copyright (C) 2013-2014 srcML, LLC. (www.srcML.org) - * - * srcSAX is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * srcSAX is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef INCLUDED_SRCSAX_H -#define INCLUDED_SRCSAX_H - -#include <srcsax_handler.h> - -#include <libxml/parser.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * srcsax_context - * - * Context data structure passed between callbacks. - */ -struct srcsax_context { - - /** user provided data */ - void * data; - - /** srcSAX handler callbacks */ - struct srcsax_handler * handler; - - /** error callback need to figure this one out probably message and errorcode. or struct. Might not need, but might be nice to avoid libxml2 stuff */ - void (*srcsax_error)(const char * message, int error_code); - - /** is the document an archive */ - int is_archive; - - /** the current unit count */ - int unit_count; - - /** size of the srcml_element stack */ - size_t stack_size; - - /** stack of open srcML elements */ - const char ** srcml_element_stack; - - /** the xml documents encoding */ - const char * encoding; - - /* Internal context handling NOT FOR PUBLIC USE */ - - /** xml parser input buffer */ - xmlParserInputBufferPtr input; - - /** boolean to indicate need to free input buffer */ - int free_input; - - /** internally used libxml2 context */ - xmlParserCtxtPtr libxml2_context; - - /** indicate stop parser */ - int terminate; - -}; - -/* srcSAX context creation/open functions */ -struct srcsax_context * srcsax_create_context_filenamesrcsax_create_context_filename(const char * filename, const char * encoding); -struct srcsax_context * srcsax_create_context_memorysrcsax_create_context_memory(const char * buffer, size_t buffer_size, const char * encoding); -struct srcsax_context * srcsax_create_context_FILEsrcsax_create_context_FILE(FILE * srcml_file, const char * encoding); -struct srcsax_context * srcsax_create_context_fdsrcsax_create_context_fd(int srcml_fd, const char * encoding); -struct srcsax_context * srcsax_create_context_io(void * srcml_context, int (*read_callback)(void * context, char * buffer, int len), int (*close_callback)(void * context), const char * encoding); -struct srcsax_context * srcsax_create_context_parser_input_buffersrcsax_create_context_parser_input_buffer(xmlParserInputBufferPtr input); - -/* srcSAX free function */ -void srcsax_free_contextsrcsax_free_context(struct srcsax_context * context); - -/* srcSAX parse function */ -int srcsax_parse(struct srcsax_context * context); -int srcsax_parse_handlersrcsax_parse_handler(struct srcsax_context * context, struct srcsax_handler * handler); - -/* srcSAX terminate parse function */ -void srcsax_stop_parsersrcsax_stop_parser(struct srcsax_context * context); - -#ifdef __cplusplus -} -#endif - -#endif - - -/** - * @file srcsax_handler.h - * - * @copyright Copyright (C) 2013-2014 srcML, LLC. (www.srcML.org) - * - * srcSAX is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * srcSAX is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef INCLUDED_SRCSAX_HANDLER_H -#define INCLUDED_SRCSAX_HANDLER_H - -#include <libxml/parser.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct srcsax_context; - -/** - * srcsax_namespace - * - * Data structure for a srcML/xml namespace - */ -struct srcsax_namespace { - - /** a namespace prefix */ - const char * prefix; - - /** a namespace uri */ - const char * uri; - -}; - -/** - * srcsax_attribute - * - * Data structure for a srcML/xml attribute - */ - struct srcsax_attribute { - - /** attribute name */ - const char * localname; - - /** attribute namespace prefix */ - const char * prefix; - - /** attribute namespace uri */ - const char * uri; - - /** attribute value */ - const char * value; - -}; - -/** - * srcsax_handler - * - * Struct of srcSAX callback functions i.e. srcSAX handler. - */ -struct srcsax_handler { - -/** - * start_document - * @param context a srcSAX context - * - * Signature for srcSAX handler function for start of document. - */ -void (*start_document)(struct srcsax_context * context); - -/** - * end_document - * @param context a srcSAX context - * - * Signature for srcSAX handler function for end of document. - */ -void (*end_document)(struct srcsax_context * context); - -/** - * start_root - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * Signature for srcSAX handler function for start of the root element. - */ -void (*start_root)(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes); - -/** - * start_unit - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * Signature srcSAX handler function for start of an unit. - */ -void (*start_unit)(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes); - -/** - * start_function - * @param context a srcSAX context - * @param name the function's name - * @param return_type the function return type - * @param parameter_list a list of the function parameters in struct containing (declaration.type/declaration.name) - * @param is_decl indicates if the call is a function declaration (true) or definition (false) - * - * Signature for srcSAX handler function for start of function with prototype. - */ -//void (*start_function(struct srcsax_context * context, const char * name, const char * return_type, const struct declaration * parameter_list, _Bool is_decl); - -/** - * start_element - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * Signature for srcSAX handler function for start of an element. - */ -void (*start_element)(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes); - -/** - * end_root - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * Signature for srcSAX handler function for end of the root element. - */ -void (*end_root)(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI); - -/** - * end_unit - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * Signature for srcSAX handler function for end of an unit. - */ -void (*end_unit)(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI); - -/** - * end_function - * @param context a srcSAX context - * - * Signature for srcSAX handler function for end of a function. - */ -//void (*end_function(struct srcsax_context * context); - -/** - * end_element - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * Signature for srcSAX handler function for end of an element. - */ -void (*end_element)(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI); - -/** - * characters_root - * @param context a srcSAX context - * @param ch the characers - * @param len number of characters - * - * Signature for srcSAX handler function for character handling at the root level. - */ -void (*characters_root)(struct srcsax_context * context, const char * ch, int len); - -/** - * characters_unit - * @param ch the characers - * @param len number of characters - * - * Signature for srcSAX handler function for character handling within a unit. - */ -void (*characters_unit)(struct srcsax_context * context, const char * ch, int len); - -/** - * meta_tag - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * Signature for srcSAX handler function for meta tags. - */ -void (*meta_tag)(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes); - -/** - * comment - * @param context a srcSAX context - * @param value the comment content - * - * Signature for srcSAX handler function for a XML comment. - */ -void (*comment)(struct srcsax_context * context, const char * value); - -/** - * cdata_block - * @param context a srcSAX context - * @param value the pcdata content - * @param len the block length - * - * Signature for srcSAX handler function for pcdata block. - */ -void (*cdata_block)(struct srcsax_context * context, const char * value, int len); - -/** - * processing_instruction - * @param context a srcSAX context - * @param target the processing instruction target. - * @param data the processing instruction data. - * - * Signature for srcSAX handler function for processing instruction. - */ -void (*processing_instruction)(struct srcsax_context * context, const char * target, const char * data); - -}; - -#ifdef __cplusplus -} -#endif - -#endif - - -/** - * @file test_srcsax_test_handler.cpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <srcsax_handler_test.hpp> -#include <sax2_srcsax_handler.hpp> - -#include <stdio.h> -#include <string.h> -#include <cassert> - -/** default initialization used throughout for testing */ -sax2_srcsax_handler sax2_handler_init; - -/** default initialization used throughout for testing */ -xmlParserCtxt ctxt_init; - -/** - * main - * - * Test the sax2_srcsax_handler/srcsax_test_handler. - * - * @returns 0 on success. - */ - int main() { - - /* - start_document - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - start_document(&ctxt); - assert(test_handler.start_document_call_number == 1); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.start_document = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - start_document(&ctxt); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - /* - end_document - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - end_document(&ctxt); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 1); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.mode = END_UNIT; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - end_document(&ctxt); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 2); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 1); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.end_document = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - end_document(&ctxt); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.end_root = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.mode = END_UNIT; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - end_document(&ctxt); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 1); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.end_document = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.mode = END_UNIT; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - end_document(&ctxt); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 1); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - /* - start_root - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - end_document(&ctxt); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.start_document = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - start_document(&ctxt); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - /* - start_element_ns_first - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - start_element_ns_first(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 1); - assert(test_handler.start_unit_call_number == 3); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 2); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - end_document(&ctxt); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - start_element_ns_first(&ctxt, (const xmlChar *)"name", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 1); - assert(test_handler.start_unit_call_number == 2); - assert(test_handler.start_element_call_number == 4); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 3); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - end_document(&ctxt); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.start_root = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - start_element_ns_first(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 2); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 1); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - end_document(&ctxt); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.start_unit = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - start_element_ns_first(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 1); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 2); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - end_document(&ctxt); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.characters_root = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - start_element_ns_first(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 1); - assert(test_handler.start_unit_call_number == 2); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - end_document(&ctxt); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.start_root = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - start_element_ns_first(&ctxt, (const xmlChar *)"name", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 1); - assert(test_handler.start_element_call_number == 3); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 2); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - end_document(&ctxt); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.start_unit = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - start_element_ns_first(&ctxt, (const xmlChar *)"name", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 1); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 3); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 2); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - end_document(&ctxt); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.characters_unit = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - start_element_ns_first(&ctxt, (const xmlChar *)"name", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 1); - assert(test_handler.start_unit_call_number == 2); - assert(test_handler.start_element_call_number == 3); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - end_document(&ctxt); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.start_element = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - start_element_ns_first(&ctxt, (const xmlChar *)"name", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 1); - assert(test_handler.start_unit_call_number == 2); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 3); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - end_document(&ctxt); - - } - - /* - start_unit - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - - start_unit(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 1); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - end_document(&ctxt); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.start_unit = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - - start_unit(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - end_document(&ctxt); - - } - - /* - start_element_ns - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - - start_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 1); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.start_element = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char * namespaces[4] = { 0, "http://www.sdml.info/srcML/src", "cpp", "http://www.sdml.info/srcML/cpp" }; - const char * values = "abc"; - const char * attributes[15] = { "filename", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "dir", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2, - "language", 0, "http://www.sdml.info/srcML/src", values + 2, values + 3 }; - - start_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 2, (const xmlChar **)namespaces, 3, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - /* - end_element_ns - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - sax.startElementNs = &start_unit; - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 1); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 1); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - end_element_ns(&ctxt, (const xmlChar *)"name", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 1); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.end_root = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - sax.startElementNs = &start_unit; - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.end_unit = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - end_element_ns(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.end_element = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - end_element_ns(&ctxt, (const xmlChar *)"name", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src"); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - /* - characters_root - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - characters_root(&ctxt, (const xmlChar *)"unit", 4); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 1); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.characters_root = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - characters_root(&ctxt, (const xmlChar *)"unit", 4); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - /* - characters_unit - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - characters_unit(&ctxt, (const xmlChar *)"unit", 4); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 1); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.characters_unit = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - characters_unit(&ctxt, (const xmlChar *)"unit", 4); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - /* - meta_tag - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - sax.startElementNs = start_element_ns_first; - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char ** namespaces = 0; - const char * values = "ab"; - const char * attributes[10] = { "token", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "type", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2 }; - - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 0, (const xmlChar **)namespaces, 2, 0, - (const xmlChar **) attributes); - start_element_ns_first(&ctxt, (const xmlChar *)"macro-list", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 0, (const xmlChar **)namespaces, 2, 0, - (const xmlChar **) attributes); - start_element_ns_first(&ctxt, (const xmlChar *)"expr_stmt", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 0, (const xmlChar **)namespaces, 2, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 1); - assert(test_handler.start_unit_call_number == 3); - assert(test_handler.start_element_call_number == 5); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 4); - assert(test_handler.meta_tag_call_number == 2); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - end_document(&ctxt); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - sax.startElementNs = start_element_ns_first; - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char ** namespaces = 0; - const char * values = "ab"; - const char * attributes[10] = { "token", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "type", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2 }; - - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 0, (const xmlChar **)namespaces, 2, 0, - (const xmlChar **) attributes); - start_element_ns_first(&ctxt, (const xmlChar *)"macro-list", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 0, (const xmlChar **)namespaces, 2, 0, - (const xmlChar **) attributes); - start_element_ns_first(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 0, (const xmlChar **)namespaces, 2, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 1); - assert(test_handler.start_unit_call_number == 4); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 3); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 2); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - end_document(&ctxt); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.meta_tag = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - sax.startElementNs = start_element_ns_first; - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - const char ** namespaces = 0; - const char * values = "ab"; - const char * attributes[10] = { "token", 0, "http://www.sdml.info/srcML/src", values, values + 1, - "type", 0, "http://www.sdml.info/srcML/src", values + 1, values + 2 }; - - start_root(&ctxt, (const xmlChar *)"unit", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 0, (const xmlChar **)namespaces, 2, 0, - (const xmlChar **) attributes); - start_element_ns_first(&ctxt, (const xmlChar *)"macro-list", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 0, (const xmlChar **)namespaces, 2, 0, - (const xmlChar **) attributes); - start_element_ns_first(&ctxt, (const xmlChar *)"expr_stmt", (const xmlChar *)0, - (const xmlChar *)"http://www.sdml.info/srcML/src", 0, (const xmlChar **)namespaces, 2, 0, - (const xmlChar **) attributes); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 1); - assert(test_handler.start_unit_call_number == 2); - assert(test_handler.start_element_call_number == 4); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 3); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - end_document(&ctxt); - - } - - /* - comment - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - comment(&ctxt, (const xmlChar *)"unit"); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 1); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.comment = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - comment(&ctxt, (const xmlChar *)"unit"); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - /* - cdata_block - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - cdata_block(&ctxt, (const xmlChar *)"unit", 4); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 1); - assert(test_handler.processing_instruction_call_number == 0); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.cdata_block = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - cdata_block(&ctxt, (const xmlChar *)"unit", 4); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - /* - processing_instruction - */ - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - processing_instruction(&ctxt, (const xmlChar *)"target", (const xmlChar *)"data"); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 1); - - } - - { - - srcsax_handler_test test_handler; - srcsax_handler srcsax_sax = srcsax_handler_test::factory(); - srcsax_sax.processing_instruction = 0; - - srcsax_context context; - context.data = &test_handler; - context.handler = &srcsax_sax; - - sax2_srcsax_handler sax2_handler = sax2_handler_init; - sax2_handler.context = &context; - - xmlParserCtxt ctxt = ctxt_init; - xmlSAXHandler sax = srcsax_sax2_factory(); - ctxt.sax = &sax; - ctxt._private = &sax2_handler; - processing_instruction(&ctxt, (const xmlChar *)"target", (const xmlChar *)"data"); - assert(test_handler.start_document_call_number == 0); - assert(test_handler.end_document_call_number == 0); - assert(test_handler.start_root_call_number == 0); - assert(test_handler.start_unit_call_number == 0); - assert(test_handler.start_element_call_number == 0); - assert(test_handler.end_root_call_number == 0); - assert(test_handler.end_unit_call_number == 0); - assert(test_handler.end_element_call_number == 0); - assert(test_handler.characters_root_call_number == 0); - assert(test_handler.characters_unit_call_number == 0); - assert(test_handler.meta_tag_call_number == 0); - assert(test_handler.comment_call_number == 0); - assert(test_handler.cdata_block_call_number == 0); - assert(test_handler.processing_instruction_call_number == 0); - - } - - return 0; - -} - - -/** - * @file srcsax_controller.cpp - * - * @copyright Copyright (C) 2013-2014 srcML, LLC. (www.srcML.org) - * - * srcSAX is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * srcSAX is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include <srcsax.h> -#include <sax2_srcsax_handler.hpp> - -#include <libxml/parserInternals.h> - -#include <cstring> - -/** - * libxml_error - * - * Silence/catch/default libxml2 errors. - */ -static void libxml_error(void * /*ctx*/, const char * /*msg*/, ... ) {} - -/* srcsax_create_parser_context forward declaration */ -static xmlParserCtxtPtr srcsax_create_parser_context(xmlParserInputBufferPtr buffer_input); - -#ifdef LIBXML2_NEW_BUFFER -struct _xmlBuf { - xmlChar * content; /* The buffer content UTF8 */ - unsigned int compat_use; /* for binary compatibility */ - unsigned int compat_size; /* for binary compatibility */ - xmlBufferAllocationScheme alloc; /* The realloc method */ - xmlChar * contentIO; /* in IO mode we may have a different base */ - size_t use; /* The buffer size used */ - size_t size; /* The buffer size */ - xmlBufferPtr buffer; /* wrapper for an old buffer */ - int error; /* an error code if a failure occured */ -}; - -#define _CHECK_COMPAT(buf ) \ - if (buf->size != (size_t) buf->compat_size) \ - if (buf->compat_size < INT_MAX) \ - buf->size = buf->compat_size; \ - if (buf->use != (size_t) buf->compat_use) \ - if (buf->compat_use < INT_MAX) \ - buf->use = buf->compat_use; - -/** - * xmlBufResetInput - * @param buf XML buffer - * @param input XML parser input - * - * Function is taken from libxml2. - * - * @returns 0 on success and -1 on error. - */ -static int -_xmlBufResetInput(xmlBuf * buf, xmlParserInputPtr input) { - if ((input == NULL) || (buf == NULL) || (buf->error)) - return(-1); - _CHECK_COMPAT(buf) - input->base = input->cur = buf->content; - input->end = &buf->content[buf->use]; - return(0); - -} -#else -/** - * xmlBufResetInput - * @param buf XML buffer - * @param input XML parser input - * - * Function is taken fro libxml2. - * - * @returns 0 on success and -1 on error. - */ -static int -_xmlBufResetInput(xmlBuffer * buf, xmlParserInputPtr input) { - if ((input == NULL) || (buf == NULL)) - return -1; - input->base = input->buf->buffer->content; - input->cur = input->buf->buffer->content; - input->end = &input->buf->buffer->content[input->buf->buffer->use]; - return 0; -} - -#endif - -/** - * srcsax_controller_init - * - * Internal method to initialize the controller module. - */ -static void srcsax_controller_init() { - - static bool initialized = false; - - if(initialized) return; - - xmlGenericErrorFunc error_handler = (xmlGenericErrorFunc) libxml_errorlibxml_error; - initGenericErrorDefaultFunc(&error_handler); - initialized = true; - -} - -/** - * srcsax_create_context_inner - * @param input a libxml2 parser input buffer - * - * A helper function that creates the srcSAX context and does error handling. - * With a supplied xmlParserInputBufferPtr. - * - * @returns srcsax_context context to be used for srcML parsing. - */ -static struct srcsax_context * srcsax_create_context_inner(xmlParserInputBufferPtr input, int free_input) { - - if(input == 0) return 0; - - struct srcsax_context * context = (struct srcsax_context *)malloc(sizeof(struct srcsax_context)); - - if(context == 0) { - - xmlFreeParserInputBuffer(input); - return 0; - - } - - memset(context, 0, sizeof(struct srcsax_context)); - context->input = input; - context->free_input = free_input; - - xmlParserCtxtPtr libxml2_context = srcsax_create_parser_context(context->input); - - if(libxml2_context == NULL) { - - xmlFreeParserInputBuffer(input); - free(context); - return 0; - - } - - /** @todo this does not make sense */ - libxml2_context->_private = context; - - context->libxml2_context = libxml2_context; - - context->terminate = 0; - - return context; - -} - -/** - * srcsax_create_context_filename - * @param filename a filename - * @param encoding the files character encoding - * - * Open the filename with the specified encoding and return a srcSAX context for parsing. - * - * @returns srcsax_context context to be used for srcML parsing. - */ -struct srcsax_context * srcsax_create_context_filename(const char * filename, const char * encoding) { - - if(filename == 0) return 0; - - srcsax_controller_initsrcsax_controller_init(); - - xmlParserInputBufferPtr input = - xmlParserInputBufferCreateFilename(filename, encoding ? xmlParseCharEncoding(encoding) : XML_CHAR_ENCODING_NONE); - - return srcsax_create_context_inner(input, 1); - -} - -/** - * srcsax_create_context_memory - * @param buffer a buffer of memory - * @param buffer_size the size of the buffer/amount of buffer to use - * @param encoding the files character encoding - * - * Create a srcsSAX context from the supplied buffer using the provided amount and encoding. - * - * @returns srcsax_context context to be used for srcML parsing. - */ -struct srcsax_context * srcsax_create_context_memory(const char * buffer, size_t buffer_size, const char * encoding) { - - if(buffer == 0 || buffer_size == 0) return 0; - - srcsax_controller_initsrcsax_controller_init(); - - xmlParserInputBufferPtr input = - xmlParserInputBufferCreateMem(buffer, (int)buffer_size, encoding ? xmlParseCharEncoding(encoding) : XML_CHAR_ENCODING_NONE); - - return srcsax_create_context_inner(input, 1); - -} - -/** - * srcsax_create_context_FILE - * @param srcml_file an opened file containing srcML - * @param encoding the files character encoding - * - * Create a srcsSAX context from the supplied FILE using the provided encoding. - * - * @returns srcsax_context context to be used for srcML parsing. - */ -struct srcsax_context * srcsax_create_context_FILE(FILE * srcml_file, const char * encoding) { - - if(srcml_file == 0) return 0; - - srcsax_controller_initsrcsax_controller_init(); - - xmlParserInputBufferPtr input = - xmlParserInputBufferCreateFile(srcml_file, encoding ? xmlParseCharEncoding(encoding) : XML_CHAR_ENCODING_NONE); - - return srcsax_create_context_inner(input, 1); - -} - -/** - * srcsax_create_context_fd - * @param srcml_fd an opened file descriptor containing srcML - * @param encoding the files character encoding - * - * Create a srcsSAX context from the supplied file descriptor using the provided encoding. - * - * @returns srcsax_context context to be used for srcML parsing. - */ -struct srcsax_context * srcsax_create_context_fd(int srcml_fd, const char * encoding) { - - if(srcml_fd < 0) return 0; - - srcsax_controller_initsrcsax_controller_init(); - - xmlParserInputBufferPtr input = - xmlParserInputBufferCreateFd(srcml_fd, encoding ? xmlParseCharEncoding(encoding) : XML_CHAR_ENCODING_NONE); - - return srcsax_create_context_inner(input, 1); - -} - -/** - * srcsax_create_context_io - * @param srcml_context an opened context for opened srcML document - * @param read_callback a read callback function - * @close_callback a close callback function - * @param encoding the files character encoding - * - * Create a srcsSAX context from a general context and read/close callbacks with the specified encoding. - * - * @returns srcsax_context context to be used for srcML parsing. - */ -struct srcsax_context * srcsax_create_context_io(void * srcml_context, int (*read_callback)(void * context, char * buffer, int len), int (*close_callback)(void * context), const char * encoding) { - - if(srcml_context == 0 || read_callbackread_callback == 0) return 0; - - srcsax_controller_initsrcsax_controller_init(); - - xmlParserInputBufferPtr input = - xmlParserInputBufferCreateIO(read_callback, close_callback, srcml_context, encoding ? xmlParseCharEncoding(encoding) : XML_CHAR_ENCODING_NONE); - - return srcsax_create_context_inner(input, 1); - -} - -/** - * srcsax_create_context_parser_input_buffer - * @param srcml_context an opened context for opened srcML document - * @param read_callback a read callback function - * @close_callback a close callback function - * @param encoding the files character encoding - * - * Create a srcsSAX context from a general context and read/close callbacks with the specified encoding. - * - * @returns srcsax_context context to be used for srcML parsing. - */ -struct srcsax_context * srcsax_create_context_parser_input_buffer(xmlParserInputBufferPtr input) { - - if(input == 0) return 0; - - srcsax_controller_initsrcsax_controller_init(); - - return srcsax_create_context_inner(input, 0); - -} - -/** - * srcsax_free_context - * @param context a srcSAX context - * - * Free the resources associated with a srcsax_context as created - * by a previous srcsax_create_context_*. - */ -void srcsax_free_context(struct srcsax_context * context) { - - if(context == 0) return; - - xmlParserInputPtr stream = inputPop(context->libxml2_context); - stream->buf = 0; - xmlFreeInputStream(stream); - if(context->libxml2_context) xmlFreeParserCtxt(context->libxml2_context); - if(context->free_input) xmlFreeParserInputBuffer(context->input); - - free(context); - -} - -/** - * srcsax_parse - * @param context srcSAX context - * - * Parse the context using the provide sax handlers. - * On error calls the error callback function before returning. - * - * @returns 0 on success -1 on error. - */ -int srcsax_parse(struct srcsax_context * context) { - - if(context == 0 || context->handler == 0) return -1; - - xmlSAXHandlerPtr save_sax = context->libxml2_context->sax; - xmlSAXHandler sax = srcsax_sax2_factory(); - context->libxml2_context->sax = &sax; - - sax2_srcsax_handler state; - state.context = context; - context->libxml2_context->_private = &state; - - int status = 0; - try { - - status = xmlParseDocument(context->libxml2_context); - - } catch(... ) { - - return -1; - - } - - context->libxml2_context->sax = save_sax; - - if(status != 0) { - - xmlErrorPtr ep = xmlCtxtGetLastError(context->libxml2_context); - - size_t str_length = strlen(ep->message); - ep->message[str_length - 1] = '\0'; - - if(context->srcsax_error) - context->srcsax_error((const char *)ep->message, ep->code); - - } - - return status; - -} - -/** - * srcsax_parse - * @param context srcSAX context - * @param handler sax callback handlers - * - * Parse the context using the provide sax handlers. - * On error calls the error callback function before returning. - * - * @returns 0 on success -1 on error. - */ -int srcsax_parse_handler(struct srcsax_context * context, struct srcsax_handler * handler) { - - if(context == 0) return -1; - - context->handler = handler; - - return srcsax_parse(context); - -} - -/** - * srcsax_create_parser_context - * @param buffer_input a parser input buffer - * - * Create a ctxt from a parser input buffer. - * Modeled after function in libxml2. - * - * @returns xml parser ctxt - */ -xmlParserCtxtPtr -srcsax_create_parser_context(xmlParserInputBufferPtr buffer_input) { - xmlParserCtxtPtr ctxt; - xmlParserInputPtr input; - xmlParserInputBufferPtr buf; - - ctxt = xmlNewParserCtxt(); - if (ctxt == NULL) - return(NULL); - - xmlCtxtUseOptions(ctxt, XML_PARSE_COMPACT | XML_PARSE_HUGE | XML_PARSE_NODICT); - - buf = buffer_input; - if (buf == NULL) { - xmlFreeParserCtxt(ctxt); - return(NULL); - } - - input = xmlNewInputStream(ctxt); - if (input == NULL) { - xmlFreeParserCtxt(ctxt); - return(NULL); - } - - input->filename = NULL; - input->buf = buf; - _xmlBufResetInput(input->buf->buffer, input); - - inputPush(ctxt, input); - - return(ctxt); -} - -/** - * srcsax_stop_parser - * @param context a srcSAX context - * - * Stop srcSAX parser. - */ -void srcsax_stop_parser(struct srcsax_context * context) { - - context->terminate = 1; - - xmlParserCtxtPtr ctxt = context->libxml2_context; - - ctxt->sax->startDocumentstartDocumentstartDocument = 0; - ctxt->sax->endDocumentendDocumentendDocument = 0; - ctxt->sax->startElementNs = 0; - ctxt->sax->endElementNs = 0; - ctxt->sax->characters = 0; - ctxt->sax->cdataBlockcdataBlockcdataBlock = 0; - ctxt->sax->commentcommentcomment = 0; - ctxt->sax->ignorableWhitespace = 0; - - xmlStopParser(ctxt); - -} - - -/** - * @file srcSAXController.hpp - * - * @copyright Copyright (C) 2013-2014 srcML, LLC. (www.srcML.org) - * - * srcSAX is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * srcSAX is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef INCLUDED_SRCSAX_CONTROLLER_HPP -#define INCLUDED_SRCSAX_CONTROLLER_HPP - -class srcSAXHandler; -#include <srcsax.h> - -#include <libxml/parser.h> -#include <libxml/parserInternals.h> - -#include <string> - -/** - * SAXError - * - * Data struct to hold contents of an error. - */ -struct SAXError { - - /** error message */ - std::string message; - - /** error code */ - int error_code; - -}; - -/** - * srcSAXController - * - * Provides execution of sax with - * given hooks. - */ -class srcSAXController { - -private : - - // xmlParserCtxt - srcsax_context * context; - - // memory buffer storage - std::string srcml_buffer; - -public : - - /** - * srcSAXController - * @param filename name of a file - * @param encoding the xml encoding - * - * Constructor - */ - srcSAXController(const char * filename, const char * encoding = 0); - - /** - * srcSAXController - * @param srcml_buffer a string buffer - * - * Constructor - */ - srcSAXController(const std::string & srcml_buffer, const char * encoding = 0); - - /** - * srcSAXController - * @param srcml_file a FILE for a srcML document - * - * Constructor - */ - srcSAXController(FILE * srcml_file, const char * encoding = 0); - - /** - * srcSAXController - * @param srcml_fd a file descriptor for a srcML document - * - * Constructor - */ - srcSAXController(int srcml_fd, const char * encoding = 0); - - - /** - * srcSAXController - * @param srcml_context a general context for a srcML document - * @param read_callback a read callback function - * @param close_callback a close callback function - * - * Constructor - */ - srcSAXController(void * srcml_context, int (*read_callback)(void * context, char * buffer, int len), int (*close_callback)(void * context), const char * encoding = 0); - - /** - * srcSAXController - * @param input a parser input buffer - * - * Constructor - */ - srcSAXController(xmlParserInputBufferPtr input); - - /** - * getCtxt - * - * Return the used parser context. - */ - srcsax_context * getContextgetContext(); - - /** - * ~srcSAXController - * - * Destructor - */ - ~srcSAXController(); - - - /** - * enable_startDocument - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables startDocument parsing. - */ - void enable_startDocumentenable_startDocument(bool enable); - - /** - * enable_endDocument - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables endDocument parsing. - */ - void enable_endDocumentenable_endDocument(bool enable); - - /** - * enable_startRoot - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables startRoot parsing. - */ - void enable_startRootenable_startRoot(bool enable); - - /** - * enable_startUnit - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables startUnit parsing. - */ - void enable_startUnitenable_startUnit(bool enable); - - /** - * enable_startElement - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables startElement parsing. - */ - void enable_startElementenable_startElement(bool enable); - - /** - * enable_endRoot - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables endRoot parsing. - */ - void enable_endRootenable_endRoot(bool enable); - - /** - * enable_endUnit - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables endUnit parsing. - */ - void enable_endUnitenable_endUnit(bool enable); - - - /** - * enable_endElement - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables endElement parsing. - */ - void enable_endElementenable_endElement(bool enable); - - /** - * enable_charactersRoot - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables charactersRoot parsing. - */ - void enable_charactersRootenable_charactersRoot(bool enable); - - /** - * enable_charactersUnit - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables charactersUnit parsing. - */ - void enable_charactersUnitenable_charactersUnit(bool enable); - - /** - * enable_metaTag - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables metaTag parsing. - */ - void enable_metaTagenable_metaTag(bool enable); - - /** - * enable_comment - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables comment parsing. - */ - void enable_commentenable_comment(bool enable); - - /** - * enable_cdataBlock - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables cdataBlock parsing. - */ - void enable_cdataBlockenable_cdataBlock(bool enable); - - /** - * enable_processingInstruction - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables processingInstruction parsing. - */ - void enable_processingInstructionenable_processingInstruction(bool enable); - - /** - * enable_function - * @param enable bool indicate enable or disable special function parsing. - * - * Enables or disables special function parsing. - */ - void enable_functionenable_function(bool enable); - - /** - * parse - * @param handler srcMLHandler with hooks for sax parsing - * - * Parse the xml document with the supplied hooks. - */ - void parseparse(srcSAXHandler * handler); - - /** - * stop_parser - * - * Stop parsing. - */ - void stop_parserstop_parser(); - -}; - -#endif - - -/** - * @file cppCallbackAdapter.hpp - * - * @copyright Copyright (C) 2013-2014 srcML, LLC. (www.srcML.org) - * - * srcSAX is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * srcSAX is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** - * cppCallbackAdapter - * - * Wrapper around C srcSAX api to provide for C++ interface. - * Simply, forward the callbacks to the provided srcSAXHandler. - */ -class cppCallbackAdapter { - -private: - - /** the srcSAXHandler to forward the callbacks */ - srcSAXHandler * handler; - -public: - - /** - * cppCallbackAdapter - * @param handler a srcSAXHandler whose callbacks will be called. - * - * Constructor. Initialize the handler - */ - cppCallbackAdapter(srcSAXHandler * handler) : handler(handler) {} - - /** - * factory - * - * Factory method to generate the srcsax_handler containin this classes - * callbacks needed to perform to use the C++ wrapper API. - * - * @returns the generated srcsax_handler with the correct callbacks for C API. - */ - /**collaborator */ - static srcsax_handler factory() { - - srcsax_handler handler; - - handler.start_document = start_document; - handler.end_document = end_document; - handler.start_root = start_root; - handler.start_unit = start_unit; - handler.start_element = start_element; - handler.end_root = end_root; - handler.end_unit = end_unit; - handler.end_element = end_element; - handler.characters_root = characters_root; - handler.characters_unit = characters_unit; - handler.meta_tag = meta_tag; - handler.comment = comment; - handler.cdata_block = cdata_block; - handler.processing_instruction = processing_instruction; - - return handler; - - } - - /** - * srcml_element_stack_push - * @param prefix the element to push prefix - * @param localname the elements name - * - * Push the element to the stack. - */ - /**command */ - void srcml_element_stack_pushsrcml_element_stack_push(const char * prefix, const char * localname) { - - std::string srcml_element_string = ""; - if(prefix) { - - srcml_element_string += prefix; - srcml_element_string += ':'; - - } - - srcml_element_string += localname; - - handler->get_stack().push_back(srcml_element_string); - - - } - - /** - * srcml_element_stack_pop - * - * Pop an element from the stack. Testing - * may try to pop with 0 items so simply return. - */ - /**command */ - void srcml_element_stack_popsrcml_element_stack_pop() { - - if(handler->get_stack().size() == 0) return; - - handler->get_stack().pop_back(); - - } - - /** - * start_document - * @param context a srcSAX context - * - * Callback. Forwards C API start_document to C++ API srcSAXHandler startDocument. - */ - /**command collaborator */ - static void start_documentstart_document(struct srcsax_context * context) { - - cppCallbackAdapter * cpp_adapter = (cppCallbackAdapter *)context->data; - - cpp_adapter->handler->set_encoding(context->encoding); - - cpp_adapter->handler->startDocument(); - - } - - /** - * end_document - * @param context a srcSAX context - * - * Callback. Forwards C API end_document to C++ API srcSAXHandler endDocument. - */ - /**command collaborator */ - static void end_documentend_document(struct srcsax_context * context) { - - cppCallbackAdapter * cpp_adapter = (cppCallbackAdapter *)context->data; - - cpp_adapter->handler->get_stack().clear(); - - cpp_adapter->handler->endDocument(); - - - } - - /** - * start_root - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * Callback. Forwards C API start_root to C++ API srcSAXHandler startRoot. - */ - /**command collaborator */ - static void start_rootstart_root(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) { - - cppCallbackAdapter * cpp_adapter = (cppCallbackAdapter *)context->data; - - cpp_adapter->handler->set_is_archive(context->is_archive); - - if(context->is_archive) - cpp_adapter->srcml_element_stack_push((const char *)prefix, (const char *)localname); - - cpp_adapter->handler->startRoot(localname, prefix, URI, num_namespaces, namespaces, num_attributes, attributes); - - } - - /** - * start_unit - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * Signature srcSAX handler function for start of an unit. - * Callback. Forwards C API start_unit to C++ API srcSAXHandler startUnit. - */ - /**command collaborator */ - static void start_unitstart_unit(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) { - - cppCallbackAdapter * cpp_adapter = (cppCallbackAdapter *)context->data; - - cpp_adapter->srcml_element_stack_push((const char *)prefix, (const char *)localname); - - cpp_adapter->handler->startUnit(localname, prefix, URI, num_namespaces, namespaces, num_attributes, attributes); - - - } -#if 0 - /** - * start_function - * @param context a srcSAX context - * @param name the function's name - * @param return_type the function return type - * @param parameter_list a list of the function parameters in struct containing (declaration.type/declaration.name) - * @param is_decl indicates if the call is a function declaration (true) or definition (false) - * - * Callback. Forwards C API start_function to C++ API srcSAXHandler startFunction. - */ - static void start_function(struct srcsax_context * context, const char * name, const char * return_type, const struct declaration * parameter_list, _Bool is_decl) { - - cppCallbackAdapter * cpp_adapter = (cppCallbackAdapter *)context->data; - - - } -#endif - - /** - * start_element - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * Signature for srcSAX handler function for start of an element. - * Callback. Forwards C API start_element to C++ API srcSAXHandler startElement. - */ - /**command collaborator */ - static void start_elementstart_element(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) { - - cppCallbackAdapter * cpp_adapter = (cppCallbackAdapter *)context->data; - - cpp_adapter->srcml_element_stack_push((const char *)prefix, (const char *)localname); - - cpp_adapter->handler->startElement(localname, prefix, URI, num_namespaces, namespaces, num_attributes, attributes); - - - } - - /** - * end_root - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * Callback. Forwards C API end_root to C++ API srcSAXHandler endRoot. - */ - /**command collaborator */ - static void end_rootend_root(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI) { - - cppCallbackAdapter * cpp_adapter = (cppCallbackAdapter *)context->data; - - cpp_adapter->srcml_element_stack_pop(); - - cpp_adapter->handler->endRoot(localname, prefix, URI); - - } - - /** - * end_unit - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * Callback. Forwards C API end_unit to C++ API srcSAXHandler endUnit. - */ - /**command collaborator */ - static void end_unitend_unit(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI) { - - cppCallbackAdapter * cpp_adapter = (cppCallbackAdapter *)context->data; - - cpp_adapter->srcml_element_stack_pop(); - - cpp_adapter->handler->endUnit(localname, prefix, URI); - - } -#if 0 - /** - * end_function - * @param context a srcSAX context - * - * Callback. Forwards C API end_function to C++ API srcSAXHandler endFunction. - */ - static void end_function(struct srcsax_context * context) { - - cppCallbackAdapter * cpp_adapter = (cppCallbackAdapter *)context->data; - - - } -#endif - /** - * end_element - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * Callback. Forwards C API end_element to C++ API srcSAXHandler endElement. - */ - /**command collaborator */ - static void end_elementend_element(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI) { - - cppCallbackAdapter * cpp_adapter = (cppCallbackAdapter *)context->data; - - cpp_adapter->srcml_element_stack_pop(); - - cpp_adapter->handler->endElement(localname, prefix, URI); - - } - - /** - * characters_root - * @param context a srcSAX context - * @param ch the characers - * @param len number of characters - * - * Callback. Forwards C API characters_root to C++ API srcSAXHandler charactersRoot. - */ - /**command collaborator */ - static void characters_rootcharacters_root(struct srcsax_context * context, const char * ch, int len) { - - cppCallbackAdapter * cpp_adapter = (cppCallbackAdapter *)context->data; - - cpp_adapter->handler->charactersRoot(ch, len); - - - } - - /** - * characters_unit - * @param context a srcSAX context - * @param ch the characers - * @param len number of characters - * - * Callback. Forwards C API characters_unit to C++ API srcSAXHandler charactersUnit. - */ - /**command collaborator */ - static void characters_unitcharacters_unit(struct srcsax_context * context, const char * ch, int len) { - - cppCallbackAdapter * cpp_adapter = (cppCallbackAdapter *)context->data; - - cpp_adapter->handler->charactersUnit(ch, len); - - } - - /** - * meta_tag - * @param context a srcSAX context - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * Callback. Forwards C API meta_tag to C++ API srcSAXHandler metaTag. - */ - /**command collaborator */ - static void meta_tagmeta_tag(struct srcsax_context * context, const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) { - - cppCallbackAdapter * cpp_adapter = (cppCallbackAdapter *)context->data; - - cpp_adapter->srcml_element_stack_push((const char *)prefix, (const char *)localname); - - cpp_adapter->handler->metaTag(localname, prefix, URI, num_namespaces, namespaces, num_attributes, attributes); - - cpp_adapter->srcml_element_stack_pop(); - - } - - /** - * comment - * @param context a srcSAX context - * @param value the comment content - * - * Callback. Forwards C API comment to C++ API srcSAXHandler comment. - */ - /**command collaborator */ - static void commentcomment(struct srcsax_context * context, const char * value) { - - cppCallbackAdapter * cpp_adapter = (cppCallbackAdapter *)context->data; - - cpp_adapter->handler->comment(value); - - } - - /** - * cdata_block - * @param context a srcSAX context - * @param value the pcdata content - * @param len the block length - * - * Callback. Forwards C API cdata_block to C++ API srcSAXHandler cdata_block. - */ - /**command collaborator */ - static void cdata_blockcdata_block(struct srcsax_context * context, const char * value, int len) { - - cppCallbackAdapter * cpp_adapter = (cppCallbackAdapter *)context->data; - - cpp_adapter->handler->cdataBlock(value, len); - - } - - /** - * processing_instruction - * @param context a srcSAX context - * @param target the processing instruction target. - * @param data the processing instruction data. - * - * Callback. Forwards C API processing_instruction to C++ API srcSAXHandler processingInstruction. - */ - /**command collaborator */ - static void processing_instructionprocessing_instruction(struct srcsax_context * context, const char * target, const char * data) { - - cppCallbackAdapter * cpp_adapter = (cppCallbackAdapter *)context->data; - - cpp_adapter->handler->processingInstruction(target, data); - - } - -}; - - -/** - * @file print_callbacks.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - /* - - Print each callback as it is called (callback trace). - - Input: input_file.xml - Useage: print_callbacks input_file.xml - - */ - -#include "print_callbacks_handler.hpp" -#include <srcSAXController.hpp> - -#include <iostream> - -/** - * main - * @param argc number of arguments - * @param argv the provided arguments (array of C strings) - * - * Invoke srcSAX handler to print out each callback as it is called. - */ -int main(int argc, char * argv[]) { - - if(argc < 2) { - - std::cerr << "Useage: print_callbacks input_file.xml\n"; - exit(1); - - } - - srcSAXController control(argv[1]); - //control.enable_function(true); - print_callbacks_handler handler; - control.parseparseparse(&handlerparse); - - return 0; -} - - -/** - * @file srcSAXController.cpp - * - * @copyright Copyright (C) 2013-2014 srcML, LLC. (www.srcML.org) - * - * srcSAX is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * srcSAX is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <srcSAXController.hpp> -#include <srcSAXHandler.hpp> -#include <cppCallbackAdapter.hpp> - -#include <sax2_srcsax_handler.hpp> - -#include <string> - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" - -/** - * srcSAXController - * @param filename name of a file - * - * Constructor - */ -srcSAXController::srcSAXController(const char * filename, const char * encoding) { - - context = srcsax_create_context_filename(filename, encoding); - - if(context == NULL) throw std::string("File does not exist"); - - -} - -/** - * srcSAXController - * @param srcml_buffer a string buffer - * - * Constructor - */ -srcSAXController::srcSAXController(const std::string & srcml_buffer, const char * encoding) : srcml_buffer(srcml_buffer) { - - context = srcsax_create_context_memory(this->srcml_buffer.c_str(), this->srcml_buffer.size(), encoding); - - if(context == NULL) throw std::string("File does not exist"); - -} - -/** - * srcSAXController - * @param srcml_file a FILE for a srcML document - * - * Constructor - */ -srcSAXController::srcSAXController(FILE * srcml_file, const char * encoding) { - - context = srcsax_create_context_FILE(srcml_file, encoding); - - if(context == NULL) throw std::string("File does not exist"); - -} - -/** - * srcSAXController - * @param srcml_fd a file descriptor for a srcML document - * - * Constructor - */ -srcSAXController::srcSAXController(int srcml_fd, const char * encoding) { - - context = srcsax_create_context_fd(srcml_fd, encoding); - - if(context == NULL) throw std::string("File does not exist"); - -} - -/** - * srcSAXController - * @param srcml_context a general context for a srcML document - * @param read_callback a read callback function - * @param close_callback a close callback function - * - * Constructor - */ -srcSAXController::srcSAXController(void * srcml_context, int (*read_callback)(void * context, char * buffer, int len), int (*close_callback)(void * context), const char * encoding) { - - context = srcsax_create_context_io(srcml_context, read_callback, close_callback, encoding); - - if(context == NULL) throw std::string("File does not exist"); - -} - - -/** - * srcSAXController - * @param input a parser input buffer - * - * Constructor - */ -srcSAXController::srcSAXController(xmlParserInputBufferPtr input) { - - context = srcsax_create_context_parser_input_buffer(input); - - if(context == NULL) throw std::string("File does not exist"); - -} - -/** - * ~srcSAXController - * - * Constructor - */ -srcSAXController::~srcSAXController() { - - if(context) srcsax_free_context(context); - -} - -/** - * getCtxt - * - * Return the used parser context. - */ -/**nonconstget collaborator */ -srcsax_context * srcSAXController::getContext() { - - return context; - -} - -/** - * enable_startDocument - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables startDocument parsing. - */ -/**unclassified */ -void srcSAXController::enable_startDocument(bool enable) { - - if(enable) context->handler->start_document = cppCallbackAdapter::start_document; - else context->handler->start_document = 0; - -} - -/** - * enable_endDocument - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables endDocument parsing. - */ -/**unclassified */ -void srcSAXController::enable_endDocument(bool enable) { - - if(enable) context->handler->end_document = cppCallbackAdapter::end_document; - else context->handler->end_document = 0; - -} - -/** - * enable_startRoot - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables startRoot parsing. - */ -/**unclassified */ -void srcSAXController::enable_startRoot(bool enable) { - - if(enable) context->handler->start_root = cppCallbackAdapter::start_root; - else context->handler->start_root = 0; - -} - -/** - * enable_startUnit - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables startUnit parsing. - */ -/**unclassified */ -void srcSAXController::enable_startUnit(bool enable) { - - if(enable) context->handler->start_unit = cppCallbackAdapter::start_unit; - else context->handler->start_unit = 0; - -} - -/** - * enable_startElement - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables startElement parsing. - */ -/**unclassified */ -void srcSAXController::enable_startElement(bool enable) { - - if(enable) context->handler->start_element = cppCallbackAdapter::start_element; - else context->handler->start_element = 0; - -} - -/** - * enable_endRoot - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables endRoot parsing. - */ -/**unclassified */ -void srcSAXController::enable_endRoot(bool enable) { - - if(enable) context->handler->end_root = cppCallbackAdapter::end_root; - else context->handler->end_root = 0; - -} - -/** - * enable_endUnit - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables endUnit parsing. - */ -/**unclassified */ -void srcSAXController::enable_endUnit(bool enable) { - - if(enable) context->handler->end_unit = cppCallbackAdapter::end_unit; - else context->handler->end_unit = 0; - -} - -/** - * enable_endElement - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables endElement parsing. - */ -/**unclassified */ -void srcSAXController::enable_endElement(bool enable) { - - if(enable) context->handler->end_element = cppCallbackAdapter::end_element; - else context->handler->end_element = 0; - -} - -/** - * enable_charactersRoot - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables charactersRoot parsing. - */ -/**unclassified */ -void srcSAXController::enable_charactersRoot(bool enable) { - - if(enable) { - - context->handler->characters_root = cppCallbackAdapter::characters_root; - - } else { - - context->handler->characters_root = 0; - - } - -} - -/** - * enable_charactersUnit - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables charactersUnit parsing. - */ -/**unclassified */ -void srcSAXController::enable_charactersUnit(bool enable) { - - if(enable) { - - context->handler->characters_unit = cppCallbackAdapter::characters_unit; - - } else { - - context->handler->characters_unit = 0; - - } - -} - -/** - * enable_metaTag - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables metaTag parsing. - */ -/**unclassified */ -void srcSAXController::enable_metaTag(bool enable) { - - if(enable) { - - context->handler->meta_tag = cppCallbackAdapter::meta_tag; - - } else { - - context->handler->meta_tag = 0; - - } - -} - -/** - * enable_comment - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables comment parsing. - */ -/**unclassified */ -void srcSAXController::enable_comment(bool enable) { - - if(enable) context->handler->comment = cppCallbackAdapter::comment; - else context->handler->comment = 0; - -} - -/** - * enable_cdataBlock - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables cdataBlock parsing. - */ -/**unclassified */ -void srcSAXController::enable_cdataBlock(bool enable) { - - if(enable) context->handler->cdata_block = cppCallbackAdapter::cdata_block; - else context->handler->cdata_block = 0; - -} - -/** - * enable_processingInstruction - * @param enable bool indicate enable or disable SAX parsing. - * - * Enables or disables processingInstruction parsing. - */ -/**unclassified */ -void srcSAXController::enable_processingInstruction(bool enable) { - - if(enable) context->handler->processing_instruction = cppCallbackAdapter::processing_instruction; - else context->handler->processing_instruction = 0; - -} - -/** -* enable_function -* @param enable bool indicate enable or disable special function parsing. -* -* Enables or disables special function parsing. -*/ -/**unclassified */ -void srcSAXController::enable_function(bool enable) { - - //sax2_handler.parse_function = enable; - -} - -/** - * parse - * @param handler srcMLHandler with hooks for sax parsing - * - * Parse the xml document with the supplied hooks. - */ -/**command collaborator */ -void srcSAXController::parse(srcSAXHandler * handler) { - - handler->set_controllerset_controllerset_controller(thisset_controller); - - cppCallbackAdapter adapter(handler); - context->data = &adapter; - srcsax_handler sax_handler = cppCallbackAdapter::factoryfactoryfactory(); - context->handler = &sax_handler; - - int status = srcsax_parse(context); - - context->data = 0; - - if(status != 0) { - - xmlErrorPtr ep = xmlCtxtGetLastError(context->libxml2_context); - - size_t str_length = strlen(ep->message); - ep->message[str_length - 1] = '\0'; - SAXError error = { std::string((const char *)ep->message), ep->code }; - - throw error; - } - -} - - - -/** - * @file identity_copy.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - /* - - Copy the srcML document. - - Input: input_file.xml - Input: output_file.xml - Useage: identity_copy input_file.xml output_file.xml - - */ - -#include "identity_copy_handler.hpp" -#include <srcSAXController.hpp> - -#include <iostream> - -/** - * main - * @param argc number of arguments - * @param argv the provided arguments (array of C strings) - * - * Invoke srcSAX handler to copy the supplied srcML document and into the given - * output file. - */ - int main(int argc, char * argv[]) { - - if(argc < 3) { - - std::cerr << "Useage: identify_copy input_file.xml output_file.xml\n"; - exit(1); - - } - - srcSAXController control(argv[1]); - identity_copy_handler handler(argv[2]); - control.parseparseparse(&handlerparse); - - return 0; -} - - -/** - * @file srcSAXHandler.hpp - * - * @copyright Copyright (C) 2013-2014 srcML, LLC. (www.srcML.org) - * - * srcSAX is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * srcSAX is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef INCLUDED_SRCSAX_HANDLER_HPP -#define INCLUDED_SRCSAX_HANDLER_HPP - -#include <srcSAXController.hpp> - -#include <libxml/parser.h> - -#include <vector> - -/** - * srcSAXHandler - * - * Base class that provides hooks for SAX processing. - */ -class srcSAXHandler { - -private : - - /** Controller for parser */ - srcSAXController * controller; - -protected: - - /** is the document an archive */ - bool is_archive; - - /** the current unit count */ - int unit_count; - - /** open srcML element stack */ - std::vector<std::string> srcml_element_stack; - - /** the xml documents encoding */ - const char * encoding; - -public : - - /** - * srcSAXHandler - * - * Default constructor default values to everything - */ - srcSAXHandler() : controller(0), is_archive(false), unit_count(0), encoding(0) {} - - /** - * set_controller - * @param controller pointer to control class - * - * Used by srcSAXController to provide access to self - * for such things as disabeling sax parsing. - */ - /**collaborational-command collaborator */ - void set_controller(srcSAXController * controller) { - - this->controller = controller; - - } - - /** - * increment_unit_count - * - * Internally used to increment the count in SAX2srcSAXHandler. - */ - /**unclassified */ - void increment_unit_countincrement_unit_count() { - - ++unit_count; - - } - - /** - * get_stack - * - * Used internally to update the stack. - */ - /**nonconstget */ - std::vector<std::string> & get_stack() { - - return srcml_element_stack; - - } - - /** - * get_controller - * - * Get the control handler. - */ - /**collaborator */ - srcSAXController & get_controllerget_controller() { - - return *controller; - - } - - /** - * stop_parser - * - * Stop the srcML parser. - */ - /**command */ - void stop_parserstop_parser() { - - srcsax_stop_parser(controller->getContext()); - - } - - /** - * set_encoding - * @param encoding set the encoding - * - * Used by SAX2srcSAXHandler when determined - * encoding. Set the input encoding if any. - */ - /**collaborational-command */ - void set_encodingset_encoding(const char * encoding) { - - this->encoding = encoding; - } - - /** - * set_is_archive - * @param is_archive is the srcML document an archive - * - * Used by SAX2srcSAXHandler when determined - * if an archive. Sets if srcML document is an archive. - */ - /**collaborational-command */ - void set_is_archiveset_is_archive(bool is_archive) { - - this->is_archive = is_archive; - - } - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" - - /** - * startDocument - * - * SAX handler function for start of document. - * Overide for desired behaviour. - */ - /**unclassified */ - virtual void startDocumentstartDocument() {} - - /** - * endDocument - * - * SAX handler function for end of document. - * Overide for desired behaviour. - */ - /**unclassified */ - virtual void endDocumentendDocument() {} - - /** - * startRoot - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for start of the root element. - * Overide for desired behaviour. - */ - /**collaborator */ - virtual void startRootstartRoot(const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) {} - - /** - * startUnit - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for start of an unit. - * Overide for desired behaviour. - */ - /**collaborator */ - virtual void startUnitstartUnit(const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) {} -#if 0 - /** - * startFunction - * @param name the function's name - * @param return_type the function return type - * @param parameter_list a list of the function parameters in struct containing (declaration.type/declaration.name) - * @param is_decl indicates if the call is a function declaration (true) or definition (false) - * - * SAX handler function for start of function with prototype. - * Accessing references after callback termination is undefined. - * - * Overide for desired behaviour. - */ - virtual void startFunction(const std::string & name, const std::string & return_type, const std::vector<declaration> & parameter_list, bool is_decl) {} -#endif - /** - * startElement - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for start of an element. - * Overide for desired behaviour. - */ - /**collaborator */ - virtual void startElementstartElement(const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) {} - - /** - * endRoot - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * SAX handler function for end of the root element. - * Overide for desired behaviour. - */ - /**unclassified */ - virtual void endRootendRoot(const char * localname, const char * prefix, const char * URI) {} - - /** - * endUnit - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * SAX handler function for end of an unit. - * Overide for desired behaviour. - */ - /**unclassified */ - virtual void endUnitendUnit(const char * localname, const char * prefix, const char * URI) {} -#if 0 - /** - * endFunction - * - * SAX handler function for end of a function. - * Overide for desired behaviour. - */ - virtual void endFunction() {} -#endif - /** - * endElement - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * SAX handler function for end of an element. - * Overide for desired behaviour. - */ - /**unclassified */ - virtual void endElementendElement(const char * localname, const char * prefix, const char * URI) {} - - /** - * charactersRoot - * @param ch the characers - * @param len number of characters - * - * SAX handler function for character handling at the root level. - * Overide for desired behaviour. - */ - /**unclassified */ - virtual void charactersRootcharactersRoot(const char * ch, int len) {} - - /** - * charactersUnit - * @param ch the characers - * @param len number of characters - * - * SAX handler function for character handling within a unit. - * Overide for desired behaviour. - */ - /**unclassified */ - virtual void charactersUnitcharactersUnit(const char * ch, int len) {} - - /** - * metaTag - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes\ - * - * SAX handler function for a meta tags. - * Overide for desired behaviour. - */ - /**collaborator */ - virtual void metaTagmetaTag(const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) {} - - /** - * comment - * @param value the comment content - * - * A comment has been parsed. - * Overide for desired behaviour. - */ - /**unclassified */ - virtual void commentcomment(const char * value) {} - - /** - * cdataBlock - * @param value the pcdata content - * @param len the block length - * - * Called when a pcdata block has been parsed. - * Overide for desired behaviour. - */ - /**unclassified */ - virtual void cdataBlockcdataBlock(const char * value, int len) {} - - /** - * processingInstruction - * @param target the processing instruction target. - * @param data the processing instruction data. - * - * Called when a processing instruction has been parsed. - * Overide for desired behaviour. - */ - /**unclassified */ - virtual void processingInstructionprocessingInstruction(const char * target, const char * data) {} - -#pragma GCC diagnostic pop - -}; - -#endif - - -/** - * @file element_count.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - /* - - Count each the occurrences of each srcML element. - - Input: input_file.xml - Useage: element_count input_file.xml - - */ - -#include "element_count_handler.hpp" -#include <srcSAXController.hpp> - -#include <map> -#include <iostream> - -/** - * main - * @param argc number of arguments - * @param argv the provided arguments (array of C strings) - * - * Invoke srcSAX handler to count element occurences and print out the resulting element counts. - */ -int main(int argc, char * argv[]) { - - if(argc < 2) { - - std::cerr << "Useage: element_count input_file.xml\n"; - exit(1); - - } - - srcSAXController control(argv[1]); - element_count_handler handler; - control.parseparseparse(&handlerparse); - - for(std::map<std::string, unsigned long long>::const_iterator citr = handler.get_countsget_counts().begin(); citr != handler.get_countsget_counts().end(); ++citr) { - - std::cout << citr->first << ": " << citr->second << '\n'; - - } - - return 0; -} - - -/** - * @file print_callbacks_handler.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef INCLUDED_PRINT_CALLBACKS_HANDLER_HPP -#define INCLUDED_PRINT_CALLBACKS_HANDLER_HPP - -#include <srcSAXHandler.hpp> - -class print_callbacks_handler : public srcSAXHandler { - -public : - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" - - /** - * startDocument - * - * SAX handler function for start of document. - * Print when callback is called. - * Overide for desired behaviour. - */ - /**command */ - virtual void startDocument() { - - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); - - } - - /** - * endDocument - * - * SAX handler function for end of document. - * Print when callback is called. - * Overide for desired behaviour. - */ - /**command */ - virtual void endDocumentendDocument() { - - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); - - } - - /** - * startRoot - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for start of the root element. - * Print when callback is called. - * Overide for desired behaviour. - */ - /**command collaborator */ - virtual void startRootstartRoot(const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) { - - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); - - } - - - /** - * startUnit - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for start of an unit. - * Print when callback is called. - * Overide for desired behaviour. - */ - /**command collaborator */ - virtual void startUnitstartUnit(const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) { - - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); - - } - - /** - * startFunction - * @param name the function's name - * @param return_type the function return type - * @param parameter_list a list of the function parameters in struct containing (declaration.type/declaration.name) - * @param is_decl indicates if the call is a function declaration (true) or definition (false) - * - * SAX handler function for start of function with prototype. - * Accessing references after callback termination is undefined. - * Print when callback is called. - * - * Overide for desired behaviour. - */ - /* - virtual void startFunction(const std::string & name, const std::string & return_type, const std::vector<declaration> & parameter_list, bool is_decl) { - - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); - - } - */ - - /** - * startElement - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for start of an element. - * Print when callback is called. - * - * Overide for desired behaviour. - */ - /**command collaborator */ - virtual void startElementstartElement(const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) { - - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); - - } - - /** - * endRoot - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * SAX handler function for end of the root element. - * Print when callback is called. - * - * Overide for desired behaviour. - */ - /**command */ - virtual void endRootendRoot(const char * localname, const char * prefix, const char * URI) { - - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); - - } - - /** - * endUnit - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * SAX handler function for end of an unit. - * Print when callback is called. - * - * Overide for desired behaviour. - */ - /**command */ - virtual void endUnitendUnit(const char * localname, const char * prefix, const char * URI) { - - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); - - } - - /** - * endFunction - * - * SAX handler function for end of a function. - * Print when callback is called. - * - * Overide for desired behaviour. - */ - /* - virtual void endFunction() { - - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); - - } - */ - - /** - * endElement - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * SAX handler function for end of an element. - * Print when callback is called. - * - * Overide for desired behaviour. - */ - /**command */ - virtual void endElementendElement(const char * localname, const char * prefix, const char * URI) { - - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); - - } - - /** - * charactersRoot - * @param ch the characers - * @param len number of characters - * - * SAX handler function for character handling at the root level. - * Print when callback is called. - * - * Overide for desired behaviour. - */ - /**command */ - virtual void charactersRootcharactersRoot(const char * ch, int len) { - - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); - - } - - /** - * charactersUnit - * @param ch the characers - * @param len number of characters - * - * SAX handler function for character handling within a unit. - * Print when callback is called. - * - * Overide for desired behaviour. - */ - /**command */ - virtual void charactersUnitcharactersUnit(const char * ch, int len) { - - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); - - } - - /** - * metaTag - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * @param meta_tags vector of elements composed of metage tags defined after root tag - * - * SAX handler function for meta tags. - * Print when callback is called. - * Overide for desired behaviour. - */ - /**command collaborator */ - virtual void metaTagmetaTag(const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) { - - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); - - } - - /** - * comment - * @param value the comment content - * - * A comment has been parsed. - * Print when callback is called. - * - * Overide for desired behaviour. - */ - /**command */ - virtual void commentcomment(const char * value) { - - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); - - } - - /** - * cdataBlock - * @param value the pcdata content - * @param len the block length - * - * Called when a pcdata block has been parsed. - * Print when callback is called. - * - * Overide for desired behaviour. - */ - /**command */ - virtual void cdataBlockcdataBlock(const char * value, int len) { - - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); - - } - - /** - * processingInstruction - * @param target the processing instruction target. - * @param data the processing instruction data. - * - * Called when a processing instruction has been parsed. - * Print when callback is called. - * - * Overide for desired behaviour. - */ - /**command */ - virtual void processingInstructionprocessingInstruction(const char * target, const char * data) { - - fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); - - } - -#pragma GCC diagnostic pop - -}; - -#endif - - -/** - * @file element_count_handler.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef INCLUDED_ELEMENT_COUNT_HANDLER_HPP -#define INCLUDED_ELEMENT_COUNT_HANDLER_HPP - -#include <srcSAXHandler.hpp> -#include <map> - -/** - * element_count_handler - * - * Base class that provides hooks for SAX processing. - */ -class element_count_handler : public srcSAXHandler { - -private : - - /** map to count srcML elements */ - std::map<std::string, unsigned long long> element_counts; - -public : - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" - - /** - * get_counts - * - * Accessor method to get the element counts. - * - * @returns the element count map. - */ - /**get */ - const std::map<std::string, unsigned long long> & get_counts() const { - - return element_counts; - - } - - /** - * update_count - * @param prefix the element's prefix - * @param localname the element name - * - * Helper function to update the count of an element or add it if necessary. - * Need the full name (prefix + localname) of elemement to disambiguate between - * elements with the same name, but different prefix/namespaces (e.g. cpp:if, if). - * A more general find approach is used instead of relying on access using the - * operator[] to default non-existant items to 0. - */ - /**command */ - void update_countupdate_count(const char * prefix, const char * localname) { - - std::string element = ""; - if(prefix) { - - element += (const char *)prefix; - element += ":"; - - } - element += (const char *)localname; - - /* Note: in map could just use operator[], however, this a bit more general */ - std::map<std::string, unsigned long long>::iterator itr = element_counts.find(element); - if(itr == element_counts.end()) { - - element_counts.insert(std::pair<std::string, unsigned long long>(element, 1)); - - } else { - - ++itr->second; - - } - - } - - /* - virtual void startDocument() {} - virtual void endDocument() {} - */ - - /** - * startRoot - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for start of the root element. - * Counts the root unit (if an archive, to avoid double count with startUnit). - * Overide for desired behaviour. - */ - /**command collaborator */ - virtual void startRoot(const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) { - - if(is_archive) - update_count(prefix, localname); - - } - - /** - * startUnit - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for start of an unit. - * Counts each unit tag (= filecount non-archive, = filecount + 1 if archive). - * Overide for desired behaviour. - */ - /**command collaborator stateless */ - virtual void startUnitstartUnit(const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) { - - update_count(prefix, localname); - - } - - /** - * startElement - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param num_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for start of an element. - * Count each element. - * Overide for desired behaviour. - */ - /**command collaborator stateless */ - virtual void startElementstartElement(const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) { - - update_count(prefix, localname); - - } - - /* - - // end elements may need to be used if you want to collect only on per file basis or some other granularity. - virtual void endRoot(const char * localname, const char * prefix, const char * URI) {} - virtual void endUnit(const char * localname, const char * prefix, const char * URI) {} - virtual void endElement(const char * localname, const char * prefix, const char * URI) {} - - // Contains information such as stuff used for parsing. So, probably do not need to count. - virtual void metaTag(const char* localname, const char* prefix, const char* URI, int num_namespaces, const char** namespaces, int num_attributes, const char** attributes) {} - - // Not typically in srcML documents - virtual void comment(const char * value) {} - virtual void cdataBlock(const char * value, int len) {} - virtual void processingInstruction(const char * target, const char * data) {} - */ - -#pragma GCC diagnostic pop - -}; - -#endif - - -/** - * @file identity_copy_handler.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef INCLUDED_IDENTITY_COPY_HANDLER_HPP -#define INCLUDED_IDENTITY_COPY_HANDLER_HPP - -#include <srcSAXHandler.hpp> -#include <iostream> -#include <string> - -#include <libxml/xmlwriter.h> - -/** - * identity_copy_handler - * - * Base class that provides hooks for SAX processing. - */ -class identity_copy_handler : public srcSAXHandler { - -private : - - xmlTextWriterPtr writer; - std::string content; - -public : - - /** - * identity_copy_handler - * - * Constructor. Open xmlwriter. - */ - identity_copy_handler(std::string output_filename) : writer(0) { - - if((writer = xmlNewTextWriterFilename(output_filename.c_str(), 0)) == 0) { - - std::cerr << "Problems opening output file: " << output_filename << '\n'; - exit(1); - - } - - } - - /** - * ~identity_copy_handler - * - * Destructor. Free writer resource. - */ - ~identity_copy_handler() { - - if(writer) - xmlFreeTextWriter(writer); - - } - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" - - /** - * startDocument - * - * SAX handler function for start of document. - * Write start of xml document. - * - * Overide for desired behaviour. - */ - /**command */ - virtual void startDocumentstartDocument() { - - xmlTextWriterStartDocument(writer, "1.0", "UTF-8", "yes"); - - } - - /** - * endDocument - * - * SAX handler function for end of document. - * Write the end of xml document. - * - * Overide for desired behaviour. - */ - /**command */ - virtual void endDocumentendDocument() { - - xmlTextWriterEndDocument(writer); - - } - - /** - * write_start_tag - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for start of the root element. - * Write out a start tag. - * - * Overide for desired behaviour. - */ - /**command collaborator */ - void write_start_tagwrite_start_tag(const char* localname, const char* prefix, const char* URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) { - - xmlTextWriterStartElementNS(writer, (const xmlChar *)prefix, (const xmlChar *)localname, 0); - - for(int pos = 0; pos < num_namespaces; ++pos) { - - std::string name = "xmlns"; - if(namespaces[pos].prefix) { - name += ":"; - - name += (const char *)namespaces[pos].prefix; - - } - - xmlTextWriterWriteAttribute(writer, (const xmlChar *)name.c_str(), (const xmlChar *)namespaces[pos].uri); - - } - - for(int pos = 0; pos < num_attributes; ++pos) { - - xmlTextWriterWriteAttributeNS(writer, (const xmlChar *)attributes[pos].prefix, (const xmlChar *)attributes[pos].localname, - (const xmlChar *)attributes[pos].uri, (const xmlChar *)attributes[pos].value); - - } - - } - - /** - * write_content - * @param text_content - * - * Write out the provided text content, escaping everything but ". - */ - /**command */ - void write_contentwrite_content(std::string & text_content) { - - if(text_content != "") { - - /* - Normal output of text is for the most part - identical to what libxml2 provides. However, - srcML does not escape " while libxml2 does escape - quotations. - */ - int ret = 0; - char * text = (char *)text_content.c_str(); - for(char * pos = text; *pos; ++pos) { - - if(*pos != '"') continue; - - *pos = 0; - ret = xmlTextWriterWriteString(writer, (const xmlChar *)text); - //if(ret == -1) return false; - - *pos = '\"'; - xmlTextWriterWriteRaw(writer, (const xmlChar *)"\""); - //if(ret == -1) return false; - - text = pos + 1; - - } - - ret = xmlTextWriterWriteString(writer, (const xmlChar *)text); - - text_content = ""; - - } - - } - - /** - * startRoot - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for start of the root element. - * Write out the root start tag (unless non-archive, startUnit will handle). - * - * Overide for desired behaviour. - */ - /**command collaborator */ - virtual void startRootstartRoot(const char* localname, const char* prefix, const char* URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int nb_attributes, - const struct srcsax_attribute * attributes) { - - if(is_archive) - write_start_tag(localname, prefix, URI, num_namespaces, namespaces, nb_attributes, attributes); - - } - - /** - * startUnit - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for start of an unit. - * Write out any saved text, then write out the unit tag. - * - * Overide for desired behaviour. - */ - /**command collaborator */ - virtual void startUnitstartUnit(const char* localname, const char* prefix, const char* URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int nb_attributes, - const struct srcsax_attribute * attributes) { - - // write out buffered root level characters - write_content(content); - - write_start_tag(localname, prefix, URI, num_namespaces, namespaces, nb_attributes, attributes); - - } - - /** - * startElement - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for start of an element. - * Write out any saved text, then write out the elementtag. - * - * Overide for desired behaviour. - */ - /**command collaborator */ - virtual void startElementstartElement(const char* localname, const char* prefix, const char* URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int nb_attributes, - const struct srcsax_attribute * attributes) { - - // write out buffered characters - write_content(content); - - write_start_tag(localname, prefix, URI, num_namespaces, namespaces, nb_attributes, attributes); - - } - - /** - * endRoot - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * SAX handler function for end of the root element. - * Write out any saved content, then end the root tag. - * - * Overide for desired behaviour. - */ - /**command */ - virtual void endRootendRoot(const char* localname, const char* prefix, const char* URI) { - - // write out buffered root level characters - if(is_archive) { - - write_content(content); - - xmlTextWriterEndElement(writer); - - } - - } - - /** - * endUnit - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * SAX handler function for end of an unit. - * Write out any saved up content, then write out ending unit tag. - * - * Overide for desired behaviour. - */ - /**command */ - virtual void endUnitendUnit(const char* localname, const char* prefix, const char* URI) { - - // write out any buffered characters - write_content(content); - - xmlTextWriterEndElement(writer); - - } - - /** - * endElement - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * - * SAX handler function for end of an element. - * Write out any saved content, then write out ending element tag. - * - * Overide for desired behaviour. - */ - /**command */ - virtual void endElementendElement(const char* localname, const char* prefix, const char* URI) { - - // write out any buffered characters - write_content(content); - - xmlTextWriterEndElement(writer); - - } - - /** - * charactersRoot - * @param ch the characers - * @param len number of characters - * - * SAX handler function for character handling at the root level. - * Collect/write root level charactes. - * - * Characters may be called multiple times in succession - * in some cases the text may need to be gathered all at once - * before output. Both methods are shown here although the delayed - * output is used. - * - * Overide for desired behaviour. - */ - /**command */ - virtual void charactersRootcharactersRoot(const char* ch, int len) { - - - //std::string content = ""; - content.append((const char *)ch, len); - //write_content(content); - - } - - /** - * charactersUnit - * @param ch the characers - * @param len number of characters - * - * SAX handler function for character handling within a unit. - * Collect/write unit level charactes. - * - * Characters may be called multiple times in succession - * in some cases the text may need to be gathered all at once - * before output. Both methods are shown here although the delayed - * output is used. - * - * Overide for desired behaviour. - */ - /**command */ - virtual void charactersUnitcharactersUnit(const char* ch, int len) { - - /* - Characters may be called multiple times in succession - in some cases the text may need to be gathered all at once - before output. Both methods are shown here although the delayed - output is used. - */ - - //std::string content = ""; - content.append((const char *)ch, len); - //write_content(content); - - } - - /** - * metaTag - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param num_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param attributes list of attributes - * - * SAX handler function for meta tag. - * Write out the meta tags. - * - * Overide for desired behaviour. - */ - /**command collaborator */ - virtual void metaTagmetaTag(const char* localname, const char* prefix, const char* URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int nb_attributes, - const struct srcsax_attribute * attributes) { - - // write out any buffered characters - write_content(content); - - write_start_tag(localname, prefix, URI, num_namespaces, namespaces, nb_attributes, attributes); - xmlTextWriterEndElement(writer); - - } - - /* - // Not typically in srcML documents - virtual void comment(const char* value) {} - virtual void cdataBlock(const char* value, int len) {} - virtual void processingInstruction(const char* target, const char* data) {} - */ - -#pragma GCC diagnostic pop - -}; - -#endif - - -#include <srcSAXEventDispatcher.hpp> -#include <srcSAXHandler.hpp> -#include <exception> -#include <SNLPolicy.hpp> -#include <stack> -class NLContextPolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - public: - struct NLContextData{ - NLContextData(){} - /**command */ - void clear(){ - category.clear(); - identifiername.clear(); - } - std::string category; - std::string identifiername; - }; - NLContextData data; - ~NLContextPolicy(){} - NLContextPolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners ){ - sourcenlpolicy.AddListener(this); - InitializeEventHandlers(); - } - /**command collaborator */ - void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - sourcenlpdata = policy->Data<SourceNLPolicy::SourceNLData>(); - std::string top; - if(!context.empty()){ - top = context.top(); - } - std::cerr<<"Output: "<<sourcenlpdata->identifiername<<" "<<sourcenlpdata->category<<" "<<top<<std::endl; - //datatotest.push_back(SourceNLData); - } - protected: - /**voidaccessor */ - void * DataInner() const override { - return new NLContextData(data); - } - private: - SourceNLPolicy sourcenlpolicy; - SourceNLPolicy::SourceNLData* sourcenlpdata; - std::string currentTypeName, currentDeclName, currentModifier, currentSpecifier; - std::stack<std::string> context; - /**command collaborator */ - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - openEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx) { - ctx.dispatcher->AddListener(&sourcenlpolicy); - }; - openEventMap[ParserState::whilestmt] = [this](srcSAXEventContext& ctx) { - std::cerr<<"seen while"<<std::endl; - context.push("while"); - }; - openEventMap[ParserState::forstmt] = [this](srcSAXEventContext& ctx) { - std::cerr<<"seen for"<<std::endl; - context.push("for"); - }; - openEventMap[ParserState::ifstmt] = [this](srcSAXEventContext& ctx) { - std::cerr<<"seen if"<<std::endl; - context.push("if"); - }; - /* - openEventMap[ParserState::whilestmt] = [this](srcSAXEventContext& ctx) { - context.push("else if"); - }; - openEventMap[ParserState::whilestmt] = [this](srcSAXEventContext& ctx) { - context.push("else"); - };*/ - closeEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx){ - ctx.dispatcher->RemoveListener(&sourcenlpolicy); - data.clear(); - }; - closeEventMap[ParserState::whilestmt] = [this](srcSAXEventContext& ctx){ - context.pop(); - }; - closeEventMap[ParserState::forstmt] = [this](srcSAXEventContext& ctx){ - context.pop(); - }; - closeEventMap[ParserState::ifstmt] = [this](srcSAXEventContext& ctx){ - context.pop(); - }; - - } -}; - -#include <srcSAXEventDispatcher.hpp> -#include <srcSAXHandler.hpp> -#include <exception> - -class DeclTypePolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - public: - struct DeclTypeData{ - DeclTypeData(): linenumber{0}, isConst{false}, isReference{false}, isPointer{false}, isStatic{false} {} - /**command */ - void clear(){ - nameoftype.clear(); - nameofidentifier.clear(); - namespaces.clear(); - linenumber = -1; - isConst = false; - isReference = false; - isPointer = false; - isStatic = false; - } - std::string nameoftype; - std::string nameofidentifier; - std::vector<std::string> namespaces; - int linenumber; - bool isConst; - bool isReference; - bool isPointer; - bool isStatic; - }; - DeclTypeData data; - ~DeclTypePolicy(){} - DeclTypePolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners ){ - InitializeEventHandlers(); - } - /**collaborator */ - void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override {} //doesn't use other parsers - protected: - /**voidaccessor */ - void * DataInnerDataInner() const override { - return new DeclTypeData(data); - } - private: - std::string currentTypeName, currentDeclName, currentModifier, currentSpecifier; - /**command collaborator */ - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - openEventMap[ParserState::op] = [this](srcSAXEventContext& ctx){ - if(ctx.And({ParserState::type, ParserState::declstmt}) && ctx.Nor({ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist})){ - data.namespaces.push_back(ctx.currentToken); - } - }; - closeEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx){ - if(ctx.IsOpen(ParserState::declstmt)){ - if(currentModifier == "*"){ - data.isPointer = true; - } - if(currentModifier == "&"){ - data.isReference = true; - } - } - }; - - closeEventMap[ParserState::decl] = [this](srcSAXEventContext& ctx){ - if(ctx.And({ParserState::declstmt})){ - data.linenumber = ctx.currentLineNumber; - data.nameofidentifier = currentDeclName; - } - }; - - closeEventMap[ParserState::type] = [this](srcSAXEventContext& ctx){ - if(ctx.And({ParserState::declstmt})){ - data.nameoftype = currentTypeName; - } - }; - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx){ - //TODO: possibly, this if-statement is suppressing more than just unmarked whitespace. Investigate. - if(!(ctx.currentToken.empty() || ctx.currentToken[0] == ' ')){ - if(ctx.And({ParserState::name, ParserState::type, ParserState::decl, ParserState::declstmt}) && ctx.Nor({ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist})){ - currentTypeName = ctx.currentToken; - } - if(ctx.And({ParserState::name, ParserState::decl, ParserState::declstmt}) && - ctx.Nor({ParserState::type, ParserState::index/*skip array portion*/, ParserState::argumentlist/*skip init list portion*/, ParserState::init, ParserState::specifier, ParserState::modifier})){ - currentDeclName = ctx.currentToken; - } - if(ctx.And({ParserState::specifier, ParserState::decl, ParserState::declstmt})){ - currentSpecifier = ctx.currentToken; - } - if(ctx.And({ParserState::modifier, ParserState::type, ParserState::declstmt})){ - currentModifier = ctx.currentToken; - } - } - }; - closeEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx){ - NotifyAll(ctx); - data.clear(); - }; - closeEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx){ - if(ctx.IsOpen(ParserState::declstmt)){ - if(currentSpecifier == "const"){ - data.isConst = true; - } - if(currentSpecifier == "static"){ - data.isStatic = true; - } - } - currentSpecifier.clear(); - }; - - } -}; - -#include <srcSAXEventDispatchUtilities.hpp> - -#include <TypePolicySingleEvent.hpp> -#include <NamePolicySingleEvent.hpp> - -#include <string> -#include <vector> - -#ifndef INCLUDED_DECL_TYPE_POLICY_SINGLE_EVENT_HPP -#define INCLUDED_DECL_TYPE_POLICY_SINGLE_EVENT_HPP - -class DeclTypePolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - -public: - - struct DeclTypeData { - - TypePolicy::TypeData * type; - NamePolicy::NameData * name; - bool isStatic; - - friend /**collaborator */ -friend std::ostream & operator<<(std::ostream & out, const DeclTypeData & declData) { - - out << *declData.type; - - if(declData.name) - out << ' ' << *declData.name; - - return out; - - } - - }; - -private: - - - DeclTypeData data; - std::size_t declDepth; - - TypePolicy * typePolicy; - NamePolicy * namePolicy; - -public: - - DeclTypePolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - declDepth(0), - typePolicy(nullptr), - namePolicy(nullptr) { - - InitializeDeclTypePolicyHandlers(); - - } - - ~DeclTypePolicy() { - - if(typePolicy) delete typePolicy; - if(namePolicy) delete namePolicy; - - } - -protected: - void * DataInner() const override { - - return new DeclTypeData(data); - - } - virtual void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - - if(typeid(TypePolicy) == typeid(*policy)) { - - data.type = policy->Data<TypePolicy::TypeData>(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - - } else if(typeid(NamePolicy) == typeid(*policy)) { - - data.name = policy->Data<NamePolicy::NameData>(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - - } - - } - -private: - - void InitializeDeclTypePolicyHandlers() { - using namespace srcSAXEventDispatch; - - // start of policy - openEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx) { - - if(!declDepth) { - - declDepth = ctx.depth; - data = DeclTypeData{}; - - CollectTypeHandlers(); - CollectNameHandlers(); - CollectSpecifiersHandlers(); - - } - - }; - - // end of policy - closeEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx) { - - if(declDepth && declDepth == ctx.depth) { - - declDepth = 0; - - NotifyAll(ctx); - InitializeDeclTypePolicyHandlers(); - - } - - }; - - } - - void CollectTypeHandlers() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::type] = [this](srcSAXEventContext& ctx) { - - if(declDepth && (declDepth + 2) == ctx.depth) { - - if(!typePolicy) typePolicy = new TypePolicy{this}; - ctx.dispatcher->AddListenerDispatch(typePolicy); - - } - - }; - - } - - void CollectNameHandlers() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - - if(declDepth && (declDepth + 2) == ctx.depth) { - - if(!namePolicy) namePolicy = new NamePolicy{this}; - ctx.dispatcher->AddListenerDispatch(namePolicy); - - } - - }; - - } - - - -void CollectSpecifiersHandlers() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx) { - - if(declDepth && (declDepth + 2) == ctx.depth) { - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - - if(ctx.currentToken == "static") - data.isStatic = true; - - }; - - } - - }; - - closeEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx) { - - if(declDepth && (declDepth + 1) == ctx.depth) { - - NopCloseEvents({ParserState::tokenstring}); - - } - - }; - -} - -}; - -#endif - - -#include <srcSAXEventDispatcher.hpp> -#include <srcSAXHandler.hpp> -#include <exception> -#include <stack> -#include <list> -/* - *Record current function being called - *Record argument names and positions - */ -class CallPolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - /* - {CalledFunction1{arg1, line#}, {arg2, line#}, ..., {argn, line#}, - NestedCalledFunction1{arg1, line#},{arg2, line#}, ..., {argn, line#} - } - */ - public: - struct CallData{ - /**command */ - void clear(){ - fnName.clear(); - callargumentlist.clear(); - } - std::string fnName; - std::list<std::string> callargumentlist; - }; - ~CallPolicy(){} - CallPolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners ){ - InitializeEventHandlers(); - } - /**collaborator */ - void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - - //data.name = policy->Data<NamePolicy::NameData>(); - - } - protected: - /**voidaccessor */ - void * DataInnerDataInner() const override { - return new CallData(data); - } - private: - CallData data; - std::string currentTypeName, currentCallName, currentModifier, currentSpecifier; - /**command collaborator */ - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - closeEventMap[ParserState::call] = [this](srcSAXEventContext& ctx){ - if(ctx.triggerField[ParserState::call] == 1){ //TODO: Fix - data.callargumentlist.push_back(")"); - NotifyAll(ctx); - data.callargumentlist.clear(); - data.fnName.clear(); - }else{ - data.callargumentlist.push_back(")"); - } - }; - - closeEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx){ - if(currentModifier == "*"){} - else if(currentModifier == "&"){} - }; - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx){ - if(ctx.IsOpen(ParserState::name) && ctx.IsGreaterThan(ParserState::call,ParserState::argumentlist) && ctx.IsClosed(ParserState::genericargumentlist)){ - data.fnName = ctx.currentToken; - data.callargumentlist.push_back("("); - data.callargumentlist.push_back(ctx.currentToken); - } - //std::cerr<<ctx.IsOpen(ParserState::name)<<" "<<ctx.IsOpen(ParserState::argument)<<" "<<ctx.IsOpen(ParserState::argumentlist)<<" "<<ctx.IsOpen(ParserState::genericargumentlist)<<std::endl; - if(ctx.And({ParserState::name, ParserState::argument, ParserState::argumentlist}) && ctx.IsEqualTo(ParserState::call,ParserState::argumentlist) && ctx.IsClosed(ParserState::genericargumentlist)){ - data.callargumentlist.push_back(ctx.currentToken); - } - }; - } -}; - -#include <srcSAXEventDispatchUtilities.hpp> - -#include <NamePolicySingleEvent.hpp> -#include <DeclTypePolicySingleEvent.hpp> -#include <FunctionSignaturePolicySingleEvent.hpp> - -#include <string> -#include <vector> - -#ifndef INCLUDED_CLASS_POLICY_SINGLE_EVENT_HPP -#define INCLUDED_CLASS_POLICY_SINGLE_EVENT_HPP - -class ClassPolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - -public: - - enum ClassType : std::size_t { CLASS, STRUCT/*, UNION, ENUM*/ }; - enum AccessSpecifier { PUBLIC = 0, PRIVATE = 1, PROTECTED = 2 }; - struct ParentData { - - // should this be a NamePolicy::NameData? - std::string name; - bool isVirtual; - AccessSpecifier accessSpecifier; - - }; - - struct ClassData { - - ClassType type; - std::string stereotype; - - bool isGeneric; - NamePolicy::NameData * name; - - std::vector<ParentData> parents; - - std::vector<DeclTypePolicy::DeclTypeData *> fields[3]; - std::vector<FunctionSignaturePolicy::FunctionSignatureData *> constructors[3]; - bool hasDestructor; - std::vector<FunctionSignaturePolicy::FunctionSignatureData *> operators[3]; - std::vector<FunctionSignaturePolicy::FunctionSignatureData *> methods[3]; - - std::vector<ClassPolicy::ClassData *> innerClasses[3]; - - bool hasPureVirtual; - - }; - -private: - - ClassData data; - std::size_t classDepth; - AccessSpecifier currentRegion; - - NamePolicy * namePolicy; - DeclTypePolicy * declPolicy; - FunctionSignaturePolicy * functionPolicy; - ClassPolicy * classPolicy; - -public: - - ClassPolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - classDepth(0), - currentRegion(PUBLIC), - namePolicy(nullptr), - declPolicy(nullptr), - functionPolicy(nullptr), - classPolicy(nullptr) { - - InitializeClassPolicyHandlers(); - - } - - ~ClassPolicy() { - - if(namePolicy) delete namePolicy; - if(declPolicy) delete declPolicy; - if(functionPolicy) delete functionPolicy; - if(classPolicy) delete classPolicy; - - } - - void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - - if(typeid(NamePolicy) == typeid(*policy)) { - - data.name = policy->Data<NamePolicy::NameData>(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - - } else if(typeid(DeclTypePolicy) == typeid(*policy)) { - - data.fields[currentRegion].emplace_back(policy->Data<DeclTypePolicy::DeclTypeData>()); - ctx.dispatcher->RemoveListenerDispatchRemoveListenerDispatch(nullptr); - - } else if(typeid(FunctionSignaturePolicy) == typeid(*policy)) { - - FunctionSignaturePolicy::FunctionSignatureData * f_data = policy->Data<FunctionSignaturePolicy::FunctionSignatureData>Data(); - - if(f_data->isPureVirtual) - data.hasPureVirtual = true; - - if(f_data->type == FunctionSignaturePolicy::CONSTRUCTOR) - data.constructors[currentRegion].emplace_back(f_data); - else if(f_data->type == FunctionSignaturePolicy::OPERATOR) - data.operators[currentRegion].emplace_back(f_data); - else - data.methods[currentRegion].emplace_back(f_data); - ctx.dispatcher->RemoveListenerDispatchRemoveListenerDispatch(nullptr); - - } else if(typeid(ClassPolicy) == typeid(*policy)) { - - data.innerClasses[currentRegion].emplace_back(policy->Data<ClassPolicy::ClassData>()); - ctx.dispatcher->RemoveListenerRemoveListener(nullptr); - - } - - } - -protected: - void * DataInner() const override { - - return new ClassData(data); - - } - -private: - - void InitializeClassPolicyHandlers() { - using namespace srcSAXEventDispatch; - - // start of policy - std::function<void(srcSAXEventDispatch::srcSAXEventContext&)> startPolicy = [this](srcSAXEventContext& ctx) { - - if(!classDepth) { - - classDepth = ctx.depth; - - data = ClassData{}; - if(ctx.elementStack.back() == "class") - data.type = CLASS; - else if(ctx.elementStack.back() == "struct") - data.type = STRUCT; - - data.name = nullptr; - - CollectXMLAttributeHandlers(); - CollectNameHandlers(); - CollectGenericHandlers(); - CollectSuperHanders(); - CollectBlockHanders(); - - } else if((classDepth + 3) == ctx.depth) { - - if(!classPolicy) classPolicy = new ClassPolicy{this}; - ctx.dispatcher->AddListenerDispatch(classPolicy); - - } - - }; - - // end of policy - std::function<void(srcSAXEventDispatch::srcSAXEventContext&)> endPolicy = [this](srcSAXEventContext& ctx) { - - if(classDepth && classDepth == ctx.depth) { - - classDepth = 0; - NotifyAll(ctx); - InitializeClassPolicyHandlers(); - - } - - }; - - openEventMap[ParserState::classn] = startPolicy; - closeEventMap[ParserState::classn] = endPolicy; - openEventMap[ParserState::structn] = startPolicy; - closeEventMap[ParserState::structn] = endPolicy; - - } - - void CollectXMLAttributeHandlers() { - using namespace srcSAXEventDispatch; - - closeEventMap[ParserState::xmlattribute] = [this](srcSAXEventContext& ctx) { - - if(classDepth == ctx.depth && ctx.currentAttributeName == "stereotype") { - - data.stereotype = ctx.currentAttributeValue; - - } - - }; - - } - - void CollectNameHandlers() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - - if((classDepth + 1) == ctx.depth) { - - if(!namePolicy) namePolicy = new NamePolicy{this}; - ctx.dispatcher->AddListenerDispatch(namePolicy); - - } - - }; - - closeEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - - if((classDepth + 1) == ctx.depth) { - - NopOpenEvents({ParserState::name}); - NopCloseEvents({ParserState::name}); - - } - - }; - - } - - void CollectGenericHandlers() { - using namespace srcSAXEventDispatch; - - closeEventMap[ParserState::templates] = [this](srcSAXEventContext& ctx) { - - if((classDepth + 1) == ctx.depth) { - - data.isGeneric = true; - - } - - }; - - } - - void CollectSuperHanders() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::super_list] = [this](srcSAXEventContext& ctx) { - - if((classDepth + 1) == ctx.depth) { - - openEventMap[ParserState::super] = [this](srcSAXEventContext& ctx) { - - data.parents.emplace_back(ParentData{ "", false, PUBLIC }); - - }; - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - - if(ctx.And({ ParserState::specifier })) { - - if(ctx.currentToken == "virtual") { - data.parents.back().isVirtual = true; - } else if(ctx.currentToken == "public") { - data.parents.back().accessSpecifier = PUBLIC; - } else if(ctx.currentToken == "private") { - data.parents.back().accessSpecifier = PRIVATE; - } else if(ctx.currentToken == "protected") { - data.parents.back().accessSpecifier = PROTECTED; - } - - } else if(ctx.And({ ParserState::name })) { - - data.parents.back().name += ctx.currentToken; - - } - - - }; - - } - - }; - - closeEventMap[ParserState::super_list] = [this](srcSAXEventContext& ctx) { - - if((classDepth + 1) == ctx.depth) { - - NopOpenEvents({ParserState::super_list, ParserState::super}); - NopCloseEvents({ParserState::super_list, ParserState::tokenstring}); - - } - - }; - - } - - void CollectBlockHanders() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::block] = [this](srcSAXEventContext& ctx) { - - if((classDepth + 1) == ctx.depth) { - - NopOpenEvents({ParserState::name, ParserState::super_list, ParserState::super}); - NopCloseEvents({ParserState::name, ParserState::super_list, ParserState::tokenstring}); - - // set up to listen to decl_stmt, member, and class policies - openEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx) { - - if((classDepth + 3) == ctx.depth) { - - if(!declPolicy) declPolicy = new DeclTypePolicy{this}; - ctx.dispatcher->AddListenerDispatch(declPolicy); - - } - - }; - std::function<void (srcSAXEventContext& ctx)> functionEvent = [this](srcSAXEventContext& ctx) { - - if((classDepth + 3) == ctx.depth) { - - if(!functionPolicy) functionPolicy = new FunctionSignaturePolicy{this}; - ctx.dispatcher->AddListenerDispatch(functionPolicy); - - } - - }; - openEventMap[ParserState::function] = functionEvent; - openEventMap[ParserState::functiondecl] = functionEvent; - openEventMap[ParserState::constructor] = functionEvent; - openEventMap[ParserState::constructordecl] = functionEvent; - - std::function<void (srcSAXEventContext& ctx)> destructorEvent = [this](srcSAXEventContext& ctx) { - - if((classDepth + 3) == ctx.depth) { - - data.hasDestructor = true; - - } - - }; - - openEventMap[ParserState::destructor] = destructorEvent; - openEventMap[ParserState::destructordecl] = destructorEvent; - - } - - }; - - - // should always be in a region once block starts, so should not have to close - openEventMap[ParserState::publicaccess] = [this](srcSAXEventContext& ctx) { - - if((classDepth + 2) == ctx.depth) { - - currentRegion = PUBLIC; - - } - - }; - - openEventMap[ParserState::protectedaccess] = [this](srcSAXEventContext& ctx) { - - if((classDepth + 2) == ctx.depth) { - - currentRegion = PROTECTED; - - } - - }; - - openEventMap[ParserState::privateaccess] = [this](srcSAXEventContext& ctx) { - - if((classDepth + 2) == ctx.depth) { - - currentRegion = PRIVATE; - - } - - }; - - closeEventMap[ParserState::block] = [this](srcSAXEventContext& ctx) { - - if((classDepth + 1) == ctx.depth) { - - NopOpenEvents({ParserState::block, ParserState::function, ParserState::functiondecl, - ParserState::constructor, ParserState::constructordecl, ParserState::destructor, ParserState::destructordecl, - ParserState::declstmt, - ParserState::publicaccess, ParserState::protectedaccess, ParserState::privateaccess}); - NopCloseEvents({ParserState::block}); - - } - - }; - - } - -}; - -#endif - - -#include <srcSAXEventDispatcher.hpp> -#include <srcSAXHandler.hpp> -#include <exception> -#include <set> -#include <vector> -class ExprPolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - public: - struct ExprData{ - ExprData() {} - /**command */ - void clear(){ - def.clear(); - use.clear(); - } - std::string nameofidentifier; - std::set<unsigned int> def; - std::set<unsigned int> use; //could be used multiple times in same expr - }; - std::map<std::string, ExprData> dataset; - ~ExprPolicy(){} - ExprPolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners ){ - seenAssignment = false; - InitializeEventHandlers(); - } - /**collaborator */ - void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override {} //doesn't use other parsers - protected: - /**voidaccessor */ - void * DataInnerDataInner() const override { - return new ExprData(data); - } - private: - ExprData data; - std::string currentTypeName, currentExprName, currentModifier, currentSpecifier; - std::vector<unsigned int> currentLine; - bool seenAssignment; - /**command collaborator */ - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - closeEventMap[ParserState::op] = [this](srcSAXEventContext& ctx){ - if(ctx.currentToken == "="){ - auto it = dataset.find(currentExprName); - if(it != dataset.end()){ - it->second.use.erase(currentLine.back()); - it->second.def.insert(currentLine.back()); - }else{ - std::cerr<<"No such thing as: "<<currentExprName<<std::endl; - } - seenAssignment = true; - //std::cerr<<"Back: "<<currentLine.back()<<std::endl; - } - }; - closeEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx){ - - }; - - closeEventMap[ParserState::name] = [this](srcSAXEventContext& ctx){ - if(currentLine.empty() || currentLine.back() != ctx.currentLineNumber){ - currentLine.push_back(ctx.currentLineNumber); - } - if(ctx.IsOpen({ParserState::exprstmt})){ - auto it = dataset.find(currentExprName); - if(it != dataset.end()){ - it->second.use.insert(currentLine.back()); //assume it's a use - }else{ - data.nameofidentifier = currentExprName; - data.use.insert(currentLine.back()); - dataset.insert(std::make_pair(currentExprName, data)); - } - } - }; - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx){ - //TODO: possibly, this if-statement is suppressing more than just unmarked whitespace. Investigate. - if(!(ctx.currentToken.empty() || ctx.currentToken == " ")){ - if(ctx.IsOpen(ParserState::exprstmt)){ - - } - if(ctx.And({ParserState::name, ParserState::expr, ParserState::exprstmt}) && ctx.Nor({ParserState::specifier, ParserState::modifier, ParserState::op})){ - currentExprName = ctx.currentToken; - } - if(ctx.And({ParserState::specifier, ParserState::expr, ParserState::exprstmt})){ - currentSpecifier = ctx.currentToken; - } - if(ctx.And({ParserState::modifier, ParserState::exprstmt})){ - currentModifier = ctx.currentToken; - } - } - }; - closeEventMap[ParserState::exprstmt] = [this](srcSAXEventContext& ctx){ - NotifyAll(ctx); - for(auto deal : dataset){ - std::cerr<<deal.second.nameofidentifier<<std::endl; - std::cerr<<"def { "; - for(auto num : deal.second.def){ - std::cerr<<num<<","; - } - std::cerr<<"}"<<std::endl; - std::cerr<<"use { "; - for(auto num : deal.second.use){ - std::cerr<<num<<","; - } - std::cerr<<"}"<<std::endl; - } - currentLine.pop_back(); - seenAssignment = false; - currentLine.clear(); - data.clear(); - }; - - } -}; - -/** - * @file test_srcsax_control_handler.cpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <srcSAXController.hpp> -#include <srcSAXHandler.hpp> -#include <cppCallbackAdapter.hpp> - -#include <srcsax.h> - -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <iostream> -#include <string.h> -#include <cassert> - -/** - * read_callback - * @param context the context to read from - * @param buffer the buffer to read into - * @param len the number of bytes to read - * - * FILE read callback for testing io. - * - * @returns the number of bytes read. - */ -int read_callback(void * context, char * buffer, int len) { - - return (int)fread(buffer, 1, len, (FILE *)context); - -} - -/** - * close_callback - * @param context the context to read from - * - * FILE close callback for testing io. - * - * @returns 0 on success EOF otherwise. - */ -int close_callback(void * context) { - - return fclose((FILE *)context); - -} - -/** - * main - * - * Test the srcsax functions. - * - * @returns 0 on success. - */ -int main() { - - /* - srcSAXController - */ - { - try { - - srcSAXController control(__FILE__); - - } catch(... ) { assert(false); } - } - - { - try { - - srcSAXController control(__FILE__, "ISO-8859-1"); - - } catch(... ) { assert(false); } - } - - { - try { - - srcSAXController control(std::string("foobar")); - - } catch(... ) { assert(false); } - } - - { - try { - - srcSAXController control(std::string("foobar"), "ISO-8859-1"); - - } catch(... ) { assert(false); } - } - - { - try { - - srcSAXController control(__FILE__, "ISO-8859-1"); - - } catch(... ) { assert(false); } - } - - { - try { - - FILE * file = fopen(__FILE__, "r"); - srcSAXController control(file); - - } catch(... ) { assert(false); } - } - - { - try { - - FILE * file = fopen(__FILE__, "r"); - srcSAXController control(file, "ISO-8859-1"); - - } catch(... ) { assert(false); } - } - - { - try { - - int fd = open(__FILE__, O_RDONLY); - srcSAXController control(fd); - - } catch(... ) { assert(false); } - } - - { - try { - - int fd = open(__FILE__, O_RDONLY); - srcSAXController control(fd, "ISO-8859-1"); - - } catch(... ) { assert(false); } - } - - { - try { - - FILE * file = fopen(__FILE__, "r"); - srcSAXController control((void *)file, read_callback, close_callback); - - } catch(... ) { assert(false); } - } - - { - try { - - FILE * file = fopen(__FILE__, "r"); - srcSAXController control((void *)file, read_callback, close_callback, "ISO-8859-1"); - - } catch(... ) { assert(false); } - } - - /* - enable_startDocument - */ - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_startDocument(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_startDocument(false); - assert(sax.start_document == 0); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_startDocument(false); - control.enable_startDocument(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - /* - enable_endDocument - */ - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_endDocument(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_endDocument(false); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == 0); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_endDocument(false); - control.enable_endDocument(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - /* - enable_startRoot - */ - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_startRoot(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_startRoot(false); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == 0); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_startRoot(false); - control.enable_startRoot(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - /* - enable_startUnit - */ - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_startUnit(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_startUnit(false); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == 0); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_startUnit(false); - control.enable_startUnit(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - /* - enable_startElement - */ - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_startElement(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_startElement(false); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == 0); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_startElement(false); - control.enable_startElement(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - /* - enable_endRoot - */ - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_endRoot(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_endRoot(false); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == 0); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_endRoot(false); - control.enable_endRoot(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - /* - enable_endUnit - */ - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_endUnit(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_endUnit(false); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == 0); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_endUnit(false); - control.enable_endUnit(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - /* - enable_endElement - */ - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_endElement(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_endElement(false); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == 0); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_endElement(false); - control.enable_endElement(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - /* - enable_charactersRoot - */ - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_charactersRoot(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_charactersRoot(false); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == 0); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_charactersRoot(false); - control.enable_charactersRoot(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - /* - enable_charactersUnit - */ - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_charactersUnit(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_charactersUnit(false); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == 0); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_charactersUnit(false); - control.enable_charactersUnit(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - /* - enable_metaTag - */ - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_metaTag(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_metaTag(false); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == 0); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_metaTag(false); - control.enable_metaTag(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - /* - enable_comment - */ - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_comment(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_comment(false); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == 0); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_comment(false); - control.enable_comment(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - /* - enable_cdataBlock - */ - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_cdataBlock(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_cdataBlock(false); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == 0); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_cdataBlock(false); - control.enable_cdataBlock(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - /* - enable_processingInstruction - */ - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_processingInstruction(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_processingInstruction(false); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == 0); - } - - { - - srcSAXController control(__FILE__); - srcsax_handler sax = cppCallbackAdapter::factory(); - control.getContext()->handler = &sax; - - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - control.enable_processingInstruction(false); - control.enable_processingInstruction(true); - assert(sax.start_document == cppCallbackAdapter::start_document); - assert(sax.end_document == cppCallbackAdapter::end_document); - assert(sax.start_root == cppCallbackAdapter::start_root); - assert(sax.start_unit == cppCallbackAdapter::start_unit); - assert(sax.start_element == cppCallbackAdapter::start_element); - assert(sax.end_root == cppCallbackAdapter::end_root); - assert(sax.end_unit == cppCallbackAdapter::end_unit); - assert(sax.end_element == cppCallbackAdapter::end_element); - assert(sax.characters_root == cppCallbackAdapter::characters_root); - assert(sax.characters_unit == cppCallbackAdapter::characters_unit); - assert(sax.meta_tag == cppCallbackAdapter::meta_tag); - assert(sax.comment == cppCallbackAdapter::comment); - assert(sax.cdata_block == cppCallbackAdapter::cdata_block); - assert(sax.processing_instruction == cppCallbackAdapter::processing_instruction); - } - - /* - parse - */ - - { - - srcSAXController control(std::string("<unit/>")); - srcSAXHandler handler; - try { - control.parse(&handler); - } catch(SAXError error) { assert(false); } - - } - - { - - srcSAXController control(__FILE__); - srcSAXHandler handler; - try { - control.parse(&handler); - assert(false); - } catch(SAXError error) { - assert(error.message != ""); - assert(error.error_code != 0); - } - - } - - return 0; -} - - -#include <srcSAXEventDispatcher.hpp> -#include <srcSAXHandler.hpp> -#include <exception> -#include <vector> -#include <ParamTypePolicy.hpp> -class FunctionSignaturePolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - struct SignatureData{ - SignatureData():isConst{false}, constPointerReturn{false}, isMethod{false}, isStatic{false}, pointerToConstReturn{false}, hasAliasedReturn{false} {} - int linenumber; - std::string returnType; - std::string functionName; - std::string returnTypeModifier; - std::vector<std::string> functionNamespaces; - std::vector<std::string> returnTypeNamespaces; - std::vector<ParamTypePolicy::ParamData> parameters; - bool isConst; - bool isMethod; - bool isStatic; - bool pointerToConstReturn; - bool constPointerReturn; - bool hasAliasedReturn; - /**command */ - void clear(){ - returnType.clear(); - functionName.clear(); - parameters.clear(); - returnTypeModifier.clear(); - isConst = false; - isMethod = false; - isStatic = false; - pointerToConstReturn = false; - constPointerReturn = false; - hasAliasedReturn = false; - } - }; - ~FunctionSignaturePolicy(){} - FunctionSignaturePolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners ){ - currentArgPosition = 1; - parampolicy.AddListener(this); - InitializeEventHandlers(); - } - /**command collaborator */ - void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - paramdata = policy->Data<ParamTypePolicy::ParamData>(); - data.parameters.push_back(*paramdata); - } - protected: - /**voidaccessor */ - void * DataInner() const override { - return new SignatureData(data); - } - private: - bool seenModifier; - ParamTypePolicy parampolicy; - ParamTypePolicy::ParamData* paramdata; - SignatureData data; - size_t currentArgPosition; - std::string currentTypeName, currentDeclName, currentModifier, currentSpecifier; - - /**command collaborator */ - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - openEventMap[ParserState::parameterlist] = [this](srcSAXEventContext& ctx) { - data.linenumber = ctx.currentLineNumber; - ctx.dispatcher->AddListener(&parampolicy); - }; - openEventMap[ParserState::op] = [this](srcSAXEventContext& ctx){ - if(ctx.And({ParserState::type, ParserState::function}) && ctx.Nor({ParserState::parameterlist, ParserState::functionblock, ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist})){ - data.returnTypeNamespaces.push_back(ctx.currentToken); - } - if(ctx.IsOpen(ParserState::function) && ctx.Nor({ParserState::type, ParserState::parameterlist, ParserState::functionblock, ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist})){ - data.functionNamespaces.push_back(ctx.currentToken); - } - }; - openEventMap[ParserState::functionblock] = [this](srcSAXEventContext& ctx){//incomplete. Blocks count too. - if(ctx.IsOpen(ParserState::classn)){ - data.isMethod = true; - } - NotifyAll(ctx); - seenModifier = false; - data.clear(); - }; - closeEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx) { - if(currentModifier == "*") { - if(ctx.And({ParserState::type, ParserState::function}) && ctx.IsClosed(ParserState::parameterlist)){ - seenModifier = true; - data.hasAliasedReturn = true; - } - } - else if(currentModifier == "&") {} - }; - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx){ - if(ctx.And({ParserState::name, ParserState::function}) && ctx.Nor({ParserState::functionblock, ParserState::type, ParserState::parameterlist, ParserState::genericargumentlist})){ - data.functionName = ctx.currentToken; - } - if(ctx.And({ParserState::name, ParserState::type, ParserState::function}) && ctx.Nor({ParserState::functionblock, ParserState::parameterlist, ParserState::genericargumentlist})){ - data.returnType = ctx.currentToken; - } - if(ctx.And({ParserState::modifier, ParserState::type, ParserState::function}) && ctx.Nor({ParserState::parameterlist, ParserState::genericargumentlist})){ - data.returnTypeModifier = ctx.currentToken; - } - if(ctx.And({ParserState::specifier, ParserState::function}) && ctx.Nor({ParserState::parameterlist, ParserState::functionblock, ParserState::genericargumentlist})){ - currentSpecifier = ctx.currentToken; - } - if(ctx.And({ParserState::modifier, ParserState::function}) && ctx.Nor({ParserState::parameterlist, ParserState::functionblock, ParserState::genericargumentlist})){ - currentModifier = ctx.currentToken; - } - }; - closeEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx) { - if(currentSpecifier == "const" && ctx.Nor({ParserState::parameterlist, ParserState::type})){ - data.isConst = true; - } - if(currentSpecifier == "const" && ctx.IsOpen(ParserState::function) && ctx.IsOpen(ParserState::type)){ - if(!seenModifier){ - data.pointerToConstReturn = true; - }else{ - data.constPointerReturn = true; - } - } - if(currentSpecifier == "static" && ctx.Nor({ParserState::parameterlist, ParserState::type})){ - data.isStatic = true; - } - currentSpecifier.clear(); - }; - closeEventMap[ParserState::parameterlist] = [this](srcSAXEventContext& ctx) { - ctx.dispatcher->RemoveListener(&parampolicy); - }; - } - -}; - -#include <srcSAXEventDispatcher.hpp> -#include <srcSAXHandler.hpp> -#include <exception> - -class ParamTypePolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - struct ParamData{ - ParamData(): linenumber{0}, isConst{false}, isConstAlias{false}, isAliasToConst{false}, isReference{false}, isPointer{false}, isStatic{false} {} - /**command */ - void clear(){ - nameoftype.clear(); - nameofidentifier.clear(); - namespaces.clear(); - linenumber = -1; - isConst = false; - isReference = false; - isPointer = false; - isStatic = false; - } - std::string nameoftype; - std::string nameofidentifier; - std::vector<std::string> namespaces; - int linenumber; - bool isConst; - bool isConstAlias; - bool isAliasToConst; - bool isReference; - bool isPointer; - bool isStatic; - }; - ParamTypePolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners ){ - InitializeEventHandlers(); - } - /**collaborator */ - void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - - //data.name = policy->Data<NamePolicy::NameData>(); - - } - protected: - /**voidaccessor */ - void * DataInnerDataInner() const override { - return new ParamData(data); - } - private: - ParamData data; - std::string currentTypeName, currentDeclName, currentModifier, currentSpecifier; - - /**command collaborator */ - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - openEventMap[ParserState::op] = [this](srcSAXEventContext& ctx){ - if(ctx.And({ParserState::type, ParserState::parameter}) && ctx.Nor({ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist})){ - data.namespaces.push_back(ctx.currentToken); - } - }; - closeEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx){ - if(ctx.IsOpen(ParserState::parameter)){ - if(currentModifier == "*"){ - data.isPointer = true; - } - else if(currentModifier == "&"){ - data.isReference = true; - } - } - }; - - closeEventMap[ParserState::decl] = [this](srcSAXEventContext& ctx){ - if(ctx.And({ParserState::parameter})){ - data.linenumber = ctx.currentLineNumber; - data.nameofidentifier = currentDeclName; - } - }; - - closeEventMap[ParserState::type] = [this](srcSAXEventContext& ctx){ - if(ctx.And({ParserState::parameter})){ - data.nameoftype = currentTypeName; - } - }; - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx){ - //TODO: possibly, this if-statement is suppressing more than just unmarked whitespace. Investigate. - if(!(ctx.currentToken.empty() || ctx.currentToken[0] == ' ')){ - if(ctx.And({ParserState::name, ParserState::type, ParserState::decl, ParserState::parameter}) && ctx.Nor({ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist})){ - currentTypeName = ctx.currentToken; - } - if(ctx.And({ParserState::name, ParserState::decl, ParserState::parameter}) && - ctx.Nor({ParserState::type, ParserState::index/*skip array portion*/, ParserState::argumentlist/*skip init list portion*/, - ParserState::init, ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist})){ - currentDeclName = ctx.currentToken; - } - if(ctx.And({ParserState::specifier, ParserState::decl, ParserState::parameter})){ - currentSpecifier = ctx.currentToken; - } - if(ctx.And({ParserState::modifier, ParserState::type, ParserState::parameter})){ - currentModifier = ctx.currentToken; - } - } - }; - closeEventMap[ParserState::parameter] = [this](srcSAXEventContext& ctx){ - NotifyAll(ctx); - data.clear(); - }; - closeEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx){ - if(ctx.IsOpen(ParserState::parameter)){ - if(currentSpecifier == "static"){ - data.isStatic = true; - } - if(currentSpecifier == "const"){ - data.isConst = true; - } - } - currentSpecifier.clear(); - }; - - } -}; - -#include <srcSAXEventDispatchUtilities.hpp> - -#include <TypePolicySingleEvent.hpp> -#include <TemplateArgumentPolicySingleEvent.hpp> - -#include <string> -#include <vector> -#include <iostream> - -#ifndef INCLUDED_NAME_POLICY_SINGLE_EVENT_HPP -#define INCLUDED_NAME_POLICY_SINGLE_EVENT_HPP - -class NamePolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - -public: - - struct NameData { - - std::string name; - std::vector<NameData *> names; - std::vector<TemplateArgumentPolicy::TemplateArgumentData *> templateArguments; - std::vector<std::string> arrayIndices; - - /**get */ - std::string SimpleName() const { - - if(!name.empty()) - return name; - - return names.back()->SimpleName(); - - } - - /**property collaborator */ - std::string ToString() const { - - std::string str = name; - - for(std::size_t pos = 0; pos < names.size(); ++pos) { - - if(pos != 0) - str += ' '; - str += names[pos]->ToString(); - - } - - return str; - - } - - friend /**collaborator */ -friend std::ostream & operator<<(std::ostream & out, const NameData & nameData) { - - if(!nameData.name.empty()) { - out << nameData.name; - } - - for(size_t pos = 0; pos < nameData.names.size(); ++pos) { - - if(pos != 0) out << "::"; - out << (*nameData.names[pos]); - - } - - if(!nameData.templateArguments.empty()) { - out << '<'; - for(const TemplateArgumentPolicy::TemplateArgumentData * arg : nameData.templateArguments) { - out << *arg; - } - out << '>'; - } - - for(const std::string & index : nameData.arrayIndices) { - out << '[' << index << ']'; - } - - return out; - - - } - - }; - -private: - - NameData data; - std::size_t nameDepth; - - NamePolicy * namePolicy; - TemplateArgumentPolicy * templateArgumentPolicy; - -public: - - - NamePolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - nameDepth(0), - namePolicy(nullptr), - templateArgumentPolicy(nullptr) { - - InitializeNamePolicyHandlers(); - - } - - ~NamePolicy() { - - if(namePolicy) delete namePolicy; - if(templateArgumentPolicy) delete templateArgumentPolicy; - - } - -protected: - void * DataInner() const override { - - return new NameData(data); - - } - virtual void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - - if(typeid(NamePolicy) == typeid(*policy)) { - - data.names.push_back(policy->Data<NameData>()); - ctx.dispatcher->RemoveListener(nullptr); - - } else if(typeid(TemplateArgumentPolicy) == typeid(*policy)) { - - data.templateArguments.push_back(policy->Data<TemplateArgumentPolicy::TemplateArgumentData>()); - ctx.dispatcher->RemoveListener(nullptr); - - } - - } - -private: - - void InitializeNamePolicyHandlers() { - using namespace srcSAXEventDispatch; - - // start of policy - openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - - if(!nameDepth) { - - nameDepth = ctx.depth; - data = NameData{}; - - CollectTemplateArgumentsHandlers(); - CollectArrayIndicesHandlers(); - - } else if((nameDepth + 1) == ctx.depth) { - - NopCloseEvents({ParserState::tokenstring}); - if(!namePolicy) namePolicy = new NamePolicy{this}; - ctx.dispatcher->AddListenerDispatch(namePolicy); - - } - - }; - - // end of policy - closeEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - - if(nameDepth && nameDepth == ctx.depth) { - - nameDepth = 0; - - NotifyAll(ctx); - InitializeNamePolicyHandlers(); - - } - - }; - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - - if(nameDepth && nameDepth == ctx.depth) { - - data.name += ctx.currentToken; - - } - - }; - - } - - void CollectTemplateArgumentsHandlers() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::genericargumentlist] = [this](srcSAXEventContext& ctx) { - - if(nameDepth && (nameDepth + 1) == ctx.depth) { - - openEventMap[ParserState::argument] = [this](srcSAXEventContext& ctx) { - - if(nameDepth && (nameDepth + 2) == ctx.depth) { - - if(!templateArgumentPolicy) templateArgumentPolicy = new TemplateArgumentPolicy{this}; - ctx.dispatcher->AddListenerDispatch(templateArgumentPolicy); - - } - - }; - - } - - }; - - closeEventMap[ParserState::genericargumentlist] = [this](srcSAXEventContext& ctx) { - - if(nameDepth && (nameDepth + 1) == ctx.depth) { - - NopOpenEvents({ParserState::argument}); - - } - - }; - - } - - void CollectArrayIndicesHandlers() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::index] = [this](srcSAXEventContext& ctx) { - - if(nameDepth && (nameDepth + 1) == ctx.depth) { - - data.arrayIndices.push_back(std::string()); - - } - - }; - - closeEventMap[ParserState::index] = [this](srcSAXEventContext& ctx) { - - if(nameDepth && (nameDepth + 1) == ctx.depth) { - - NopOpenEvents({ParserState::expr}); - NopCloseEvents({ParserState::expr}); - - } - - }; - - openEventMap[ParserState::expr] = [this](srcSAXEventContext& ctx) { - - size_t num_elements = ctx.elementStack.size(); - if(nameDepth && (nameDepth + 2) == ctx.depth && num_elements > 1 && ctx.elementStack[num_elements - 2] == "index") { - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { data.arrayIndices.back() += ctx.currentToken; }; - - } - - }; - - closeEventMap[ParserState::expr] = [this](srcSAXEventContext& ctx) { - - size_t num_elements = ctx.elementStack.size(); - if(nameDepth && (nameDepth + 2) == ctx.depth && num_elements > 0 && ctx.elementStack.back() == "index") { - - NopCloseEvents({ParserState::tokenstring}); - - } - - }; - - } - -}; - -#endif - - -#include <srcSAXEventDispatcher.hpp> -#include <srcSAXHandler.hpp> -#include <exception> - -class SourceNLPolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - public: - struct SourceNLData{ - SourceNLData(){} - /**command */ - void clear(){ - category.clear(); - identifiername.clear(); - } - std::string category; - std::string identifiername; - }; - SourceNLData data; - ~SourceNLPolicy(){} - SourceNLPolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners ){ - InitializeEventHandlers(); - } - /**collaborator */ - void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override {} //doesn't use other parsers - protected: - /**voidaccessor */ - void * DataInnerDataInner() const override { - return new SourceNLData(data); - } - private: - std::string currentTypeName, currentDeclName, currentModifier, currentSpecifier; - /**command collaborator */ - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - closeEventMap[ParserState::snoun] = [this](srcSAXEventContext& ctx){ - //std::cerr<<ctx.currentTag<<" "<<data.identifiername<<std::endl; - data.category = "snoun"; - NotifyAll(ctx); - data.identifiername.clear(); - }; - - closeEventMap[ParserState::propersnoun] = [this](srcSAXEventContext& ctx){ - //std::cerr<<ctx.currentTag<<" "<<data.identifiername<<std::endl; - data.category = "propersnoun"; - NotifyAll(ctx); - data.identifiername.clear(); - }; - - closeEventMap[ParserState::spronoun] = [this](srcSAXEventContext& ctx){ - //std::cerr<<ctx.currentTag<<" "<<data.identifiername<<std::endl; - data.category = "spronoun"; - NotifyAll(ctx); - data.identifiername.clear(); - }; - - closeEventMap[ParserState::sadjective] = [this](srcSAXEventContext& ctx){ - //std::cerr<<ctx.currentTag<<" "<<data.identifiername<<std::endl; - data.category = "sadjective"; - NotifyAll(ctx); - data.identifiername.clear(); - }; - - closeEventMap[ParserState::sverb] = [this](srcSAXEventContext& ctx){ - //std::cerr<<ctx.currentTag<<" "<<data.identifiername<<std::endl; - data.category = "sverb"; - NotifyAll(ctx); - data.identifiername.clear(); - }; - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx){ - //TODO: possibly, this if-statement is suppressing more than just unmarked whitespace. Investigate. - if(ctx.Or({ParserState::snoun, ParserState::spronoun, ParserState::propersnoun, ParserState::sverb, ParserState::sadjective})){ - data.identifiername.append(ctx.currentToken); - } - }; - closeEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx){ - //NotifyAll(ctx); - data.clear(); - }; - - } -}; - -#include <srcSAXEventDispatchUtilities.hpp> - -#include <TypePolicySingleEvent.hpp> -#include <NamePolicySingleEvent.hpp> - -#include <string> -#include <vector> - -#ifndef INCLUDED_PARAM_TYPE_POLICY_SINGLE_EVENT_HPP -#define INCLUDED_PARAM_TYPE_POLICY_SINGLE_EVENT_HPP - -class ParamTypePolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - -public: - - struct ParamTypeData { - - TypePolicy::TypeData * type; - NamePolicy::NameData * name; - - friend /**collaborator */ -friend std::ostream & operator<<(std::ostream & out, const ParamTypeData & paramData) { - - out << *paramData.type; - - if(paramData.name) - out << ' ' << *paramData.name; - - return out; - - } - - }; - -private: - - - ParamTypeData data; - std::size_t paramDepth; - - TypePolicy * typePolicy; - NamePolicy * namePolicy; - -public: - - ParamTypePolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - paramDepth(0), - typePolicy(nullptr), - namePolicy(nullptr) { - - InitializeParamTypePolicyHandlers(); - - } - - ~ParamTypePolicy() { - - if(typePolicy) delete typePolicy; - if(namePolicy) delete namePolicy; - - } - -protected: - void * DataInner() const override { - - return new ParamTypeData(data); - - } - virtual void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - - if(typeid(TypePolicy) == typeid(*policy)) { - - data.type = policy->Data<TypePolicy::TypeData>(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - - } else if(typeid(NamePolicy) == typeid(*policy)) { - - data.name = policy->Data<NamePolicy::NameData>(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - - } - - } - -private: - - void InitializeParamTypePolicyHandlers() { - using namespace srcSAXEventDispatch; - - // start of policy - openEventMap[ParserState::parameter] = [this](srcSAXEventContext& ctx) { - - if(!paramDepth) { - - paramDepth = ctx.depth; - data = ParamTypeData{}; - - CollectTypeHandlers(); - CollectNameHandlers(); - - } - - }; - - // end of policy - closeEventMap[ParserState::parameter] = [this](srcSAXEventContext& ctx) { - - if(paramDepth && paramDepth == ctx.depth) { - - paramDepth = 0; - - NotifyAll(ctx); - InitializeParamTypePolicyHandlers(); - - } - - }; - - } - - void CollectTypeHandlers() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::type] = [this](srcSAXEventContext& ctx) { - - if(paramDepth && (paramDepth + 2) == ctx.depth) { - - if(!typePolicy) typePolicy = new TypePolicy{this}; - ctx.dispatcher->AddListenerDispatch(typePolicy); - - } - - }; - - } - - void CollectNameHandlers() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - - if(paramDepth && (paramDepth + 2) == ctx.depth) { - - if(!namePolicy) namePolicy = new NamePolicy{this}; - ctx.dispatcher->AddListenerDispatch(namePolicy); - - } - - }; - - } - -}; - -#endif - - -#include <srcSAXEventDispatchUtilities.hpp> - -#include <exception> - -#ifndef INCLUDED_TEMPLATE_ARGUMENT_POLICY_SINGLE_EVENT_HPP -#define INCLUDED_TEMPLATE_ARGUMENT_POLICY_SINGLE_EVENT_HPP - -class NamePolicy; -class TemplateArgumentPolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - -public: - enum TemplateArgumentType { NAME, LITERAL, MODIFIER, POINTER, REFERENCE, RVALUE, OPERATOR, CALL }; - - struct TemplateArgumentData { - std::vector<std::pair<void *, TemplateArgumentType>> data; - - friend std::ostream & operator<<(std::ostream & out, const TemplateArgumentData & argumentData); - - }; - private: - TemplateArgumentData data; - std::size_t argumentDepth; - NamePolicy * namePolicy; - - public: - TemplateArgumentPolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners); - ~TemplateArgumentPolicy(); - virtual void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override; - protected: - virtual void * DataInnerDataInner() const override; - private: - void InitializeTemplateArgumentPolicyHandlers(); - - void CollectNamesHandler(); - void CollectOthersHandler(); - -}; - -#endif - - -#include <srcSAXEventDispatchUtilities.hpp> - -#include <TypePolicySingleEvent.hpp> -#include <NamePolicySingleEvent.hpp> -#include <ParamTypePolicySingleEvent.hpp> - -#include <string> -#include <vector> - -#ifndef INCLUDED_FUNCTION_SIGNATURE_POLICY_SINGE_EVENT_HPP -#define INCLUDED_FUNCTION_SIGNATURE_POLICY_SINGE_EVENT_HPP - -class FunctionSignaturePolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - -public: - - enum FunctionSignatureType { CONSTRUCTOR, DESTURCTOR, OPERATOR, FUNCTION }; - - struct FunctionSignatureData { - - FunctionSignatureType type; - std::string stereotype; - - TypePolicy::TypeData * returnType; - NamePolicy::NameData * name; - - std::vector<ParamTypePolicy::ParamTypeData *> parameters; - - bool isVirtual; - bool isPureVirtual; - bool isConst; - bool isStatic; - bool isInline; - bool isFinal; - bool isOverride; - bool isConstExpr; - bool isDelete; - - /**property collaborator */ - std::string ToString() const { - - std::string signature = name->ToString(); - signature += '('; - for(std::size_t pos = 0; pos < parameters.size(); ++pos) { - if(pos > 0) - signature += ", "; - signature += parameters[pos]->type->ToString(); - } - signature += ')'; - if(isConst) - signature += " const"; - - return signature; - - } - - friend /**collaborator */ -friend std::ostream & operator<<(std::ostream & out, const FunctionSignatureData & functionData) { - - out << *functionData.returnType << ' ' << *functionData.name; - - out << '('; - - for(std::size_t pos = 0; pos < functionData.parameters.size(); ++pos) { - - if(pos != 0) - out << ", "; - - out << *functionData.parameters[pos]; - - } - - out << ')'; - - return out; - - } - - }; - -private: - - FunctionSignatureData data; - std::size_t functionDepth; - - TypePolicy * typePolicy; - NamePolicy * namePolicy; - ParamTypePolicy * paramPolicy; - -public: - - FunctionSignaturePolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - functionDepth(0), - typePolicy(nullptr), - namePolicy(nullptr), - paramPolicy(nullptr) { - - InitializeFunctionSignaturePolicyHandlers(); - - } - - ~FunctionSignaturePolicy() { - - if(typePolicy) delete typePolicy; - if(namePolicy) delete namePolicy; - if(paramPolicy) delete paramPolicy; - - } - -protected: - void * DataInner() const override { - - return new FunctionSignatureData(data); - - } - virtual void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - - if(typeid(TypePolicy) == typeid(*policy)) { - - data.returnType = policy->Data<TypePolicy::TypeData>(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - - } else if(typeid(NamePolicy) == typeid(*policy)) { - - data.name = policy->Data<NamePolicy::NameData>(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - - } else if(typeid(ParamTypePolicy) == typeid(*policy)) { - - data.parameters.push_back(policy->Data<ParamTypePolicy::ParamTypeData>()); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - - } - - } - -private: - - void InitializeFunctionSignaturePolicyHandlers() { - using namespace srcSAXEventDispatch; - - // start of policy - std::function<void (srcSAXEventContext& ctx)> functionStart = [this](srcSAXEventContext& ctx) { - - if(!functionDepth) { - - functionDepth = ctx.depth; - data = FunctionSignatureData{}; - - if(ctx.elementStack.back() == "function" || ctx.elementStack.back() == "function_decl") { - - if(ctx.isOperator) - data.type = OPERATOR; - else - data.type = FUNCTION; - - } else if(ctx.elementStack.back() == "constructor" || ctx.elementStack.back() == "constructor_decl") { - data.type = CONSTRUCTOR; - } else if(ctx.elementStack.back() == "destructor" || ctx.elementStack.back() == "destructor_decl") { - data.type = DESTURCTOR; - } - - CollectXMLAttributeHandlers(); - CollectTypeHandlers(); - CollectNameHandlers(); - CollectParameterHandlers(); - CollectOtherHandlers(); - - } - - }; - - // end of policy - std::function<void (srcSAXEventContext& ctx)> functionEnd = [this](srcSAXEventContext& ctx) { - - if(functionDepth && functionDepth == ctx.depth) { - - functionDepth = 0; - - NotifyAll(ctx); - InitializeFunctionSignaturePolicyHandlers(); - - } - - }; - - openEventMap[ParserState::function] = functionStart; - openEventMap[ParserState::functiondecl] = functionStart; - openEventMap[ParserState::constructor] = functionStart; - openEventMap[ParserState::constructordecl] = functionStart; - openEventMap[ParserState::destructor] = functionStart; - openEventMap[ParserState::destructordecl] = functionStart; - - closeEventMap[ParserState::functiondecl] = functionEnd; - closeEventMap[ParserState::constructordecl] = functionEnd; - closeEventMap[ParserState::destructordecl] = functionEnd; - - openEventMap[ParserState::functionblock] = [this](srcSAXEventContext& ctx) { - - if(functionDepth && (functionDepth + 1) == ctx.depth) { - - functionDepth = 0; - - NotifyAll(ctx); - InitializeFunctionSignaturePolicyHandlers(); - - } - - }; - - } - - void CollectXMLAttributeHandlers() { - using namespace srcSAXEventDispatch; - - closeEventMap[ParserState::xmlattribute] = [this](srcSAXEventContext& ctx) { - - if(functionDepth == ctx.depth && ctx.currentAttributeName == "stereotype") { - - data.stereotype = ctx.currentAttributeValue; - - } - - }; - - } - - void CollectTypeHandlers() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::type] = [this](srcSAXEventContext& ctx) { - - if(functionDepth && (functionDepth + 1) == ctx.depth) { - - if(!typePolicy) typePolicy = new TypePolicy{this}; - ctx.dispatcher->AddListenerDispatch(typePolicy); - - } - - }; - - } - - void CollectNameHandlers() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - - if(functionDepth && (functionDepth + 1) == ctx.depth) { - - if(!namePolicy) namePolicy = new NamePolicy{this}; - ctx.dispatcher->AddListenerDispatch(namePolicy); - - } - - }; - - } - - - void CollectParameterHandlers() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::parameterlist] = [this](srcSAXEventContext& ctx) { - - if(functionDepth && (functionDepth + 1) == ctx.depth) { - - openEventMap[ParserState::parameter] = [this](srcSAXEventContext& ctx) { - - if(functionDepth && (functionDepth + 2) == ctx.depth) { - - if(!paramPolicy) paramPolicy = new ParamTypePolicy{this}; - ctx.dispatcher->AddListenerDispatch(paramPolicy); - - } - - }; - - } - - }; - - closeEventMap[ParserState::parameterlist] = [this](srcSAXEventContext& ctx) { - - if(functionDepth && (functionDepth + 1) == ctx.depth) { - - NopOpenEvents({ParserState::parameter}); - - } - - }; - - } - - - void CollectOtherHandlers() { - using namespace srcSAXEventDispatch; - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - - if(functionDepth && (functionDepth + 1) == ctx.depth) { - - if(ctx.And({ParserState::specifier})) { - - if(ctx.currentToken == "virtual") - data.isVirtual = true; - else if(ctx.currentToken == "static") - data.isStatic = true; - else if(ctx.currentToken == "const") - data.isConst = true; - else if(ctx.currentToken == "final") - data.isFinal = true; - else if(ctx.currentToken == "override") - data.isOverride = true; - else if(ctx.currentToken == "delete") - data.isDelete = true; - else if(ctx.currentToken == "inline") - data.isInline = true; - else if(ctx.currentToken == "constexpr") - data.isConstExpr = true; - - } else if(ctx.And({ParserState::literal})) { - - data.isPureVirtual = true; - - } - - } - - }; - - } - -}; - -#endif - - -#include <srcSAXEventDispatchUtilities.hpp> - -#include <exception> - -#ifndef INCLUDED_TYPE_POLICY_SINGLE_EVENT_HPP -#define INCLUDED_TYPE_POLICY_SINGLE_EVENT_HPP - -class NamePolicy; -class TypePolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - -public: - enum TypeType { NAME, POINTER, REFERENCE, RVALUE, SPECIFIER, NONE }; - - struct TypeData { - std::vector<std::pair<void *, TypeType>> types; - - std::string ToString() const; - friend std::ostream & operator<<(std::ostream & out, const TypeData & typeData); - - }; - private: - TypeData data; - std::size_t typeDepth; - - NamePolicy * namePolicy; - - public: - TypePolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners); - ~TypePolicy(); - virtual void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override; - protected: - virtual void * DataInnerDataInner() const override; - private: - void InitializeTypePolicyHandlers(); - - void CollectNamesHandler(); - void CollectModifersHandler(); - void CollectSpecifiersHandler(); - -}; - -#endif - - -#include <TypePolicySingleEvent.hpp> - -#include <NamePolicySingleEvent.hpp> - -/**property collaborator */ -std::string TypePolicy::TypeData::ToString() const { - - std::string type_str; - - for(std::size_t pos = 0; pos < types.size(); ++pos) { - - if(pos != 0) type_str += ' '; - - const std::pair<void *, TypePolicy::TypeType> & type = types[pos]; - - if(type.second == TypePolicy::POINTER) - type_str += '*'; - else if(type.second == TypePolicy::REFERENCE) - type_str += '&'; - else if(type.second == TypePolicy::RVALUE) - type_str += "&&"; - else if(type.second == TypePolicy::SPECIFIER) - type_str += *static_cast<std::string *>(type.first); - else if(type.second == TypePolicy::NAME) - type_str += static_cast<NamePolicy::NameData *>(type.first)->ToString(); - - } - - return type_str; - - -} - -std::ostream & operator<<(std::ostream & out, const TypePolicy::TypeData & typeData) { - - for(std::size_t pos = 0; pos < typeData.types.size(); ++pos) { - - if(pos != 0) out << ' '; - - const std::pair<void *, TypePolicy::TypeType> & type = typeData.types[pos]; - - if(type.second == TypePolicy::POINTER) - out << '*'; - else if(type.second == TypePolicy::REFERENCE) - out << '&'; - else if(type.second == TypePolicy::RVALUE) - out << "&&"; - else if(type.second == TypePolicy::SPECIFIER) - out << *static_cast<std::string *>(type.first); - else if(type.second == TypePolicy::NAME) - out << *static_cast<NamePolicy::NameData *>(type.first); - - } - - return out; - -} - -TypePolicy::TypePolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - typeDepth(0), - namePolicy(nullptr) { - - InitializeTypePolicyHandlers(); - -} - -TypePolicy::~TypePolicy(){ - - if(namePolicy) delete namePolicy; - -} - -/**command collaborator */ -void TypePolicy::Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) { - - data.types.back().first = policy->Data<NamePolicy::NameData>Data(); - ctx.dispatcher->RemoveListenerDispatchRemoveListenerDispatch(nullptr); - -} - -/**voidaccessor */ -void * TypePolicy::DataInner() const { - return new TypePolicy::TypeData(data); -} - -/**command collaborator */ -void TypePolicy::InitializeTypePolicyHandlers() { - using namespace srcSAXEventDispatch; - - // start of policy - openEventMap[ParserState::type] = [this](srcSAXEventContext& ctx) { - - if(!typeDepth) { - - typeDepth = ctx.depth; - data = TypePolicy::TypeData{}; - - CollectNamesHandler(); - CollectModifersHandler(); - CollectSpecifiersHandler(); - - } - - }; - - // end of policy - closeEventMap[ParserState::type] = [this](srcSAXEventContext& ctx) { - - if(typeDepth && typeDepth == ctx.depth) { - - typeDepth = 0; - - NotifyAll(ctx); - InitializeTypePolicyHandlers(); - - } - - }; - -} - -/**command collaborator */ -void TypePolicy::CollectNamesHandler() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - - if(typeDepth && (typeDepth + 1) == ctx.depth) { - - data.types.push_back(std::make_pair(nullptr, TypePolicy::NAME)); - if(!namePolicy) namePolicy = new NamePolicy{this}; - ctx.dispatcher->AddListenerDispatch(namePolicy); - - } - - }; - -} - -/**command collaborator */ -void TypePolicy::CollectModifersHandler() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx) { - - if(typeDepth && (typeDepth + 1) == ctx.depth) { - - data.types.push_back(std::make_pair(nullptr, NONE)); - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - - if(ctx.currentToken == "*") - data.types.back().second = TypePolicy::POINTER; - else if(ctx.currentToken == "&") - data.types.back().second = TypePolicy::REFERENCE; - else if(ctx.currentToken == "&&") - data.types.back().second = TypePolicy::RVALUE; - - }; - - } - - }; - - closeEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx) { - - if(typeDepth && (typeDepth + 1) == ctx.depth) { - - NopCloseEvents({ParserState::tokenstring}); - - } - - }; - -} - -/**command collaborator */ -void TypePolicy::CollectSpecifiersHandler() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx) { - - if(typeDepth && (typeDepth + 1) == ctx.depth) { - - data.types.push_back(std::make_pair(new std::string(), TypePolicy::SPECIFIER)); - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - - (*static_cast<std::string *>(data.types.back().first)) += ctx.currentToken; - - }; - - } - - }; - - closeEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx) { - - if(typeDepth && (typeDepth + 1) == ctx.depth) { - - NopCloseEvents({ParserState::tokenstring}); - - } - - }; - -} - - -#include <srcSAXEventDispatcher.hpp> -namespace srcSAXEventDispatch{ - -} - - -#include <srcSAXEventDispatcher.hpp> -#include <srcSAXHandler.hpp> -#include <exception> - -class srcSlicePolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - public: - struct DeclTypeData{ - DeclTypeData(): linenumber{0}, isConst{false}, isReference{false}, isPointer{false}, isStatic{false} {} - /**command */ - void clear(){ - nameoftype.clear(); - nameofidentifier.clear(); - namespaces.clear(); - linenumber = -1; - isConst = false; - isReference = false; - isPointer = false; - isStatic = false; - } - std::string nameoftype; - std::string nameofidentifier; - std::vector<std::string> namespaces; - int linenumber; - bool isConst; - bool isReference; - bool isPointer; - bool isStatic; - }; - DeclTypeData data; - ~srcSlicePolicy(){} - srcSlicePolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners ){ - InitializeEventHandlers(); - } - /**collaborator */ - void NotifyNotify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override {} //doesn't use other parsers - protected: - /**voidaccessor */ - void * DataInnerDataInner() const override { - return new DeclTypeData(data); - } - private: - std::string currentTypeName, currentDeclName, currentModifier, currentSpecifier; - /**command collaborator */ - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - openEventMap[ParserState::op] = [this](srcSAXEventContext& ctx){ - if(ctx.And({ParserState::type, ParserState::declstmt}) && ctx.Nor({ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist})){ - data.namespaces.push_back(ctx.currentToken); - } - }; - closeEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx){ - if(ctx.IsOpen(ParserState::declstmt)){ - if(currentModifier == "*"){ - data.isPointer = true; - } - if(currentModifier == "&"){ - data.isReference = true; - } - } - }; - - closeEventMap[ParserState::decl] = [this](srcSAXEventContext& ctx){ - if(ctx.And({ParserState::declstmt})){ - data.linenumber = ctx.currentLineNumber; - data.nameofidentifier = currentDeclName; - } - }; - - closeEventMap[ParserState::type] = [this](srcSAXEventContext& ctx){ - if(ctx.And({ParserState::declstmt})){ - data.nameoftype = currentTypeName; - } - }; - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx){ - //TODO: possibly, this if-statement is suppressing more than just unmarked whitespace. Investigate. - if(!(ctx.currentToken.empty() || ctx.currentToken[0] == ' ')){ - if(ctx.And({ParserState::name, ParserState::type, ParserState::decl, ParserState::declstmt}) && ctx.Nor({ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist})){ - currentTypeName = ctx.currentToken; - } - if(ctx.And({ParserState::name, ParserState::decl, ParserState::declstmt}) && - ctx.Nor({ParserState::type, ParserState::index/*skip array portion*/, ParserState::argumentlist/*skip init list portion*/, ParserState::init, ParserState::specifier, ParserState::modifier})){ - currentDeclName = ctx.currentToken; - } - if(ctx.And({ParserState::specifier, ParserState::decl, ParserState::declstmt})){ - currentSpecifier = ctx.currentToken; - } - if(ctx.And({ParserState::modifier, ParserState::type, ParserState::declstmt})){ - currentModifier = ctx.currentToken; - } - } - }; - closeEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx){ - NotifyAll(ctx); - data.clear(); - }; - closeEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx){ - if(ctx.IsOpen(ParserState::declstmt)){ - if(currentSpecifier == "const"){ - data.isConst = true; - } - if(currentSpecifier == "static"){ - data.isStatic = true; - } - } - currentSpecifier.clear(); - }; - - } -}; - -#include <TemplateArgumentPolicySingleEvent.hpp> - -#include <NamePolicySingleEvent.hpp> - -std::ostream & operator<<(std::ostream & out, const TemplateArgumentPolicy::TemplateArgumentData & argumentData) { - - for(std::size_t pos = 0; pos < argumentData.data.size(); ++pos) { - - if(pos != 0) - out << ' '; - - const std::pair<void *, TemplateArgumentPolicy::TemplateArgumentType> & element = argumentData.data[pos]; - if(element.second == TemplateArgumentPolicy::NAME) - out << *static_cast<NamePolicy::NameData *>(element.first); - else if(element.second == TemplateArgumentPolicy::POINTER) - out << '*'; - else if(element.second == TemplateArgumentPolicy::REFERENCE) - out << '&'; - else if(element.second == TemplateArgumentPolicy::RVALUE) - out << "&&"; - else - out << *static_cast<std::string *>(element.first); - - } - - return out; - -} - -TemplateArgumentPolicy::TemplateArgumentPolicy(std::initializer_list<srcSAXEventDispatch::PolicyListener *> listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - argumentDepth(0), - namePolicy(nullptr) { - - InitializeTemplateArgumentPolicyHandlers(); - -} - -TemplateArgumentPolicy::~TemplateArgumentPolicy() { - - if(namePolicy) delete namePolicy; - -} - -/**command collaborator */ -void TemplateArgumentPolicy::Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) { - - data.data.back().first = policy->Data<NamePolicy::NameData>Data(); - ctx.dispatcher->RemoveListenerDispatchRemoveListenerDispatch(nullptr); - -} - -/**voidaccessor */ -void * TemplateArgumentPolicy::DataInner() const { - return new TemplateArgumentPolicy::TemplateArgumentData(data); -} - -/**command collaborator */ -void TemplateArgumentPolicy::InitializeTemplateArgumentPolicyHandlers() { - using namespace srcSAXEventDispatch; - - // start of policy - openEventMap[ParserState::argument] = [this](srcSAXEventContext& ctx) { - - if(!argumentDepth) { - - argumentDepth = ctx.depth; - data = TemplateArgumentPolicy::TemplateArgumentData{}; - - CollectNamesHandler(); - CollectOthersHandler(); - - } - - }; - - // end of policy - closeEventMap[ParserState::argument] = [this](srcSAXEventContext& ctx) { - - if(argumentDepth && argumentDepth == ctx.depth) { - - argumentDepth = 0; - - NotifyAll(ctx); - InitializeTemplateArgumentPolicyHandlers(); - - } - - }; - -} - -/**command collaborator */ -void TemplateArgumentPolicy::CollectNamesHandler() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - - // C++ has depth of 2 others 1 - std::size_t elementStackSize = ctx.elementStack.size(); - if( argumentDepth && (((argumentDepth + 2) == ctx.depth && elementStackSize > 1 && ctx.elementStack[elementStackSize - 2] == "expr") - || (argumentDepth + 1) == ctx.depth)) { - - data.data.push_back(std::make_pair(nullptr, TemplateArgumentPolicy::NAME)); - if(!namePolicy) namePolicy = new NamePolicy{this}; - ctx.dispatcher->AddListenerDispatch(namePolicy); - - } - - }; - -} - -/**command collaborator */ -void TemplateArgumentPolicy::CollectOthersHandler() { - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::literal] = [this](srcSAXEventContext& ctx) { - - // C++ has depth of 2 others 1 - std::size_t elementStackSize = ctx.elementStack.size(); - if( argumentDepth && (((argumentDepth + 2) == ctx.depth && elementStackSize > 1 && ctx.elementStack[elementStackSize - 2] == "expr") - || (argumentDepth + 1) == ctx.depth)) { - - data.data.push_back(std::make_pair(new std::string(), LITERAL)); - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - (*static_cast<std::string *>(data.data.back().first)) += ctx.currentToken; - }; - - } - - }; - - closeEventMap[ParserState::literal] = [this](srcSAXEventContext& ctx) { - - if( argumentDepth && (((argumentDepth + 2) == ctx.depth && ctx.elementStack.back() == "expr") - || (argumentDepth + 1) == ctx.depth)) { - - NopCloseEvents({ParserState::tokenstring}); - - } - - }; - - openEventMap[ParserState::op] = [this](srcSAXEventContext& ctx) { - - // C++ has depth of 2 others 1 - std::size_t elementStackSize = ctx.elementStack.size(); - if( argumentDepth && (((argumentDepth + 2) == ctx.depth && elementStackSize > 1 && ctx.elementStack[elementStackSize - 2] == "expr") - || (argumentDepth + 1) == ctx.depth)) { - - data.data.push_back(std::make_pair(new std::string(), OPERATOR)); - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - (*static_cast<std::string *>(data.data.back().first)) += ctx.currentToken; - }; - - } - - }; - - closeEventMap[ParserState::op] = [this](srcSAXEventContext& ctx) { - - if( argumentDepth && (((argumentDepth + 2) == ctx.depth && ctx.elementStack.back() == "expr") - || (argumentDepth + 1) == ctx.depth)) { - - NopCloseEvents({ParserState::tokenstring}); - - } - - }; - - openEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx) { - - // C++ has depth of 2 others 1 - std::size_t elementStackSize = ctx.elementStack.size(); - if( argumentDepth && (((argumentDepth + 2) == ctx.depth && elementStackSize > 1 && ctx.elementStack[elementStackSize - 2] == "expr") - || (argumentDepth + 1) == ctx.depth)) { - - data.data.push_back(std::make_pair(nullptr, MODIFIER)); - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - - if(ctx.currentToken == "*") - data.data.back().second = POINTER; - else if(ctx.currentToken == "&") - data.data.back().second = REFERENCE; - else if(ctx.currentToken == "&&") - data.data.back().second = RVALUE; - - }; - - } - - }; - - closeEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx) { - - if( argumentDepth && (((argumentDepth + 2) == ctx.depth && ctx.elementStack.back() == "expr") - || (argumentDepth + 1) == ctx.depth)) { - - NopCloseEvents({ParserState::tokenstring}); - - } - - }; - - openEventMap[ParserState::call] = [this](srcSAXEventContext& ctx) { - - // C++ has depth of 2 others 1 - std::size_t elementStackSize = ctx.elementStack.size(); - if( argumentDepth && (((argumentDepth + 2) == ctx.depth && elementStackSize > 1 && ctx.elementStack[elementStackSize - 2] == "expr") - || (argumentDepth + 1) == ctx.depth)) { - - data.data.push_back(std::make_pair(new std::string(), CALL)); - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - (*static_cast<std::string *>(data.data.back().first)) += ctx.currentToken; - }; - - } - - }; - - closeEventMap[ParserState::call] = [this](srcSAXEventContext& ctx) { - - if( argumentDepth && (((argumentDepth + 2) == ctx.depth && ctx.elementStack.back() == "expr") - || (argumentDepth + 1) == ctx.depth)) { - - NopCloseEvents({ParserState::tokenstring}); - - } - - }; - -} - - -#ifndef INCLUDED_SRCSAX_SINGLE_EVENT_DISPATCHER_HPP -#define INCLUDED_SRCSAX_SINGLE_EVENT_DISPATCHER_HPP - -#include <srcSAXEventDispatcher.hpp> - -namespace srcSAXEventDispatch { - - class srcSAXSingleEventDispatcher : public srcSAXEventDispatcher<policies...> { - - private: - bool dispatched; - - public: - - srcSAXSingleEventDispatcher(PolicyListener * listener) : srcSAXEventDispatcher<policies...>(listener), dispatched(false) {} - /**command collaborational-command collaborator */ - virtual void AddListener(EventListener * listener) override { - EventDispatcher::elementListeners.back()->SetDispatched(false); - EventDispatcher::elementListeners.push_back(listener); - } - /**set collaborator */ - virtual void AddListenerDispatch(EventListener * listener) override { - AddListener(listener); - dispatched = false; - } - /**command collaborator stateless */ - virtual void AddListenerNoDispatch(EventListener * listener) override { - AddListener(listener); - } - /**command collaborational-command collaborator */ - virtual void RemoveListener(EventListener * listener) override { - EventDispatcher::elementListeners.back()->SetDispatched(false); - EventDispatcher::elementListeners.pop_back(); - } - /**set collaborator */ - virtual void RemoveListenerDispatch(EventListener * listener) override { - RemoveListener(listener); - dispatched = false; - } - /**command collaborator stateless */ - virtual void RemoveListenerNoDispatch(EventListener * listener) override { - RemoveListener(listener); - } - protected: - /**command collaborator */ - virtual void DispatchEvent(srcSAXEventDispatch::ParserState pstate, srcSAXEventDispatch::ElementState estate) override { - - while(!dispatched) { - - dispatched = true; - - EventDispatcher::elementListeners.back()->HandleEvent(pstate, estate, EventDispatcher::ctx); - EventDispatcher::elementListeners.back()->SetDispatched(false); - - } - - dispatched = false; - - } - - }; - -} - -#endif - - -#include <memory> -#include <unordered_map> -#include <functional> -#include <string> -#include <vector> -#include <list> -#include <initializer_list> -#include <algorithm> -#include <iostream> - -#ifndef INCLUDED_SRCSAX_EVENT_DISPATCH_UTILITIES_HPP -#define INCLUDED_SRCSAX_EVENT_DISPATCH_UTILITIES_HPP - -namespace srcSAXEventDispatch{ - class EventDispatcher; - enum ElementState {open, close}; - enum ParserState {decl, expr, parameter, declstmt, exprstmt, parameterlist, - argumentlist, argumentlisttemplate, call, templates, ctrlflow, endflow, genericargumentlist, - name, function, functiondecl, constructor, constructordecl, destructordecl, destructor, - argument, index, block, type, init, op, literal, modifier, memberlist, classn, structn, - super_list, super, publicaccess, privateaccess, protectedaccess, preproc, whilestmt, forstmt, - ifstmt, nonterminal, macro, classblock, functionblock, ifblock, whileblock, forblock, specifier, typedefexpr, - userdefined, snoun, propersnoun, spronoun, sadjective, sverb, - - // do not put anything after these - xmlattribute, tokenstring, empty, MAXENUMVALUE = empty}; - class srcSAXEventContext { - public: - srcSAXEventContext() = delete; - srcSAXEventContext(EventDispatcher * dispatcher, const std::vector<std::string> & elementStack) - : dispatcher(dispatcher), - elementStack(elementStack), - triggerField(std::vector<unsigned short int>(MAXENUMVALUE, 0)), - depth(0), - isOperator(false), - currentLineNumber{0} {} - - EventDispatcher * dispatcher; - const std::vector<std::string> & elementStack; - std::vector<int> genericDepth; - unsigned int currentLineNumber; - std::vector<unsigned short int> triggerField; - std::string currentFilePath, currentFileName, currentFileLanguage, currentsrcMLRevision, - currentTag, currentToken, currentAttributeName, currentAttributeValue; - std::size_t depth; - bool isOperator; - - public: - /**predicate collaborator */ - inline bool And(std::vector<ParserState> vec) const{ - for(auto field : vec){ - if(triggerField[field]) continue; - else return false; - } - return true; - } - /**predicate collaborator */ - inline bool Nand(std::vector<ParserState> vec) const{ - for(auto field : vec){ - if(triggerField[field]) return false; - else continue; - } - return true; - } - /**predicate collaborator */ - inline bool Or(std::vector<ParserState> vec) const{ - for(auto field : vec){ - if(triggerField[field]) return true; - else continue; - } - return false; - } - /**predicate collaborator */ - inline bool Nor(std::vector<ParserState> vec) const{ - for(auto field : vec){ - if(triggerField[field]) return false; - else continue; - } - return true; - } - /**predicate collaborator */ - inline bool IsEqualTo(ParserState lhs, ParserState rhs) const{ - return triggerField[lhs] == triggerField[rhs] ? true : false; - } - /**predicate collaborator */ - inline bool IsGreaterThan(ParserState lhs, ParserState rhs) const{ - return triggerField[lhs] > triggerField[rhs] ? true : false; - } - /**predicate collaborator */ - inline bool IsGreaterThanOrEqualTo(ParserState lhs, ParserState rhs) const{ - return triggerField[lhs] >= triggerField[rhs] ? true : false; - } - /**predicate collaborator */ - inline bool IsLessThan(ParserState lhs, ParserState rhs) const{ - return triggerField[lhs] < triggerField[rhs] ? true : false; - } - /**predicate collaborator */ - inline bool IsLessThanOrEqualTo(ParserState lhs, ParserState rhs) const{ - return triggerField[lhs] <= triggerField[rhs] ? true : false; - } - /**predicate collaborator */ - inline bool IsOpen(ParserState field) const{ - if(triggerField[field]) return true; - else return false; - } - /**predicate collaborator */ - inline bool IsClosed(ParserState field) const{ - if(triggerField[field]) return false; - else return true; - } - }; - - class EventListener { - typedef std::unordered_map<srcSAXEventDispatch::ParserState, std::function<void(srcSAXEventDispatch::srcSAXEventContext&)>, std::hash<int>> EventMap; - protected: - bool dispatched; - EventMap openEventMap, closeEventMap; - - - public: - - EventListener() : dispatched(false) { - DefaultEventHandlers(); - } - - /**set */ - void SetDispatched(bool isDispatched) { dispatched = isDispatched; } - - /**get collaborator */ - virtual const EventMap & GetOpenEventMap() const { return openEventMap; } - /**get collaborator */ - virtual const EventMap & GetCloseEventMap() const { return closeEventMap; } - - /**set */ - virtual void HandleEvent() { dispatched = true; } - /**command collaborator */ - virtual void HandleEvent(srcSAXEventDispatch::ParserState pstate, srcSAXEventDispatch::ElementState estate, srcSAXEventDispatch::srcSAXEventContext& ctx) { - - if(dispatched) return; - - dispatched = true; - - switch(estate){ - - case srcSAXEventDispatch::ElementState::open: { - auto event = openEventMap.find(pstate); - if(event != openEventMap.end()){ - event->second(ctx); - } - break; - } - - case srcSAXEventDispatch::ElementState::close: { - auto event = closeEventMap.find(pstate); - if(event != closeEventMap.end()){ - event->second(ctx); - } - break; - } - - default: - throw std::runtime_error("Something went terribly, terribly wrong"); - - } - - } - - protected: - /**collaborator */ - void NopOpenEvents(std::initializer_list<ParserState> states) { - - for(ParserState state : states) { - - openEventMap[state] = [this](const srcSAXEventContext& ctx) {}; - - } - - } - /**collaborator */ - void NopCloseEvents(std::initializer_list<ParserState> states) { - - for(ParserState state : states) { - - closeEventMap[state] = [this](const srcSAXEventContext& ctx) {}; - - } - - } - - private: - - /**command */ - void DefaultEventHandlers() { - using namespace srcSAXEventDispatch; - - NopOpenEvents({ - ParserState::declstmt, - ParserState::exprstmt, - ParserState::parameterlist, - ParserState::ifstmt, - ParserState::forstmt, - ParserState::whilestmt, - ParserState::templates, - ParserState::argumentlist, - ParserState::genericargumentlist, - ParserState::call, - ParserState::function, - ParserState::constructor, - ParserState::functiondecl, - ParserState::destructordecl, - ParserState::constructordecl, - ParserState::classn, - ParserState::structn, - ParserState::publicaccess, - ParserState::protectedaccess, - ParserState::privateaccess, - ParserState::destructor, - ParserState::parameter, - ParserState::memberlist, - ParserState::index, - ParserState::op, - ParserState::block, - ParserState::init, - ParserState::argument, - ParserState::literal, - ParserState::modifier, - ParserState::decl, - ParserState::type, - ParserState::typedefexpr, - ParserState::expr, - ParserState::name, - ParserState::macro, - ParserState::specifier, - ParserState::snoun, - ParserState::propersnoun, - ParserState::sadjective, - ParserState::spronoun, - ParserState::sverb, - }); - - NopCloseEvents({ - ParserState::declstmt, - ParserState::exprstmt, - ParserState::parameterlist, - ParserState::ifstmt, - ParserState::forstmt, - ParserState::whilestmt, - ParserState::templates, - ParserState::argumentlist, - ParserState::genericargumentlist, - ParserState::call, - ParserState::function, - ParserState::constructor, - ParserState::destructor, - ParserState::functiondecl, - ParserState::constructordecl, - ParserState::destructordecl, - ParserState::classn, - ParserState::structn, - ParserState::publicaccess, - ParserState::protectedaccess, - ParserState::privateaccess, - ParserState::parameter, - ParserState::memberlist, - ParserState::index, - ParserState::op, - ParserState::block, - ParserState::init, - ParserState::argument, - ParserState::literal, - ParserState::modifier, - ParserState::decl, - ParserState::type, - ParserState::typedefexpr, - ParserState::expr, - ParserState::name, - ParserState::macro, - ParserState::tokenstring, - ParserState::specifier, - ParserState::snoun, - ParserState::propersnoun, - ParserState::sadjective, - ParserState::spronoun, - ParserState::sverb, - }); - - } - - }; - class EventDispatcher { - public: - virtual void AddListener(EventListener* l) = 0; - virtual void AddListenerDispatch(EventListener* listener) = 0; - virtual void AddListenerNoDispatch(EventListener* listener) = 0; - virtual void RemoveListener(EventListener* l) = 0; - virtual void RemoveListenerDispatch(EventListener* listener) = 0; - virtual void RemoveListenerNoDispatch(EventListener* listener) = 0; - protected: - srcSAXEventContext ctx; - std::list<EventListener*> elementListeners; - - EventDispatcher(const std::vector<std::string> & elementStack) - : elementListeners(), ctx(this, elementStack) {} - virtual void DispatchEvent(ParserState , ElementState ) = 0; - }; - class PolicyDispatcher; - class PolicyListener{ - - public: - - PolicyListener() {} - virtual void Notify(const PolicyDispatcher * policy, const srcSAXEventContext & ctx) = 0; - - }; - class PolicyDispatcher{ - public: - PolicyDispatcher(std::initializer_list<PolicyListener *> listeners) : policyListeners(listeners){} - /**command collaborator stateless */ - virtual void AddListener(PolicyListener* listener){ - policyListeners.push_back(listener); - } - /**command collaborator */ - virtual void RemoveListener(PolicyListener* listener){ - policyListeners.erase(std::find(policyListeners.begin(), policyListeners.end(), listener)); - } - - /**property collaborator */ - - T * Data() const { - - return static_cast<T *>(DataInner()); - - } - - protected: - std::list<PolicyListener*> policyListeners; - virtual void * DataInner() const = 0; - /**command collaborator */ - virtual void NotifyAll(const srcSAXEventContext & ctx) { - std::cerr<<"Size: "<<policyListeners.size()<<std::endl; - for(std::list<PolicyListener*>::iterator listener = policyListeners.begin(); listener != policyListeners.end(); ++listener){ - std::cerr<<"Listen man"<<std::endl; - (*listener)->Notify(this, ctx); - } - - } - - }; -} - -#endif - - -/* This source file must have a .cpp extension so that all C++ compilers - recognize the extension without flags. Borland does not know .cxx for - example. */ -#ifndef __cplusplus -# error "A C compiler has been selected for C++." -#endif - -/* Version number components: V=Version, R=Revision, P=Patch - Version date components: YYYY=Year, MM=Month, DD=Day */ - -#if defined(__COMO__) -# define COMPILER_ID "Comeau" - /* __COMO_VERSION__ = VRR */ -# define COMPILER_VERSION_MAJOR DEC(__COMO_VERSION__ / 100) -# define COMPILER_VERSION_MINOR DEC(__COMO_VERSION__ % 100) - -#elif defined(__INTEL_COMPILER) || defined(__ICC) -# define COMPILER_ID "Intel" - /* __INTEL_COMPILER = VRP */ -# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100) -# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10) -# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10) -# if defined(__INTEL_COMPILER_BUILD_DATE) - /* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */ -# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE) -# endif - -#elif defined(__PATHCC__) -# define COMPILER_ID "PathScale" -# define COMPILER_VERSION_MAJOR DEC(__PATHCC__) -# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__) -# if defined(__PATHCC_PATCHLEVEL__) -# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__) -# endif - -#elif defined(__clang__) -# define COMPILER_ID "Clang" -# define COMPILER_VERSION_MAJOR DEC(__clang_major__) -# define COMPILER_VERSION_MINOR DEC(__clang_minor__) -# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) - -#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__) -# define COMPILER_ID "Embarcadero" -# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF) -# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF) -# define COMPILER_VERSION_PATCH HEX(__CODEGEARC_VERSION__ & 0xFFFF) - -#elif defined(__BORLANDC__) -# define COMPILER_ID "Borland" - /* __BORLANDC__ = 0xVRR */ -# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8) -# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF) - -#elif defined(__WATCOMC__) -# define COMPILER_ID "Watcom" - /* __WATCOMC__ = VVRR */ -# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100) -# define COMPILER_VERSION_MINOR DEC(__WATCOMC__ % 100) - -#elif defined(__SUNPRO_CC) -# define COMPILER_ID "SunPro" -# if __SUNPRO_CC >= 0x5100 - /* __SUNPRO_CC = 0xVRRP */ -# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12) -# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF) -# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF) -# else - /* __SUNPRO_CC = 0xVRP */ -# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8) -# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF) -# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF) -# endif - -#elif defined(__HP_aCC) -# define COMPILER_ID "HP" - /* __HP_aCC = VVRRPP */ -# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000) -# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100) -# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100) - -#elif defined(__DECCXX) -# define COMPILER_ID "Compaq" - /* __DECCXX_VER = VVRRTPPPP */ -# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000) -# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100) -# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000) - -#elif defined(__IBMCPP__) -# if defined(__COMPILER_VER__) -# define COMPILER_ID "zOS" -# else -# if __IBMCPP__ >= 800 -# define COMPILER_ID "XL" -# else -# define COMPILER_ID "VisualAge" -# endif - /* __IBMCPP__ = VRP */ -# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100) -# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10) -# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10) -# endif - -#elif defined(__PGI) -# define COMPILER_ID "PGI" -# define COMPILER_VERSION_MAJOR DEC(__PGIC__) -# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__) -# if defined(__PGIC_PATCHLEVEL__) -# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__) -# endif - -#elif defined(_CRAYC) -# define COMPILER_ID "Cray" -# define COMPILER_VERSION_MAJOR DEC(_RELEASE) -# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR) - -#elif defined(__TI_COMPILER_VERSION__) -# define COMPILER_ID "TI" - /* __TI_COMPILER_VERSION__ = VVVRRRPPP */ -# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000) -# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000) -# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000) - -#elif defined(__SCO_VERSION__) -# define COMPILER_ID "SCO" - -#elif defined(__GNUC__) -# define COMPILER_ID "GNU" -# define COMPILER_VERSION_MAJOR DEC(__GNUC__) -# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__) -# if defined(__GNUC_PATCHLEVEL__) -# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) -# endif - -#elif defined(_MSC_VER) -# define COMPILER_ID "MSVC" - /* _MSC_VER = VVRR */ -# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100) -# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100) -# if defined(_MSC_FULL_VER) -# if _MSC_VER >= 1400 - /* _MSC_FULL_VER = VVRRPPPPP */ -# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000) -# else - /* _MSC_FULL_VER = VVRRPPPP */ -# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000) -# endif -# endif -# if defined(_MSC_BUILD) -# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD) -# endif - -/* Analog VisualDSP++ >= 4.5.6 */ -#elif defined(__VISUALDSPVERSION__) -# define COMPILER_ID "ADSP" - /* __VISUALDSPVERSION__ = 0xVVRRPP00 */ -# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24) -# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF) -# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF) - -/* Analog VisualDSP++ < 4.5.6 */ -#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__) -# define COMPILER_ID "ADSP" - -/* IAR Systems compiler for embedded systems. - http://www.iar.com */ -#elif defined(__IAR_SYSTEMS_ICC__ ) || defined(__IAR_SYSTEMS_ICC) -# define COMPILER_ID "IAR" - -#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION) -# define COMPILER_ID "MIPSpro" -# if defined(_SGI_COMPILER_VERSION) - /* _SGI_COMPILER_VERSION = VRP */ -# define COMPILER_VERSION_MAJOR DEC(_SGI_COMPILER_VERSION/100) -# define COMPILER_VERSION_MINOR DEC(_SGI_COMPILER_VERSION/10 % 10) -# define COMPILER_VERSION_PATCH DEC(_SGI_COMPILER_VERSION % 10) -# else - /* _COMPILER_VERSION = VRP */ -# define COMPILER_VERSION_MAJOR DEC(_COMPILER_VERSION/100) -# define COMPILER_VERSION_MINOR DEC(_COMPILER_VERSION/10 % 10) -# define COMPILER_VERSION_PATCH DEC(_COMPILER_VERSION % 10) -# endif - -/* This compiler is either not known or is too old to define an - identification macro. Try to identify the platform and guess that - it is the native compiler. */ -#elif defined(__sgi) -# define COMPILER_ID "MIPSpro" - -#elif defined(__hpux) || defined(__hpua) -# define COMPILER_ID "HP" - -#else /* unknown compiler */ -# define COMPILER_ID "" - -#endif - -/* Construct the string literal in pieces to prevent the source from - getting matched. Store it in a pointer rather than an array - because some compilers will just produce instructions to fill the - array rather than assigning a pointer to a static array. */ -char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; - -/* Identify known platforms by name. */ -#if defined(__linux) || defined(__linux__) || defined(linux) -# define PLATFORM_ID "Linux" - -#elif defined(__CYGWIN__) -# define PLATFORM_ID "Cygwin" - -#elif defined(__MINGW32__) -# define PLATFORM_ID "MinGW" - -#elif defined(__APPLE__) -# define PLATFORM_ID "Darwin" - -#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) -# define PLATFORM_ID "Windows" - -#elif defined(__FreeBSD__) || defined(__FreeBSD) -# define PLATFORM_ID "FreeBSD" - -#elif defined(__NetBSD__) || defined(__NetBSD) -# define PLATFORM_ID "NetBSD" - -#elif defined(__OpenBSD__) || defined(__OPENBSD) -# define PLATFORM_ID "OpenBSD" - -#elif defined(__sun) || defined(sun) -# define PLATFORM_ID "SunOS" - -#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) -# define PLATFORM_ID "AIX" - -#elif defined(__sgi) || defined(__sgi__) || defined(_SGI) -# define PLATFORM_ID "IRIX" - -#elif defined(__hpux) || defined(__hpux__) -# define PLATFORM_ID "HP-UX" - -#elif defined(__HAIKU__) -# define PLATFORM_ID "Haiku" - -#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) -# define PLATFORM_ID "BeOS" - -#elif defined(__QNX__) || defined(__QNXNTO__) -# define PLATFORM_ID "QNX" - -#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) -# define PLATFORM_ID "Tru64" - -#elif defined(__riscos) || defined(__riscos__) -# define PLATFORM_ID "RISCos" - -#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) -# define PLATFORM_ID "SINIX" - -#elif defined(__UNIX_SV__) -# define PLATFORM_ID "UNIX_SV" - -#elif defined(__bsdos__) -# define PLATFORM_ID "BSDOS" - -#elif defined(_MPRAS) || defined(MPRAS) -# define PLATFORM_ID "MP-RAS" - -#elif defined(__osf) || defined(__osf__) -# define PLATFORM_ID "OSF1" - -#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) -# define PLATFORM_ID "SCO_SV" - -#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) -# define PLATFORM_ID "ULTRIX" - -#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) -# define PLATFORM_ID "Xenix" - -#else /* unknown platform */ -# define PLATFORM_ID "" - -#endif - -/* For windows compilers MSVC and Intel we can determine - the architecture of the compiler being used. This is because - the compilers do not have flags that can change the architecture, - but rather depend on which compiler is being used -*/ -#if defined(_WIN32) && defined(_MSC_VER) -# if defined(_M_IA64) -# define ARCHITECTURE_ID "IA64" - -# elif defined(_M_X64) || defined(_M_AMD64) -# define ARCHITECTURE_ID "x64" - -# elif defined(_M_IX86) -# define ARCHITECTURE_ID "X86" - -# elif defined(_M_ARM) -# define ARCHITECTURE_ID "ARM" - -# elif defined(_M_MIPS) -# define ARCHITECTURE_ID "MIPS" - -# elif defined(_M_SH) -# define ARCHITECTURE_ID "SHx" - -# else /* unknown architecture */ -# define ARCHITECTURE_ID "" -# endif - -#else -# define ARCHITECTURE_ID "" -#endif - -/* Convert integer to decimal digit literals. */ -#define DEC(n ) \ - ('0' + (((n) / 10000000)%10)), \ - ('0' + (((n) / 1000000)%10)), \ - ('0' + (((n) / 100000)%10)), \ - ('0' + (((n) / 10000)%10)), \ - ('0' + (((n) / 1000)%10)), \ - ('0' + (((n) / 100)%10)), \ - ('0' + (((n) / 10)%10)), \ - ('0' + ((n) % 10)) - -/* Convert integer to hex digit literals. */ -#define HEX(n ) \ - ('0' + ((n)>>28 & 0xF)), \ - ('0' + ((n)>>24 & 0xF)), \ - ('0' + ((n)>>20 & 0xF)), \ - ('0' + ((n)>>16 & 0xF)), \ - ('0' + ((n)>>12 & 0xF)), \ - ('0' + ((n)>>8 & 0xF)), \ - ('0' + ((n)>>4 & 0xF)), \ - ('0' + ((n) & 0xF)) - -/* Construct a string literal encoding the version number components. */ -#ifdef COMPILER_VERSION_MAJOR -char const info_version[] = { - 'I', 'N', 'F', 'O', ':', - 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[', - COMPILER_VERSION_MAJOR, -# ifdef COMPILER_VERSION_MINOR - '.', COMPILER_VERSION_MINOR, -# ifdef COMPILER_VERSION_PATCH - '.', COMPILER_VERSION_PATCH, -# ifdef COMPILER_VERSION_TWEAK - '.', COMPILER_VERSION_TWEAK, -# endif -# endif -# endif - ']','\0'}; -#endif - -/* Construct the string literal in pieces to prevent the source from - getting matched. Store it in a pointer rather than an array - because some compilers will just produce instructions to fill the - array rather than assigning a pointer to a static array. */ -char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; -char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; - - - -/*--------------------------------------------------------------------------*/ - -int main(int argc, char* argv[]) -{ - int require = 0; - require += info_compiler[argc]; - require += info_platform[argc]; -#ifdef COMPILER_VERSION_MAJOR - require += info_version[argc]; -#endif - (void)argv; - return require; -} - - -#ifdef __cplusplus -# error "A C++ compiler has been selected for C." -#endif - -/* Version number components: V=Version, R=Revision, P=Patch - Version date components: YYYY=Year, MM=Month, DD=Day */ - -#if defined(__18CXX) -# define ID_VOID_MAIN -#endif - -#if defined(__INTEL_COMPILER) || defined(__ICC) -# define COMPILER_ID "Intel" - /* __INTEL_COMPILER = VRP */ -# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100) -# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10) -# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10) -# if defined(__INTEL_COMPILER_BUILD_DATE) - /* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */ -# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE) -# endif - -#elif defined(__PATHCC__) -# define COMPILER_ID "PathScale" -# define COMPILER_VERSION_MAJOR DEC(__PATHCC__) -# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__) -# if defined(__PATHCC_PATCHLEVEL__) -# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__) -# endif - -#elif defined(__clang__) -# define COMPILER_ID "Clang" -# define COMPILER_VERSION_MAJOR DEC(__clang_major__) -# define COMPILER_VERSION_MINOR DEC(__clang_minor__) -# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) - -#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__) -# define COMPILER_ID "Embarcadero" -# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF) -# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF) -# define COMPILER_VERSION_PATCH HEX(__CODEGEARC_VERSION__ & 0xFFFF) - -#elif defined(__BORLANDC__) -# define COMPILER_ID "Borland" - /* __BORLANDC__ = 0xVRR */ -# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8) -# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF) - -#elif defined(__WATCOMC__) -# define COMPILER_ID "Watcom" - /* __WATCOMC__ = VVRR */ -# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100) -# define COMPILER_VERSION_MINOR DEC(__WATCOMC__ % 100) - -#elif defined(__SUNPRO_C) -# define COMPILER_ID "SunPro" -# if __SUNPRO_C >= 0x5100 - /* __SUNPRO_C = 0xVRRP */ -# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>12) -# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xFF) -# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF) -# else - /* __SUNPRO_C = 0xVRP */ -# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>8) -# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xF) -# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF) -# endif - -#elif defined(__HP_cc) -# define COMPILER_ID "HP" - /* __HP_cc = VVRRPP */ -# define COMPILER_VERSION_MAJOR DEC(__HP_cc/10000) -# define COMPILER_VERSION_MINOR DEC(__HP_cc/100 % 100) -# define COMPILER_VERSION_PATCH DEC(__HP_cc % 100) - -#elif defined(__DECC) -# define COMPILER_ID "Compaq" - /* __DECC_VER = VVRRTPPPP */ -# define COMPILER_VERSION_MAJOR DEC(__DECC_VER/10000000) -# define COMPILER_VERSION_MINOR DEC(__DECC_VER/100000 % 100) -# define COMPILER_VERSION_PATCH DEC(__DECC_VER % 10000) - -#elif defined(__IBMC__) -# if defined(__COMPILER_VER__) -# define COMPILER_ID "zOS" -# else -# if __IBMC__ >= 800 -# define COMPILER_ID "XL" -# else -# define COMPILER_ID "VisualAge" -# endif - /* __IBMC__ = VRP */ -# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) -# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) -# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) -# endif - -#elif defined(__PGI) -# define COMPILER_ID "PGI" -# define COMPILER_VERSION_MAJOR DEC(__PGIC__) -# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__) -# if defined(__PGIC_PATCHLEVEL__) -# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__) -# endif - -#elif defined(_CRAYC) -# define COMPILER_ID "Cray" -# define COMPILER_VERSION_MAJOR DEC(_RELEASE) -# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR) - -#elif defined(__TI_COMPILER_VERSION__) -# define COMPILER_ID "TI" - /* __TI_COMPILER_VERSION__ = VVVRRRPPP */ -# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000) -# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000) -# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000) - -#elif defined(__TINYC__) -# define COMPILER_ID "TinyCC" - -#elif defined(__SCO_VERSION__) -# define COMPILER_ID "SCO" - -#elif defined(__GNUC__) -# define COMPILER_ID "GNU" -# define COMPILER_VERSION_MAJOR DEC(__GNUC__) -# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__) -# if defined(__GNUC_PATCHLEVEL__) -# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) -# endif - -#elif defined(_MSC_VER) -# define COMPILER_ID "MSVC" - /* _MSC_VER = VVRR */ -# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100) -# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100) -# if defined(_MSC_FULL_VER) -# if _MSC_VER >= 1400 - /* _MSC_FULL_VER = VVRRPPPPP */ -# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000) -# else - /* _MSC_FULL_VER = VVRRPPPP */ -# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000) -# endif -# endif -# if defined(_MSC_BUILD) -# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD) -# endif - -/* Analog VisualDSP++ >= 4.5.6 */ -#elif defined(__VISUALDSPVERSION__) -# define COMPILER_ID "ADSP" - /* __VISUALDSPVERSION__ = 0xVVRRPP00 */ -# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24) -# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF) -# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF) - -/* Analog VisualDSP++ < 4.5.6 */ -#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__) -# define COMPILER_ID "ADSP" - -/* IAR Systems compiler for embedded systems. - http://www.iar.com */ -#elif defined(__IAR_SYSTEMS_ICC__ ) || defined(__IAR_SYSTEMS_ICC) -# define COMPILER_ID "IAR" - -/* sdcc, the small devices C compiler for embedded systems, - http://sdcc.sourceforge.net */ -#elif defined(SDCC) -# define COMPILER_ID "SDCC" - /* SDCC = VRP */ -# define COMPILER_VERSION_MAJOR DEC(SDCC/100) -# define COMPILER_VERSION_MINOR DEC(SDCC/10 % 10) -# define COMPILER_VERSION_PATCH DEC(SDCC % 10) - -#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION) -# define COMPILER_ID "MIPSpro" -# if defined(_SGI_COMPILER_VERSION) - /* _SGI_COMPILER_VERSION = VRP */ -# define COMPILER_VERSION_MAJOR DEC(_SGI_COMPILER_VERSION/100) -# define COMPILER_VERSION_MINOR DEC(_SGI_COMPILER_VERSION/10 % 10) -# define COMPILER_VERSION_PATCH DEC(_SGI_COMPILER_VERSION % 10) -# else - /* _COMPILER_VERSION = VRP */ -# define COMPILER_VERSION_MAJOR DEC(_COMPILER_VERSION/100) -# define COMPILER_VERSION_MINOR DEC(_COMPILER_VERSION/10 % 10) -# define COMPILER_VERSION_PATCH DEC(_COMPILER_VERSION % 10) -# endif - -/* This compiler is either not known or is too old to define an - identification macro. Try to identify the platform and guess that - it is the native compiler. */ -#elif defined(__sgi) -# define COMPILER_ID "MIPSpro" - -#elif defined(__hpux) || defined(__hpua) -# define COMPILER_ID "HP" - -#else /* unknown compiler */ -# define COMPILER_ID "" - -#endif - -/* Construct the string literal in pieces to prevent the source from - getting matched. Store it in a pointer rather than an array - because some compilers will just produce instructions to fill the - array rather than assigning a pointer to a static array. */ -char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; - -/* Identify known platforms by name. */ -#if defined(__linux) || defined(__linux__) || defined(linux) -# define PLATFORM_ID "Linux" - -#elif defined(__CYGWIN__) -# define PLATFORM_ID "Cygwin" - -#elif defined(__MINGW32__) -# define PLATFORM_ID "MinGW" - -#elif defined(__APPLE__) -# define PLATFORM_ID "Darwin" - -#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) -# define PLATFORM_ID "Windows" - -#elif defined(__FreeBSD__) || defined(__FreeBSD) -# define PLATFORM_ID "FreeBSD" - -#elif defined(__NetBSD__) || defined(__NetBSD) -# define PLATFORM_ID "NetBSD" - -#elif defined(__OpenBSD__) || defined(__OPENBSD) -# define PLATFORM_ID "OpenBSD" - -#elif defined(__sun) || defined(sun) -# define PLATFORM_ID "SunOS" - -#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) -# define PLATFORM_ID "AIX" - -#elif defined(__sgi) || defined(__sgi__) || defined(_SGI) -# define PLATFORM_ID "IRIX" - -#elif defined(__hpux) || defined(__hpux__) -# define PLATFORM_ID "HP-UX" - -#elif defined(__HAIKU__) -# define PLATFORM_ID "Haiku" - -#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) -# define PLATFORM_ID "BeOS" - -#elif defined(__QNX__) || defined(__QNXNTO__) -# define PLATFORM_ID "QNX" - -#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) -# define PLATFORM_ID "Tru64" - -#elif defined(__riscos) || defined(__riscos__) -# define PLATFORM_ID "RISCos" - -#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) -# define PLATFORM_ID "SINIX" - -#elif defined(__UNIX_SV__) -# define PLATFORM_ID "UNIX_SV" - -#elif defined(__bsdos__) -# define PLATFORM_ID "BSDOS" - -#elif defined(_MPRAS) || defined(MPRAS) -# define PLATFORM_ID "MP-RAS" - -#elif defined(__osf) || defined(__osf__) -# define PLATFORM_ID "OSF1" - -#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) -# define PLATFORM_ID "SCO_SV" - -#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) -# define PLATFORM_ID "ULTRIX" - -#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) -# define PLATFORM_ID "Xenix" - -#else /* unknown platform */ -# define PLATFORM_ID "" - -#endif - -/* For windows compilers MSVC and Intel we can determine - the architecture of the compiler being used. This is because - the compilers do not have flags that can change the architecture, - but rather depend on which compiler is being used -*/ -#if defined(_WIN32) && defined(_MSC_VER) -# if defined(_M_IA64) -# define ARCHITECTURE_ID "IA64" - -# elif defined(_M_X64) || defined(_M_AMD64) -# define ARCHITECTURE_ID "x64" - -# elif defined(_M_IX86) -# define ARCHITECTURE_ID "X86" - -# elif defined(_M_ARM) -# define ARCHITECTURE_ID "ARM" - -# elif defined(_M_MIPS) -# define ARCHITECTURE_ID "MIPS" - -# elif defined(_M_SH) -# define ARCHITECTURE_ID "SHx" - -# else /* unknown architecture */ -# define ARCHITECTURE_ID "" -# endif - -#else -# define ARCHITECTURE_ID "" -#endif - -/* Convert integer to decimal digit literals. */ -#define DEC(n ) \ - ('0' + (((n) / 10000000)%10)), \ - ('0' + (((n) / 1000000)%10)), \ - ('0' + (((n) / 100000)%10)), \ - ('0' + (((n) / 10000)%10)), \ - ('0' + (((n) / 1000)%10)), \ - ('0' + (((n) / 100)%10)), \ - ('0' + (((n) / 10)%10)), \ - ('0' + ((n) % 10)) - -/* Convert integer to hex digit literals. */ -#define HEX(n ) \ - ('0' + ((n)>>28 & 0xF)), \ - ('0' + ((n)>>24 & 0xF)), \ - ('0' + ((n)>>20 & 0xF)), \ - ('0' + ((n)>>16 & 0xF)), \ - ('0' + ((n)>>12 & 0xF)), \ - ('0' + ((n)>>8 & 0xF)), \ - ('0' + ((n)>>4 & 0xF)), \ - ('0' + ((n) & 0xF)) - -/* Construct a string literal encoding the version number components. */ -#ifdef COMPILER_VERSION_MAJOR -char const info_version[] = { - 'I', 'N', 'F', 'O', ':', - 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[', - COMPILER_VERSION_MAJOR, -# ifdef COMPILER_VERSION_MINOR - '.', COMPILER_VERSION_MINOR, -# ifdef COMPILER_VERSION_PATCH - '.', COMPILER_VERSION_PATCH, -# ifdef COMPILER_VERSION_TWEAK - '.', COMPILER_VERSION_TWEAK, -# endif -# endif -# endif - ']','\0'}; -#endif - -/* Construct the string literal in pieces to prevent the source from - getting matched. Store it in a pointer rather than an array - because some compilers will just produce instructions to fill the - array rather than assigning a pointer to a static array. */ -char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; -char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; - - - -/*--------------------------------------------------------------------------*/ - -#ifdef ID_VOID_MAIN -void main() {} -#else -int main(int argc, char* argv[]) -{ - int require = 0; - require += info_compiler[argc]; - require += info_platform[argc]; - require += info_arch[argc]; -#ifdef COMPILER_VERSION_MAJOR - require += info_version[argc]; -#endif - (void)argv; - return require; -} -#endif - - -/** - * @file srcSAXEventDispatcher.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef INCLUDED_SRCSAXEVENTDISPATCHER_HPP -#define INCLUDED_SRCSAXEVENTDISPATCHER_HPP - -#include <srcSAXHandler.hpp> -#include <functional> -#include <iostream> -#include <map> -#include <unordered_map> -#include <vector> -#include <algorithm> -#include <srcSAXEventDispatchUtilities.hpp> -#include <vector> -#include <memory> -namespace srcSAXEventDispatch { - - - static std::list<EventListener*> CreateListenersImpl(PolicyListener * policyListener, std::list<EventListener*> & listeners); - - - static std::list<EventListener*> CreateListeners(PolicyListener * policyListener) { - std::list<EventListener*> listeners; - return CreateListenersImpl<policies...>(policyListener, listeners); - } - - - static std::list<EventListener*> CreateListenersHelper(PolicyListener * policyListener, std::list<EventListener*> & listeners); - - - static std::list<EventListener*> CreateListenersImpl(PolicyListener * policyListener, std::list<EventListener*> & listeners) { - return CreateListenersHelper<policies...>(policyListener, listeners); - } - - - static std::list<EventListener*> CreateListenersHelper(PolicyListener * policyListener, std::list<EventListener*> & listeners) { - listeners.emplace_back(new policy({policyListener})); - return CreateListenersImpl<remaining...>(policyListener, listeners); - } - - std::list<EventListener*> CreateListenersImpl<>(PolicyListener * listener, std::list<EventListener*> & listeners) { - return listeners; - } - - - class srcSAXEventDispatcher : public srcSAXHandler, public EventDispatcher { - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wunused-parameter" - - private: - std::unordered_map< std::string, std::function<void()>> process_map, process_map2; - bool classflagopen, functionflagopen, whileflagopen, ifflagopen, elseflagopen, ifelseflagopen, forflagopen, switchflagopen; - - bool dispatching; - ParserState currentPState; - ElementState currentEState; - - std::size_t numberAllocatedListeners; - - protected: - /**command collaborator */ - void DispatchEvent(ParserState pstate, ElementState estate) override { - - dispatching = true; - currentPState = pstate; - currentEState = estate; - - for(std::list<EventListener*>::iterator listener = elementListeners.begin(); listener != elementListeners.end(); ++listener ){ - (*listener)->HandleEvent(pstate, estate, ctx); - } - for(std::list<EventListener*>::iterator listener = elementListeners.begin(); listener != elementListeners.end(); ++listener ){ - (*listener)->SetDispatched(false); - } - - dispatching = false; - - } - - /**command collaborator */ - virtual void AddEvent(const std::string & event) { - - std::pair<std::string, std::function<void()>> openEvent(event, [this, event]() { - ctx.currentTag = event; - ++ctx.triggerField[ParserState::userdefined]; - DispatchEvent(ParserState::userdefined, ElementState::open); - } ); - process_map.insert(openEvent); - - std::pair<std::string, std::function<void()>> closeEvent(event, [this, event]() { - ctx.currentTag = event; - DispatchEvent(ParserState::userdefined, ElementState::close); - --ctx.triggerField[ParserState::userdefined]; - } ); - - process_map2.insert(closeEvent); - - } - - /**command collaborator stateless */ - virtual void AddEvents(std::initializer_list<std::string> events) { - - for(const std::string & event : events){ - AddEvent(event); - } - - } - - /**command */ - virtual void RemoveEvent(const std::string & event) { - process_map.erase(event); - process_map2.erase(event); - } - - /**command collaborator stateless */ - virtual void RemoveEvents(std::initializer_list<std::string> events) { - - for(const std::string & event : events){ - RemoveEvent(event); - } - - } - - public: - ~srcSAXEventDispatcher() { - for(std::size_t count = 0; count < numberAllocatedListeners; ++count) { - delete elementListeners.front(); - elementListeners.pop_front(); - } - } - - srcSAXEventDispatcher(PolicyListener * listener) : EventDispatcher(srcml_element_stack) { - elementListeners = CreateListeners<policies...>(listener); - numberAllocatedListeners = elementListeners.size(); - dispatching = false; - classflagopen = functionflagopen = whileflagopen = ifflagopen = elseflagopen = ifelseflagopen = forflagopen = switchflagopen = false; - InitializeHandlers(); - } - - /**command collaborator stateless */ - void AddListener(EventListener* listener) override { - elementListeners.push_back(listener); - } - /**command collaborator */ - void AddListenerDispatch(EventListener* listener) override { - if(dispatching){ - listener->HandleEvent(currentPState, currentEState, ctx); - } - AddListener(listener); - } - /**command collaborator */ - void AddListenerNoDispatch(EventListener* listener) override { - if(dispatching){ - listener->SetDispatched(true); - } - AddListener(listener); - } - /**command collaborator */ - void RemoveListener(EventListener* listener) override { - elementListeners.erase(std::find(elementListeners.begin(), elementListeners.end(), listener)); - } - /**command collaborator */ - void RemoveListenerDispatch(EventListener* listener) override { - if(dispatching){ - listener->HandleEvent(currentPState, currentEState, ctx); - } - RemoveListener(listener); - } - /**command collaborator */ - void RemoveListenerNoDispatch(EventListener* listener) override { - if(dispatching){ - listener->SetDispatched(true); - } - RemoveListener(listener); - } - /**command */ - void InitializeHandlers(){ - process_map = { - {"decl_stmt", [this](){ - ++ctx.triggerField[ParserState::declstmt]; - DispatchEvent(ParserState::declstmt, ElementState::open); - } }, - { "expr_stmt", [this](){ - ++ctx.triggerField[ParserState::exprstmt]; - DispatchEvent(ParserState::exprstmt, ElementState::open); - } }, - { "parameter_list", [this](){ - ++ctx.triggerField[ParserState::parameterlist]; - DispatchEvent(ParserState::parameterlist, ElementState::open); - } }, - { "if", [this](){ - ifflagopen = true; - ++ctx.triggerField[ParserState::ifstmt]; - DispatchEvent(ParserState::ifstmt, ElementState::open); - } }, - { "for", [this](){ - ++ctx.triggerField[ParserState::forstmt]; - DispatchEvent(ParserState::forstmt, ElementState::open); - } }, - { "while", [this](){ - whileflagopen = true; - ++ctx.triggerField[ParserState::whilestmt]; - DispatchEvent(ParserState::whilestmt, ElementState::open); - } }, - { "template", [this](){ - ++ctx.triggerField[ParserState::templates]; - DispatchEvent(ParserState::templates, ElementState::open); - } }, - { "argument_list", [this](){ - if(!ctx.genericDepth.empty()){ - if(ctx.genericDepth.back() == ctx.depth){ - ++ctx.triggerField[ParserState::genericargumentlist]; - DispatchEvent(ParserState::genericargumentlist, ElementState::open); - } - } - DispatchEvent(ParserState::argumentlist, ElementState::open); - ++ctx.triggerField[ParserState::argumentlist]; - } }, - { "call", [this](){ - ++ctx.triggerField[ParserState::call]; - DispatchEvent(ParserState::call, ElementState::open); - } }, - { "function", [this](){ - functionflagopen = true; - ++ctx.triggerField[ParserState::function]; - DispatchEvent(ParserState::function, ElementState::open); - } }, - { "constructor", [this](){ - functionflagopen = true; - ++ctx.triggerField[ParserState::constructor]; - DispatchEvent(ParserState::constructor, ElementState::open); - } }, - { "function_decl", [this](){ - ++ctx.triggerField[ParserState::functiondecl]; - DispatchEvent(ParserState::functiondecl, ElementState::open); - } }, - { "destructor_decl", [this](){ - ++ctx.triggerField[ParserState::destructordecl]; - DispatchEvent(ParserState::destructordecl, ElementState::open); - } }, - { "constructor_decl", [this](){ - ++ctx.triggerField[ParserState::constructordecl]; - DispatchEvent(ParserState::constructordecl, ElementState::open); - } }, - { "class", [this](){ - classflagopen = true; - ++ctx.triggerField[ParserState::classn]; - DispatchEvent(ParserState::classn, ElementState::open); - } }, - { "struct", [this](){ - classflagopen = true; - ++ctx.triggerField[ParserState::classn]; - DispatchEvent(ParserState::structn, ElementState::open); - } }, - { "super_list", [this](){ - ++ctx.triggerField[ParserState::super_list]; - DispatchEvent(ParserState::super_list, ElementState::open); - } }, - { "super", [this](){ - ++ctx.triggerField[ParserState::super]; - DispatchEvent(ParserState::super, ElementState::open); - } }, - { "public", [this](){ - ++ctx.triggerField[ParserState::publicaccess]; - DispatchEvent(ParserState::publicaccess, ElementState::open); - } }, - { "protected", [this](){ - ++ctx.triggerField[ParserState::protectedaccess]; - DispatchEvent(ParserState::protectedaccess, ElementState::open); - } }, - { "private", [this](){ - ++ctx.triggerField[ParserState::privateaccess]; - DispatchEvent(ParserState::privateaccess, ElementState::open); - } }, - { "destructor", [this](){ - functionflagopen = true; - ++ctx.triggerField[ParserState::destructor]; - DispatchEvent(ParserState::destructor, ElementState::open); - } }, - { "parameter", [this](){ - ++ctx.triggerField[ParserState::parameter]; - DispatchEvent(ParserState::parameter, ElementState::open); - } }, - { "member_list", [this](){ - ++ctx.triggerField[ParserState::memberlist]; - DispatchEvent(ParserState::memberlist, ElementState::open); - } }, - { "index", [this](){ - ++ctx.triggerField[ParserState::index]; - DispatchEvent(ParserState::index, ElementState::open); - } }, - { "operator", [this](){ - ++ctx.triggerField[ParserState::op]; - DispatchEvent(ParserState::op, ElementState::open); - } }, - { "block", [this](){ - ++ctx.triggerField[ParserState::block]; - if(functionflagopen){ - functionflagopen = false; - ++ctx.triggerField[ParserState::functionblock]; - DispatchEvent(ParserState::functionblock, ElementState::open); - } - if(classflagopen){ - classflagopen = false; //next time it's set to true, we definitely are in a new one. - ++ctx.triggerField[ParserState::classblock]; - } - if(whileflagopen){ - whileflagopen = false; - ++ctx.triggerField[ParserState::whileblock]; - } - if(ifelseflagopen){ - ifflagopen = false; - ++ctx.triggerField[ParserState::ifblock]; - } - if(forflagopen){ - forflagopen = false; - ++ctx.triggerField[ParserState::forblock]; - } - DispatchEvent(ParserState::block, ElementState::open); - } }, - { "init", [this](){ - ++ctx.triggerField[ParserState::init]; - DispatchEvent(ParserState::init, ElementState::open); - } }, - { "argument", [this](){ - ++ctx.triggerField[ParserState::argument]; - DispatchEvent(ParserState::argument, ElementState::open); - } }, - { "literal", [this](){ - ++ctx.triggerField[ParserState::literal]; - DispatchEvent(ParserState::literal, ElementState::open); - } }, - { "modifier", [this](){ - ++ctx.triggerField[ParserState::modifier]; - DispatchEvent(ParserState::modifier, ElementState::open); - } }, - { "decl", [this](){ - ++ctx.triggerField[ParserState::decl]; - DispatchEvent(ParserState::decl, ElementState::open); - } }, - { "type", [this](){ - ++ctx.triggerField[ParserState::type]; - DispatchEvent(ParserState::type, ElementState::open); - } }, - { "typedef", [this](){ - ++ctx.triggerField[ParserState::typedefexpr]; - DispatchEvent(ParserState::typedefexpr, ElementState::open); - } }, - { "expr", [this](){ - ++ctx.triggerField[ParserState::expr]; - DispatchEvent(ParserState::expr, ElementState::open); - } }, - { "name", [this](){ - ++ctx.triggerField[ParserState::name]; - DispatchEvent(ParserState::name, ElementState::open); - } }, - { "macro", [this](){ - ++ctx.triggerField[ParserState::macro]; - DispatchEvent(ParserState::macro, ElementState::open); - } }, - { "specifier", [this](){ - ++ctx.triggerField[ParserState::specifier]; - DispatchEvent(ParserState::specifier, ElementState::open); - } }, - { "noun", [this](){ - ++ctx.triggerField[ParserState::snoun]; - DispatchEvent(ParserState::snoun, ElementState::open); - } }, - { "propernoun", [this](){ - ++ctx.triggerField[ParserState::propersnoun]; - DispatchEvent(ParserState::propersnoun, ElementState::open); - } }, - { "pronoun", [this](){ - ++ctx.triggerField[ParserState::spronoun]; - DispatchEvent(ParserState::spronoun, ElementState::open); - } }, - { "adjective", [this](){ - ++ctx.triggerField[ParserState::sadjective]; - DispatchEvent(ParserState::sadjective, ElementState::open); - } }, - { "verb", [this](){ - ++ctx.triggerField[ParserState::sverb]; - DispatchEvent(ParserState::sverb, ElementState::open); - } } - }; - process_map2 = { - {"decl_stmt", [this](){ - DispatchEvent(ParserState::declstmt, ElementState::close); - --ctx.triggerField[ParserState::declstmt]; - } }, - { "expr_stmt", [this](){ - DispatchEvent(ParserState::exprstmt, ElementState::close); - --ctx.triggerField[ParserState::exprstmt]; - } }, - { "parameter_list", [this](){ - DispatchEvent(ParserState::parameterlist, ElementState::close); - --ctx.triggerField[ParserState::parameterlist]; - } }, - { "if", [this](){ - --ctx.triggerField[ParserState::ifblock]; - DispatchEvent(ParserState::ifstmt, ElementState::close); - --ctx.triggerField[ParserState::ifstmt]; - } }, - { "for", [this](){ - --ctx.triggerField[ParserState::forblock]; - DispatchEvent(ParserState::forstmt, ElementState::close); - --ctx.triggerField[ParserState::forstmt]; - } }, - { "while", [this](){ - --ctx.triggerField[ParserState::whileblock]; - DispatchEvent(ParserState::whilestmt, ElementState::close); - --ctx.triggerField[ParserState::whilestmt]; - } }, - { "template", [this](){ - DispatchEvent(ParserState::templates, ElementState::close); - --ctx.triggerField[ParserState::templates]; - } }, - { "argument_list", [this](){ - if(!ctx.genericDepth.empty()){ - if(ctx.genericDepth.back() == ctx.depth){ - DispatchEvent(ParserState::genericargumentlist, ElementState::close); - --ctx.triggerField[ParserState::genericargumentlist]; - ctx.genericDepth.pop_back(); - } - } - DispatchEvent(ParserState::argumentlist, ElementState::close); - --ctx.triggerField[ParserState::argumentlist]; - } }, - { "call", [this](){ - DispatchEvent(ParserState::call, ElementState::close); - --ctx.triggerField[ParserState::call]; - } }, - { "function", [this](){ - DispatchEvent(ParserState::functionblock, ElementState::close); - --ctx.triggerField[ParserState::functionblock]; - - DispatchEvent(ParserState::function, ElementState::close); - --ctx.triggerField[ParserState::function]; - } }, - { "constructor", [this](){ - DispatchEvent(ParserState::functionblock, ElementState::close); - --ctx.triggerField[ParserState::functionblock]; - - DispatchEvent(ParserState::constructor, ElementState::close); - --ctx.triggerField[ParserState::constructor]; - } }, - { "destructor", [this](){ - DispatchEvent(ParserState::functionblock, ElementState::close); - --ctx.triggerField[ParserState::functionblock]; - - DispatchEvent(ParserState::destructor, ElementState::close); - --ctx.triggerField[ParserState::destructor]; - } }, - { "function_decl", [this](){ - DispatchEvent(ParserState::functiondecl, ElementState::close); - --ctx.triggerField[ParserState::functiondecl]; - } }, - { "constructor_decl", [this](){ - DispatchEvent(ParserState::constructordecl, ElementState::close); - --ctx.triggerField[ParserState::constructordecl]; - } }, - { "destructor_decl", [this](){ - DispatchEvent(ParserState::destructordecl, ElementState::close); - --ctx.triggerField[ParserState::destructordecl]; - } }, - { "class", [this](){ - --ctx.triggerField[ParserState::classblock]; - DispatchEvent(ParserState::classn, ElementState::close); - --ctx.triggerField[ParserState::classn]; - } }, - { "struct", [this](){ - DispatchEvent(ParserState::structn, ElementState::close); - --ctx.triggerField[ParserState::classn]; - } }, - { "super_list", [this](){ - DispatchEvent(ParserState::super_list, ElementState::close); - --ctx.triggerField[ParserState::super_list]; - } }, - { "super", [this](){ - DispatchEvent(ParserState::super, ElementState::close); - --ctx.triggerField[ParserState::super]; - } }, - { "public", [this](){ - DispatchEvent(ParserState::publicaccess, ElementState::close); - --ctx.triggerField[ParserState::publicaccess]; - } }, - { "protected", [this](){ - DispatchEvent(ParserState::protectedaccess, ElementState::close); - --ctx.triggerField[ParserState::protectedaccess]; - } }, - { "private", [this](){ - DispatchEvent(ParserState::privateaccess, ElementState::close); - --ctx.triggerField[ParserState::privateaccess]; - } }, - { "parameter", [this](){ - DispatchEvent(ParserState::parameter, ElementState::close); - --ctx.triggerField[ParserState::parameter]; - } }, - { "member_list", [this](){ - DispatchEvent(ParserState::memberlist, ElementState::close); - --ctx.triggerField[ParserState::memberlist]; - } }, - { "index", [this](){ - DispatchEvent(ParserState::index, ElementState::close); - --ctx.triggerField[ParserState::index]; - } }, - { "operator", [this](){ - DispatchEvent(ParserState::op, ElementState::close); - --ctx.triggerField[ParserState::op]; - } }, - { "block", [this](){ - DispatchEvent(ParserState::block, ElementState::close); - --ctx.triggerField[ParserState::block]; - } }, - { "init", [this](){ - DispatchEvent(ParserState::init, ElementState::close); - --ctx.triggerField[ParserState::init]; - } }, - { "argument", [this](){ - DispatchEvent(ParserState::argument, ElementState::close); - --ctx.triggerField[ParserState::argument]; - } }, - { "literal", [this](){ - DispatchEvent(ParserState::literal, ElementState::close); - --ctx.triggerField[ParserState::literal]; - } }, - { "modifier", [this](){ - DispatchEvent(ParserState::modifier, ElementState::close); - --ctx.triggerField[ParserState::modifier]; - } }, - { "decl", [this](){ - DispatchEvent(ParserState::decl, ElementState::close); - --ctx.triggerField[ParserState::decl]; - } }, - { "type", [this](){ - DispatchEvent(ParserState::type, ElementState::close); - --ctx.triggerField[ParserState::type]; - } }, - { "typedef", [this](){ - DispatchEvent(ParserState::typedefexpr, ElementState::close); - --ctx.triggerField[ParserState::typedefexpr]; - } }, - { "expr", [this](){ - DispatchEvent(ParserState::expr, ElementState::close); - --ctx.triggerField[ParserState::expr]; - } }, - { "name", [this](){ - DispatchEvent(ParserState::name, ElementState::close); - --ctx.triggerField[ParserState::name]; - } }, - { "macro", [this](){ - DispatchEvent(ParserState::macro, ElementState::close); - --ctx.triggerField[ParserState::macro]; - } }, - { "specifier", [this](){ - DispatchEvent(ParserState::specifier, ElementState::close); - --ctx.triggerField[ParserState::specifier]; - } }, - { "noun", [this](){ - --ctx.triggerField[ParserState::snoun]; - DispatchEvent(ParserState::snoun, ElementState::close); - } }, - { "propernoun", [this](){ - --ctx.triggerField[ParserState::propersnoun]; - DispatchEvent(ParserState::propersnoun, ElementState::close); - } }, - { "pronoun", [this](){ - --ctx.triggerField[ParserState::spronoun]; - DispatchEvent(ParserState::spronoun, ElementState::close); - } }, - { "adjective", [this](){ - --ctx.triggerField[ParserState::sadjective]; - DispatchEvent(ParserState::sadjective, ElementState::close); - } }, - { "verb", [this](){ - --ctx.triggerField[ParserState::sverb]; - DispatchEvent(ParserState::sverb, ElementState::close); - } }, - { "xmlattribute", [this](){ - ctx.triggerField[ParserState::xmlattribute] = 1; - DispatchEvent(ParserState::xmlattribute, ElementState::close); - ctx.triggerField[ParserState::xmlattribute] = 0; - } }, - { "tokenstring", [this](){ - ctx.triggerField[ParserState::tokenstring] = 1; - DispatchEvent(ParserState::tokenstring, ElementState::close); - ctx.triggerField[ParserState::tokenstring] = 0; - } } - }; - } - - /* - virtual void startDocument() {} - virtual void endDocument() {} - */ - - /** - * startRoot - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param nb_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param nb_defaulted the number of defaulted attributes - * @param attributes list of attribute name value pairs (localname/prefix/URI/value/end) - * - * SAX handler function for start of the root element. - * Counts the root unit (if an archive, to avoid double count with startUnit). - * Overide for desired behaviour. - */ - virtual void startRoot(const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) override { - - } - /** - * startUnit - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param nb_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param nb_defaulted the number of defaulted attributes - * @param attributes list of attribute name value pairs (localname/prefix/URI/value/end) - * - * SAX handler function for start of an unit. - * Counts each unit tag (= filecount non-archive, = filecount + 1 if archive). - * Overide for desired behaviour. - */ - virtual void startUnit(const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) override { - if(num_attributes >= 3){ - ctx.currentFilePath = std::string(attributes[2].value); - ctx.currentFileLanguage = std::string(attributes[1].value); - ctx.currentsrcMLRevision = std::string(attributes[0].value); - } - } - /** - * startElementNs - * @param localname the name of the element tag - * @param prefix the tag prefix - * @param URI the namespace of tag - * @param nb_namespaces number of namespaces definitions - * @param namespaces the defined namespaces - * @param nb_attributes the number of attributes on the tag - * @param nb_defaulted the number of defaulted attributes - * @param attributes list of attribute name value pairs (localname/prefix/URI/value/end) - * - * SAX handler function for start of an element. - * Overide for desired behaviour. - */ - virtual void startElement(const char * localname, const char * prefix, const char * URI, - int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, - const struct srcsax_attribute * attributes) override { - - ++ctx.depth; - - std::string localName; - if(prefix) { - localName += prefix; - localName += ':'; - } - localName += localname; - - ctx.currentTag = localName; - - if(localName == "pos:position"){ - ctx.currentLineNumber = strtoul(attributes[0].value, NULL, 0); - } - std::string name; - if(num_attributes){ - name = attributes[0].value; - } - if(name == "generic" && localName == "argument_list"){ - ctx.genericDepth.push_back(ctx.depth); - } - - if(name == "operator" && (localName == "function" || localName == "function_decl")) { - ctx.isOperator = true; - } - - if(localName != ""){ - //std::cerr<<"local: "<<localname<<std::endl; - std::unordered_map<std::string, std::function<void()>>::const_iterator process = process_map.find(localname); - if (process != process_map.end()) { - process->second(); - } - } - - for(int pos = 0; pos < num_attributes; ++pos) { - - ctx.currentAttributeName = ""; - if(attributes[pos].prefix) { - ctx.currentAttributeName += attributes[pos].prefix; - ctx.currentAttributeName += ':'; - } - ctx.currentAttributeName += attributes[pos].localname; - ctx.currentAttributeValue = attributes[pos].value; - std::unordered_map<std::string, std::function<void()>>::const_iterator process = process_map2.find("xmlattribute"); - process->second(); - - } - - ctx.isOperator = false; - - } - /** - * charactersUnit - * @param ch the characers - * @param len number of characters - * - * SAX handler function for character handling within a unit. - * Overide for desired behaviour. - */ - virtual void charactersUnit(const char * ch, int len) override { - ctx.currentToken.clearclearclear(); - ctx.currentToken.append(ch, len); - std::unordered_map<std::string, std::function<void()>>::const_iterator process = process_map2.find("tokenstring"); - process->second(); - } - - // end elements may need to be used if you want to collect only on per file basis or some other granularity. - virtual void endRoot(const char * localname, const char * prefix, const char * URI) override { - - } - virtual void endUnit(const char * localname, const char * prefix, const char * URI) override { - - } - - virtual void endElement(const char * localname, const char * prefix, const char * URI) override { - - std::string localName; - if(prefix) { - localName += prefix; - localName += ':'; - } - localName += localname; - - ctx.currentTag = localName; - - std::unordered_map<std::string, std::function<void()>>::const_iterator process2 = process_map2.find(localname); - if (process2 != process_map2.end()) { - process2->second(); - } - - --ctx.depth; - - } - #pragma GCC diagnostic pop - - }; -} -#endif - - \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aa011d8..9cac515 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,8 +28,10 @@ file(GLOB POLICY_CLASSES_HEADER policy_classes/*.hpp) # find needed libraries find_package(LibXml2 REQUIRED) -add_library(srcsaxeventdispatch ${DISPATCHER_SOURCE} ${DISPATCHER_HEADER} ${POLICY_CLASSES_SOURCE} ${POLICY_CLASSES_HEADER}) -target_link_libraries(srcsaxeventdispatch PRIVATE LibXml2::LibXml2) +add_compile_options(-Wno-unused-function) -install(TARGETS srcsaxeventdispatch) +add_library(srcdispatch ${DISPATCHER_SOURCE} ${DISPATCHER_HEADER} ${POLICY_CLASSES_SOURCE} ${POLICY_CLASSES_HEADER}) +target_link_libraries(srcdispatch PRIVATE LibXml2::LibXml2) + +install(TARGETS srcdispatch) install(FILES ${DISPATCHER_HEADER} ${POLICY_CLASSES_HEADER} DESTINATION include/dispatch) diff --git a/src/dispatcher/srcSAXEventDispatchUtilities.hpp b/src/dispatcher/srcDispatchUtilities.hpp similarity index 52% rename from src/dispatcher/srcSAXEventDispatchUtilities.hpp rename to src/dispatcher/srcDispatchUtilities.hpp index b3e1c5d..c31dab8 100644 --- a/src/dispatcher/srcSAXEventDispatchUtilities.hpp +++ b/src/dispatcher/srcDispatchUtilities.hpp @@ -1,5 +1,5 @@ /** - * @file srcSAXEventDispatchUtilities.hpp + * @file srcDispatchUtilities.hpp * * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) * @@ -29,23 +29,28 @@ #include #include #include +#include + +#include +#include + #include #include #ifndef INCLUDED_SRCSAX_EVENT_DISPATCH_UTILITIES_HPP #define INCLUDED_SRCSAX_EVENT_DISPATCH_UTILITIES_HPP -namespace srcSAXEventDispatch{ +namespace srcDispatch { + class EventDispatcher; enum ElementState {open, close}; - enum ParserState {decl, expr, parameter, declstmt, exprstmt, parameterlist, elseif, elsestmt, - argumentlist, argumentlisttemplate, call, templates, ctrlflow, endflow, genericargumentlist, - name, function, functiondecl, constructor, constructordecl, destructordecl, destructor, - argument, index, block, type, typeprev, init, op, literal, modifier, memberlist, classn, structn, namespacen, - super_list, super, publicaccess, privateaccess, protectedaccess, preproc, whilestmt, forstmt, - ifstmt, nonterminal, macro, classblock, functionblock, constructorblock, ifblock, whileblock, forblock, - switchstmt, switchcase, specifier, throws, typedefexpr, userdefined, comment, annotation, condition, - dostmt, incr, decr, control, + enum ParserState {decl, expr, parameter, declstmt, exprstmt, parameterlist, genericparameterlist, elseif, elsestmt, argumentlist, argumentlisttemplate, + call, templates, ctrlflow, endflow, genericargumentlist, name, function, functiondecl, constructor, constructordecl, + destructordecl, destructor, argument, index, block, type, typeprev, init, op, literal, + modifier, memberlist, classn, structn, namespacen, super_list, super, publicaccess, privateaccess, protectedaccess, + preproc, whilestmt, forstmt, ifstmt, nonterminal, macro, switchstmt, switchcase, specifier, throws, + typedefexpr, userdefined, comment, annotation, condition, gotostmt, breakstmt, continuestmt, label, throwstmt, + trystmt, catchstmt, dostmt, incr, decr, control, ifgroup, range, returnstmt, // NLP states snoun, propersnoun, spronoun, sadjective, sverb, @@ -53,29 +58,31 @@ namespace srcSAXEventDispatch{ // stereotype state stereotype, - // srcDiff states - diff_common, diff_insert, diff_delete, diff_ws, - - archive, unit, returnstmt, + archive, unit, // do not put anything after these xmlattribute, tokenstring, empty, MAXENUMVALUE = empty}; + class srcSAXEventContext { public: srcSAXEventContext() = delete; srcSAXEventContext(EventDispatcher * dispatcher, const std::vector & elementStack) - : dispatcher(dispatcher), + : writer{0}, + archiveBuffer{0}, + dispatcher(dispatcher), elementStack(elementStack), + diffStack{COMMON}, + startLineNumber(0), + endLineNumber(0), triggerField(std::vector(MAXENUMVALUE, 0)), depth(0), + isArchive(false), isPrev(false), isOperator(false), - endArchive(false), - currentLineNumber{0}, - archiveBuffer{0}, - writer{0} {} - ~srcSAXEventContext(){ - if(writer){ + endArchive(false) {} + + ~srcSAXEventContext() { + if(writer) { xmlBufferFree(archiveBuffer); xmlFreeTextWriter(writer); } @@ -85,17 +92,19 @@ namespace srcSAXEventDispatch{ xmlBufferPtr archiveBuffer; EventDispatcher * dispatcher; - const std::vector & elementStack; + const std::vector& elementStack; + std::vector diffStack; std::vector genericDepth; - unsigned int currentLineNumber; + DeltaElement startLineNumber; + DeltaElement endLineNumber; std::vector triggerField; std::string currentFilePath, currentFileName, currentFileLanguage, currentsrcMLRevision, - currentTag, currentToken, currentAttributeName, currentAttributeValue, currentFunctionName, + currentTag, currentToken, currentAttributeName, currentAttributeValue, currentClassName, currentFileChecksum; std::vector currentNamespaces; std::size_t depth; std::map attributes; - bool isPrev, isOperator, endArchive; + bool isArchive, isPrev, isOperator, isPseudo, endArchive; /** * write_start_tag @@ -113,13 +122,13 @@ namespace srcSAXEventDispatch{ * Overide for desired behaviour. */ void write_start_tag(const char* localname, const char* prefix, const char* URI [[maybe_unused]], - int num_namespaces [[maybe_unused]], const struct srcsax_namespace * namespaces [[maybe_unused]], int num_attributes, - const struct srcsax_attribute * attributes) { - xmlTextWriterStartElementNS(writer, (const xmlChar *)prefix, (const xmlChar *)localname, 0); + int num_namespaces [[maybe_unused]], const struct srcsax_namespace* namespaces [[maybe_unused]], int num_attributes, + const struct srcsax_attribute* attributes) { + xmlTextWriterStartElementNS(writer, (const xmlChar*)prefix, (const xmlChar*)localname, 0); for(int pos = 0; pos < num_attributes; ++pos) { std::string str(attributes[pos].localname); - xmlTextWriterWriteAttributeNS(writer, (const xmlChar *)attributes[pos].prefix, (const xmlChar *)attributes[pos].localname, - (const xmlChar *)attributes[pos].uri, (const xmlChar *)attributes[pos].value); + xmlTextWriterWriteAttributeNS(writer, (const xmlChar*)attributes[pos].prefix, (const xmlChar*)attributes[pos].localname, + (const xmlChar*)attributes[pos].uri, (const xmlChar*)attributes[pos].value); } } /** @@ -128,7 +137,7 @@ namespace srcSAXEventDispatch{ * * Write out the provided text content, escaping everything but ". */ - void write_content(const std::string &text_content) { + void write_content(const std::string& text_content) { if(!text_content.empty()) { /* Normal output of text is for the most part @@ -136,117 +145,122 @@ namespace srcSAXEventDispatch{ srcML does not escape " while libxml2 does escape quotations. */ - int ret = 0; char * text = (char *)text_content.c_str(); for(char * pos = text; *pos; ++pos) { if(*pos != '"') continue; *pos = 0; - ret = xmlTextWriterWriteString(writer, (const xmlChar *)text); + xmlTextWriterWriteString(writer, (const xmlChar *)text); *pos = '\"'; xmlTextWriterWriteRaw(writer, (const xmlChar *)"\""); text = pos + 1; } - ret = xmlTextWriterWriteString(writer, (const xmlChar *)text); + xmlTextWriterWriteString(writer, (const xmlChar *)text); } } - inline bool And(const std::vector vec) const{ - for(auto field : vec){ + inline bool And(const std::vector vec) const { + for(auto field : vec) { if(triggerField[field]) continue; else return false; } return true; } - inline bool Nand(const std::vector vec) const{ - for(auto field : vec){ + inline bool Nand(const std::vector vec) const { + for(auto field : vec) { if(triggerField[field]) return false; else continue; } return true; } - inline bool Or(const std::vector vec) const{ - for(auto field : vec){ + inline bool Or(const std::vector vec) const { + for(auto field : vec) { if(triggerField[field]) return true; else continue; } return false; } - inline bool Nor(const std::vector vec) const{ - for(auto field : vec){ + inline bool Nor(const std::vector vec) const { + for(auto field : vec) { if(triggerField[field]) return false; else continue; } return true; } - inline bool IsEqualTo(const ParserState lhs, const ParserState rhs) const{ + inline bool IsEqualTo(const ParserState lhs, const ParserState rhs) const { return triggerField[lhs] == triggerField[rhs] ? true : false; } - inline bool IsGreaterThan(const ParserState lhs, const ParserState rhs) const{ + inline bool IsGreaterThan(const ParserState lhs, const ParserState rhs) const { return triggerField[lhs] > triggerField[rhs] ? true : false; } - inline bool IsGreaterThanOrEqualTo(const ParserState lhs, const ParserState rhs) const{ + inline bool IsGreaterThanOrEqualTo(const ParserState lhs, const ParserState rhs) const { return triggerField[lhs] >= triggerField[rhs] ? true : false; } - inline bool IsLessThan(const ParserState lhs, const ParserState rhs) const{ + inline bool IsLessThan(const ParserState lhs, const ParserState rhs) const { return triggerField[lhs] < triggerField[rhs] ? true : false; } - inline bool IsLessThanOrEqualTo(const ParserState lhs, const ParserState rhs) const{ + inline bool IsLessThanOrEqualTo(const ParserState lhs, const ParserState rhs) const { return triggerField[lhs] <= triggerField[rhs] ? true : false; } - inline bool IsOpen(const ParserState field) const{ + inline bool IsOpen(const ParserState field) const { if(triggerField[field]) return true; else return false; } - inline bool IsClosed(const ParserState field) const{ + inline bool IsClosed(const ParserState field) const { if(triggerField[field]) return false; else return true; } - inline unsigned int NumCurrentlyOpen(const ParserState field){ + inline unsigned int NumCurrentlyOpen(const ParserState field) { return triggerField[field]; } }; + class EventError : public std::runtime_error { + public: EventError(const std::string& msg) : std::runtime_error(msg) {} + }; + class EventListener { - typedef std::unordered_map, std::hash> EventMap; + typedef std::unordered_map, std::hash> EventMap; protected: + std::size_t depth; + bool dispatched; EventMap openEventMap, closeEventMap; - public: - EventListener() : dispatched(false) { + EventListener() : depth(0), dispatched(false) { DefaultEventHandlers(); } + virtual ~EventListener() {} void SetDispatched(bool isDispatched) { dispatched = isDispatched; } - virtual const EventMap & GetOpenEventMap() const { return openEventMap; } - virtual const EventMap & GetCloseEventMap() const { return closeEventMap; } + virtual const EventMap& GetOpenEventMap() const { return openEventMap; } + virtual const EventMap& GetCloseEventMap() const { return closeEventMap; } virtual void HandleEvent() { dispatched = true; } - virtual void HandleEvent(srcSAXEventDispatch::ParserState pstate, srcSAXEventDispatch::ElementState estate, srcSAXEventDispatch::srcSAXEventContext& ctx) { + virtual void HandleEvent(srcDispatch::ParserState pstate, srcDispatch::ElementState estate, srcDispatch::srcSAXEventContext& ctx) { if(dispatched) return; dispatched = true; - switch(estate){ + switch(estate) { - case srcSAXEventDispatch::ElementState::open: { + case srcDispatch::ElementState::open: { auto event = openEventMap.find(pstate); - if(event != openEventMap.end()){ + if(event != openEventMap.end()) { event->second(ctx); } break; } - case srcSAXEventDispatch::ElementState::close: { + case srcDispatch::ElementState::close: { auto event = closeEventMap.find(pstate); - if(event != closeEventMap.end()){ + if(event != closeEventMap.end()) { event->second(ctx); } break; @@ -263,18 +277,14 @@ namespace srcSAXEventDispatch{ void NopOpenEvents(std::initializer_list states) { for(ParserState state : states) { - - openEventMap[state] = [this](const srcSAXEventContext& ctx [[maybe_unused]]) {}; - + openEventMap[state] = [](const srcSAXEventContext& ctx [[maybe_unused]]) {}; } } void NopCloseEvents(std::initializer_list states) { for(ParserState state : states) { - - closeEventMap[state] = [this](const srcSAXEventContext& ctx [[maybe_unused]]) {}; - + closeEventMap[state] = [](const srcSAXEventContext& ctx [[maybe_unused]]) {}; } } @@ -282,130 +292,7 @@ namespace srcSAXEventDispatch{ private: void DefaultEventHandlers() { - using namespace srcSAXEventDispatch; - - NopOpenEvents({ - ParserState::declstmt, - ParserState::exprstmt, - ParserState::parameterlist, - ParserState::condition, - ParserState::dostmt, - ParserState::incr, - ParserState::decr, - ParserState::ifstmt, - ParserState::forstmt, - ParserState::control, - ParserState::whilestmt, - ParserState::switchstmt, - ParserState::switchcase, - ParserState::templates, - ParserState::argumentlist, - ParserState::genericargumentlist, - ParserState::call, - ParserState::function, - ParserState::constructor, - ParserState::functiondecl, - ParserState::destructordecl, - ParserState::constructordecl, - ParserState::classn, - ParserState::structn, - ParserState::publicaccess, - ParserState::protectedaccess, - ParserState::privateaccess, - ParserState::destructor, - ParserState::parameter, - ParserState::super, - ParserState::super_list, - ParserState::memberlist, - ParserState::index, - ParserState::op, - ParserState::block, - ParserState::init, - ParserState::argument, - ParserState::literal, - ParserState::modifier, - ParserState::decl, - ParserState::type, - ParserState::typedefexpr, - ParserState::expr, - ParserState::name, - ParserState::macro, - ParserState::specifier, - ParserState::snoun, - ParserState::propersnoun, - ParserState::sadjective, - ParserState::spronoun, - ParserState::sverb, - ParserState::returnstmt, - ParserState::throws, - ParserState::comment, - ParserState::stereotype, - ParserState::annotation, - ParserState::archive, - }); - - NopCloseEvents({ - ParserState::declstmt, - ParserState::exprstmt, - ParserState::parameterlist, - ParserState::condition, - ParserState::dostmt, - ParserState::incr, - ParserState::decr, - ParserState::ifstmt, - ParserState::forstmt, - ParserState::control, - ParserState::whilestmt, - ParserState::switchstmt, - ParserState::switchcase, - ParserState::templates, - ParserState::argumentlist, - ParserState::genericargumentlist, - ParserState::call, - ParserState::function, - ParserState::constructor, - ParserState::destructor, - ParserState::functiondecl, - ParserState::constructordecl, - ParserState::destructordecl, - ParserState::classn, - ParserState::structn, - ParserState::publicaccess, - ParserState::protectedaccess, - ParserState::privateaccess, - ParserState::parameter, - ParserState::super, - ParserState::super_list, - ParserState::memberlist, - ParserState::index, - ParserState::op, - ParserState::block, - ParserState::init, - ParserState::argument, - ParserState::literal, - ParserState::modifier, - ParserState::decl, - ParserState::type, - ParserState::typedefexpr, - ParserState::expr, - ParserState::name, - ParserState::macro, - ParserState::tokenstring, - ParserState::specifier, - ParserState::snoun, - ParserState::propersnoun, - ParserState::sadjective, - ParserState::spronoun, - ParserState::sverb, - ParserState::stereotype, - ParserState::returnstmt, - ParserState::throws, - ParserState::comment, - ParserState::annotation, - ParserState::archive, - }); - - } + } }; class EventDispatcher { @@ -416,15 +303,40 @@ namespace srcSAXEventDispatch{ virtual void RemoveListener(EventListener* l) = 0; virtual void RemoveListenerDispatch(EventListener* listener) = 0; virtual void RemoveListenerNoDispatch(EventListener* listener) = 0; - xmlBufferPtr GetXmlBuffer(){return ctx.archiveBuffer;} + xmlBufferPtr GetXmlBuffer() {return ctx.archiveBuffer;} protected: srcSAXEventContext ctx; std::list elementListeners; - EventDispatcher(const std::vector & elementStack) - : elementListeners(), ctx(this, elementStack) {} + ParserState currentPState; + ElementState currentEState; + + EventDispatcher(const std::vector& elementStack) + : ctx(this, elementStack), elementListeners() {} virtual ~EventDispatcher() {} virtual void DispatchEvent(ParserState, ElementState) = 0; + +public: + const srcSAXEventContext& GetContext() const { + return ctx; + } + + srcSAXEventContext& GetContext() { + return ctx; + } + + ParserState CurrentPState() const { + return currentPState; + } + + ElementState CurrentEState() const { + return currentEState; + } + + }; + + class PolicyError : public std::runtime_error { + public: PolicyError(const std::string& msg) : std::runtime_error(msg) {} }; class PolicyDispatcher; class PolicyListener { @@ -433,17 +345,17 @@ namespace srcSAXEventDispatch{ PolicyListener() {} virtual ~PolicyListener() {} - virtual void Notify(const PolicyDispatcher * policy, const srcSAXEventContext & ctx) = 0; - virtual void NotifyWrite(const PolicyDispatcher * policy, srcSAXEventContext & ctx) = 0; + virtual void Notify(const PolicyDispatcher* policy, const srcSAXEventContext& ctx) = 0; + virtual void NotifyWrite(const PolicyDispatcher* policy, srcSAXEventContext& ctx) = 0; }; - class PolicyDispatcher{ + class PolicyDispatcher { public: - PolicyDispatcher(std::initializer_list listeners) : policyListeners(listeners){} + PolicyDispatcher(std::initializer_list listeners) : policyListeners(listeners) {} virtual ~PolicyDispatcher() {} - virtual void AddListener(PolicyListener* listener){ + virtual void AddListener(PolicyListener* listener) { policyListeners.push_back(listener); } - virtual void RemoveListener(PolicyListener* listener){ + virtual void RemoveListener(PolicyListener* listener) { policyListeners.erase(std::find(policyListeners.begin(), policyListeners.end(), listener)); } @@ -456,17 +368,23 @@ namespace srcSAXEventDispatch{ std::list policyListeners; virtual std::any DataInner() const = 0; //TODO: These may not need to be synchronous or even called in the same method (i.e., notifyall) - virtual void NotifyAll(/*const*/ srcSAXEventContext & ctx) { - for(std::list::iterator listener = policyListeners.begin(); listener != policyListeners.end(); ++listener){ + virtual void NotifyAll(/*const*/ srcSAXEventContext& ctx) { + for(std::list::iterator listener = policyListeners.begin(); listener != policyListeners.end(); ++listener) { (*listener)->Notify(this, ctx); } - for(std::list::iterator listener = policyListeners.begin(); listener != policyListeners.end(); ++listener){ + for(std::list::iterator listener = policyListeners.begin(); listener != policyListeners.end(); ++listener) { (*listener)->NotifyWrite(this, ctx); } } }; + + template + constexpr std::unique_ptr make_unique_policy(const std::initializer_list& args) { + return std::make_unique(args); + } + } #endif diff --git a/src/dispatcher/srcSAXEventDispatcher.hpp b/src/dispatcher/srcDispatcher.hpp similarity index 67% rename from src/dispatcher/srcSAXEventDispatcher.hpp rename to src/dispatcher/srcDispatcher.hpp index 68708a4..35172a5 100644 --- a/src/dispatcher/srcSAXEventDispatcher.hpp +++ b/src/dispatcher/srcDispatcher.hpp @@ -1,5 +1,5 @@ /** - * @file srcSAXEventDispatcher.hpp + * @file srcDispatcher.hpp * * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) * @@ -18,9 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#ifndef INCLUDED_SRCSAXEVENTDISPATCHER_HPP -#define INCLUDED_SRCSAXEVENTDISPATCHER_HPP +#ifndef INCLUDED_SRCDISPATCHER_HPP +#define INCLUDED_SRCDISPATCHER_HPP #include #include @@ -29,12 +28,15 @@ #include #include #include -#include +#include #include +#include +#include +#include #include -#include +#include -namespace srcSAXEventDispatch { +namespace srcDispatch { template static std::list CreateListenersImpl(PolicyListener * policyListener, std::list & listeners); @@ -63,37 +65,44 @@ namespace srcSAXEventDispatch { return listeners; } + const std::string DIFF_URI = "http://www.srcML.org/srcDiff"; + template - class srcSAXEventDispatcher : public srcSAXHandler, public EventDispatcher { + class srcDispatcher : public srcSAXHandler, public EventDispatcher { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" private: std::unordered_map< std::string, std::function> process_map, process_map2; - bool classflagopen, functionflagopen, constructorflagopen, whileflagopen, ifflagopen, elseflagopen, ifelseflagopen, forflagopen, switchflagopen; + + std::vector elseif_positions; bool dispatching; + bool dispatched; bool generateArchive; - ParserState currentPState; - ElementState currentEState; std::size_t numberAllocatedListeners; + const std::unordered_set nameCollectElements{ "class", "struct", "namespace" }; + std::optional collectedText; + protected: - void DispatchEvent(ParserState pstate, ElementState estate) override { - dispatching = true; - currentPState = pstate; - currentEState = estate; + virtual void DispatchEvent(srcDispatch::ParserState pstate, srcDispatch::ElementState estate) override { + + srcDispatcher::currentPState = pstate; + srcDispatcher::currentEState = estate; + + while(!dispatched) { + + dispatched = true; + + EventDispatcher::elementListeners.back()->HandleEvent(pstate, estate, EventDispatcher::ctx); + EventDispatcher::elementListeners.back()->SetDispatched(false); - for(std::list::iterator listener = elementListeners.begin(); listener != elementListeners.end(); ++listener ){ - (*listener)->HandleEvent(pstate, estate, ctx); - } - for(std::list::iterator listener = elementListeners.begin(); listener != elementListeners.end(); ++listener ){ - (*listener)->SetDispatched(false); } - dispatching = false; + dispatched = false; } @@ -118,7 +127,7 @@ namespace srcSAXEventDispatch { virtual void AddEvents(std::initializer_list events) { - for(const std::string & event : events){ + for(const std::string & event : events) { AddEvent(event); } @@ -131,26 +140,26 @@ namespace srcSAXEventDispatch { virtual void RemoveEvents(std::initializer_list events) { - for(const std::string & event : events){ + for(const std::string & event : events) { RemoveEvent(event); } } public: - virtual ~srcSAXEventDispatcher() { + virtual ~srcDispatcher() { for(std::size_t count = 0; count < numberAllocatedListeners; ++count) { delete elementListeners.front(); elementListeners.pop_front(); } } - srcSAXEventDispatcher(PolicyListener * listener, bool genArchive = false) : EventDispatcher(srcml_element_stack) { + srcDispatcher(PolicyListener * listener, bool genArchive = false) + : EventDispatcher(element_stack), + elseif_positions(), dispatching(false), generateArchive(genArchive), collectedText(std::optional()) { + elementListeners = CreateListeners(listener); numberAllocatedListeners = elementListeners.size(); - dispatching = false; - generateArchive = genArchive; - classflagopen = functionflagopen = constructorflagopen = whileflagopen = ifflagopen = elseflagopen = ifelseflagopen = forflagopen = switchflagopen = false; if(genArchive) { ctx.archiveBuffer = xmlBufferCreate(); @@ -159,120 +168,120 @@ namespace srcSAXEventDispatch { InitializeHandlers(); } - srcSAXEventDispatcher(std::initializer_list listeners, bool genArchive = false) : EventDispatcher(srcml_element_stack) { + srcDispatcher(std::initializer_list listeners, bool genArchive = false) + : EventDispatcher(element_stack), + elseif_positions(), dispatching(false), generateArchive(genArchive), collectedText(std::optional()) { + elementListeners = listeners; numberAllocatedListeners = elementListeners.size(); - dispatching = false; - generateArchive = genArchive; - classflagopen = functionflagopen = constructorflagopen = whileflagopen = ifflagopen = elseflagopen = ifelseflagopen = forflagopen = switchflagopen = false; + if(genArchive) { ctx.archiveBuffer = xmlBufferCreate(); ctx.writer = xmlNewTextWriterMemory(ctx.archiveBuffer, 0); } InitializeHandlers(); } - void AddListener(EventListener* listener) override { - elementListeners.push_back(listener); + virtual void AddListener(EventListener * listener) override { + EventDispatcher::elementListeners.back()->SetDispatched(false); + EventDispatcher::elementListeners.push_back(listener); } - void AddListenerDispatch(EventListener* listener) override { - if(dispatching){ - listener->HandleEvent(currentPState, currentEState, ctx); - } + virtual void AddListenerDispatch(EventListener * listener) override { AddListener(listener); + dispatched = false; } - void AddListenerNoDispatch(EventListener* listener) override { - if(dispatching){ - listener->SetDispatched(true); - } + virtual void AddListenerNoDispatch(EventListener * listener) override { AddListener(listener); } - void RemoveListener(EventListener* listener) override { - elementListeners.erase(std::find(elementListeners.begin(), elementListeners.end(), listener)); + virtual void RemoveListener(EventListener * listener) override { + EventDispatcher::elementListeners.back()->SetDispatched(false); + EventDispatcher::elementListeners.pop_back(); } - void RemoveListenerDispatch(EventListener* listener) override { - if(dispatching){ - listener->HandleEvent(currentPState, currentEState, ctx); - } + virtual void RemoveListenerDispatch(EventListener * listener) override { RemoveListener(listener); + dispatched = false; } - void RemoveListenerNoDispatch(EventListener* listener) override { - if(dispatching){ - listener->SetDispatched(true); - } + virtual void RemoveListenerNoDispatch(EventListener * listener) override { RemoveListener(listener); } - void InitializeHandlers(){ + void InitializeHandlers() { process_map = { - {"decl_stmt", [this](){ + {"decl_stmt", [this]() { ++ctx.triggerField[ParserState::declstmt]; DispatchEvent(ParserState::declstmt, ElementState::open); } }, - { "expr_stmt", [this](){ + { "expr_stmt", [this]() { ++ctx.triggerField[ParserState::exprstmt]; DispatchEvent(ParserState::exprstmt, ElementState::open); } }, - { "parameter_list", [this](){ + { "parameter_list", [this]() { + if(!ctx.genericDepth.empty()) { + if(ctx.genericDepth.back() == ctx.depth) { + ++ctx.triggerField[ParserState::genericparameterlist]; + DispatchEvent(ParserState::genericparameterlist, ElementState::open); + } + } ++ctx.triggerField[ParserState::parameterlist]; DispatchEvent(ParserState::parameterlist, ElementState::open); } }, - { "condition", [this](){ + { "condition", [this]() { ++ctx.triggerField[ParserState::condition]; DispatchEvent(ParserState::condition, ElementState::open); } }, - { "switch", [this](){ + { "switch", [this]() { ++ctx.triggerField[ParserState::switchstmt]; DispatchEvent(ParserState::switchstmt, ElementState::open); } }, - { "case", [this](){ + { "case", [this]() { ++ctx.triggerField[ParserState::switchcase]; DispatchEvent(ParserState::switchcase, ElementState::open); } }, - { "do", [this](){ + { "do", [this]() { ++ctx.triggerField[ParserState::dostmt]; DispatchEvent(ParserState::dostmt, ElementState::open); } }, - { "incr", [this](){ + { "incr", [this]() { ++ctx.triggerField[ParserState::incr]; DispatchEvent(ParserState::incr, ElementState::open); } }, - { "decr", [this](){ + { "decr", [this]() { ++ctx.triggerField[ParserState::decr]; DispatchEvent(ParserState::decr, ElementState::open); } }, - { "if", [this](){ - if(!ifelseflagopen){ - ifflagopen = true; - ++ctx.triggerField[ParserState::ifstmt]; - DispatchEvent(ParserState::ifstmt, ElementState::open); - }else{ - ++ctx.triggerField[ParserState::elseif]; - DispatchEvent(ParserState::elseif, ElementState::open); - } + { "if_stmt", [this]() { + ++ctx.triggerField[ParserState::ifgroup]; + DispatchEvent(ParserState::ifgroup, ElementState::open); + } }, + { "if", [this]() { + ++ctx.triggerField[ParserState::ifstmt]; + DispatchEvent(ParserState::ifstmt, ElementState::open); + } }, + { "elseif", [this]() { + ++ctx.triggerField[ParserState::elseif]; + DispatchEvent(ParserState::elseif, ElementState::open); } }, - { "else", [this](){ + { "else", [this]() { ++ctx.triggerField[ParserState::elsestmt]; DispatchEvent(ParserState::elsestmt, ElementState::open); } }, - { "for", [this](){ + { "for", [this]() { ++ctx.triggerField[ParserState::forstmt]; DispatchEvent(ParserState::forstmt, ElementState::open); } }, - { "control", [this](){ + { "control", [this]() { ++ctx.triggerField[ParserState::control]; DispatchEvent(ParserState::control, ElementState::open); } }, - { "while", [this](){ - whileflagopen = true; + { "while", [this]() { ++ctx.triggerField[ParserState::whilestmt]; DispatchEvent(ParserState::whilestmt, ElementState::open); } }, - { "template", [this](){ + { "template", [this]() { ++ctx.triggerField[ParserState::templates]; DispatchEvent(ParserState::templates, ElementState::open); } }, - { "argument_list", [this](){ - if(!ctx.genericDepth.empty()){ - if(ctx.genericDepth.back() == ctx.depth){ + { "argument_list", [this]() { + if(!ctx.genericDepth.empty()) { + if(ctx.genericDepth.back() == ctx.depth) { ++ctx.triggerField[ParserState::genericargumentlist]; DispatchEvent(ParserState::genericargumentlist, ElementState::open); } @@ -280,139 +289,111 @@ namespace srcSAXEventDispatch { DispatchEvent(ParserState::argumentlist, ElementState::open); ++ctx.triggerField[ParserState::argumentlist]; } }, - { "call", [this](){ + { "call", [this]() { ++ctx.triggerField[ParserState::call]; DispatchEvent(ParserState::call, ElementState::open); } }, - { "function", [this](){ - functionflagopen = true; + { "function", [this]() { ++ctx.triggerField[ParserState::function]; DispatchEvent(ParserState::function, ElementState::open); } }, - { "constructor", [this](){ - constructorflagopen = true; + { "constructor", [this]() { ++ctx.triggerField[ParserState::constructor]; DispatchEvent(ParserState::constructor, ElementState::open); } }, - { "function_decl", [this](){ + { "function_decl", [this]() { ++ctx.triggerField[ParserState::functiondecl]; DispatchEvent(ParserState::functiondecl, ElementState::open); } }, - { "destructor_decl", [this](){ + { "destructor_decl", [this]() { ++ctx.triggerField[ParserState::destructordecl]; DispatchEvent(ParserState::destructordecl, ElementState::open); } }, - { "constructor_decl", [this](){ + { "constructor_decl", [this]() { ++ctx.triggerField[ParserState::constructordecl]; DispatchEvent(ParserState::constructordecl, ElementState::open); } }, - { "class", [this](){ - classflagopen = true; + { "class", [this]() { ++ctx.triggerField[ParserState::classn]; DispatchEvent(ParserState::classn, ElementState::open); } }, - { "struct", [this](){ - classflagopen = true; + { "struct", [this]() { ++ctx.triggerField[ParserState::classn]; DispatchEvent(ParserState::structn, ElementState::open); } }, - { "namespace", [this](){ - // classflagopen = true; + { "namespace", [this]() { ++ctx.triggerField[ParserState::namespacen]; DispatchEvent(ParserState::namespacen, ElementState::open); } }, - { "super_list", [this](){ + { "super_list", [this]() { ++ctx.triggerField[ParserState::super_list]; DispatchEvent(ParserState::super_list, ElementState::open); } }, - { "super", [this](){ + { "super", [this]() { ++ctx.triggerField[ParserState::super]; DispatchEvent(ParserState::super, ElementState::open); } }, - { "public", [this](){ + { "public", [this]() { ++ctx.triggerField[ParserState::publicaccess]; DispatchEvent(ParserState::publicaccess, ElementState::open); } }, - { "protected", [this](){ + { "protected", [this]() { ++ctx.triggerField[ParserState::protectedaccess]; DispatchEvent(ParserState::protectedaccess, ElementState::open); } }, - { "private", [this](){ + { "private", [this]() { ++ctx.triggerField[ParserState::privateaccess]; DispatchEvent(ParserState::privateaccess, ElementState::open); } }, - { "destructor", [this](){ - //functionflagopen = true; + { "destructor", [this]() { ++ctx.triggerField[ParserState::destructor]; DispatchEvent(ParserState::destructor, ElementState::open); } }, - { "parameter", [this](){ + { "parameter", [this]() { ++ctx.triggerField[ParserState::parameter]; DispatchEvent(ParserState::parameter, ElementState::open); } }, - { "member_list", [this](){ + { "member_list", [this]() { ++ctx.triggerField[ParserState::memberlist]; DispatchEvent(ParserState::memberlist, ElementState::open); } }, - { "index", [this](){ + { "index", [this]() { ++ctx.triggerField[ParserState::index]; DispatchEvent(ParserState::index, ElementState::open); } }, - { "operator", [this](){ + { "operator", [this]() { ++ctx.triggerField[ParserState::op]; DispatchEvent(ParserState::op, ElementState::open); } }, - { "block", [this](){ + { "block", [this]() { ++ctx.triggerField[ParserState::block]; - if(constructorflagopen){ - constructorflagopen = false; - ++ctx.triggerField[ParserState::constructorblock]; - DispatchEvent(ParserState::constructorblock, ElementState::open); - } - if(functionflagopen){ - functionflagopen = false; - ++ctx.triggerField[ParserState::functionblock]; - DispatchEvent(ParserState::functionblock, ElementState::open); - } - if(classflagopen){ - classflagopen = false; //next time it's set to true, we definitely are in a new one. - ++ctx.triggerField[ParserState::classblock]; - } - if(whileflagopen){ - whileflagopen = false; - ++ctx.triggerField[ParserState::whileblock]; - } - if(ifelseflagopen){ - ifflagopen = false; - ++ctx.triggerField[ParserState::ifblock]; - } - if(forflagopen){ - forflagopen = false; - ++ctx.triggerField[ParserState::forblock]; - } DispatchEvent(ParserState::block, ElementState::open); } }, - { "init", [this](){ + { "init", [this]() { ++ctx.triggerField[ParserState::init]; DispatchEvent(ParserState::init, ElementState::open); } }, - { "argument", [this](){ + { "range", [this]() { + ++ctx.triggerField[ParserState::range]; + DispatchEvent(ParserState::range, ElementState::open); + } }, + { "argument", [this]() { ++ctx.triggerField[ParserState::argument]; DispatchEvent(ParserState::argument, ElementState::open); } }, - { "literal", [this](){ + { "literal", [this]() { ++ctx.triggerField[ParserState::literal]; DispatchEvent(ParserState::literal, ElementState::open); } }, - { "modifier", [this](){ + { "modifier", [this]() { ++ctx.triggerField[ParserState::modifier]; DispatchEvent(ParserState::modifier, ElementState::open); } }, - { "decl", [this](){ + { "decl", [this]() { ++ctx.triggerField[ParserState::decl]; DispatchEvent(ParserState::decl, ElementState::open); } }, - { "type", [this](){ + { "type", [this]() { if(ctx.isPrev) { ++ctx.triggerField[ParserState::typeprev]; DispatchEvent(ParserState::typeprev, ElementState::open); @@ -420,164 +401,182 @@ namespace srcSAXEventDispatch { ++ctx.triggerField[ParserState::type]; DispatchEvent(ParserState::type, ElementState::open); } }, - { "typedef", [this](){ + { "typedef", [this]() { ++ctx.triggerField[ParserState::typedefexpr]; DispatchEvent(ParserState::typedefexpr, ElementState::open); } }, - { "expr", [this](){ + { "expr", [this]() { ++ctx.triggerField[ParserState::expr]; DispatchEvent(ParserState::expr, ElementState::open); } }, - { "name", [this](){ + { "name", [this]() { ++ctx.triggerField[ParserState::name]; DispatchEvent(ParserState::name, ElementState::open); } }, - { "macro", [this](){ + { "macro", [this]() { ++ctx.triggerField[ParserState::macro]; DispatchEvent(ParserState::macro, ElementState::open); } }, - { "specifier", [this](){ + { "specifier", [this]() { ++ctx.triggerField[ParserState::specifier]; DispatchEvent(ParserState::specifier, ElementState::open); } }, - { "noun", [this](){ + { "noun", [this]() { ++ctx.triggerField[ParserState::snoun]; DispatchEvent(ParserState::snoun, ElementState::open); } }, - { "propernoun", [this](){ + { "propernoun", [this]() { ++ctx.triggerField[ParserState::propersnoun]; DispatchEvent(ParserState::propersnoun, ElementState::open); } }, - { "pronoun", [this](){ + { "pronoun", [this]() { ++ctx.triggerField[ParserState::spronoun]; DispatchEvent(ParserState::spronoun, ElementState::open); } }, - { "adjective", [this](){ + { "adjective", [this]() { ++ctx.triggerField[ParserState::sadjective]; DispatchEvent(ParserState::sadjective, ElementState::open); } }, - { "verb", [this](){ + { "verb", [this]() { ++ctx.triggerField[ParserState::sverb]; DispatchEvent(ParserState::sverb, ElementState::open); } }, - { "stereotype", [this](){ + { "stereotype", [this]() { ++ctx.triggerField[ParserState::stereotype]; DispatchEvent(ParserState::stereotype, ElementState::open); } }, - { "diff:delete", [this](){ - ++ctx.triggerField[ParserState::diff_delete]; - DispatchEvent(ParserState::diff_delete, ElementState::open); - } }, - { "diff:insert", [this](){ - ++ctx.triggerField[ParserState::diff_insert]; - DispatchEvent(ParserState::diff_insert, ElementState::open); - } }, - { "diff:common", [this](){ - ++ctx.triggerField[ParserState::diff_common]; - DispatchEvent(ParserState::diff_common, ElementState::open); - } }, - { "diff:ws", [this](){ - ++ctx.triggerField[ParserState::diff_ws]; - DispatchEvent(ParserState::diff_ws, ElementState::open); - } }, - { "unit", [this](){ - if(ctx.triggerField[ParserState::unit] == 0){ + { "unit", [this]() { + if(ctx.triggerField[ParserState::unit] == 0) { ctx.triggerField[ParserState::archive] = 1; DispatchEvent(ParserState::archive, ElementState::open); } ++ctx.triggerField[ParserState::unit]; DispatchEvent(ParserState::unit, ElementState::open); } }, - { "throws", [this](){ + { "throws", [this]() { ++ctx.triggerField[ParserState::throws]; DispatchEvent(ParserState::throws, ElementState::open); } }, - { "annotation", [this](){ + { "throw", [this]() { + ++ctx.triggerField[ParserState::throwstmt]; + DispatchEvent(ParserState::throwstmt, ElementState::open); + } }, + { "try", [this]() { + ++ctx.triggerField[ParserState::trystmt]; + DispatchEvent(ParserState::trystmt, ElementState::open); + } }, + { "catch", [this]() { + ++ctx.triggerField[ParserState::catchstmt]; + DispatchEvent(ParserState::catchstmt, ElementState::open); + } }, + { "annotation", [this]() { ++ctx.triggerField[ParserState::annotation]; DispatchEvent(ParserState::annotation, ElementState::open); } }, - { "return", [this](){ + { "return", [this]() { ++ctx.triggerField[ParserState::returnstmt]; DispatchEvent(ParserState::returnstmt, ElementState::open); } }, - { "comment", [this](){ + { "goto", [this]() { + ++ctx.triggerField[ParserState::gotostmt]; + DispatchEvent(ParserState::gotostmt, ElementState::open); + } }, + { "break", [this]() { + ++ctx.triggerField[ParserState::breakstmt]; + DispatchEvent(ParserState::breakstmt, ElementState::open); + } }, + { "continue", [this]() { + ++ctx.triggerField[ParserState::continuestmt]; + DispatchEvent(ParserState::continuestmt, ElementState::open); + } }, + { "label", [this]() { + ++ctx.triggerField[ParserState::label]; + DispatchEvent(ParserState::label, ElementState::open); + } }, + { "comment", [this]() { ++ctx.triggerField[ParserState::comment]; DispatchEvent(ParserState::comment, ElementState::open); } }, }; process_map2 = { - {"decl_stmt", [this](){ + {"decl_stmt", [this]() { DispatchEvent(ParserState::declstmt, ElementState::close); --ctx.triggerField[ParserState::declstmt]; } }, - { "expr_stmt", [this](){ + { "expr_stmt", [this]() { DispatchEvent(ParserState::exprstmt, ElementState::close); --ctx.triggerField[ParserState::exprstmt]; } }, - { "parameter_list", [this](){ + { "parameter_list", [this]() { + if(!ctx.genericDepth.empty()) { + if(ctx.genericDepth.back() == ctx.depth) { + DispatchEvent(ParserState::genericparameterlist, ElementState::close); + --ctx.triggerField[ParserState::genericparameterlist]; + ctx.genericDepth.pop_back(); + } + } DispatchEvent(ParserState::parameterlist, ElementState::close); --ctx.triggerField[ParserState::parameterlist]; } }, - { "condition", [this](){ + { "condition", [this]() { DispatchEvent(ParserState::condition, ElementState::close); --ctx.triggerField[ParserState::condition]; } }, - { "switch", [this](){ + { "switch", [this]() { DispatchEvent(ParserState::switchstmt, ElementState::close); --ctx.triggerField[ParserState::switchstmt]; } }, - { "case", [this](){ + { "case", [this]() { DispatchEvent(ParserState::switchcase, ElementState::close); --ctx.triggerField[ParserState::switchcase]; } }, - { "do", [this](){ + { "do", [this]() { DispatchEvent(ParserState::dostmt, ElementState::close); --ctx.triggerField[ParserState::dostmt]; } }, - { "incr", [this](){ + { "incr", [this]() { DispatchEvent(ParserState::incr, ElementState::close); --ctx.triggerField[ParserState::incr]; } }, - { "decr", [this](){ + { "decr", [this]() { DispatchEvent(ParserState::decr, ElementState::close); --ctx.triggerField[ParserState::decr]; } }, - { "if", [this](){ - if(!ifelseflagopen){ - --ctx.triggerField[ParserState::ifblock]; - DispatchEvent(ParserState::ifstmt, ElementState::close); - --ctx.triggerField[ParserState::ifstmt]; - }else{ - --ctx.triggerField[ParserState::elseif]; - DispatchEvent(ParserState::elseif, ElementState::close); - ifelseflagopen = false; - } - } }, - { "else", [this](){ + { "if_stmt", [this]() { + DispatchEvent(ParserState::ifgroup, ElementState::close); + --ctx.triggerField[ParserState::ifgroup]; + } }, + { "if", [this]() { + DispatchEvent(ParserState::ifstmt, ElementState::close); + --ctx.triggerField[ParserState::ifstmt]; + } }, + { "elseif", [this]() { + DispatchEvent(ParserState::elseif, ElementState::close); + --ctx.triggerField[ParserState::elseif]; + } }, + { "else", [this]() { --ctx.triggerField[ParserState::elsestmt]; DispatchEvent(ParserState::elsestmt, ElementState::close); } }, - { "for", [this](){ - --ctx.triggerField[ParserState::forblock]; + { "for", [this]() { DispatchEvent(ParserState::forstmt, ElementState::close); --ctx.triggerField[ParserState::forstmt]; } }, - { "control", [this](){ + { "control", [this]() { --ctx.triggerField[ParserState::control]; DispatchEvent(ParserState::control, ElementState::close); } }, - { "while", [this](){ - --ctx.triggerField[ParserState::whileblock]; + { "while", [this]() { DispatchEvent(ParserState::whilestmt, ElementState::close); --ctx.triggerField[ParserState::whilestmt]; } }, - { "template", [this](){ + { "template", [this]() { DispatchEvent(ParserState::templates, ElementState::close); --ctx.triggerField[ParserState::templates]; } }, - { "argument_list", [this](){ - if(!ctx.genericDepth.empty()){ - if(ctx.genericDepth.back() == ctx.depth){ + { "argument_list", [this]() { + if(!ctx.genericDepth.empty()) { + if(ctx.genericDepth.back() == ctx.depth) { DispatchEvent(ParserState::genericargumentlist, ElementState::close); --ctx.triggerField[ParserState::genericargumentlist]; ctx.genericDepth.pop_back(); @@ -586,125 +585,113 @@ namespace srcSAXEventDispatch { DispatchEvent(ParserState::argumentlist, ElementState::close); --ctx.triggerField[ParserState::argumentlist]; } }, - { "call", [this](){ + { "call", [this]() { DispatchEvent(ParserState::call, ElementState::close); --ctx.triggerField[ParserState::call]; } }, - { "function", [this](){ - DispatchEvent(ParserState::functionblock, ElementState::close); - ctx.currentFunctionName.clear(); - --ctx.triggerField[ParserState::functionblock]; - + { "function", [this]() { DispatchEvent(ParserState::function, ElementState::close); --ctx.triggerField[ParserState::function]; } }, - { "constructor", [this](){ - //This code causes problems for some reason. FIX. - DispatchEvent(ParserState::constructorblock, ElementState::close); - ctx.currentFunctionName.clear(); - --ctx.triggerField[ParserState::constructorblock]; - + { "constructor", [this]() { DispatchEvent(ParserState::constructor, ElementState::close); --ctx.triggerField[ParserState::constructor]; } }, - { "destructor", [this](){ - //This code causes problems for some reason. FIX. -/* DispatchEvent(ParserState::functionblock, ElementState::close); - --ctx.triggerField[ParserState::functionblock];*/ - + { "destructor", [this]() { DispatchEvent(ParserState::destructor, ElementState::close); --ctx.triggerField[ParserState::destructor]; } }, - { "function_decl", [this](){ + { "function_decl", [this]() { DispatchEvent(ParserState::functiondecl, ElementState::close); --ctx.triggerField[ParserState::functiondecl]; } }, - { "constructor_decl", [this](){ + { "constructor_decl", [this]() { DispatchEvent(ParserState::constructordecl, ElementState::close); --ctx.triggerField[ParserState::constructordecl]; } }, - { "destructor_decl", [this](){ + { "destructor_decl", [this]() { DispatchEvent(ParserState::destructordecl, ElementState::close); --ctx.triggerField[ParserState::destructordecl]; } }, - { "class", [this](){ - --ctx.triggerField[ParserState::classblock]; - DispatchEvent(ParserState::classn, ElementState::close); + { "class", [this]() { ctx.currentClassName.clear(); + DispatchEvent(ParserState::classn, ElementState::close); --ctx.triggerField[ParserState::classn]; } }, - { "struct", [this](){ - --ctx.triggerField[ParserState::classblock]; - DispatchEvent(ParserState::structn, ElementState::close); + { "struct", [this]() { ctx.currentClassName.clear(); + DispatchEvent(ParserState::structn, ElementState::close); --ctx.triggerField[ParserState::classn]; } }, - { "namespace", [this](){ + { "namespace", [this]() { DispatchEvent(ParserState::namespacen, ElementState::close); - ctx.currentNamespaces.pop_back(); --ctx.triggerField[ParserState::namespacen]; } }, - { "super_list", [this](){ + { "super_list", [this]() { DispatchEvent(ParserState::super_list, ElementState::close); --ctx.triggerField[ParserState::super_list]; } }, - { "super", [this](){ + { "super", [this]() { DispatchEvent(ParserState::super, ElementState::close); --ctx.triggerField[ParserState::super]; } }, - { "public", [this](){ + { "public", [this]() { DispatchEvent(ParserState::publicaccess, ElementState::close); --ctx.triggerField[ParserState::publicaccess]; } }, - { "protected", [this](){ + { "protected", [this]() { DispatchEvent(ParserState::protectedaccess, ElementState::close); --ctx.triggerField[ParserState::protectedaccess]; } }, - { "private", [this](){ + { "private", [this]() { DispatchEvent(ParserState::privateaccess, ElementState::close); --ctx.triggerField[ParserState::privateaccess]; } }, - { "parameter", [this](){ + { "parameter", [this]() { DispatchEvent(ParserState::parameter, ElementState::close); --ctx.triggerField[ParserState::parameter]; } }, - { "member_list", [this](){ + { "member_list", [this]() { DispatchEvent(ParserState::memberlist, ElementState::close); --ctx.triggerField[ParserState::memberlist]; } }, - { "index", [this](){ + { "index", [this]() { DispatchEvent(ParserState::index, ElementState::close); --ctx.triggerField[ParserState::index]; } }, - { "operator", [this](){ + { "operator", [this]() { DispatchEvent(ParserState::op, ElementState::close); --ctx.triggerField[ParserState::op]; } }, - { "block", [this](){ + { "block", [this]() { DispatchEvent(ParserState::block, ElementState::close); --ctx.triggerField[ParserState::block]; } }, - { "init", [this](){ + { "init", [this]() { DispatchEvent(ParserState::init, ElementState::close); --ctx.triggerField[ParserState::init]; - } }, - { "argument", [this](){ + } }, + { "range", [this]() { + DispatchEvent(ParserState::range, ElementState::close); + --ctx.triggerField[ParserState::range]; + } }, + { "argument", [this]() { DispatchEvent(ParserState::argument, ElementState::close); --ctx.triggerField[ParserState::argument]; } }, - { "literal", [this](){ + { "literal", [this]() { DispatchEvent(ParserState::literal, ElementState::close); --ctx.triggerField[ParserState::literal]; } }, - { "modifier", [this](){ + { "modifier", [this]() { DispatchEvent(ParserState::modifier, ElementState::close); --ctx.triggerField[ParserState::modifier]; } }, - { "decl", [this](){ + { "decl", [this]() { DispatchEvent(ParserState::decl, ElementState::close); --ctx.triggerField[ParserState::decl]; } }, - { "type", [this](){ + { "type", [this]() { if(ctx.isPrev) { DispatchEvent(ParserState::typeprev, ElementState::close); --ctx.triggerField[ParserState::typeprev]; @@ -712,96 +699,108 @@ namespace srcSAXEventDispatch { DispatchEvent(ParserState::type, ElementState::close); --ctx.triggerField[ParserState::type]; } }, - { "typedef", [this](){ + { "typedef", [this]() { DispatchEvent(ParserState::typedefexpr, ElementState::close); --ctx.triggerField[ParserState::typedefexpr]; } }, - { "expr", [this](){ + { "expr", [this]() { DispatchEvent(ParserState::expr, ElementState::close); --ctx.triggerField[ParserState::expr]; } }, - { "name", [this](){ + { "name", [this]() { DispatchEvent(ParserState::name, ElementState::close); --ctx.triggerField[ParserState::name]; } }, - { "macro", [this](){ + { "macro", [this]() { DispatchEvent(ParserState::macro, ElementState::close); --ctx.triggerField[ParserState::macro]; } }, - { "specifier", [this](){ + { "specifier", [this]() { DispatchEvent(ParserState::specifier, ElementState::close); --ctx.triggerField[ParserState::specifier]; } }, - { "noun", [this](){ + { "noun", [this]() { --ctx.triggerField[ParserState::snoun]; DispatchEvent(ParserState::snoun, ElementState::close); } }, - { "propernoun", [this](){ + { "propernoun", [this]() { --ctx.triggerField[ParserState::propersnoun]; DispatchEvent(ParserState::propersnoun, ElementState::close); } }, - { "pronoun", [this](){ + { "pronoun", [this]() { --ctx.triggerField[ParserState::spronoun]; DispatchEvent(ParserState::spronoun, ElementState::close); } }, - { "adjective", [this](){ + { "adjective", [this]() { --ctx.triggerField[ParserState::sadjective]; DispatchEvent(ParserState::sadjective, ElementState::close); } }, - { "verb", [this](){ + { "verb", [this]() { --ctx.triggerField[ParserState::sverb]; DispatchEvent(ParserState::sverb, ElementState::close); } }, - { "stereotype", [this](){ + { "stereotype", [this]() { DispatchEvent(ParserState::stereotype, ElementState::close); --ctx.triggerField[ParserState::stereotype]; } }, - { "diff:delete", [this](){ - DispatchEvent(ParserState::diff_delete, ElementState::close); - --ctx.triggerField[ParserState::diff_delete]; - } }, - { "diff_insert", [this](){ - DispatchEvent(ParserState::diff_insert, ElementState::close); - --ctx.triggerField[ParserState::diff_insert]; - } }, - { "diff_common", [this](){ - DispatchEvent(ParserState::diff_common, ElementState::close); - --ctx.triggerField[ParserState::diff_common]; - } }, - { "diff_ws", [this](){ - DispatchEvent(ParserState::diff_ws, ElementState::close); - --ctx.triggerField[ParserState::diff_ws]; - } }, - { "unit", [this](){ + { "unit", [this]() { --ctx.triggerField[ParserState::unit]; DispatchEvent(ParserState::unit, ElementState::close); - if(ctx.triggerField[ParserState::unit] == 0){ + if(ctx.triggerField[ParserState::unit] == 0) { ctx.triggerField[ParserState::archive] = 0; DispatchEvent(ParserState::archive, ElementState::close); } } }, - { "return", [this](){ + { "return", [this]() { --ctx.triggerField[ParserState::returnstmt]; DispatchEvent(ParserState::returnstmt, ElementState::close); } }, - { "throws", [this](){ + { "goto", [this]() { + --ctx.triggerField[ParserState::gotostmt]; + DispatchEvent(ParserState::gotostmt, ElementState::close); + } }, + { "break", [this]() { + --ctx.triggerField[ParserState::breakstmt]; + DispatchEvent(ParserState::breakstmt, ElementState::close); + } }, + { "continue", [this]() { + --ctx.triggerField[ParserState::continuestmt]; + DispatchEvent(ParserState::continuestmt, ElementState::close); + } }, + { "label", [this]() { + --ctx.triggerField[ParserState::label]; + DispatchEvent(ParserState::label, ElementState::close); + } }, + { "throws", [this]() { --ctx.triggerField[ParserState::throws]; DispatchEvent(ParserState::throws, ElementState::close); } }, - { "annotation", [this](){ + { "throw", [this]() { + --ctx.triggerField[ParserState::throwstmt]; + DispatchEvent(ParserState::throwstmt, ElementState::close); + } }, + { "try", [this]() { + --ctx.triggerField[ParserState::trystmt]; + DispatchEvent(ParserState::trystmt, ElementState::close); + } }, + { "catch", [this]() { + --ctx.triggerField[ParserState::catchstmt]; + DispatchEvent(ParserState::catchstmt, ElementState::close); + } }, + { "annotation", [this]() { --ctx.triggerField[ParserState::annotation]; DispatchEvent(ParserState::annotation, ElementState::close); } }, - { "comment", [this](){ + { "comment", [this]() { --ctx.triggerField[ParserState::comment]; DispatchEvent(ParserState::comment, ElementState::close); } }, - { "xmlattribute", [this](){ + { "xmlattribute", [this]() { ctx.triggerField[ParserState::xmlattribute] = 1; DispatchEvent(ParserState::xmlattribute, ElementState::close); ctx.triggerField[ParserState::xmlattribute] = 0; } }, - { "tokenstring", [this](){ + { "tokenstring", [this]() { ctx.triggerField[ParserState::tokenstring] = 1; DispatchEvent(ParserState::tokenstring, ElementState::close); ctx.triggerField[ParserState::tokenstring] = 0; @@ -838,7 +837,7 @@ namespace srcSAXEventDispatch { virtual void startRoot(const char * localname, const char * prefix, const char * URI, int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, const struct srcsax_attribute * attributes) override { - if(is_archive && generateArchive){ + if(is_archive && generateArchive) { ctx.write_start_tag(localname, prefix, URI, num_namespaces, namespaces, num_attributes, attributes); } std::unordered_map>::const_iterator process = process_map.find("unit"); @@ -864,8 +863,9 @@ namespace srcSAXEventDispatch { virtual void startUnit(const char * localname, const char * prefix, const char * URI, int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, const struct srcsax_attribute * attributes) override { - - if (generateArchive){ + ctx.isArchive = is_archive; + ++ctx.depth; + if (generateArchive) { ctx.write_start_tag(localname, prefix, URI, num_namespaces, namespaces, num_attributes, attributes); } std::unordered_map>::const_iterator process = process_map.find("unit"); @@ -873,7 +873,7 @@ namespace srcSAXEventDispatch { process->second(); } - if(num_attributes >= 3){ + if(num_attributes >= 3) { if (num_attributes >= 5) ctx.currentFileChecksum = std::string(attributes[4].value); ctx.currentFilePath = std::string(attributes[2].value); @@ -881,6 +881,23 @@ namespace srcSAXEventDispatch { ctx.currentsrcMLRevision = std::string(attributes[0].value); } } + + + static DeltaElement parseLineAttr(const char* attrValue) { + DeltaElement posAttr(attrValue); + + DeltaElement lineNumber(posAttr.GetOperation()); + if(posAttr.HasOriginal()) { + int length = posAttr.GetOriginal().find(':'); + lineNumber.SetOriginal(std::stoi(posAttr.GetOriginal().substr(0, length))); + } + + if(posAttr.HasModified()) { + int length = posAttr.GetModified().find(':'); + lineNumber.SetModified(std::stoi(posAttr.GetModified().substr(0, length))); + } + return lineNumber; + } /** * startElementNs * @param localname the name of the element tag @@ -899,62 +916,82 @@ namespace srcSAXEventDispatch { int num_namespaces, const struct srcsax_namespace * namespaces, int num_attributes, const struct srcsax_attribute * attributes) override { - if(generateArchive){ + if(generateArchive) { ctx.write_start_tag(localname, prefix, URI, num_namespaces, namespaces, num_attributes, attributes); } - - ++ctx.depth; - std::string localName; - if(prefix) { - localName += prefix; - localName += ':'; + if(URI == DIFF_URI) { + if(localname == std::string("ws")) return; + + static std::unordered_map diff_op_map = { + { "delete", DiffOperation::DELETE }, + { "insert", DiffOperation::INSERT }, + { "common", DiffOperation::COMMON }, + }; + + bool isReplace = false; + bool isConvert = false; + if(num_attributes) { + isReplace = attributes[0].value == std::string("replace"); + isConvert = attributes[0].value == std::string("convert"); + + } + + ctx.diffStack.emplace_back(diff_op_map[std::string(localname)], ctx.depth + 1, isReplace, isConvert); + + + return; } - localName += localname; + + ++ctx.depth; + std::string localName = srcSAXHandler::get_qualified_name(localname, prefix); ctx.currentTag = localName; + // Re-think this. At least use processed list later and think about having a special object. std::string name; - if(num_attributes){ + if(num_attributes) { name = attributes[0].value; } - if(name == "generic" && localName == "argument_list"){ + if(name == "generic" && localName == "argument_list") { ctx.genericDepth.push_back(ctx.depth); } - if(name == "prev" && localName == "type"){ + if(name == "generic" && localName == "parameter_list") { + ctx.genericDepth.push_back(ctx.depth); + } + if(name == "prev" && localName == "type") { ctx.isPrev = true; } if(name == "operator" && (localName == "function" || localName == "function_decl")) { ctx.isOperator = true; } - if(name == "elseif" && localName == "if"){ - ifelseflagopen = true; + if(name == "pseudo" && localName == "block") { + ctx.isPseudo = true; + } + + if(name == "elseif" && localName == "if") { + localName = "elseif"; + elseif_positions.push_back(element_stack.size()); } + if(localName != "") { - if(localName != ""){ // form attribute map for(int pos = 0; pos < num_attributes; ++pos) { - std::string attributeName; - if(attributes[pos].prefix) { - attributeName += attributes[pos].prefix; - attributeName += ':'; - } - attributeName += attributes[pos].localname; - if(strcmp(attributes[pos].localname, "start") == 0){ - std::string posString; - for(int i = 0; attributes[pos].value[i] != ':'; ++i){ - posString+=attributes[pos].value[i]; - } - ctx.currentLineNumber = std::stoi(posString); + + std::string attributeName = srcSAXHandler::get_qualified_name(attributes[pos].localname, attributes[pos].prefix); + if(strcmp(attributes[pos].localname, "start") == 0) { + ctx.startLineNumber = parseLineAttr(attributes[pos].value); + } else if(strcmp(attributes[pos].localname, "end") == 0) { + ctx.endLineNumber = parseLineAttr(attributes[pos].value); } - std::string attributeValue = attributes[pos].value; + std::string attributeValue = attributes[pos].value; ctx.attributes.emplace(attributeName, attributeValue); } - std::unordered_map>::const_iterator process = process_map.find(localname); + std::unordered_map>::const_iterator process = process_map.find(localName); if (process != process_map.end()) { process->second(); } @@ -962,6 +999,21 @@ namespace srcSAXEventDispatch { ctx.attributes.clear(); } + if(ctx.currentTag == "namespace") { + ctx.currentNamespaces.emplace_back(); + } + + if(ctx.currentTag == "name" && nameCollectElements.contains(element_stack.back())) { + collectedText = std::string(); + } else if(collectedText && (ctx.currentTag == "block" || ctx.currentTag == "super_list")) { + if(element_stack.back() == "namespace") { + ctx.currentNamespaces.back() = *collectedText; + } else { + ctx.currentClassName = *collectedText; + } + collectedText = std::optional(); + } + for(int pos = 0; pos < num_attributes; ++pos) { ctx.currentAttributeName = ""; @@ -992,39 +1044,11 @@ namespace srcSAXEventDispatch { ctx.currentToken.clear(); ctx.currentToken.append(ch, len); std::unordered_map>::const_iterator process = process_map2.find("tokenstring"); - - if(ctx.Or({ParserState::classn, ParserState::structn}) && ctx.IsOpen(ParserState::name) && ctx.Nor({ParserState::classblock, ParserState::super_list})){ - ctx.currentClassName = std::all_of( - std::begin(ctx.currentToken), - std::end(ctx.currentToken), - [](char c){ - if(std::isalnum(c) || c == '_') return true; - return false; - }) ? ctx.currentToken : ""; - } - if(ctx.IsOpen({ParserState::namespacen}) && ctx.IsOpen(ParserState::name) && ctx.IsClosed({ParserState::block})){ - std::string namespaceName = std::all_of( - std::begin(ctx.currentToken), - std::end(ctx.currentToken), - [](char c){ - if(std::isalnum(c) || c == '_') return true; - return false; - }) ? ctx.currentToken : ""; - - if (namespaceName != "") - ctx.currentNamespaces.push_back(namespaceName); + if(collectedText) { + collectedText->append(ch, len); } - if((ctx.And({ParserState::name, ParserState::function}) || ctx.And({ParserState::name, ParserState::constructor})) && ctx.Nor({ParserState::functionblock, ParserState::type, ParserState::parameterlist, ParserState::genericargumentlist, ParserState::constructorblock, ParserState::throws, ParserState::annotation})){ - ctx.currentFunctionName = std::all_of( - std::begin(ctx.currentToken), - std::end(ctx.currentToken), - [](char c){ - if(std::isalnum(c) || c == '_') return true; - return false; - }) ? ctx.currentToken : ""; - } process->second(); if (generateArchive) { ctx.write_content(ctx.currentToken); } } @@ -1046,24 +1070,38 @@ namespace srcSAXEventDispatch { } if (generateArchive) { xmlTextWriterEndElement(ctx.writer); } + --ctx.depth; + } virtual void endElement(const char * localname, const char * prefix, const char * URI) override { - std::string localName; - if(prefix) { - localName += prefix; - localName += ':'; + if(URI == DIFF_URI) { + if(localname == std::string("ws")) return; + + ctx.diffStack.pop_back(); + return; + } + + std::string localName = srcSAXHandler::get_qualified_name(localname, prefix); + + if(!elseif_positions.empty() && element_stack.size() == elseif_positions.back()) { + localName = "elseif"; + elseif_positions.pop_back(); } - localName += localname; ctx.currentTag = localName; - std::unordered_map>::const_iterator process2 = process_map2.find(localname); + std::unordered_map>::const_iterator process2 = process_map2.find(localName); if (process2 != process_map2.end()) { process2->second(); } + if(ctx.currentTag == "namespace") { + collectedText = std::optional(); + ctx.currentNamespaces.pop_back(); + } + --ctx.depth; if (generateArchive) { xmlTextWriterEndElement(ctx.writer); } @@ -1072,4 +1110,4 @@ namespace srcSAXEventDispatch { }; } -#endif \ No newline at end of file +#endif diff --git a/src/dispatcher/srcDispatcherMultiEvent.hpp b/src/dispatcher/srcDispatcherMultiEvent.hpp new file mode 100644 index 0000000..83acd9d --- /dev/null +++ b/src/dispatcher/srcDispatcherMultiEvent.hpp @@ -0,0 +1,86 @@ +/** + * @file srcDispatcherMultiEvent.hpp + * + * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) + * + * The srcML Toolkit is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The srcML Toolkit is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the srcML Toolkit; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef INCLUDED_SRC_DISPATCH_SINGLE_EVENT_HPP +#define INCLUDED_SRC_DISPATCH_SINGLE_EVENT_HPP + +#include + +namespace srcDispatch { + template + class srcDispatcherMultiEvent : public srcDispatcher { + + public: + + srcDispatcherMultiEvent(PolicyListener * listener) : srcDispatcher(listener), dispatched(false) {} + + void AddListener(EventListener* listener) override { + elementListeners.push_back(listener); + } + void AddListenerDispatch(EventListener* listener) override { + if(dispatching) { + listener->HandleEvent(currentPState, currentEState, ctx); + } + AddListener(listener); + } + void AddListenerNoDispatch(EventListener* listener) override { + if(dispatching) { + listener->SetDispatched(true); + } + AddListener(listener); + } + void RemoveListener(EventListener* listener) override { + elementListeners.erase(std::find(elementListeners.begin(), elementListeners.end(), listener)); + } + void RemoveListenerDispatch(EventListener* listener) override { + if(dispatching) { + listener->HandleEvent(currentPState, currentEState, ctx); + } + RemoveListener(listener); + } + void RemoveListenerNoDispatch(EventListener* listener) override { + if(dispatching) { + listener->SetDispatched(true); + } + RemoveListener(listener); + } + protected: + + void DispatchEvent(ParserState pstate, ElementState estate) override { + + dispatching = true; + currentPState = pstate; + currentEState = estate; + + for(std::list::iterator listener = elementListeners.begin(); listener != elementListeners.end(); ++listener ) { + (*listener)->HandleEvent(pstate, estate, ctx); + } + for(std::list::iterator listener = elementListeners.begin(); listener != elementListeners.end(); ++listener ) { + (*listener)->SetDispatched(false); + } + + dispatching = false; + + } + + }; + +} + +#endif diff --git a/src/dispatcher/srcSAXEventDispatcher.cpp b/src/dispatcher/srcSAXEventDispatcher.cpp deleted file mode 100644 index 9ee5fed..0000000 --- a/src/dispatcher/srcSAXEventDispatcher.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @file srcSAXEventDispatcher.cpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -namespace srcSAXEventDispatch{ - -} diff --git a/src/dispatcher/srcSAXSingleEventDispatcher.hpp b/src/dispatcher/srcSAXSingleEventDispatcher.hpp deleted file mode 100644 index ee933d1..0000000 --- a/src/dispatcher/srcSAXSingleEventDispatcher.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file srcSAXSingleEventDispatcher.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef INCLUDED_SRCSAX_SINGLE_EVENT_DISPATCHER_HPP -#define INCLUDED_SRCSAX_SINGLE_EVENT_DISPATCHER_HPP - -#include - -namespace srcSAXEventDispatch { - template - class srcSAXSingleEventDispatcher : public srcSAXEventDispatcher { - - private: - bool dispatched; - - public: - - srcSAXSingleEventDispatcher(PolicyListener * listener) : srcSAXEventDispatcher(listener), dispatched(false) {} - virtual void AddListener(EventListener * listener) override { - EventDispatcher::elementListeners.back()->SetDispatched(false); - EventDispatcher::elementListeners.push_back(listener); - } - virtual void AddListenerDispatch(EventListener * listener) override { - AddListener(listener); - dispatched = false; - } - virtual void AddListenerNoDispatch(EventListener * listener) override { - AddListener(listener); - } - virtual void RemoveListener(EventListener * listener) override { - EventDispatcher::elementListeners.back()->SetDispatched(false); - EventDispatcher::elementListeners.pop_back(); - } - virtual void RemoveListenerDispatch(EventListener * listener) override { - RemoveListener(listener); - dispatched = false; - } - virtual void RemoveListenerNoDispatch(EventListener * listener) override { - RemoveListener(listener); - } - protected: - virtual void DispatchEvent(srcSAXEventDispatch::ParserState pstate, srcSAXEventDispatch::ElementState estate) override { - - while(!dispatched) { - - dispatched = true; - - EventDispatcher::elementListeners.back()->HandleEvent(pstate, estate, EventDispatcher::ctx); - EventDispatcher::elementListeners.back()->SetDispatched(false); - - } - - dispatched = false; - - } - - }; - -} - -#endif diff --git a/src/policy_classes/AccessSpecifier.hpp b/src/policy_classes/AccessSpecifier.hpp new file mode 100644 index 0000000..ef4b8bb --- /dev/null +++ b/src/policy_classes/AccessSpecifier.hpp @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file AccessSpecifier.hpp + * + * @copyright Copyright (C) 2025-2025 srcML, LLC. (www.srcML.org) + * + * This file is part of the srcML Infrastructure. + */ + +#ifndef INCLUDED_ACCESS_SPECIFIER_HPP +#define INCLUDED_ACCESS_SPECIFIER_HPP + +enum AccessSpecifier { + NONE = 0, + PUBLIC = 1, + PRIVATE = 2, + PROTECTED = 3 +}; + +#endif diff --git a/src/policy_classes/BlockPolicy.cpp b/src/policy_classes/BlockPolicy.cpp new file mode 100644 index 0000000..ef64d6b --- /dev/null +++ b/src/policy_classes/BlockPolicy.cpp @@ -0,0 +1,361 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file BlockPolicy.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace srcDispatch { + + BlockPolicy::BlockPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeBlockPolicyHandlers(); + } + + BlockPolicy::~BlockPolicy() {} + + std::any BlockPolicy::DataInner() const { return std::make_shared(data); } + + void BlockPolicy::Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) { + if(typeid(DeclStmtPolicy) == typeid(*policy)) { + data.statements.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(ExprStmtPolicy) == typeid(*policy)) { + data.statements.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(ReturnPolicy) == typeid(*policy)) { + data.statements.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(IfStmtPolicy) == typeid(*policy)) { + data.statements.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else if(typeid(SwitchPolicy) == typeid(*policy)) { + data.statements.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else if(typeid(WhilePolicy) == typeid(*policy)) { + data.statements.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else if(typeid(ForPolicy) == typeid(*policy)) { + data.statements.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else if(typeid(DoPolicy) == typeid(*policy)) { + data.statements.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else if(typeid(TryPolicy) == typeid(*policy)) { + data.statements.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(ThrowPolicy) == typeid(*policy)) { + data.statements.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else if(typeid(GotoPolicy) == typeid(*policy)) { + data.statements.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(ConvertPlexerPolicy) == typeid(*policy)) { + data.statements.push_back(policy->Data()->construct); + } else if(typeid(ClassPolicy) == typeid(*policy)) { + srcDispatch::DiffOperation operation = ctx.diffStack.back().isConvert? srcDispatch::COMMON : ctx.diffStack.back().operation; + data.localClasses.emplace_back(operation, policy->Data()); + } else if(typeid(BlockPolicy) == typeid(*policy)) { + data.blocks.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(CasePolicy) == typeid(*policy)) { + data.cases.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(LabelPolicy) == typeid(*policy)) { + data.labels.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + ctx.dispatcher->RemoveListenerDispatch(nullptr); + } + + void BlockPolicy::InitializeBlockPolicyHandlers() { + using namespace srcDispatch; + + CollectBlockHandlers(); + CollectDeclstmtHandlers(); + CollectExpressionHandlers(); + CollectReturnHandlers(); + CollectIfStmtHandlers(); + CollectSwitchHandlers(); + CollectWhileHandlers(); + CollectForHandlers(); + CollectDoHandlers(); + CollectTryHandlers(); + CollectThrowHandlers(); + CollectGotoHandlers(); + CollectClassHandlers(); + CollectCaseHandlers(); + CollectLabelHandlers(); + } + + template + bool BlockPolicy::ConvertRegistrationCheck(srcDispatch::srcSAXEventContext& ctx) { + if(!ctx.diffStack.back().isConvert) return false; + + if(!plexer) { + plexer = srcDispatch::make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(plexer.get()); + + return true; + } + + void BlockPolicy::CollectBlockHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::block] = [this](srcSAXEventContext& ctx) { + if(!depth) { + depth = ctx.depth; + data = BlockData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + } else { + if(!blockPolicy) + blockPolicy = make_unique_policy({this}); + ctx.dispatcher->AddListenerDispatch(blockPolicy.get()); + } + }; + + closeEventMap[ParserState::block] = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeBlockPolicyHandlers(); + }; + } + + void BlockPolicy::CollectDeclstmtHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + if(ConvertRegistrationCheck(ctx)) return; + + if(!declstmtPolicy) { + declstmtPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(declstmtPolicy.get()); + }; + + closeEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(plexer) { + plexer.reset(); + } + }; + } + + void BlockPolicy::CollectExpressionHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::exprstmt] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + if(ConvertRegistrationCheck(ctx)) return; + + if(!exprStmtPolicy) { + exprStmtPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(exprStmtPolicy.get()); + }; + + closeEventMap[ParserState::exprstmt] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(plexer) { + plexer.reset(); + } + }; + } + + void BlockPolicy::CollectReturnHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::returnstmt] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + if(ConvertRegistrationCheck(ctx)) return; + + if(!returnPolicy) { + returnPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(returnPolicy.get()); + }; + + closeEventMap[ParserState::returnstmt] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(plexer) { + plexer.reset(); + } + }; + } + + void BlockPolicy::CollectIfStmtHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::ifgroup] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + if(ConvertRegistrationCheck(ctx)) return; + + if(!ifStmtPolicy) { + ifStmtPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(ifStmtPolicy.get()); + }; + + closeEventMap[ParserState::ifgroup] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(plexer) { + plexer.reset(); + } + }; + } + + void BlockPolicy::CollectSwitchHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::switchstmt] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!switchPolicy) { + switchPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(switchPolicy.get()); + }; + } + + void BlockPolicy::CollectWhileHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::whilestmt] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + if(ConvertRegistrationCheck(ctx)) return; + + if(!whilePolicy) { + whilePolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(whilePolicy.get()); + }; + + closeEventMap[ParserState::whilestmt] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(plexer) { + plexer.reset(); + } + }; + } + + void BlockPolicy::CollectForHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::forstmt] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + if(ConvertRegistrationCheck(ctx)) return; + + if(!forPolicy) { + forPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(forPolicy.get()); + }; + + closeEventMap[ParserState::forstmt] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(plexer) { + plexer.reset(); + } + }; + } + + void BlockPolicy::CollectDoHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::dostmt] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!doPolicy) { + doPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(doPolicy.get()); + }; + } + + void BlockPolicy::CollectTryHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::trystmt] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!tryPolicy) { + tryPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(tryPolicy.get()); + }; + } + + void BlockPolicy::CollectThrowHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::throwstmt] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!throwPolicy) { + throwPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(throwPolicy.get()); + }; + } + + void BlockPolicy::CollectGotoHandlers() { + using namespace srcDispatch; + std::function startGoto = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!gotoPolicy) { + gotoPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(gotoPolicy.get()); + }; + + openEventMap[ParserState::gotostmt] = startGoto; + openEventMap[ParserState::breakstmt] = startGoto; + openEventMap[ParserState::continuestmt] = startGoto; + } + + void BlockPolicy::CollectClassHandlers() { + using namespace srcDispatch; + std::function startClassPolicy = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!classPolicy) { + classPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(classPolicy.get()); + }; + + openEventMap[ParserState::classn] = startClassPolicy; + openEventMap[ParserState::structn] = startClassPolicy; + } + + void BlockPolicy::CollectCaseHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::switchcase] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!casePolicy) { + casePolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(casePolicy.get()); + }; + } + + void BlockPolicy::CollectLabelHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::label] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!labelPolicy) { + labelPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(labelPolicy.get()); + }; + } + +} diff --git a/src/policy_classes/BlockPolicy.hpp b/src/policy_classes/BlockPolicy.hpp new file mode 100644 index 0000000..4721d4f --- /dev/null +++ b/src/policy_classes/BlockPolicy.hpp @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file BlockPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_BLOCK_POLICY_HPP +#define INCLUDED_BLOCK_POLICY_HPP + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace srcDispatch { + + class IfStmtPolicy; + class SwitchPolicy; + class WhilePolicy; + class ForPolicy; + class DoPolicy; + class TryPolicy; + + class ClassPolicy; + struct ClassData; + + class ConvertPlexerPolicy; + + struct BlockData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + std::vector> statements; + std::vector>> localClasses; + std::vector>> labels; + std::vector>> cases; + std::vector>> blocks; + + }; + + class BlockPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + BlockData data; + + std::unique_ptr blockPolicy; + + std::unique_ptr declstmtPolicy; + std::unique_ptr exprStmtPolicy; + std::unique_ptr returnPolicy; + + std::unique_ptr gotoPolicy; + std::unique_ptr labelPolicy; + std::unique_ptr throwPolicy; + + std::unique_ptr ifStmtPolicy; + + std::unique_ptr forPolicy; + std::unique_ptr whilePolicy; + std::unique_ptr doPolicy; + + std::unique_ptr tryPolicy; + + std::unique_ptr switchPolicy; + std::unique_ptr casePolicy; + + std::unique_ptr classPolicy; + + std::unique_ptr plexer; + + public: + BlockPolicy(std::initializer_list listeners); + + ~BlockPolicy(); + + protected: + std::any DataInner() const override; + virtual void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override; + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + private: + void InitializeBlockPolicyHandlers(); + + void CollectBlockHandlers(); + void CollectDeclstmtHandlers(); + void CollectExpressionHandlers(); + void CollectReturnHandlers(); + void CollectIfStmtHandlers(); + void CollectSwitchHandlers(); + void CollectWhileHandlers(); + void CollectForHandlers(); + void CollectDoHandlers(); + void CollectTryHandlers(); + void CollectThrowHandlers(); + void CollectGotoHandlers(); + void CollectClassHandlers(); + void CollectCaseHandlers(); + void CollectLabelHandlers(); + + template + bool ConvertRegistrationCheck(srcDispatch::srcSAXEventContext& ctx); + }; + +} + +#endif diff --git a/src/policy_classes/CallPolicy.cpp b/src/policy_classes/CallPolicy.cpp new file mode 100644 index 0000000..e4b2e1a --- /dev/null +++ b/src/policy_classes/CallPolicy.cpp @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file CallPolicy.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#include +#include + +namespace srcDispatch { + + std::string CallData::ToString(srcDispatch::DiffOperation operation) const { + + std::string str = name.ToString(operation); + + if(name.IsOfOperation(operation)) { + str += '('; + } + + bool printComma = false; + for (const DeltaElement>& arg : arguments) { + + bool outputRaw = arg.IsOfOperation(operation); + if(outputRaw) { + if(printComma) { + str += ", "; + } + printComma = true; + } + str += arg.ToString(operation); + + } + + if(name.IsOfOperation(operation)) { + str += ')'; + } + + return str; + } + + std::shared_ptr CallData::copyAs(srcDispatch::DiffOperation operation) const { + std::shared_ptr data = std::make_shared(); + data->startLineNumber = startLineNumber; + data->endLineNumber = endLineNumber; + + data->name = name.GetElement()->copyAs(operation); + + for (const DeltaElement>& argument : arguments) { + data->arguments.emplace_back(DeltaElement(operation, argument.GetElement()->copyAs(operation))); + } + + return data; + } + + CallPolicy::~CallPolicy() {} + + std::any CallPolicy::DataInner() const { return std::make_shared(data); } + + void CallPolicy::Notify(const srcDispatch::PolicyDispatcher *policy, const srcDispatch::srcSAXEventContext& ctx) { + using namespace srcDispatch; + if(typeid(NamePolicy) == typeid(*policy)) { + data.name = DeltaElement(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(ExpressionPolicy) == typeid(*policy)) { + data.arguments.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else { + throw PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + + ctx.dispatcher->RemoveListener(nullptr); + } + + void CallPolicy::InitializeCallPolicyHandlers() { + using namespace srcDispatch; + // start of policy + openEventMap[ParserState::call] = [this](srcSAXEventContext& ctx) { + if(depth) return; + + depth = ctx.depth; + data = CallData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectNameHandlers(); + CollectCallArgumentHandlers(); + }; + + // end of policy + closeEventMap[ParserState::call] = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeCallPolicyHandlers(); + }; + } + + void CallPolicy::CollectNameHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!namePolicy) { + namePolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(namePolicy.get()); + }; + } + + void CallPolicy::CollectCallArgumentHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::argument] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!expressionPolicy) { + expressionPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(expressionPolicy.get()); + }; + } + +} diff --git a/src/policy_classes/CallPolicy.hpp b/src/policy_classes/CallPolicy.hpp new file mode 100644 index 0000000..d95372c --- /dev/null +++ b/src/policy_classes/CallPolicy.hpp @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file CallPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_CALL_POLICY_HPP +#define INCLUDED_CALL_POLICY_HPP + +#include +#include +#include +#include + +#include +#include +#include + +// +// Collects information +// foo(x) +// obj.foo(x) +// +// Gets the name and list of arguments +// + +namespace srcDispatch { + + struct ExpressionData; + class ExpressionPolicy; + + struct NameData; + class NamePolicy; + + struct CallData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement> name; + std::vector>> arguments; // expressions + + std::shared_ptr copyAs(srcDispatch::DiffOperation operation) const; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const; + }; + + class CallPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + CallData data; + + std::unique_ptr namePolicy; + std::unique_ptr expressionPolicy; + + public: + CallPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeCallPolicyHandlers(); + } + + ~CallPolicy(); + + protected: + std::any DataInner() const override; + virtual void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override; + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + private: + void InitializeCallPolicyHandlers(); + void CollectNameHandlers(); + void CollectCallArgumentHandlers(); + }; + +} + +#endif diff --git a/src/policy_classes/CallPolicySingleEvent.cpp b/src/policy_classes/CallPolicySingleEvent.cpp deleted file mode 100644 index 708f66a..0000000 --- a/src/policy_classes/CallPolicySingleEvent.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @file CallPolicySingleEvent.cpp - * - */ -#include - -std::ostream & operator<<(std::ostream & out, const CallData &call) { - out << *(call.name) << "("; - bool printComma=false; - for (std::shared_ptr arg : call.arguments) { - if (printComma) out << ", "; - out << *arg; - printComma = true; - } - out << ")"; - return out; -} - -CallPolicy::~CallPolicy() { - if (namePolicy) delete namePolicy; - if (expressionPolicy) delete expressionPolicy; -} - -std::any CallPolicy::DataInner() const { return std::make_shared(data); } - -void CallPolicy::Notify(const srcSAXEventDispatch::PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) { - using namespace srcSAXEventDispatch; - if (typeid(NamePolicy) == typeid(*policy)) { - data.name = policy->Data(); - ctx.dispatcher->RemoveListener(nullptr); - } - if (typeid(ExpressionPolicy) == typeid(*policy)) { - data.arguments.push_back(policy->Data()); - ctx.dispatcher->RemoveListener(nullptr); - } -} - -void CallPolicy::InitializeCallPolicyHandlers() { - using namespace srcSAXEventDispatch; - // start of policy - openEventMap[ParserState::call] = [this](srcSAXEventContext& ctx) { - if (!callDepth) { - callDepth = ctx.depth; - data = CallData{}; - data.lineNumber = ctx.currentLineNumber; - CollectNameHandlers(); - CollectCallArgumentHandlers(); - } - }; - - // end of policy - closeEventMap[ParserState::call] = [this](srcSAXEventContext& ctx) { - if (callDepth && callDepth == ctx.depth) { - callDepth = 0; - NotifyAll(ctx); - InitializeCallPolicyHandlers(); - } - }; -} - - -void CallPolicy::CollectNameHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - if(!namePolicy) namePolicy = new NamePolicy{this}; - ctx.dispatcher->AddListenerDispatch(namePolicy); - }; -} - - -void CallPolicy::CollectCallArgumentHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::argument] = [this](srcSAXEventContext& ctx) { - if(!expressionPolicy) expressionPolicy = new ExpressionPolicy{this}; - ctx.dispatcher->AddListenerDispatch(expressionPolicy); - }; -} - diff --git a/src/policy_classes/CallPolicySingleEvent.hpp b/src/policy_classes/CallPolicySingleEvent.hpp deleted file mode 100644 index de8c1b0..0000000 --- a/src/policy_classes/CallPolicySingleEvent.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @file CallPolicySingleEvent.hpp - * - */ -#ifndef INCLUDED_CALL_POLICY_SINGLE_EVENT_HPP -#define INCLUDED_CALL_POLICY_SINGLE_EVENT_HPP - -#include - -#include -#include -#include - -#include -#include -#include - -// -// Collects information -// foo(x) -// obj.foo(x) -// -// Gets the name and list of arguments -// - -struct ExpressionData; -class ExpressionPolicy; - -struct NameData; -class NamePolicy; - -struct CallData { - - unsigned int lineNumber; - std::shared_ptr name; - std::vector> arguments; //expressions - - friend std::ostream & operator<<(std::ostream & out, const CallData &call); -}; - -class CallPolicy : -public srcSAXEventDispatch::EventListener, -public srcSAXEventDispatch::PolicyDispatcher, -public srcSAXEventDispatch::PolicyListener { - -private: - CallData data; - std::size_t callDepth; - NamePolicy *namePolicy; - ExpressionPolicy *expressionPolicy; - -public: - CallPolicy(std::initializer_list listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - callDepth(0), - expressionPolicy(nullptr), - namePolicy(nullptr) { - InitializeCallPolicyHandlers(); - } - - ~CallPolicy(); - -protected: - std::any DataInner() const override; - virtual void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override; - void NotifyWrite(const PolicyDispatcher * policy, srcSAXEventDispatch::srcSAXEventContext & ctx) override {} //doesn't use other parsers - -private: - void InitializeCallPolicyHandlers(); - void CollectNameHandlers(); - void CollectCallArgumentHandlers(); -}; - -#endif diff --git a/src/policy_classes/CasePolicy.hpp b/src/policy_classes/CasePolicy.hpp new file mode 100644 index 0000000..8b0ebfd --- /dev/null +++ b/src/policy_classes/CasePolicy.hpp @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file CasePolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_CASE_POLICY_HPP +#define INCLUDED_CASE_POLICY_HPP + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + struct CaseData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement> expr; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + return expr.ToString(operation); + } + }; + + // Collect the expression in the return + class CasePolicy : public ExprTypePolicy { + public: + CasePolicy(std::initializer_list listeners) + : ExprTypePolicy(listeners) { + } + + }; + +} + +#endif diff --git a/src/policy_classes/CatchPolicy.hpp b/src/policy_classes/CatchPolicy.hpp new file mode 100644 index 0000000..f6b8c63 --- /dev/null +++ b/src/policy_classes/CatchPolicy.hpp @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file CatchPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_CATCH_POLICY_HPP +#define INCLUDED_CATCH_POLICY_HPP + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + struct CatchData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + std::vector>> parameters; + DeltaElement> block; + }; + + class CatchPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + CatchData data; + + std::unique_ptr declPolicy; + std::unique_ptr blockPolicy; + + public: + CatchPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeCatchPolicyHandlers(); + } + + ~CatchPolicy() {} + + protected: + std::any DataInner() const { return std::make_shared(data); } + + void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) { + if(typeid(DeclPolicy) == typeid(*policy)) { + data.parameters.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(BlockPolicy) == typeid(*policy)) { + data.block.Update(ctx.diffStack.back().operation, policy->Data()); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + + ctx.dispatcher->RemoveListener(nullptr); + } + + void NotifyWrite(const PolicyDispatcher* policy, srcDispatch::srcSAXEventContext& ctx) {} // doesn't use other parsers + + private: + void InitializeCatchPolicyHandlers() { + using namespace srcDispatch; + + openEventMap[ParserState::catchstmt] = [this](srcSAXEventContext& ctx) { + if(depth) return; + + depth = ctx.depth; + data = CatchData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectParametersHandlers(); + CollectBlockHandlers(); + }; + + // end of policy + closeEventMap[ParserState::catchstmt] = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeCatchPolicyHandlers(); + }; + } + + void CollectParametersHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::parameterlist] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + openEventMap[ParserState::parameter] = [this](srcSAXEventContext& ctx) { + if(!declPolicy) { + declPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(declPolicy.get()); + }; + }; + + closeEventMap[ParserState::parameterlist] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + NopOpenEvents({ParserState::parameter}); + }; + } + + void CollectBlockHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::block] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!blockPolicy) { + blockPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(blockPolicy.get()); + }; + } + + }; + +} + +#endif diff --git a/src/policy_classes/ClassPolicy.cpp b/src/policy_classes/ClassPolicy.cpp new file mode 100644 index 0000000..a21bb87 --- /dev/null +++ b/src/policy_classes/ClassPolicy.cpp @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file BlockPolicy.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#include + +namespace srcDispatch { + +const std::unordered_map ClassPolicy::stateToTypeMapper = { + {srcDispatch::ParserState::classn, ClassData::CLASS}, + {srcDispatch::ParserState::structn, ClassData::STRUCT}, +}; + +} diff --git a/src/policy_classes/ClassPolicy.hpp b/src/policy_classes/ClassPolicy.hpp index e907cc6..5b9e444 100644 --- a/src/policy_classes/ClassPolicy.hpp +++ b/src/policy_classes/ClassPolicy.hpp @@ -1,159 +1,348 @@ +// SPDX-License-Identifier: GPL-3.0-only /** * @file ClassPolicy.hpp * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This file is part of the Dispatch Infrastructure. */ #ifndef INCLUDED_CLASS_POLICY_HPP #define INCLUDED_CLASS_POLICY_HPP -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include -class ClassPolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - public: +#include +#include +#include +#include +#include - struct ClassData { - void Clear() { - className = ""; - methods.clear(); - members.clear(); - isStruct = false; - } - - std::string className; - bool isStruct = false; //False -> Class; True -> Struct - std::vector methods; - std::vector members; - }; - - ~ClassPolicy() { - delete funcSigPolicy; - delete declTypePolicy; - } +#include +#include +#include +#include +#include + +namespace srcDispatch { + + struct ParentData; + + struct ClassData { + enum ClassType : std::size_t { CLASS, STRUCT }; + + std::vector namespaces; + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + std::string language; + std::string filename; + + /*** @todo implement */ + std::set stereotypes; + + std::vector>> generics; + DeltaElement type; + DeltaElement> name; + std::vector>> parents; + + std::vector>> fields; + std::vector>> constructors; + DeltaElement> destructor; + + std::vector>> operators; + std::vector>> methods; + std::vector>> innerClasses; + + DeltaElement isAbstract; + }; + + struct ParentData { + DeltaElement> name; + DeltaElement isVirtual; + DeltaElement accessSpecifier; + }; - ClassPolicy(std::initializer_list listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners) { - funcSigPolicy = new FunctionSignaturePolicy({this}); - declTypePolicy = new DeclTypePolicy({this}); + class ClassPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { - InitializeEventHandlers(); + private: + ClassData data; + + DeltaElement currentRegion; + + std::unique_ptr genericPolicy; + std::unique_ptr namePolicy; + std::unique_ptr declStmtPolicy; + std::unique_ptr functionPolicy; + std::unique_ptr classPolicy; + + static const std::unordered_map stateToTypeMapper; + + public: + ClassPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{}, currentRegion() { + InitializeClassPolicyHandlers(); } - void NotifyWrite(const PolicyDispatcher * policy, srcSAXEventDispatch::srcSAXEventContext & ctx) override {} //doesn't use other parsers - void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - if (typeid(FunctionSignaturePolicy) == typeid(*policy)) { - SignatureData signatureData = *policy->Data(); - data_stack.top().methods.push_back(signatureData); - } + ~ClassPolicy() {} - else if (typeid(DeclTypePolicy) == typeid(*policy)) { - if(!(ctx.IsOpen(srcSAXEventDispatch::ParserState::function))) { - DeclData declarationData = *policy->Data(); - data_stack.top().members.push_back(declarationData); + void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override { + if(typeid(GenericPolicy) == typeid(*policy)) { + data.generics.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(NamePolicy) == typeid(*policy)) { + if(ctx.And({srcDispatch::ParserState::super})) { + data.parents.back()->name.Update(ctx.diffStack.back().operation, policy->Data()); + } else { + data.name = DeltaElement(ctx.diffStack.back().operation, policy->Data()); } - } - } + } else if(typeid(DeclStmtPolicy) == typeid(*policy)) { + data.fields.emplace_back(ctx.diffStack.back().operation, policy->Data()); + if(currentRegion) { + for (DeltaElement>& decl : data.fields.back()->decls) { + decl->accessSpecifier = currentRegion; + } + } + } else if(typeid(FunctionPolicy) == typeid(*policy)) { - protected: + std::shared_ptr f_data = policy->Data(); + FunctionData::FunctionType f_type = f_data->type.GetElement(); + if(currentRegion) { + f_data->accessSpecifier = currentRegion; + } + if(f_data->isPureVirtual) { + data.isAbstract.Update(ctx.diffStack.back().operation, true); + } + + if(f_type == FunctionData::CONSTRUCTOR) { + data.constructors.emplace_back(ctx.diffStack.back().operation, f_data); + } else if(f_type == FunctionData::DESTRUCTOR) { + data.destructor.Update(ctx.diffStack.back().operation, f_data); + } else if(f_type == FunctionData::OPERATOR) { + data.operators.emplace_back(ctx.diffStack.back().operation, f_data); + } else { + data.methods.emplace_back(ctx.diffStack.back().operation, f_data); + } + } else if(typeid(ClassPolicy) == typeid(*policy)) { + srcDispatch::DiffOperation operation = ctx.diffStack.back().isConvert? srcDispatch::COMMON : ctx.diffStack.back().operation; + data.innerClasses.emplace_back(operation, policy->Data()); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } - void * DataInner() const override { - return new std::vector(data); + ctx.dispatcher->RemoveListenerDispatch(nullptr); } - private: + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} - std::stack data_stack; + protected: + std::any DataInner() const override { return std::make_shared(data); } - std::vector data; + private: + void InitializeClassPolicyHandlers() { + using namespace srcDispatch; + // start of policy + std::function startPolicy = [this](srcSAXEventContext& ctx) { + if(!depth) { - FunctionSignaturePolicy *funcSigPolicy; - DeclTypePolicy *declTypePolicy; + depth = ctx.depth; + data = ClassData{}; + data.namespaces = ctx.currentNamespaces; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + std::map::const_iterator stereotype_attr_itr = ctx.attributes.find("stereotype"); + if(stereotype_attr_itr != ctx.attributes.end()) { + std::istringstream stereostring(stereotype_attr_itr->second); + data.stereotypes = std::set(std::istream_iterator(stereostring), std::istream_iterator()); + } - bool gotClassName = true; + data.type = DeltaElement(ctx.diffStack.back().operation, stateToTypeMapper.at(ctx.dispatcher->CurrentPState())); + data.name = DeltaElement>(); + data.language = ctx.currentFileLanguage; + data.filename = ctx.currentFilePath; + CollectGenericHandlers(); + CollectNameHandlers(); + CollectSuperHanders(); + CollectBlockHanders(); + } else { - void InitializeEventHandlers() { - using namespace srcSAXEventDispatch; + if(ctx.diffStack.back().isConvert && ctx.diffStack.back().operation == srcDispatch::INSERT) { + data.type.Update(ctx.diffStack.back().operation, stateToTypeMapper.at(ctx.dispatcher->CurrentPState())); + } else { - //Classes - openEventMap[ParserState::classn] = [this](srcSAXEventContext &ctx) { - if(data_stack.empty()) { - ctx.dispatcher->AddListenerDispatch(funcSigPolicy); - ctx.dispatcher->AddListenerDispatch(declTypePolicy); + if(!classPolicy) { + classPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(classPolicy.get()); + } } + }; - ClassData current; - current.isStruct = false; - data_stack.push(current); + // end of policy + std::function endPolicy = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return; - gotClassName = false; + depth = 0; + NotifyAll(ctx); + InitializeClassPolicyHandlers(); }; - closeEventMap[ParserState::classn] = [this](srcSAXEventContext &ctx) { - data.push_back(data_stack.top()); - data_stack.pop(); + openEventMap[ParserState::classn] = startPolicy; + closeEventMap[ParserState::classn] = endPolicy; - if(data_stack.empty()) { - ctx.dispatcher->RemoveListenerDispatch(funcSigPolicy); - ctx.dispatcher->RemoveListenerDispatch(declTypePolicy); + openEventMap[ParserState::structn] = startPolicy; + closeEventMap[ParserState::structn] = endPolicy; + } + + void CollectGenericHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::templates] = [this](srcSAXEventContext& ctx) { + if(!depth) return; - NotifyAll(ctx); - data.clear(); + if(!genericPolicy) { + genericPolicy = make_unique_policy({this}); } + ctx.dispatcher->AddListenerDispatch(genericPolicy.get()); }; + } + + void CollectNameHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { + if(!depth) return; - //Structs - openEventMap[ParserState::structn] = [this](srcSAXEventContext &ctx) { - if(data_stack.empty()) { - ctx.dispatcher->AddListenerDispatch(funcSigPolicy); - ctx.dispatcher->AddListenerDispatch(declTypePolicy); + if(!namePolicy) { + namePolicy = make_unique_policy({this}); } + ctx.dispatcher->AddListenerDispatch(namePolicy.get()); + }; + closeEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + NopOpenEvents({ParserState::name}); + NopCloseEvents({ParserState::name}); + }; + } - ClassData current; - current.isStruct = true; - data_stack.push(current); + void CollectSuperHanders() { + using namespace srcDispatch; + openEventMap[ParserState::super_list] = [this](srcSAXEventContext& ctx) { + if(!depth) return; - gotClassName = false; + openEventMap[ParserState::super] = [this](srcSAXEventContext& ctx) { + data.parents.emplace_back(ctx.diffStack.back().operation, + std::make_shared( + ParentData{DeltaElement>(), DeltaElement(), DeltaElement()} + ) + ); + + openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { + if(!namePolicy) { + namePolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(namePolicy.get()); + }; + + closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { + if(ctx.And({ParserState::specifier})) { + if(ctx.currentToken == "virtual") { + data.parents.back()->isVirtual.Update(ctx.diffStack.back().operation, true); + } else if(ctx.currentToken == "public") { + data.parents.back()->accessSpecifier.Update(ctx.diffStack.back().operation, PUBLIC); + } else if(ctx.currentToken == "private") { + data.parents.back()->accessSpecifier.Update(ctx.diffStack.back().operation, PRIVATE); + } else if(ctx.currentToken == "protected") { + data.parents.back()->accessSpecifier.Update(ctx.diffStack.back().operation, PROTECTED); + } + } + }; + }; + closeEventMap[ParserState::super] = [this](srcSAXEventContext& ctx) { + NopCloseEvents({ParserState::tokenstring}); + }; }; - closeEventMap[ParserState::structn] = [this](srcSAXEventContext &ctx) { - data.push_back(data_stack.top()); - data_stack.pop(); - if(data_stack.empty()) { - ctx.dispatcher->RemoveListenerDispatch(funcSigPolicy); - ctx.dispatcher->RemoveListenerDispatch(declTypePolicy); + closeEventMap[ParserState::super_list] = [this](srcSAXEventContext& ctx) { + if(!depth) return; - NotifyAll(ctx); - data.clear(); + NopOpenEvents({ParserState::super}); + }; + } + + void CollectBlockHanders() { + using namespace srcDispatch; + openEventMap[ParserState::block] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + NopOpenEvents({ParserState::name, ParserState::super_list, ParserState::super}); + NopCloseEvents({ParserState::name, ParserState::super_list, ParserState::tokenstring}); + + openEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx) { + if(!declStmtPolicy) { + declStmtPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(declStmtPolicy.get()); + }; + + std::function functionEvent = [this](srcSAXEventContext& ctx) { + if(!functionPolicy) { + functionPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(functionPolicy.get()); + }; + + openEventMap[ParserState::function] = functionEvent; + openEventMap[ParserState::functiondecl] = functionEvent; + openEventMap[ParserState::constructor] = functionEvent; + openEventMap[ParserState::constructordecl] = functionEvent; + openEventMap[ParserState::destructor] = functionEvent; + openEventMap[ParserState::destructordecl] = functionEvent; + }; + + openEventMap[ParserState::publicaccess] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(ctx.diffStack.back().isConvert) { + currentRegion.Update(ctx.diffStack.back().operation, PUBLIC); + } else { + currentRegion = DeltaElement(ctx.diffStack.back().operation, PUBLIC); } }; - closeEventMap[ParserState::name] = [this](srcSAXEventContext& ctx){ - if((ctx.IsOpen(ParserState::structn) || ctx.IsOpen(ParserState::classn)) && !gotClassName) { - data_stack.top().className = ctx.currentToken; - gotClassName = true; + openEventMap[ParserState::protectedaccess] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(ctx.diffStack.back().isConvert) { + currentRegion.Update(ctx.diffStack.back().operation, PROTECTED); + } else { + currentRegion = DeltaElement(ctx.diffStack.back().operation, PROTECTED); } }; + openEventMap[ParserState::privateaccess] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(ctx.diffStack.back().isConvert) { + currentRegion.Update(ctx.diffStack.back().operation, PRIVATE); + } else { + currentRegion = DeltaElement(ctx.diffStack.back().operation, PRIVATE); + } + }; + + closeEventMap[ParserState::block] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + NopOpenEvents({ParserState::block, ParserState::function, ParserState::functiondecl, + ParserState::constructor, ParserState::constructordecl, ParserState::destructor, ParserState::destructordecl, + ParserState::declstmt, + ParserState::publicaccess, ParserState::protectedaccess, ParserState::privateaccess}); + NopCloseEvents({ParserState::block}); + }; } -}; + }; +} -#endif \ No newline at end of file +#endif diff --git a/src/policy_classes/ClassPolicySingleEvent.hpp b/src/policy_classes/ClassPolicySingleEvent.hpp deleted file mode 100644 index 1442b09..0000000 --- a/src/policy_classes/ClassPolicySingleEvent.hpp +++ /dev/null @@ -1,289 +0,0 @@ -/** - * @file ClassPolicySingleEvent.hpp - * - */ -#ifndef INCLUDED_CLASS_POLICY_SINGLE_EVENT_HPP -#define INCLUDED_CLASS_POLICY_SINGLE_EVENT_HPP - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - - -struct ParentData; - -struct ClassData { - enum ClassType : std::size_t { CLASS, STRUCT }; //UNION, ENUM? - enum AccessSpecifier { PUBLIC = 0, PRIVATE = 1, PROTECTED = 2 }; - - unsigned int lineNumber; - std::string language; - std::string filename; - ClassType type; - std::set stereotypes; - std::shared_ptr name; - std::vector parents; - - std::vector> fields[3]; - std::vector> constructors[3]; - std::vector> operators[3]; - std::vector> methods[3]; - std::vector> innerClasses[3]; - - bool hasDestructor; - bool isGeneric; - bool hasPureVirtual; -}; - -struct ParentData { - std::string name; - bool isVirtual; - ClassData::AccessSpecifier accessSpecifier; -}; - - -class ClassPolicy : -public srcSAXEventDispatch::EventListener, -public srcSAXEventDispatch::PolicyDispatcher, -public srcSAXEventDispatch::PolicyListener { - -private: - ClassData data; - std::size_t classDepth; - ClassData::AccessSpecifier currentRegion; - - NamePolicy * namePolicy; - DeclTypePolicy * declPolicy; - FunctionPolicy * functionPolicy; - ClassPolicy * classPolicy; - -public: - ClassPolicy(std::initializer_list listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - classDepth(0), - currentRegion(ClassData::PUBLIC), - namePolicy(nullptr), - declPolicy(nullptr), - functionPolicy(nullptr), - classPolicy(nullptr) { - InitializeClassPolicyHandlers(); - } - - ~ClassPolicy() { - if (namePolicy) delete namePolicy; - if (declPolicy) delete declPolicy; - if (functionPolicy) delete functionPolicy; - if (classPolicy) delete classPolicy; - } - - void NotifyWrite(const PolicyDispatcher * policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers - - void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - if (typeid(NamePolicy) == typeid(*policy)) { - data.name = policy->Data(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - } else if (typeid(DeclTypePolicy) == typeid(*policy)) { - std::shared_ptr>> decl_data = policy->Data>>(); - for (std::shared_ptr decl : *decl_data) - data.fields[currentRegion].emplace_back(decl); - decl_data->clear(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - } else if (typeid(FunctionPolicy) == typeid(*policy)) { - std::shared_ptr f_data = policy->Data(); - if (f_data->isPureVirtual) - data.hasPureVirtual = true; - if (f_data->type == FunctionData::CONSTRUCTOR) - data.constructors[currentRegion].emplace_back(f_data); - else if (f_data->type == FunctionData::OPERATOR) - data.operators[currentRegion].emplace_back(f_data); - else - data.methods[currentRegion].emplace_back(f_data); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - } else if (typeid(ClassPolicy) == typeid(*policy)) { - data.innerClasses[currentRegion].emplace_back(policy->Data()); - ctx.dispatcher->RemoveListener(nullptr); - } - } - -protected: - std::any DataInner() const override { return std::make_shared(data); } - -private: - void InitializeClassPolicyHandlers() { - using namespace srcSAXEventDispatch; - // start of policy - std::function startPolicy = [this](srcSAXEventContext& ctx) { - if (!classDepth) { - classDepth = ctx.depth; - data = ClassData{}; - data.lineNumber = ctx.currentLineNumber; - std::map::const_iterator stereotype_attr_itr = ctx.attributes.find("stereotype"); - if (stereotype_attr_itr != ctx.attributes.end()){ - std::istringstream stereostring(stereotype_attr_itr->second); - data.stereotypes = std::set(std::istream_iterator(stereostring), std::istream_iterator()); - } - if (ctx.currentTag == "class") - data.type = ClassData::CLASS; - else if (ctx.currentTag == "struct") - data.type = ClassData::STRUCT; - data.name = nullptr; - data.language = ctx.currentFileLanguage; - data.filename = ctx.currentFilePath; - CollectNameHandlers(); - CollectGenericHandlers(); - CollectSuperHanders(); - CollectBlockHanders(); - } else if ((classDepth + 3) == ctx.depth) { - if (!classPolicy) classPolicy = new ClassPolicy{this}; - ctx.dispatcher->AddListenerDispatch(classPolicy); - } - }; - - // end of policy - std::function endPolicy = [this](srcSAXEventContext& ctx) { - if (classDepth && classDepth == ctx.depth) { - classDepth = 0; - NotifyAll(ctx); - InitializeClassPolicyHandlers(); - } - }; - openEventMap[ParserState::classn] = startPolicy; - closeEventMap[ParserState::classn] = endPolicy; - - openEventMap[ParserState::structn] = startPolicy; - closeEventMap[ParserState::structn] = endPolicy; - } - - void CollectNameHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - if ((classDepth + 1) == ctx.depth) { - if (!namePolicy) namePolicy = new NamePolicy{this}; - ctx.dispatcher->AddListenerDispatch(namePolicy); - } - }; - closeEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - if ((classDepth + 1) == ctx.depth) { - NopOpenEvents({ParserState::name}); - NopCloseEvents({ParserState::name}); - } - }; - } - - void CollectGenericHandlers() { - using namespace srcSAXEventDispatch; - closeEventMap[ParserState::templates] = [this](srcSAXEventContext& ctx) { - if ((classDepth + 1) == ctx.depth) { - data.isGeneric = true; - } - }; - } - - void CollectSuperHanders() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::super_list] = [this](srcSAXEventContext& ctx) { - if ((classDepth + 1) == ctx.depth) { - openEventMap[ParserState::super] = [this](srcSAXEventContext& ctx) { - data.parents.emplace_back(ParentData{ "", false, ClassData::PUBLIC }); - }; - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - if (ctx.And({ ParserState::specifier })) { - if (ctx.currentToken == "virtual") { - data.parents.back().isVirtual = true; - } else if (ctx.currentToken == "public") { - data.parents.back().accessSpecifier = ClassData::PUBLIC; - } else if (ctx.currentToken == "private") { - data.parents.back().accessSpecifier = ClassData::PRIVATE; - } else if (ctx.currentToken == "protected") { - data.parents.back().accessSpecifier = ClassData::PROTECTED; - } - } else if (ctx.And({ ParserState::name })) { - data.parents.back().name += ctx.currentToken; - } - }; - } - }; - closeEventMap[ParserState::super_list] = [this](srcSAXEventContext& ctx) { - if ((classDepth + 1) == ctx.depth) { - NopOpenEvents({ParserState::super_list, ParserState::super}); - NopCloseEvents({ParserState::super_list, ParserState::tokenstring}); - } - }; - } - - void CollectBlockHanders() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::block] = [this](srcSAXEventContext& ctx) { - if ((classDepth + 1) == ctx.depth) { - NopOpenEvents({ParserState::name, ParserState::super_list, ParserState::super}); - NopCloseEvents({ParserState::name, ParserState::super_list, ParserState::tokenstring}); - // set up to listen to decl_stmt, member, and class policies - openEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx) { - if ((classDepth + 3) == ctx.depth) { - if (!declPolicy) declPolicy = new DeclTypePolicy{this}; - ctx.dispatcher->AddListenerDispatch(declPolicy); - } - }; - std::function functionEvent = [this](srcSAXEventContext& ctx) { - if ((classDepth + 3) == ctx.depth) { - if (!functionPolicy) functionPolicy = new FunctionPolicy{this}; - ctx.dispatcher->AddListenerDispatch(functionPolicy); - } - }; - openEventMap[ParserState::function] = functionEvent; - openEventMap[ParserState::functiondecl] = functionEvent; - openEventMap[ParserState::constructor] = functionEvent; - openEventMap[ParserState::constructordecl] = functionEvent; - - std::function destructorEvent = [this](srcSAXEventContext& ctx) { - if ((classDepth + 3) == ctx.depth) { - data.hasDestructor = true; - } - }; - openEventMap[ParserState::destructor] = destructorEvent; - openEventMap[ParserState::destructordecl] = destructorEvent; - } - }; - - // should always be in a region once block starts, so should not have to close - openEventMap[ParserState::publicaccess] = [this](srcSAXEventContext& ctx) { - if ((classDepth + 2) == ctx.depth) { - currentRegion = ClassData::PUBLIC; - } - }; - - openEventMap[ParserState::protectedaccess] = [this](srcSAXEventContext& ctx) { - if ((classDepth + 2) == ctx.depth) { - currentRegion = ClassData::PROTECTED; - } - }; - - openEventMap[ParserState::privateaccess] = [this](srcSAXEventContext& ctx) { - if ((classDepth + 2) == ctx.depth) { - currentRegion = ClassData::PRIVATE; - } - }; - - closeEventMap[ParserState::block] = [this](srcSAXEventContext& ctx) { - if ((classDepth + 1) == ctx.depth) { - NopOpenEvents({ParserState::block, ParserState::function, ParserState::functiondecl, - ParserState::constructor, ParserState::constructordecl, ParserState::destructor, ParserState::destructordecl, - ParserState::declstmt, - ParserState::publicaccess, ParserState::protectedaccess, ParserState::privateaccess}); - NopCloseEvents({ParserState::block}); - } - }; - } - -}; - -#endif diff --git a/src/policy_classes/CollectNLContext.hpp b/src/policy_classes/CollectNLContext.hpp deleted file mode 100644 index 0059781..0000000 --- a/src/policy_classes/CollectNLContext.hpp +++ /dev/null @@ -1,187 +0,0 @@ -/** - * @file CollectNLContext.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -#include -#include - -#ifndef NLCONTEXTPOLICY -#define NLCONTEXTPOLICY -class NLContextPolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - public: - struct NLSet{ - NLSet(std::string idname, std::string acategory, std::string acontext, std::string astereo){ - name = idname; - category = acategory; - context = acontext; - stereotype = astereo; - } - std::string category; - std::string name; - std::string context; - std::string stereotype; - }; - struct NLContextData{ - NLContextData(){} - void clear(){ - category.clear(); - identifiername.clear(); - } - std::string category; - std::string identifiername; - std::list nlsetmap; - }; - std::map identifierposmap; - NLContextData data; - ~NLContextPolicy(){} - NLContextPolicy(std::initializer_list listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners){ - sourcenlpolicy.AddListener(this); - exprpolicy.AddListener(this); - stereotypepolicy.AddListener(this); - InitializeEventHandlers(); - } - void NotifyWrite(const PolicyDispatcher * policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers - void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - using namespace srcSAXEventDispatch; - if(ctx.IsOpen(ParserState::declstmt) && ctx.IsClosed(ParserState::exprstmt)){ - sourcenlpdata = *policy->Data(); - std::string top; - if(!context.empty()){ - top = context.top(); - } - auto it = identifierposmap.find(sourcenlpdata.identifiername); - if(it == identifierposmap.end()){ - identifierposmap.insert(std::make_pair(sourcenlpdata.identifiername, sourcenlpdata.category)); - }else{ - if(it->second != sourcenlpdata.category){ - it->second = "multiple"; - } - } - //std::cerr<<"Def: "<Data(); - std::string top; - if(!context.empty()){ - top = context.top(); - }else{ - top = "none"; - } - std::string stereo; - if(!stereotype.stereotypes.empty()){ - stereo = stereotype.stereotypes.front(); - }else{ - stereo = "none"; - } - for(auto deal : exprdata.dataset){ - auto it = identifierposmap.find(deal.second.nameofidentifier); - if(it != identifierposmap.end()){ - std::string categorystr; - if(it->second.empty()){ - categorystr = "none"; - }else{ - categorystr = it->second; - } - NLSet nlset = NLSet(deal.second.nameofidentifier,categorystr,top,stereo); - data.nlsetmap.push_back(nlset); - } - } - } - if(ctx.IsOpen(ParserState::stereotype)){ - stereotype = *policy->Data(); - } - //datatotest.push_back(SourceNLData); - } - protected: - void * DataInner() const override { - return new NLContextData(data); - } - private: - SourceNLPolicy sourcenlpolicy; - SourceNLPolicy::SourceNLData sourcenlpdata; - ExprPolicy exprpolicy; - ExprPolicy::ExprDataSet exprdata; - StereotypePolicy stereotypepolicy; - StereotypePolicy::StereotypeData stereotype; - std::string currentTypeName, currentDeclName, currentModifier, currentSpecifier; - std::stack context; - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - openEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx) { - ctx.dispatcher->AddListenerDispatch(&sourcenlpolicy); - }; - closeEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx){ - ctx.dispatcher->RemoveListenerDispatch(&sourcenlpolicy); - ///data.clear(); - }; - - openEventMap[ParserState::exprstmt] = [this](srcSAXEventContext& ctx) { - ctx.dispatcher->AddListenerDispatch(&exprpolicy); - }; - closeEventMap[ParserState::exprstmt] = [this](srcSAXEventContext& ctx){ - ctx.dispatcher->RemoveListenerDispatch(&exprpolicy); - //data.clear(); - }; - - openEventMap[ParserState::stereotype] = [this](srcSAXEventContext& ctx){ - ctx.dispatcher->AddListenerDispatch(&stereotypepolicy); - }; - closeEventMap[ParserState::stereotype] = [this](srcSAXEventContext& ctx){ - ctx.dispatcher->RemoveListenerDispatch(&stereotypepolicy); - }; - - openEventMap[ParserState::whilestmt] = [this](srcSAXEventContext& ctx) { - context.push("while"); - }; - closeEventMap[ParserState::whilestmt] = [this](srcSAXEventContext& ctx){ - context.pop(); - }; - - openEventMap[ParserState::forstmt] = [this](srcSAXEventContext& ctx) { - context.push("for"); - }; - closeEventMap[ParserState::forstmt] = [this](srcSAXEventContext& ctx){ - context.pop(); - }; - - openEventMap[ParserState::ifstmt] = [this](srcSAXEventContext& ctx) { - context.push("if"); - }; - closeEventMap[ParserState::ifstmt] = [this](srcSAXEventContext& ctx){ - context.pop(); - }; - - /* - openEventMap[ParserState::whilestmt] = [this](srcSAXEventContext& ctx) { - context.push("else if"); - }; - openEventMap[ParserState::whilestmt] = [this](srcSAXEventContext& ctx) { - context.push("else"); - };*/ - - closeEventMap[ParserState::archive] = [this](srcSAXEventContext& ctx){ - NotifyAll(ctx); - }; - - } -}; -#endif \ No newline at end of file diff --git a/src/policy_classes/ConditionPolicy.hpp b/src/policy_classes/ConditionPolicy.hpp new file mode 100644 index 0000000..d7a83fd --- /dev/null +++ b/src/policy_classes/ConditionPolicy.hpp @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file ConditionPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_CONDITION_POLICY_HPP +#define INCLUDED_CONDITION_POLICY_HPP + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + struct ConditionData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + std::vector> conditions; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + if(conditions.empty()) return ""; + + std::string str; + bool printComma = false; + for (const DeltaElement& condition : conditions) { + + bool outputRaw = condition.IsOfOperation(operation); + if(outputRaw) { + if(printComma) { + str += ", "; + } + printComma = true; + } + + if(condition.GetElement().type() == typeid(std::shared_ptr)) { + str += condition.ToString>(operation); + } else { + str += condition.ToString>(operation); + } + } + + return str; + } + }; + + // Collect the expression in the return + // + class ConditionPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + ConditionData data; + + std::unique_ptr exprPolicy; + std::unique_ptr declPolicy; + + public: + ConditionPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeConditionPolicyHandlers(); + } + + ~ConditionPolicy() {} + + protected: + std::any DataInner() const override { return std::make_shared(data); } + + virtual void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override { + if(typeid(ExpressionPolicy) == typeid(*policy)) { + if(data.conditions.size() && ctx.diffStack.back().isReplace && data.conditions.back().GetElement().type() == typeid(std::shared_ptr)) { + data.conditions.back().Update(ctx.diffStack.back().operation, policy->Data()); + } else { + data.conditions.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } + } else if(typeid(DeclPolicy) == typeid(*policy)) { + // not sure how safe GetElement is here + std::shared_ptr decl = policy->Data(); + if(data.conditions.size() && decl->type->types.empty() + && data.conditions.back().GetElement().type() == typeid(std::shared_ptr)) { + decl->type = std::any_cast>(data.conditions.back().GetElement())->type; + decl->isStatic = std::any_cast>(data.conditions.back().GetElement())->isStatic; + } + srcDispatch::DiffOperation operation = ctx.diffStack.back().operation; + data.conditions.emplace_back(operation, decl); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + ctx.dispatcher->RemoveListener(nullptr); + } + + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + private: + void InitializeConditionPolicyHandlers() { + using namespace srcDispatch; + // start of policy + openEventMap[ParserState::condition] = [this](srcSAXEventContext& ctx) { + if(depth) return; + + depth = ctx.depth; + data = ConditionData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectExpressionHandlers(); + CollectDeclPolicyHandlers(); + }; + + // end of policy + closeEventMap[ParserState::condition] = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeConditionPolicyHandlers(); + }; + } + + void CollectExpressionHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::expr] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!exprPolicy) { + exprPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(exprPolicy.get()); + }; + } + + void CollectDeclPolicyHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::decl] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!declPolicy) { + declPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(declPolicy.get()); + }; + } + }; + +} + +#endif diff --git a/src/policy_classes/ConditionalPolicy.hpp b/src/policy_classes/ConditionalPolicy.hpp index 183eadb..7a4274c 100644 --- a/src/policy_classes/ConditionalPolicy.hpp +++ b/src/policy_classes/ConditionalPolicy.hpp @@ -1,265 +1,115 @@ -#include -#include -#include -#include +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file ConditionalPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_CONDITIONAL_POLICY_HPP +#define INCLUDED_CONDITIONAL_POLICY_HPP + +#include +#include +#include +#include +#include +#include + +#include #include -#include -#ifndef CONDITIONALPOLICY -#define CONDITIONALPOLICY -struct DvarData{ - DvarData(std::string func, std::string name, unsigned int line) { - function = func; - lhsName = name; - lhsDefLine = line; - dvars.clear(); - } - std::string function, lhsName; - unsigned int lhsDefLine; - std::set> dvars; -}; +#include -class ConditionalPolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - public: - ConditionalPolicy(std::initializer_list listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners){ - InitializeEventHandlers(); - } - ~ConditionalPolicy(){} +namespace srcDispatch { - void Notify(const PolicyDispatcher * policy [[maybe_unused]], const srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers - void NotifyWrite(const PolicyDispatcher * policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers + template + class ConditionalPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { - std::unordered_map>* GetConditionalUses() { - return &conditionalUses; - } - std::unordered_map>* GetConditionalDefs() { - return &conditionalDefs; - } + protected: + ConditionalData data; - std::unordered_map>* GetSwitchUses() { - return &switchUses; - } - std::unordered_map>* GetSwitchDefs() { - return &switchDefs; - } + std::unique_ptr conditionPolicy; + std::unique_ptr blockPolicy; - std::string GetVarName() { - return currentExprName; + public: + ConditionalPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeConditionalPolicyHandlers(); } - void EditDepth(int d) { + ~ConditionalPolicy() {} - if (switchControlVars.size() > 0 && d < 0) { - switchControlVars.erase(switchDepth); + protected: + std::any DataInner() const override { return std::make_shared(data); } + + void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override { + if(typeid(ConditionPolicy) == typeid(*policy)) { + data.condition = DeltaElement(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(BlockPolicy) == typeid(*policy)) { + data.block = DeltaElement(ctx.diffStack.back().operation, policy->Data()); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); } - switchDepth += d; - if (switchDepth < 0) switchDepth = 0; - } - void DeleteUsesCollection(std::string name) { conditionalUses.erase(name); } - void DeleteDefsCollection(std::string name) { conditionalDefs.erase(name); } + ctx.dispatcher->RemoveListener(nullptr); + } - std::vector* GetPossibleDvars() { return &dvarSet; } + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} - const std::string& GetLastFunction() { return recentFunction; } + void InitializeConditionalPolicyHandlers() { - protected: - std::any DataInner() const override {} - - private: - std::unordered_map> conditionalUses, conditionalDefs; - std::unordered_map> switchUses, switchDefs; - std::unordered_map< unsigned int, std::set > switchControlVars; - unsigned int switchDepth = 0; - std::string currentExprName = "", currentExprOp = "", currentType = ""; - std::vector dvarSet; - std::string recentFunction; - bool insertDvar = false; + using namespace srcDispatch; - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; + openEventMap[DispatchEvent] = [this](srcSAXEventContext& ctx) { + if(depth) return; - closeEventMap[ParserState::function] = [this](srcSAXEventContext &ctx) { - NotifyAll(ctx); + depth = ctx.depth; + data = ConditionalData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectConditionHandlers(); + CollectBlockHandlers(); }; - - closeEventMap[ParserState::name] = [this](srcSAXEventContext &ctx) { - recentFunction = ctx.currentFunctionName; - currentExprName = ctx.currentToken; - - if (ctx.IsOpen({ParserState::decl}) && ctx.IsClosed({ParserState::type}) && dvarSet.size() > 0 && insertDvar) { - dvarSet.back().dvars.insert( std::make_pair(ctx.currentToken, ctx.currentLineNumber) ); - } - - if ( ctx.IsClosed({ParserState::comment}) ) { - // The following is for detecting possible uses within various Conditionals - if ( (ctx.IsOpen({ParserState::ifstmt}) || ctx.IsOpen({ParserState::elseif})) && ctx.IsOpen({ParserState::condition}) ) { - // switch using data-type capturing: - // xml will appear as `inti` - // using this switch when I hit the name when I've detected - // a type within an if-stmt I wont add the line as a use of - // a line where it is being declared: - // `4 | if (int a = i; i < 10) {...}` I want to mark: - // "a" with only def on line 4, and "i" use on 4 - - if (currentType.empty()) { - if (conditionalUses[ctx.currentToken].empty() || ctx.currentLineNumber != conditionalUses[ctx.currentToken].back()) { - conditionalUses[ctx.currentToken].push_back(ctx.currentLineNumber); - } - } else { - currentType.clear(); - } - } - - // The following is for detecting possible uses within various Conditionals - if ( ctx.IsOpen({ParserState::whilestmt}) && ctx.IsOpen({ParserState::condition}) ){ - if (conditionalUses[ctx.currentToken].empty() || ctx.currentLineNumber != conditionalUses[ctx.currentToken].back()) { - conditionalUses[ctx.currentToken].push_back(ctx.currentLineNumber); - } - } - - // The following is for detecting possible uses within various Conditionals - if ( ctx.IsOpen({ParserState::forstmt}) ) { - if ( ctx.And({ParserState::decl, ParserState::init, ParserState::expr}) ) { - if (conditionalUses[ctx.currentToken].empty() || ctx.currentLineNumber != conditionalUses[ctx.currentToken].back()) { - conditionalUses[ctx.currentToken].push_back(ctx.currentLineNumber); - } - } - - if ( ctx.IsOpen({ParserState::condition}) ){ - if (conditionalUses[ctx.currentToken].empty() || ctx.currentLineNumber != conditionalUses[ctx.currentToken].back()) { - conditionalUses[ctx.currentToken].push_back(ctx.currentLineNumber); - } - } - - if ( ctx.IsOpen({ParserState::incr}) || ctx.IsOpen({ParserState::decr}) ){ - if (conditionalDefs[ctx.currentToken].empty() || ctx.currentLineNumber != conditionalDefs[ctx.currentToken].back()) { - conditionalDefs[ctx.currentToken].push_back(ctx.currentLineNumber); - } - if (conditionalUses[ctx.currentToken].empty() || ctx.currentLineNumber != conditionalUses[ctx.currentToken].back()) { - conditionalUses[ctx.currentToken].push_back(ctx.currentLineNumber); - } - } - } - - // The following is for detecting possible uses within various Conditionals - if ( ctx.IsOpen({ParserState::dostmt}) && ctx.IsOpen({ParserState::condition}) ){ - if (conditionalUses[ctx.currentToken].empty() || ctx.currentLineNumber != conditionalUses[ctx.currentToken].back()) { - conditionalUses[ctx.currentToken].push_back(ctx.currentLineNumber); - } - } + // end of policy + closeEventMap[DispatchEvent] = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return ; - // Get uses or use/defs within switch conditions - if ( ctx.IsOpen({ParserState::switchstmt}) && ctx.IsOpen({ParserState::condition}) ){ - if ( ctx.IsOpen({ParserState::init}) ) { - if (switchUses[ctx.currentToken].empty() || ctx.currentLineNumber != switchUses[ctx.currentToken].back()) { - switchUses[ctx.currentToken].push_back(ctx.currentLineNumber); - } - } else { - switchControlVars[switchDepth].insert(ctx.currentToken); - - if (switchUses[ctx.currentToken].empty() || ctx.currentLineNumber != switchUses[ctx.currentToken].back()) { - switchUses[ctx.currentToken].push_back(ctx.currentLineNumber); - } - - if (!currentExprOp.empty()) { - // prefix : ++c - if (switchDefs[ctx.currentToken].empty() || ctx.currentLineNumber != switchDefs[ctx.currentToken].back()) { - switchDefs[ctx.currentToken].push_back(ctx.currentLineNumber); - } - - currentExprName = ""; - currentExprOp = ""; - } - } - - } - } - }; - - // Assume switch cases are a use of the condition value - closeEventMap[ParserState::switchcase] = [this](srcSAXEventContext &ctx) { - if ( ctx.IsOpen({ParserState::switchstmt}) ){ - for (auto varName : switchControlVars[switchDepth]) { - if (switchUses[varName].empty() || ctx.currentLineNumber != switchUses[varName].back()) { - switchUses[varName].push_back(ctx.currentLineNumber); - } - } - } - }; - - closeEventMap[ParserState::type] = [this](srcSAXEventContext& ctx){ - if (ctx.And({ParserState::ifstmt, ParserState::condition})) { - currentType = ctx.currentToken; - } + depth = 0; + NotifyAll(ctx); + InitializeConditionalPolicyHandlers(); }; + } - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx){ - std::string token = ctx.currentToken; - std::string extractedToken = ""; - - // Extract white-spaces from token - for (int i = 0; i < token.length(); ++i) { - if (std::isalnum(token[i]) || token[i] == '=' || token[i] == '-' || - token[i] == '+' || token[i] == '*' || token[i] == '/' || - token[i] == '%' || token[i] == '&') { - extractedToken += token[i]; - } - } - - if (extractedToken == "+=" || extractedToken == "-=" || extractedToken == "*=" || - extractedToken == "/=" || extractedToken == "%=" || extractedToken == "=") { + void CollectConditionHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::condition] = [this](srcSAXEventContext& ctx) { + if(!depth) return; - if ( (ctx.IsOpen({ParserState::decl}) && ctx.IsClosed({ParserState::name}) && ctx.IsClosed({ParserState::type})) && !currentExprName.empty()) { - dvarSet.push_back(DvarData(ctx.currentFunctionName, currentExprName, ctx.currentLineNumber)); - insertDvar = true; - } + if(!conditionPolicy) { + conditionPolicy = make_unique_policy({this}); } + ctx.dispatcher->AddListenerDispatch(conditionPolicy.get()); }; + } - closeEventMap[ParserState::init] = [this](srcSAXEventContext& ctx [[maybe_unused]]){ - insertDvar = false; - }; - - closeEventMap[ParserState::op] = [this](srcSAXEventContext& ctx){ - // Long or-statement allows various declaration operators to get planted into - // a slices def data output - // if (ctx.currentToken == "=" || ctx.currentToken == "++" || ctx.currentToken == "+=" || - // ctx.currentToken == "--" || ctx.currentToken == "-=" || ctx.currentToken == "*=" || - // ctx.currentToken == "/=" || ctx.currentToken == "%=" || ctx.currentToken == "&=" || - // ctx.currentToken == "|=" || ctx.currentToken == "^=" || ctx.currentToken == "<<=" || - // ctx.currentToken == ">>=") - bool isMutatorOp = (ctx.currentToken == "+=" || ctx.currentToken == "-=" || - ctx.currentToken == "*=" || ctx.currentToken == "/=" || - ctx.currentToken == "%=" || ctx.currentToken == "++" || - ctx.currentToken == "--"); - - // Within conditional blocks find use/defs - if ( isMutatorOp ) { - currentExprOp = ctx.currentToken; - if (!currentExprName.empty()) { - // postfix : c++ - if (conditionalDefs[currentExprName].empty() || ctx.currentLineNumber != conditionalDefs[currentExprName].back()) { - conditionalDefs[currentExprName].push_back(ctx.currentLineNumber); - } - - if (conditionalUses[currentExprName].empty() || ctx.currentLineNumber != conditionalUses[currentExprName].back()) { - conditionalUses[currentExprName].push_back(ctx.currentLineNumber); - } - - currentExprName = ""; - currentExprOp = ""; - } - } + void CollectBlockHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::block] = [this](srcSAXEventContext& ctx) { + if(!depth) return; - if (ctx.currentToken == "+=" || ctx.currentToken == "-=" || - ctx.currentToken == "*=" || ctx.currentToken == "/=" || - ctx.currentToken == "%=" || ctx.currentToken == "=") { - if ( ctx.IsOpen({ParserState::decl}) && !currentExprName.empty() && !currentType.empty() ) { - dvarSet.push_back(DvarData(ctx.currentFunctionName, currentExprName, ctx.currentLineNumber)); - } + if(!blockPolicy) { + blockPolicy = make_unique_policy({this}); } + ctx.dispatcher->AddListenerDispatch(blockPolicy.get()); }; } -}; -#endif \ No newline at end of file + }; + +} + +#endif diff --git a/src/policy_classes/ControlPolicy.hpp b/src/policy_classes/ControlPolicy.hpp new file mode 100644 index 0000000..d38b540 --- /dev/null +++ b/src/policy_classes/ControlPolicy.hpp @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file ControlPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_CONTROL_POLICY_HPP +#define INCLUDED_CONTROL_POLICY_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + struct ControlData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement> init; + DeltaElement> condition; + DeltaElement> incr; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + + std::string str = init.ToString(operation); + + if(condition) { + if(condition.IsOfOperation(operation)) { + str += "; "; + } + + str += condition.ToString(operation); + if(condition.IsOfOperation(operation)) { + str += "; "; + } + } + + str += incr.ToString(operation); + + return str; + } + }; + + // Collect the expression in the return + // + class ControlPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + ControlData data; + + std::unique_ptr declPolicy; + std::unique_ptr initPolicy; + std::unique_ptr conditionPolicy; + std::unique_ptr incrPolicy; + + public: + ControlPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeControlPolicyHandlers(); + } + + ~ControlPolicy() {} + + protected: + std::any DataInner() const override { return std::make_shared(data); } + + virtual void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override { + using namespace srcDispatch; + if(typeid(InitPolicy) == typeid(*policy)) { + data.init.Update(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(ConditionPolicy) == typeid(*policy)) { + data.condition = DeltaElement(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(IncrPolicy) == typeid(*policy)) { + data.incr.Update(ctx.diffStack.back().operation, policy->Data()); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + + ctx.dispatcher->RemoveListener(nullptr); + } + + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + private: + void InitializeControlPolicyHandlers() { + using namespace srcDispatch; + // start of policy + openEventMap[ParserState::control] = [this](srcSAXEventContext& ctx) { + if(depth) return; + + depth = ctx.depth; + data = ControlData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectInitHandlers(); + CollectConditionHandlers(); + CollectIncrHandlers(); + }; + + // end of policy + closeEventMap[ParserState::control] = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) + + depth = 0; + NotifyAll(ctx); + InitializeControlPolicyHandlers(); + }; + } + + void CollectInitHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::init] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!initPolicy) { + initPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(initPolicy.get()); + }; + } + + void CollectConditionHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::condition] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!conditionPolicy) { + conditionPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(conditionPolicy.get()); + }; + } + + void CollectIncrHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::incr] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!incrPolicy) { + incrPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(incrPolicy.get()); + }; + } + }; + +} + +#endif diff --git a/src/policy_classes/ConvertPlexerPolicy.hpp b/src/policy_classes/ConvertPlexerPolicy.hpp new file mode 100644 index 0000000..d4de843 --- /dev/null +++ b/src/policy_classes/ConvertPlexerPolicy.hpp @@ -0,0 +1,269 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file ConvertPlexerPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_CONVERT_PLEXER_POLICY_HPP +#define INCLUDED_CONVERT_PLEXER_POLICY_HPP + +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +// #define CONVERT_DEBUG + +namespace srcDispatch { + + struct ConvertData { + DeltaElement construct; + }; + + class ConvertPlexerPolicy : + public srcDispatch::EventListener, + public srcDispatch::EventDispatcher, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + protected: + ConvertData data; + + std::stack dispatcherStack; + std::stack dispatchingState; + + std::unique_ptr originalPolicy; + std::unique_ptr modifiedPolicy; + + std::stack originalPolicyStack; + std::stack modifiedPolicyStack; +public: + static std::size_t s_index; + std::size_t index; +protected: + static std::unordered_map(std::initializer_list listeners)> + > policyFactory; + public: + ConvertPlexerPolicy(std::initializer_list listeners) + : srcDispatch::EventDispatcher({}), srcDispatch::PolicyDispatcher(listeners), data(), + dispatcherStack(), dispatchingState(), originalPolicy(), modifiedPolicy(), originalPolicyStack(), modifiedPolicyStack() { + dispatchingState.push(srcDispatch::NONE); + index = ++s_index; + } + + ~ConvertPlexerPolicy() {} + + void Stop() { + dispatched = true; + EventDispatcher* currentDispatcher = dispatcherStack.top()->GetContext().dispatcher; + dispatcherStack.top()->GetContext().dispatcher = dispatcherStack.top(); + NotifyAll(dispatcherStack.top()->GetContext()); + dispatcherStack.top()->GetContext().dispatcher = currentDispatcher; + } + + virtual void AddListener(PolicyListener* listener) override { + PolicyDispatcher::AddListener(listener); + } + + virtual void RemoveListener(PolicyListener* listener) override { + PolicyDispatcher::RemoveListener(listener); + } + + virtual void AddListener(EventListener* listener) override { +#ifdef CONVERT_DEBUG + std::cerr << "ADD: " << std::string(index * 4, ' ') << index << ' ' << __LINE__ << ' ' << dispatchingState.top() << '\n'; +#endif + if(dispatchingState.top() == srcDispatch::DELETE) { +#ifdef CONVERT_DEBUG + std::cerr << "ADD: " << std::string(index * 4, ' ') << index << ' ' << __LINE__ << '\n'; +#endif + originalPolicyStack.top()->SetDispatched(false); + originalPolicyStack.push(listener); + } else if(dispatchingState.top() == srcDispatch::INSERT) { +#ifdef CONVERT_DEBUG + std::cerr << "ADD: " << std::string(index * 4, ' ') << index << ' ' << __LINE__ << '\n'; +#endif + modifiedPolicyStack.top()->SetDispatched(false); + modifiedPolicyStack.push(listener); + } + } + + virtual void AddListenerDispatch(EventListener* listener) override { + AddListener(listener); + dispatched = false; + } + + virtual void AddListenerNoDispatch(EventListener* listener) override { + throw std::string("AddListenerNoDispatch not implemented"); + } + + virtual void RemoveListener(EventListener* listener) override { + if(dispatchingState.top() == srcDispatch::DELETE) { +#ifdef CONVERT_DEBUG + std::cerr << "REMOVE: " << std::string(index * 4, ' ') << index << ' ' << __LINE__ << '\n'; +#endif + originalPolicyStack.top()->SetDispatched(false); + originalPolicyStack.pop(); + } else if(dispatchingState.top() == srcDispatch::INSERT) { +#ifdef CONVERT_DEBUG + std::cerr << "REMOVE: " << std::string(index * 4, ' ') << index << ' ' << __LINE__ << '\n'; +#endif + modifiedPolicyStack.top()->SetDispatched(false); + modifiedPolicyStack.pop(); + } + } + + virtual void RemoveListenerDispatch(EventListener* listener) override { + RemoveListener(listener); + dispatched = false; + } + + virtual void RemoveListenerNoDispatch(EventListener* listener) override { + throw std::string("RemoveListenerNoDispatch not implemented"); + } + + virtual void DispatchEvent(srcDispatch::ParserState, srcDispatch::ElementState) override { + } + + virtual void HandleEvent(srcDispatch::ParserState pstate, srcDispatch::ElementState estate, srcDispatch::srcSAXEventContext& ctx) override { +#ifdef CONVERT_DEBUG + std::cerr << "HERE: " << std::string(index * 4, ' ') << index << ' ' << __LINE__ << ' ' << pstate << ":" << estate << '\n'; + std::cerr << "HERE: " << std::string(index * 4, ' ') << index << ' ' << __LINE__ << ' ' << ctx.diffStack.back().operation << '\n'; + std::cerr << "HERE: " << std::string(index * 4, ' ') << index << ' ' << __LINE__ << ' ' << ctx.currentTag << '\n'; + std::cerr << "HERE: " << std::string(index * 4, ' ') << index << ' ' << __LINE__ << ' ' << ctx.depth << '\n'; + std::cerr << "HERE: " << std::string(index * 4, ' ') << index << ' ' << __LINE__ << ' ' << depth << '\n'; +#endif + + dispatcherStack.push(ctx.dispatcher); + ctx.dispatcher = this; + while(!dispatched) { + + dispatched = true; + + if( dispatchingState.size() && dispatchingState.top() != srcDispatch::INSERT + && (ctx.diffStack.back().operation != srcDispatch::INSERT || (depth && ctx.depth > depth))) { + + if(!originalPolicy) { + originalPolicy = policyFactory[pstate]({this}); + originalPolicyStack.push(originalPolicy.get()); + } + +#ifdef CONVERT_DEBUG + std::cerr << "HERE: " << std::string(index * 4, ' ') << index << ' ' << __LINE__ << ' ' << originalPolicyStack.size() << '\n'; +#endif + + dispatchingState.push(srcDispatch::DELETE); + originalPolicyStack.top()->HandleEvent(pstate, estate, ctx); + dispatchingState.pop(); + if(dispatchingState.size() == 1) { + originalPolicyStack.top()->SetDispatched(false); + } + } + +#ifdef CONVERT_DEBUG + std::cerr << "HERE: " << std::string(index * 4, ' ') << index << ' ' << __LINE__ << '\n'; +#endif + + if( dispatchingState.size() && dispatchingState.top() != srcDispatch::DELETE + && (ctx.diffStack.back().operation != srcDispatch::DELETE || (depth && ctx.depth > depth))) { + + if(!modifiedPolicy) { + modifiedPolicy = policyFactory[pstate]({this}); + modifiedPolicyStack.push(modifiedPolicy.get()); + + if(pstate != srcDispatch::ParserState::ifgroup) { + depth = ctx.diffStack.back().depth + 1; + } else { + depth = ctx.diffStack.back().depth + 2; + } + } + +#ifdef CONVERT_DEBUG + std::cerr << "HERE: " << std::string(index * 4, ' ') << index << ' ' << __LINE__ << ' ' << modifiedPolicyStack.size() << '\n'; +#endif + + dispatchingState.push(srcDispatch::INSERT); + modifiedPolicyStack.top()->HandleEvent(pstate, estate, ctx); + dispatchingState.pop(); + if(dispatchingState.size() == 1) { + modifiedPolicyStack.top()->SetDispatched(false); + } + } + } + ctx.dispatcher = dispatcherStack.top(); + dispatcherStack.pop(); + } + + protected: + std::any DataInner() const override { return std::make_shared(data); } + + void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override { +#ifdef CONVERT_DEBUG + std::cerr << "HERE: " << std::string(index * 4, ' ') << index << ' ' << __LINE__ << ' ' << '\n'; +#endif + + std::any anyData; + if(typeid(WhilePolicy) == typeid(*policy)) { + anyData = policy->Data(); + } else if(typeid(ForPolicy) == typeid(*policy)) { + anyData = policy->Data(); + } else if(typeid(IfStmtPolicy) == typeid(*policy)) { + anyData = policy->Data(); + } else if(typeid(DeclStmtPolicy) == typeid(*policy)) { + anyData = policy->Data(); + } else if(typeid(ExprStmtPolicy) == typeid(*policy)) { + anyData = policy->Data(); + } else if(typeid(ReturnPolicy) == typeid(*policy)) { + anyData = policy->Data(); + } + + data.construct.Update(ctx.diffStack.back().operation, anyData); + if(data.construct.HasOriginal() && data.construct.HasModified()) { + +#ifdef CONVERT_DEBUG + std::cerr << "HERE: " << std::string(index * 4, ' ') << index << ' ' << __LINE__ << ' ' << '\n'; +#endif + + Stop(); + } + } + + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + }; + + std::unordered_map(std::initializer_list listeners)> + >ConvertPlexerPolicy::policyFactory = { + { srcDispatch::ParserState::ifgroup, [](std::initializer_list listeners) { return srcDispatch::make_unique_policy(listeners); } }, + { srcDispatch::ParserState::whilestmt, [](std::initializer_list listeners) { return srcDispatch::make_unique_policy (listeners); } }, + { srcDispatch::ParserState::forstmt, [](std::initializer_list listeners) { return srcDispatch::make_unique_policy (listeners); } }, + + { srcDispatch::ParserState::declstmt, [](std::initializer_list listeners) { return srcDispatch::make_unique_policy (listeners); } }, + { srcDispatch::ParserState::exprstmt, [](std::initializer_list listeners) { return srcDispatch::make_unique_policy (listeners); } }, + { srcDispatch::ParserState::returnstmt, [](std::initializer_list listeners) { return srcDispatch::make_unique_policy (listeners); } }, + + }; + + std::size_t ConvertPlexerPolicy::s_index = 0; +} + +#endif diff --git a/src/policy_classes/DeclDS.hpp b/src/policy_classes/DeclDS.hpp deleted file mode 100644 index 25f664f..0000000 --- a/src/policy_classes/DeclDS.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/** - * @file DeclTypePolicy.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef INCLUDED_DECL_DS_HPP -#define INCLUDED_DECL_DS_HPP -struct SignatureData; -struct DeclData{ - DeclData(): lineNumber{0}, isConstValue{false}, isConstAlias{false}, isAliasToConst{false}, isReference{false}, - isPointer{false}, isStatic{false}, isClassMember{false}, usesSubscript{false}, hasSideEffect{false}, - numOfContainingFunctionParams{0}{} - void clear(){ - lineNumber = -1; - isFinal = false; - isStatic = false; - isPointer = false; - nameOfType.clear(); - namespaces.clear(); - isLocalVar = false; - isReference = false; - isParameter = false; - isConstValue = false; - isConstAlias = false; - isClassMember = false; - usesSubscript = false; - hasSideEffect = false; - sLexicalCategory.clear(); - nameOfIdentifier.clear(); - nameOfContainingFile.clear(); - nameOfContainingClass.clear(); - numOfContainingFunctionParams = 0; - nameOfContainingFunction.clear(); - } - unsigned int lineNumber; - int numOfContainingFunctionParams; - bool isFinal; - bool isConstValue; - bool isStatic; - bool isPointer; - bool isReference; - bool isConstAlias; - bool isClassMember; - bool usesSubscript; - bool hasSideEffect; - bool isAliasToConst; - bool isParameter; - bool isLocalVar; - - std::string nameOfType; - std::string sLexicalCategory; - std::string nameOfIdentifier; - std::string nameOfContainingFile; - std::string nameOfContainingClass; - std::string nameOfContainingFunction; - - std::vector namespaces; -}; - -#endif \ No newline at end of file diff --git a/src/policy_classes/DeclPolicy.hpp b/src/policy_classes/DeclPolicy.hpp new file mode 100644 index 0000000..70f3c2b --- /dev/null +++ b/src/policy_classes/DeclPolicy.hpp @@ -0,0 +1,314 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file DeclPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_DECL_POLICY_HPP +#define INCLUDED_DECL_POLICY_HPP + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +namespace srcDispatch { + + struct DeclData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + std::vector>> generics; + DeltaElement accessSpecifier; + DeltaElement> type; + DeltaElement> name; + DeltaElement> init; + std::vector>> arguments; + DeltaElement> range; + + DeltaElement isStatic; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + + std::string str; + if(type) { + str += type.ToString(operation); + } + + if(name) { + if(name.IsOfOperation(operation)) { + str += ' '; + } + str += name.ToString(operation); + } + + if(init) { + if(init.IsOfOperation(operation)) { + str += " = "; + } + str += init.ToString(operation); + } + + if(!arguments.empty()) { + + bool isArgument = false; + for(const DeltaElement>& argument : arguments) { + + bool outputRaw = argument.IsOfOperation(operation); + if(outputRaw) { + if(!isArgument) { + str += '('; + } else { + str += ", "; + } + isArgument = true; + } + str += argument.ToString(operation); + } + + if(isArgument) { + str += ')'; + } + } + + if(range) { + if(range.IsOfOperation(operation)) { + str += " : "; + } + str += range.ToString(operation); + } + + return str; + } + }; + + class DeclPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + DeclData data; + + std::unique_ptr genericPolicy; + std::unique_ptr typePolicy; + std::unique_ptr namePolicy; + std::unique_ptr exprPolicy; + + public: + DeclPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeDeclPolicyHandlers(); + } + + ~DeclPolicy() {} + + protected: + std::any DataInner() const override { return std::make_shared(data); } + + virtual void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override { + using namespace srcDispatch; + if(typeid(GenericPolicy) == typeid(*policy)) { + data.generics.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(TypePolicy) == typeid(*policy)) { + data.type = DeltaElement(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(NamePolicy) == typeid(*policy)) { + data.name = DeltaElement(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(ExpressionPolicy) == typeid(*policy)) { + if(ctx.IsOpen(ParserState::range)) { + data.range.Update(ctx.diffStack.back().operation, policy->Data()); + } else if(ctx.IsOpen(ParserState::init)) { + data.init.Update(ctx.diffStack.back().operation, policy->Data()); + } else if(ctx.IsOpen(ParserState::argumentlist)) { + data.arguments.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else { + throw std::string("Unhandled ExpressionPolicy condition"); + } + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + + ctx.dispatcher->RemoveListener(nullptr); + } + + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + private: + void InitializeDeclPolicyHandlers() { + using namespace srcDispatch; + + // start of policy + std::function startDecl = [this](srcSAXEventContext &ctx) { + if(depth) return; + + depth = ctx.depth; + data = DeclData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + + CollectGenericHandlers(); + CollectSpecifiersHandlers(); + CollectTypeHandlers(); + CollectNameHandlers(); + CollectInitHandlers(); + CollectArgumentList(); + CollectRangeHandlers(); + }; + + openEventMap[ParserState::decl] = startDecl; + // For generic template parameter + openEventMap[ParserState::parameter] = startDecl; + + // close policy + std::function endDecl = [this](srcSAXEventContext &ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + data = DeclData{}; + InitializeDeclPolicyHandlers(); + }; + + closeEventMap[ParserState::decl] = endDecl; + closeEventMap[ParserState::parameter] = endDecl; + + } + + void CollectGenericHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::templates] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!genericPolicy) { + genericPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(genericPolicy.get()); + }; + } + + void CollectSpecifiersHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::specifier] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext &ctx) { + if(ctx.currentToken == "static") { + data.isStatic.Update(ctx.diffStack.back().operation, true); + } + }; + }; + + closeEventMap[ParserState::specifier] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + NopCloseEvents({ParserState::tokenstring}); + }; + } + + void CollectTypeHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::type] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + if(!typePolicy) { + typePolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(typePolicy.get()); + }; + } + + void CollectNameHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::name] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + if(!namePolicy) { + namePolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(namePolicy.get()); + }; + } + + void CollectInitHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::init] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + openEventMap[ParserState::expr] = [this](srcSAXEventContext &ctx) { + if(!exprPolicy) { + exprPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(exprPolicy.get()); + }; + }; + + closeEventMap[ParserState::init] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + NopOpenEvents({ParserState::expr}); + }; + + } + + void CollectArgumentList() { + using namespace srcDispatch; + openEventMap[ParserState::argumentlist] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + openEventMap[ParserState::argument] = [this](srcSAXEventContext &ctx) { + openEventMap[ParserState::expr] = [this](srcSAXEventContext &ctx) { + if(!exprPolicy) {fprintf(stderr, "HERE: %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); + exprPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(exprPolicy.get()); + }; + }; + + closeEventMap[ParserState::argument] = [this](srcSAXEventContext &ctx) { + NopOpenEvents({ParserState::expr}); + }; + + }; + + closeEventMap[ParserState::argumentlist] = [this](srcSAXEventContext &ctx) { + NopOpenEvents({ParserState::argument}); + }; + } + + void CollectRangeHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::range] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + openEventMap[ParserState::expr] = [this](srcSAXEventContext &ctx) { + if(!exprPolicy) { + exprPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(exprPolicy.get()); + }; + }; + + closeEventMap[ParserState::range] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + NopOpenEvents({ParserState::expr}); + }; + } + }; +} + +#endif diff --git a/src/policy_classes/DeclStmtPolicy.hpp b/src/policy_classes/DeclStmtPolicy.hpp new file mode 100644 index 0000000..75ddd7a --- /dev/null +++ b/src/policy_classes/DeclStmtPolicy.hpp @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file DeclStmtPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_DECL_TYPE_POLICY_HPP +#define INCLUDED_DECL_TYPE_POLICY_HPP + +#include +#include +#include + +#include +#include + +namespace srcDispatch { + + struct DeclStmtData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + std::vector>> decls; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + std::string str; + for(const DeltaElement>& decl : decls) { + str += decl.ToString(operation); + } + return str; + } + }; + + class DeclStmtPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + DeclStmtData data; + + std::unique_ptr declPolicy; + + public: + DeclStmtPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeDeclStmtPolicyHandlers(); + } + + ~DeclStmtPolicy() {} + + protected: + std::any DataInner() const override { return std::make_shared(data); } + + virtual void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override { + if(typeid(DeclPolicy) == typeid(*policy)) { + // not sure how safe GetElement is here + srcDispatch::DiffOperation operation = ctx.diffStack.back().operation; + DeltaElement> decl(operation, policy->Data()); + if(data.decls.size() && decl.GetElement()->type->types.empty()) { + decl.GetElement()->type = data.decls.back().GetElement()->type; + decl.GetElement()->isStatic = data.decls.back().GetElement()->isStatic; + } + data.decls.push_back(decl); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + ctx.dispatcher->RemoveListener(nullptr); + } + + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + private: + void InitializeDeclStmtPolicyHandlers() { + using namespace srcDispatch; + + // start of policy + openEventMap[ParserState::declstmt] = [this](srcSAXEventContext &ctx) { + if(depth) return; + + depth = ctx.depth; + data = DeclStmtData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectDeclHandlers(ctx); + }; + + // end of policy + closeEventMap[ParserState::declstmt] = [this](srcSAXEventContext &ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + data = DeclStmtData{}; + InitializeDeclStmtPolicyHandlers(); + }; + } + + void CollectDeclHandlers(srcDispatch::srcSAXEventContext& ctx) { + using namespace srcDispatch; + + openEventMap[ParserState::decl] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + if(!declPolicy) { + declPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(declPolicy.get()); + }; + } + }; + +} + +#endif diff --git a/src/policy_classes/DeclTypePolicy.hpp b/src/policy_classes/DeclTypePolicy.hpp deleted file mode 100644 index 96fc3e0..0000000 --- a/src/policy_classes/DeclTypePolicy.hpp +++ /dev/null @@ -1,228 +0,0 @@ -/** - * @file DeclTypePolicy.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef INCLUDED_DECL_TYPE_POLICY_HPP -#define INCLUDED_DECL_TYPE_POLICY_HPP - -#include -#include -#include -#include -class DeclTypePolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - public: - DeclData data; - ~DeclTypePolicy(){} - DeclTypePolicy(std::initializer_list listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners){ - InitializeEventHandlers(); - } - void NotifyWrite(const PolicyDispatcher * policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers - void Notify(const PolicyDispatcher * policy [[maybe_unused]], const srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers - - void Finalize(srcSAXEventDispatch::srcSAXEventContext& ctx){ - using namespace srcSAXEventDispatch; - - if( ctx.And({ParserState::declstmt}) || ctx.And({ParserState::forstmt, ParserState::control, ParserState::init}) || - ctx.And({ParserState::switchstmt, ParserState::condition}) ){ - if(ctx.IsOpen(ParserState::classblock) && ctx.Nor({ParserState::function, ParserState::constructor, ParserState::destructor})){ - data.isClassMember = true; - data.nameOfContainingClass = ctx.currentClassName; - } - - data.nameOfContainingFile = ctx.currentFilePath; - - if(ctx.currentFunctionName.empty() && !ctx.currentClassName.empty()){ - data.nameOfContainingClass = ctx.currentClassName; - } - - data.nameOfContainingFunction = ctx.currentFunctionName; - - data.lineNumber = ctx.currentLineNumber; - data.nameOfIdentifier = currentDeclName; - - - data.isLocalVar = true; - if(ctx.currentFileLanguage == "Java" && !data.isFinal){ - data.isReference = true; - } - - currentDeclName.clear(); - NotifyAll(ctx); - data.clear(); - } - - if(ctx.And({ParserState::parameter})){ - data.lineNumber = ctx.currentLineNumber; - data.nameOfIdentifier = currentDeclName; - - // Used to mark line numbers where parameters are declared - if (possibleDefs.size() == 0) { - possibleDefs.push_back(ctx.currentLineNumber); - } else { - if (possibleDefs.back() != ctx.currentLineNumber) { - possibleDefs.push_back(ctx.currentLineNumber); - } - } - - data.isParameter = true; - data.nameOfContainingFunction = ctx.currentFunctionName; - data.nameOfContainingFile = ctx.currentFilePath; - if (ctx.currentFileLanguage == "Java" && !data.isFinal){ - data.isReference = true; - } - NotifyAll(ctx); - data.clear(); - } - } - - std::vector* GetPossibleDefs() { - return &possibleDefs; - } - std::vector* GetParamNames() { - return ¶mNames; - } - protected: - std::any DataInner() const override { - return std::make_shared(data); - } - private: - std::string currentTypeName, currentDeclName, currentModifier, currentSpecifier; - std::vector possibleDefs; - std::vector paramNames; - - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - openEventMap[ParserState::op] = [this](srcSAXEventContext& ctx){ - bool isDeclToken = ( ctx.And({ParserState::type, ParserState::declstmt}) && - ctx.Nor({ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist}) || - ctx.IsOpen({ParserState::init}) ); - bool isParamToken = ( ctx.And({ParserState::type, ParserState::parameter}) && ctx.Nor({ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist}) ); - - if(isDeclToken || isParamToken){ - data.namespaces.push_back(ctx.currentToken); - } - }; - - openEventMap[ParserState::index] = [this](srcSAXEventContext& ctx [[maybe_unused]]){ - data.usesSubscript = true; - }; - - closeEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx){ - if( ctx.IsOpen(ParserState::declstmt) || ctx.IsOpen({ParserState::init}) || ctx.IsOpen(ParserState::parameter) ){ - if(currentModifier == "*"){ - data.isPointer = true; - } - if(currentModifier == "&"){ - data.isReference = true; - } - } - }; - - closeEventMap[ParserState::type] = [this](srcSAXEventContext& ctx){ - // Capture the data-type when a condition is met - if( ctx.And({ParserState::declstmt}) || ctx.IsOpen({ParserState::init}) || - ctx.And({ParserState::switchstmt, ParserState::condition, ParserState::decl}) ){ - data.nameOfType = currentTypeName; - } - - if(ctx.And({ParserState::parameter})){ - data.nameOfType = currentTypeName; - currentTypeName.clear(); - } - }; - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx){ - //TODO: possibly, this if-statement is suppressing more than just unmarked whitespace. Investigate. - if(!(ctx.currentToken.empty() || ctx.currentToken[0] == ' ')){ - if(ctx.And({ParserState::name, ParserState::type, ParserState::decl, ParserState::declstmt}) && ctx.Nor({ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist, ParserState::index})){ - currentTypeName = ctx.currentToken; - } - if(ctx.And({ParserState::name, ParserState::type, ParserState::decl, ParserState::parameter}) && ctx.Nor({ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist, ParserState::index})){ - currentTypeName = ctx.currentToken; // parameter data type - } - - bool openConditional = ctx.IsOpen(ParserState::ifstmt) || ctx.IsOpen(ParserState::forstmt) || - ctx.IsOpen(ParserState::whilestmt) || ctx.IsOpen(ParserState::switchstmt); - - if( openConditional && ctx.And({ParserState::name, ParserState::type, ParserState::decl}) && - ctx.Nor({ParserState::index, ParserState::argumentlist, ParserState::specifier, ParserState::modifier}) ) { - currentTypeName = ctx.currentToken; - } - - - if( ctx.And({ParserState::name, ParserState::decl, ParserState::declstmt}) && - ctx.Nor({ParserState::type, ParserState::index/*skip array portion*/, ParserState::argumentlist/*skip init list portion*/, ParserState::init, ParserState::specifier, ParserState::modifier}) ){ - currentDeclName = ctx.currentToken; - } - if( ctx.IsOpen(ParserState::forstmt) && ctx.And({ParserState::name, ParserState::decl}) && - ctx.Nor({ParserState::type, ParserState::index, ParserState::argumentlist, ParserState::specifier, ParserState::modifier, ParserState::expr}) ) { - currentDeclName = ctx.currentToken; - } - if( ctx.IsOpen(ParserState::switchstmt) && ctx.And({ParserState::name, ParserState::decl}) && - ctx.Nor({ParserState::type, ParserState::index, ParserState::argumentlist, ParserState::specifier, ParserState::modifier, ParserState::expr}) ) { - currentDeclName = ctx.currentToken; - } - - if(ctx.And({ParserState::name, ParserState::decl, ParserState::parameter}) && - ctx.Nor({ParserState::type, ParserState::index/*skip array portion*/, ParserState::argumentlist/*skip init list portion*/, - ParserState::init, ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist})){ - currentDeclName = ctx.currentToken; // parameter variable name - - if (paramNames.size() == 0) { - paramNames.push_back(ctx.currentToken); - } else { - if (paramNames.back() != ctx.currentToken) { - paramNames.push_back(ctx.currentToken); - } - } - } - - if( ctx.And({ParserState::specifier, ParserState::decl, ParserState::declstmt}) || ctx.And({ParserState::specifier, ParserState::decl, ParserState::parameter}) ){ - currentSpecifier = ctx.currentToken; - } - - if( ctx.And({ParserState::modifier, ParserState::type, ParserState::declstmt}) || ctx.And({ParserState::modifier, ParserState::type, ParserState::parameter}) ){ - currentModifier = ctx.currentToken; - } - } - }; - - closeEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx){ - if( ctx.IsOpen(ParserState::declstmt) || ctx.IsOpen({ParserState::init}) || ctx.IsOpen(ParserState::parameter) ){ - if(currentSpecifier == "const"){ - if(data.isPointer){ - data.isConstAlias = true; - }else{ - data.isConstValue = true; - } - } - if(currentSpecifier == "final"){ - data.isFinal = true; - } - if(currentSpecifier == "static"){ - data.isStatic = true; - } - } - - currentSpecifier.clear(); - }; - - } -}; - -#endif \ No newline at end of file diff --git a/src/policy_classes/DeclTypePolicySingleEvent.hpp b/src/policy_classes/DeclTypePolicySingleEvent.hpp deleted file mode 100644 index fa3d332..0000000 --- a/src/policy_classes/DeclTypePolicySingleEvent.hpp +++ /dev/null @@ -1,183 +0,0 @@ -/** - * @file DeclTypePolicySingleEvent.hpp - * - * - * MODIFIED from srcSAXEventDispatcher - * This collects the initializer - * - */ -#ifndef INCLUDED_DECL_TYPE_POLICY_SINGLE_EVENT_HPP -#define INCLUDED_DECL_TYPE_POLICY_SINGLE_EVENT_HPP - -#include - -#include -#include -#include - -#include -#include - -struct DeclTypeData { - - DeclTypeData(unsigned int lineNumber) - : lineNumber(lineNumber), type(), name(), initializer(), isStatic() { - } - - unsigned int lineNumber; - std::shared_ptr type; - std::shared_ptr name; - std::shared_ptr initializer; - bool isStatic; - - friend std::ostream & operator<<(std::ostream & out, const DeclTypeData & declData) { - out << declData.type->ToString(); - if (declData.name) - out << ' ' << *declData.name; - if (declData.initializer) - out << " = " << *declData.initializer; - return out; - } -}; - - - -class DeclTypePolicy : -public srcSAXEventDispatch::EventListener, -public srcSAXEventDispatch::PolicyDispatcher, -public srcSAXEventDispatch::PolicyListener { - -private: - std::vector> data; - std::size_t declDepth; - TypePolicy *typePolicy; - NamePolicy *namePolicy; - ExpressionPolicy *expressionPolicy; - - bool isStatic; - std::shared_ptr type; - std::shared_ptr initializer; - -public: - DeclTypePolicy(std::initializer_list listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - declDepth(0), - typePolicy(nullptr), - isStatic(false), - type(), - expressionPolicy(nullptr), - namePolicy(nullptr) { - InitializeDeclTypePolicyHandlers(); - } - - ~DeclTypePolicy() { - if (typePolicy) delete typePolicy; - if (namePolicy) delete namePolicy; - if (expressionPolicy) delete expressionPolicy; - } - -protected: - std::any DataInner() const override { return std::make_shared>>(data); } - - void NotifyWrite(const PolicyDispatcher * policy, srcSAXEventDispatch::srcSAXEventContext & ctx) override {} //doesn't use other parsers - - virtual void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - if (typeid(TypePolicy) == typeid(*policy)) { - type = std::shared_ptr(policy->Data()); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - } else if (typeid(NamePolicy) == typeid(*policy)) { - data.back()->name = policy->Data(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - } else if (typeid(ExpressionPolicy) == typeid(*policy)) { - initializer = policy->Data(); - ctx.dispatcher->RemoveListener(nullptr); - } - - } - -private: - void InitializeDeclTypePolicyHandlers() { - using namespace srcSAXEventDispatch; - // start of policy - openEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx) { - if (!declDepth) { - data.clear(); - declDepth = ctx.depth; - CollectTypeHandlers(); - CollectNameHandlers(); - CollectSpecifiersHandlers(); - CollectInitHandlers(); - } - openEventMap[ParserState::decl] = [this](srcSAXEventContext& ctx) { - if (declDepth && (declDepth + 1) == ctx.depth) { - data.push_back(std::make_shared(ctx.currentLineNumber)); - } - }; - closeEventMap[ParserState::decl] = [this](srcSAXEventContext& ctx) { - if (declDepth && (declDepth + 1) == ctx.depth) { - data.back()->isStatic = isStatic; - data.back()->type = type; - data.back()->initializer = initializer; - } - }; - }; - - // end of policy - closeEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx) { - if (declDepth && declDepth == ctx.depth) { - declDepth = 0; - NotifyAll(ctx); - InitializeDeclTypePolicyHandlers(); - } - }; - } - - void CollectTypeHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::type] = [this](srcSAXEventContext& ctx) { - if (declDepth && (declDepth + 2) == ctx.depth) { - if (!typePolicy) typePolicy = new TypePolicy{this}; - ctx.dispatcher->AddListenerDispatch(typePolicy); - } - }; - } - - void CollectNameHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - if (declDepth && (declDepth + 2) == ctx.depth) { - if (!namePolicy) namePolicy = new NamePolicy{this}; - ctx.dispatcher->AddListenerDispatch(namePolicy); - } - }; - } - - void CollectSpecifiersHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx) { - if (declDepth && (declDepth + 2) == ctx.depth) { - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - if (ctx.currentToken == "static") - isStatic = true; - }; - } - }; - closeEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx) { - if (declDepth && (declDepth + 1) == ctx.depth) { - NopCloseEvents({ParserState::tokenstring}); - } - }; - } - - void CollectInitHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::init] = [this](srcSAXEventContext& ctx) { - if(!expressionPolicy) expressionPolicy = new ExpressionPolicy{this}; - ctx.dispatcher->AddListenerDispatch(expressionPolicy); - }; - } - -}; - -#endif diff --git a/src/policy_classes/DeltaElement.hpp b/src/policy_classes/DeltaElement.hpp new file mode 100644 index 0000000..07df39c --- /dev/null +++ b/src/policy_classes/DeltaElement.hpp @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file DeltaElement.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_DELTA_ELEMENT_HPP +#define INCLUDED_DELTA_ELEMENT_HPP + +#include + +#include +#include +#include + +namespace srcDispatch { + +template +class DeltaElement { + +private: + std::optional original; + std::optional modified; + + srcDispatch::DiffOperation operation; + +protected: + +public: + DeltaElement(); + DeltaElement(const type& element); + DeltaElement(srcDispatch::DiffOperation operation, const type& element = type()); + + DeltaElement copyAs(srcDispatch::DiffOperation operation) const; + + bool IsCommon() const; + bool IsDelete() const; + bool IsInsert() const; + bool IsChange() const; + + bool HasOriginal() const; + bool HasModified() const; + + const std::type_info& OriginalType() const; + const std::type_info& ModifiedType() const; + + const type& GetOriginal() const; + type& GetOriginal(); + void SetOriginal(const type& original); + + const type& GetModified() const; + type& GetModified(); + void SetModified(const type& modified); + + const type& GetElement() const; + type& GetElement(); + + const auto operator->() const; + auto operator->(); + + operator bool() const; + bool operator==(const DeltaElement& that) const; + bool operator==(const type& that) const; + + template + friend bool operator==(const compare_type& lhs, const DeltaElement& rhs); + + srcDispatch::DiffOperation GetOperation() const; + void SetOperation(srcDispatch::DiffOperation operation); + + bool IsOfOperation(srcDispatch::DiffOperation operation) const; + const type& GetOfOperation(srcDispatch::DiffOperation operation) const; + + void Update(srcDispatch::DiffOperation operation, const type& element); + + template + void Append(srcDispatch::DiffOperation operation, const std::string& str); + void Clear(); + + template + std::string ToString(srcDispatch::DiffOperation operation = srcDispatch::NONE) const; +}; + +} + +#include + +#endif diff --git a/src/policy_classes/DeltaElement.tcc b/src/policy_classes/DeltaElement.tcc new file mode 100644 index 0000000..afa55b1 --- /dev/null +++ b/src/policy_classes/DeltaElement.tcc @@ -0,0 +1,385 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file DeltaElement.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#include + +#ifdef __linux__ + #include +#endif + +#include +#include +#include + +template +struct Value { + Value(type& value) : value(value) {} + type& value; +}; + +template +struct Value> { + Value(std::shared_ptr& value) : value(*value) {} + type& value; +}; + +template +struct ValueConst { + ValueConst(const type& value) : value(value) {} + const type& value; +}; + +template +struct ValueConst> { + ValueConst(const std::shared_ptr& value) : value(*value) {} + const type& value; +}; + +template +std::ostream& operator<<(std::ostream& out, const srcDispatch::DeltaElement& element) { + assert(element.GetOperation() != srcDispatch::NONE); + + return out << element.ToString(srcDispatch::NONE); +} + +namespace srcDispatch { + +template +DeltaElement::DeltaElement() + : original(), modified(), operation(srcDispatch::NONE) { +} + +template +DeltaElement::DeltaElement(const type& element) + : original(element), modified(), operation(srcDispatch::COMMON) { + + static const char ATTR_SEPARATOR = '|'; + if constexpr (std::is_same_v || std::is_same_v>) { + std::string str = ValueConst(element).value; + std::size_t pos = str.find(ATTR_SEPARATOR); + if(pos != std::string::npos) { + std::size_t length = element.size(); + operation = pos == 0? srcDispatch::INSERT : (pos == (length - 1)? srcDispatch::DELETE : srcDispatch::CHANGE); + + original.reset(); + if(operation == srcDispatch::DELETE || operation == srcDispatch::CHANGE) { + original = str.substr(0, pos); + } + + if(operation == srcDispatch::INSERT || operation == srcDispatch::CHANGE) { + modified = str.substr(pos + 1, length - (pos + 1)); + } + } + } +} + +template +DeltaElement::DeltaElement(srcDispatch::DiffOperation operation, const type& element) + : operation(srcDispatch::NONE) { + Update(operation, element); +} +template +DeltaElement DeltaElement::copyAs(srcDispatch::DiffOperation operation) const { + if constexpr (std::is_same_v>) { + return DeltaElement(operation, std::make_shared(this->GetElement()->copyAs())); + } else { + return DeltaElement(operation, this->GetElement()->copyAs()); + } +} + +template +bool DeltaElement::IsCommon() const { + return operation == srcDispatch::COMMON; +} + +template +bool DeltaElement::IsDelete() const { + return operation == srcDispatch::DELETE; +} + +template +bool DeltaElement::IsInsert() const { + return operation == srcDispatch::INSERT; +} + +template +bool DeltaElement::IsChange() const { + return operation == srcDispatch::CHANGE; +} + +template +bool DeltaElement::HasOriginal() const { + return bool(original); +} + +template +bool DeltaElement::HasModified() const { + return bool(modified); +} + +template +const std::type_info& DeltaElement::OriginalType() const { + return original->type(); +} + +template +const std::type_info& DeltaElement::ModifiedType() const { + return modified->type(); +} + +template +const type& DeltaElement::GetOriginal() const { + assert(HasOriginal()); + return *original; +} + +template +type& DeltaElement::GetOriginal() { + assert(HasOriginal()); + return *original; +} + +template +void DeltaElement::SetOriginal(const type& original) { + this->original = original; +} + +template +const type& DeltaElement::GetModified() const { + assert(HasModified()); + return *modified; +} + +template +type& DeltaElement::GetModified() { + assert(HasModified()); + return *modified; +} + +template +void DeltaElement::SetModified(const type& modified) { + this->modified = modified; +} + +template +const type& DeltaElement::GetElement() const { + if(operation == srcDispatch::COMMON) return *original; + if(operation == srcDispatch::DELETE) return *original; + + return *modified; +} + +template +type& DeltaElement::GetElement() { + if(operation == srcDispatch::COMMON) return *original; + if(operation == srcDispatch::DELETE) return *original; + + return *modified; +} + +template +const auto DeltaElement::operator->() const { + if constexpr (std::is_same_v>) { + return &*GetElement(); + } else { + return &GetElement(); + } +} + +template +auto DeltaElement::operator->() { + if constexpr (std::is_same_v> ) { + return &*GetElement(); + } else { + return &GetElement(); + } +} + +template +DeltaElement::operator bool() const { + return operation != srcDispatch::NONE; +} + +template +bool DeltaElement::operator==(const DeltaElement& that) const { + if(this->operation != that.operation) return false; + if(this->HasOriginal() != that.HasOriginal()) return false; + if(this->HasModified() != that.HasModified()) return false; + if(this->HasOriginal() && this->original != that.original) return false; + if(this->HasModified() && this->modified != that.modified) return false; + + return true; +} + +template +bool DeltaElement::operator==(const type& that) const { + return *this == DeltaElement(that); +} + +template +bool operator==(const type& lhs, const DeltaElement& rhs) { + return rhs == lhs; +} + +template +srcDispatch::DiffOperation DeltaElement::GetOperation() const { + return operation; +} + +template +void DeltaElement::SetOperation(enum srcDispatch::DiffOperation operation) { + this->operation = operation; +} + +template +bool DeltaElement::IsOfOperation(srcDispatch::DiffOperation operation) const { + if(this->operation == srcDispatch::NONE) return false; + if(this->operation == srcDispatch::COMMON) return true; + if(this->operation == srcDispatch::CHANGE) return true; + + return this->operation == operation; +} + +template +const type& DeltaElement::GetOfOperation(srcDispatch::DiffOperation operation) const { + assert(IsOfOperation(operation)); + + if(this->operation == srcDispatch::COMMON) return *original; + if(this->operation == srcDispatch::CHANGE) return operation == srcDispatch::DELETE? *original : *modified; + if(operation == srcDispatch::DELETE) return *original; + return *modified; +} + +template +void DeltaElement::Update(srcDispatch::DiffOperation operation, const type& element) { + + if( (this->operation == srcDispatch::DELETE && operation == srcDispatch::INSERT) + || (this->operation == srcDispatch::INSERT && operation == srcDispatch::DELETE)) { + this->operation = srcDispatch::CHANGE; + } else if(this->operation != srcDispatch::CHANGE) { + this->operation = operation; + } + + if(operation == srcDispatch::COMMON) { + original = element; + } else if(operation == srcDispatch::DELETE) { + original = element; + } else if(operation == srcDispatch::INSERT) { + modified = element; + } else if(operation == srcDispatch::CHANGE) { + original = element; + modified = element; + } + +} + +template +template +void DeltaElement::Append(srcDispatch::DiffOperation operation, const std::string& str) { + + if(this->operation == srcDispatch::DELETE && operation == srcDispatch::INSERT) { + this->operation = srcDispatch::CHANGE; + } else if(this->operation != srcDispatch::CHANGE) { + this->operation = operation; + } + + if constexpr (!std::is_same_v) { + static const any_type null_any_type; + any_type* innerOriginal = original? std::any_cast(&*original) : nullptr; + any_type* innerModified = modified? std::any_cast(&*modified) : nullptr; + + if(operation == srcDispatch::COMMON) { + Value(*innerOriginal).value += str; + } else if(operation == srcDispatch::DELETE) { + Value(*innerOriginal).value += str; + } else if(operation == srcDispatch::INSERT) { + Value(*innerModified).value += str; + } else if(operation == srcDispatch::CHANGE) { + Value(*innerOriginal).value += str; + Value(*innerModified).value += str; + } + + } else { + + if(operation == srcDispatch::COMMON) { + Value(original).value += str; + } else if(operation == srcDispatch::DELETE) { + Value(original).value += str; + } else if(operation == srcDispatch::INSERT) { + Value(modified).value += str; + } else if(operation == srcDispatch::CHANGE) { + Value(original).value += str; + Value(modified).value += str; + } + + } + +} + +template +void DeltaElement::Clear() { + original = std::optional(); + modified = std::optional(); +} + +template +template +std::string DeltaElement::ToString(srcDispatch::DiffOperation operation) const { + + if(this->operation == srcDispatch::NONE) return ""; + + std::string originalStr; + std::string modifiedStr; + + if constexpr (!std::is_same_v) { + + DeltaElement innerElement(this->operation); + if(original) { + innerElement.GetOriginal() = std::any_cast(*original); + } + + if(modified) { + innerElement.GetModified() = std::any_cast(*modified); + } + + return innerElement.ToString(operation); + } else { + + if constexpr (std::is_same_v || std::is_same_v>) { + if(HasOriginal()) { + originalStr = ValueConst(*original).value; + } + } else { + const type& element = HasOriginal()? *original : *modified; + originalStr = ValueConst(*element).value.ToString(srcDispatch::DELETE); + } + + if constexpr (std::is_same_v || std::is_same_v>) { + if(HasModified() || this->operation == srcDispatch::COMMON) { + const type& element = this->operation == srcDispatch::COMMON? *original : *modified; + modifiedStr = ValueConst(element).value; + } + } else { + const type& element = HasModified()? *modified : *original; + modifiedStr = ValueConst(element).value.ToString(srcDispatch::INSERT); + } + + if(operation == srcDispatch::DELETE) { + return originalStr; + } else if(operation == srcDispatch::INSERT) { + return modifiedStr; + } else if(originalStr != modifiedStr) { + return originalStr + '|' + modifiedStr; + } + } + + return originalStr; +} + +} diff --git a/src/policy_classes/Diff.hpp b/src/policy_classes/Diff.hpp new file mode 100644 index 0000000..eb0bebe --- /dev/null +++ b/src/policy_classes/Diff.hpp @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file Diff.hpp + * + * @copyright Copyright (C) 2025-2025 srcML, LLC. (www.srcML.org) + * + * This file is part of the srcML Infrastructure. + */ + +#ifndef INCLUDED_DIFF_HPP +#define INCLUDED_DIFF_HPP + +namespace srcDispatch { + +enum DiffOperation { COMMON, DELETE, INSERT, CHANGE, NONE }; +struct Diff { + Diff(DiffOperation operation, size_t depth = 0, bool isReplace = false, bool isConvert = false) + : operation(operation), depth(depth), isReplace(isReplace), isConvert(isConvert) {} + + DiffOperation operation; + size_t depth; + bool isReplace; + bool isConvert; +}; + +} + +#endif diff --git a/src/policy_classes/DoPolicy.hpp b/src/policy_classes/DoPolicy.hpp new file mode 100644 index 0000000..045c493 --- /dev/null +++ b/src/policy_classes/DoPolicy.hpp @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file DoPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_DO_POLICY_HPP +#define INCLUDED_DO_POLICY_HPP + +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + struct DoData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement> condition; + DeltaElement> block; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + return condition.ToString(operation); + } + }; + + class DoPolicy : public ConditionalPolicy { + public: + DoPolicy(std::initializer_list listeners) + : ConditionalPolicy(listeners) {} + }; + +} + +#endif diff --git a/src/policy_classes/ElseIfPolicy.hpp b/src/policy_classes/ElseIfPolicy.hpp new file mode 100644 index 0000000..363467e --- /dev/null +++ b/src/policy_classes/ElseIfPolicy.hpp @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file ElseIfPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_ELSEIF_POLICY_HPP +#define INCLUDED_ELSEIF_POLICY_HPP + +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + struct ElseIfData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement> condition; + DeltaElement> block; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + return condition.ToString(operation); + } + }; + + class ElseIfPolicy : public ConditionalPolicy { + public: + ElseIfPolicy(std::initializer_list listeners) + : ConditionalPolicy(listeners) {} + }; + +} + +#endif diff --git a/src/policy_classes/ElsePolicy.hpp b/src/policy_classes/ElsePolicy.hpp new file mode 100644 index 0000000..b159bf5 --- /dev/null +++ b/src/policy_classes/ElsePolicy.hpp @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file ElsePolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_ELSE_POLICY_HPP +#define INCLUDED_ELSE_POLICY_HPP + +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + struct ElseData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement> condition; + DeltaElement> block; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + assert(!condition); + return ""; + } + }; + + class ElsePolicy : public ConditionalPolicy { + public: + ElsePolicy(std::initializer_list listeners) + : ConditionalPolicy(listeners) {} + }; + +} + +#endif diff --git a/src/policy_classes/ExprPolicy.hpp b/src/policy_classes/ExprPolicy.hpp deleted file mode 100644 index 6543fea..0000000 --- a/src/policy_classes/ExprPolicy.hpp +++ /dev/null @@ -1,149 +0,0 @@ -/** - * @file ExprPolicy.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -#ifndef EXPRPOLICY -#define EXPRPOLICY -class ExprPolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - public: - struct ExprData{ - ExprData() {lhs = false;} - void clear(){ - definitions.clear(); - uses.clear(); - lhs = false; - } - bool lhs; - std::string nameOfIdentifier; - std::set definitions; - std::set uses; //could be used multiple times in same expr - }; - struct ExprDataSet{ - ExprDataSet() = default; - ExprDataSet(std::map dat){ - dataSet = dat; - } - void clear(){ - dataSet.clear(); - } - std::string lhsName; - std::map dataSet; - }; - ~ExprPolicy(){} - ExprPolicy(std::initializer_list listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners){ - InitializeEventHandlers(); - } - void Notify(const PolicyDispatcher * policy [[maybe_unused]], const srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers - void NotifyWrite(const PolicyDispatcher * policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers - protected: - std::any DataInner() const override { - return std::make_shared(exprDataSet); - } - private: - ExprData data; - ExprDataSet exprDataSet; - std::string currentTypeName, currentExprName, currentModifier, currentSpecifier; - std::pair currentExprOp; - std::vector currentLine; - - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - - closeEventMap[ParserState::op] = [this](srcSAXEventContext& ctx){ - // Long or-statement allows various declaration operators to get planted into - // a slices def data output - // if (ctx.currentToken == "=" || ctx.currentToken == "++" || ctx.currentToken == "+=" || - // ctx.currentToken == "--" || ctx.currentToken == "-=" || ctx.currentToken == "*=" || - // ctx.currentToken == "/=" || ctx.currentToken == "%=" || ctx.currentToken == "&=" || - // ctx.currentToken == "|=" || ctx.currentToken == "^=" || ctx.currentToken == "<<=" || - // ctx.currentToken == ">>=") - - if (ctx.currentToken == "=" || ctx.currentToken == "+=" || - ctx.currentToken == "-=" || ctx.currentToken == "*=" || - ctx.currentToken == "/=" || ctx.currentToken == "%=" || - ctx.currentToken == "--" || ctx.currentToken == "++"){ - currentExprOp = std::make_pair(ctx.currentToken, ctx.currentLineNumber); - auto it = exprDataSet.dataSet.find(currentExprName); - - if(it != exprDataSet.dataSet.end()){ - exprDataSet.lhsName = currentExprName; - it->second.lhs = true; - it->second.uses.erase(currentLine.back()); - it->second.definitions.insert(currentLine.back()); - }else{ - std::cerr<<"No such thing as: "<second.uses.insert(currentLine.back()); //assume it's a use - - if ( (currentExprOp.first == "++" || currentExprOp.first == "--") && currentExprOp.second == ctx.currentLineNumber ) - it->second.definitions.insert(currentLine.back()); - }else{ - data.nameOfIdentifier = currentExprName; - - data.uses.insert(currentLine.back()); - - if ( (currentExprOp.first == "++" || currentExprOp.first == "--") && currentExprOp.second == ctx.currentLineNumber ) - data.definitions.insert(currentLine.back()); - - exprDataSet.dataSet.insert(std::make_pair(currentExprName, data)); - } - } - }; - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx){ - //TODO: possibly, this if-statement is suppressing more than just unmarked whitespace. Investigate. - if(!(ctx.currentToken.empty() || ctx.currentToken == " ")){ - if(ctx.And({ParserState::name, ParserState::expr, ParserState::exprstmt}) && ctx.Nor({ParserState::specifier, ParserState::modifier, ParserState::op})){ - currentExprName = ctx.currentToken; - } - if(ctx.And({ParserState::specifier, ParserState::expr, ParserState::exprstmt})){ - currentSpecifier = ctx.currentToken; - } - if(ctx.And({ParserState::modifier, ParserState::exprstmt})){ - currentModifier = ctx.currentToken; - } - } - }; - closeEventMap[ParserState::exprstmt] = [this](srcSAXEventContext& ctx){ - NotifyAll(ctx); - currentLine.pop_back(); - currentLine.clear(); - exprDataSet.dataSet.clear(); - data.clear(); - }; - - } -}; -#endif \ No newline at end of file diff --git a/src/policy_classes/ExprStmtPolicy.hpp b/src/policy_classes/ExprStmtPolicy.hpp new file mode 100644 index 0000000..03291df --- /dev/null +++ b/src/policy_classes/ExprStmtPolicy.hpp @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file ExprStmtPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_EXPR_STMT_POLICY_HPP +#define INCLUDED_EXPR_STMT_POLICY_HPP + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + struct ExprStmtData { + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement> expr; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + return expr.ToString(operation); + } + }; + + class ExprStmtPolicy : public ExprTypePolicy { + public: + ExprStmtPolicy(std::initializer_list listeners) + : ExprTypePolicy(listeners) { + } + + }; + +} + +#endif diff --git a/src/policy_classes/ExprTypePolicy.hpp b/src/policy_classes/ExprTypePolicy.hpp new file mode 100644 index 0000000..1dc7548 --- /dev/null +++ b/src/policy_classes/ExprTypePolicy.hpp @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file ExprTypePolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_EXPR_TYPE_POLICY_HPP +#define INCLUDED_EXPR_TYPE_POLICY_HPP + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + template + class ExprTypePolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + ExprTypeData data; + + std::unique_ptr exprPolicy; + + public: + ExprTypePolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeExprTypePolicyHandlers(); + } + + ~ExprTypePolicy() {} + + protected: + std::any DataInner() const override { return std::make_shared(data); } + + virtual void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override { + if(typeid(ExpressionPolicy) == typeid(*policy)) { + data.expr.Update(ctx.diffStack.back().operation, policy->Data()); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + ctx.dispatcher->RemoveListener(nullptr); + } + + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + private: + void InitializeExprTypePolicyHandlers() { + using namespace srcDispatch; + // start of policy + openEventMap[DispatchEvent] = [this](srcSAXEventContext& ctx) { + if(depth) return; + + depth = ctx.depth; + data = ExprTypeData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectExpressionHandlers(); + }; + + // end of policy + closeEventMap[DispatchEvent] = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeExprTypePolicyHandlers(); + }; + } + + void CollectExpressionHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::expr] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!exprPolicy) + exprPolicy = make_unique_policy({this}); + ctx.dispatcher->AddListenerDispatch(exprPolicy.get()); + }; + } + }; + +} + +#endif diff --git a/src/policy_classes/ExpressionPolicy.cpp b/src/policy_classes/ExpressionPolicy.cpp new file mode 100644 index 0000000..ccfd0c3 --- /dev/null +++ b/src/policy_classes/ExpressionPolicy.cpp @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file ExpressionPolicy.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#include +#include + +namespace srcDispatch { + + std::string ExpressionData::ToString(srcDispatch::DiffOperation operation) const { + + std::string str = ""; + bool outputSpace = false; + for (const DeltaElement& item : expr) { + + bool outputRaw = item.IsOfOperation(operation); + if(outputRaw) { + if(outputSpace) { + str += ' '; + } + outputSpace = true; + } + + const std::type_info& type = item.HasOriginal()? item.GetOriginal().type() : item.GetModified().type(); + if(type == typeid(std::shared_ptr)) { + str += item.ToString>(operation); + } else if(type == typeid(std::shared_ptr)) { + str += item.ToString>(operation); + } else if(type == typeid(std::shared_ptr)) { + str += item.ToString>(operation); + } else if(type == typeid(std::shared_ptr)) { + str += item.ToString>(operation); + } + } + + return str; + } + + std::shared_ptr ExpressionData::copyAs(srcDispatch::DiffOperation operation) const { + std::shared_ptr data = std::make_shared(); + data->startLineNumber = startLineNumber; + data->endLineNumber = endLineNumber; + + for (const DeltaElement& item : expr) { + DeltaElement exprAny; + if(item.GetElement().type() == typeid(std::shared_ptr)) { + exprAny = DeltaElement(operation, std::any_cast>(item)->copyAs(operation)); + } else if(item.GetElement().type() == typeid(std::shared_ptr)) { + exprAny = DeltaElement(operation, std::any_cast>(item)->copyAs(operation)); + } else if(item.GetElement().type() == typeid(std::shared_ptr)) { + exprAny = DeltaElement(operation, std::any_cast>(item)->copyAs(operation)); + } else { + exprAny = DeltaElement(operation, std::any_cast>(item)->copyAs(operation)); + } + + data->expr.emplace_back(exprAny); + } + + return data; + } + + ExpressionPolicy::~ExpressionPolicy() {} + + void ExpressionPolicy::Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) { + if(typeid(NamePolicy) == typeid(*policy)) { + data.expr.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else if(typeid(OperatorPolicy) == typeid(*policy)) { + data.expr.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else if(typeid(LiteralPolicy) == typeid(*policy)) { + data.expr.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else if(typeid(CallPolicy) == typeid(*policy)) { + data.expr.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + + // Operators are added in CollectOtherHandlers() + ctx.dispatcher->RemoveListenerDispatch(nullptr); + } + + void ExpressionPolicy::InitializeExpressionPolicyHandlers() + { + using namespace srcDispatch; + // start of policy + std::function expressionStart = [this](srcSAXEventContext& ctx) { + if(depth) return; + + depth = ctx.depth; + data = ExpressionData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectNameHandlers(); + CollectCallHandlers(); + CollectOperatorHandlers(); + CollectLiteralHandlers(); + }; + + // end of policy + std::function expressionEnd = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeExpressionPolicyHandlers(); + }; + + openEventMap[ParserState::expr] = expressionStart; + closeEventMap[ParserState::expr] = expressionEnd; + } + + void ExpressionPolicy::CollectNameHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!namePolicy) { + namePolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(namePolicy.get()); + }; + } + + void ExpressionPolicy::CollectCallHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::call] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!callPolicy) { + callPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(callPolicy.get()); + }; + } + + void ExpressionPolicy::CollectOperatorHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::op] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!operatorPolicy) { + operatorPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(operatorPolicy.get()); + }; + } + + void ExpressionPolicy::CollectLiteralHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::literal] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!literalPolicy) { + literalPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(literalPolicy.get()); + }; + } + +} diff --git a/src/policy_classes/ExpressionPolicy.hpp b/src/policy_classes/ExpressionPolicy.hpp new file mode 100644 index 0000000..b16cd19 --- /dev/null +++ b/src/policy_classes/ExpressionPolicy.hpp @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file ExpressionPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_EXPRESSION_POLICY_HPP +#define INCLUDED_EXPRESSION_POLICY_HPP + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace srcDispatch { + + struct CallData; + class CallPolicy; + + struct NameData; + class NamePolicy; + + // A vector of elements in the expression. + // Names, operators, calls in the correct order. + // Need for determining variable use, variable modification, calls + + struct ExpressionData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + std::vector> expr; + + std::shared_ptr copyAs(srcDispatch::DiffOperation operation) const; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const; + }; + + class ExpressionPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + ExpressionData data; + + std::unique_ptr namePolicy; + std::unique_ptr operatorPolicy; + std::unique_ptr literalPolicy; + std::unique_ptr callPolicy; + + public: + ExpressionPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeExpressionPolicyHandlers(); + } + + ~ExpressionPolicy(); + + protected: + std::any DataInner() const override { return std::make_shared(data); } + virtual void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override; + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + private: + void InitializeExpressionPolicyHandlers(); + void CollectCallHandlers(); + void CollectNameHandlers(); + void CollectOperatorHandlers(); + void CollectLiteralHandlers(); + }; + +} + +#endif diff --git a/src/policy_classes/ExpressionPolicySingleEvent.cpp b/src/policy_classes/ExpressionPolicySingleEvent.cpp deleted file mode 100644 index 55a40d6..0000000 --- a/src/policy_classes/ExpressionPolicySingleEvent.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/** - * @file ExpressionPolicy.cpp - * - */ - -#include - - -std::ostream & operator<<(std::ostream & out, const Token & token) { - return out << token.token; -} - -std::ostream & operator<<(std::ostream & out, const ExpressionData & ex) { - for (std::shared_ptr item : ex.expr) { - //out << " Type " << item->type << " "; - switch (item->type) { - case ExpressionElement::NAME: out << *item->name; break; - case ExpressionElement::OP: out << *item->token; break; - case ExpressionElement::LITERAL: out << *item->token; break; - case ExpressionElement::CALL: out << *item->call; break; - } - out << " "; - } - return out; -} - -ExpressionPolicy::~ExpressionPolicy() { - if(namePolicy) delete namePolicy; - if(callPolicy) delete callPolicy; -} - -void ExpressionPolicy::Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) { - if(typeid(NamePolicy) == typeid(*policy)) { - data.expr.push_back(std::make_shared(ExpressionElement::NAME, policy->Data())); - //std::cerr << "Return Name found: " << *(data.expr.back())->name << std::endl; - ctx.dispatcher->RemoveListenerDispatch(nullptr); - } else if(typeid(CallPolicy) == typeid(*policy)) { - data.expr.push_back(std::make_shared(ExpressionElement::CALL, policy->Data())); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - } - //Operators are added in CollectOtherHandlers() -} - -void ExpressionPolicy::InitializeExpressionPolicyHandlers() { - using namespace srcSAXEventDispatch; - // start of policy - std::function expressionStart = [this](srcSAXEventContext& ctx) { - if(!exprDepth) { - exprDepth = ctx.depth; - data = ExpressionData{}; - data.lineNumber = ctx.currentLineNumber; - CollectNameHandlers(); - CollectCallHandlers(); - CollectOtherHandlers(); - } - }; - - // end of policy - std::function expressionEnd = [this](srcSAXEventContext& ctx) { - if(exprDepth && exprDepth == ctx.depth) { - exprDepth = 0; - NotifyAll(ctx); - InitializeExpressionPolicyHandlers(); - } - }; - - openEventMap[ParserState::expr] = expressionStart; - closeEventMap[ParserState::expr] = expressionEnd; -} - - -void ExpressionPolicy::CollectNameHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - if(!namePolicy) namePolicy = new NamePolicy{this}; - ctx.dispatcher->AddListenerDispatch(namePolicy); - }; -} - -void ExpressionPolicy::CollectCallHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::call] = [this](srcSAXEventContext& ctx) { - if(!callPolicy) callPolicy = new CallPolicy{this}; - ctx.dispatcher->AddListenerDispatch(callPolicy); - }; -} - -void ExpressionPolicy::CollectOtherHandlers() { //Get the operators - using namespace srcSAXEventDispatch; - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - std::shared_ptr token = std::make_shared(ctx.currentLineNumber, ctx.currentToken); - if (ctx.currentTag == "operator") { - data.expr.push_back(std::make_shared(ExpressionElement::OP, token)); - } - if (ctx.currentTag == "literal") { - data.expr.push_back(std::make_shared(ExpressionElement::LITERAL, token)); - } - - }; -} - diff --git a/src/policy_classes/ExpressionPolicySingleEvent.hpp b/src/policy_classes/ExpressionPolicySingleEvent.hpp deleted file mode 100644 index 6d37d00..0000000 --- a/src/policy_classes/ExpressionPolicySingleEvent.hpp +++ /dev/null @@ -1,96 +0,0 @@ -/** - * @file ExpressionPolicy.hpp - * - */ -#ifndef INCLUDED_EXPRESSION_POLICY_SINGE_EVENT_HPP -#define INCLUDED_EXPRESSION_POLICY_SINGE_EVENT_HPP - -#include - -#include -#include - -#include -#include -#include -#include -#include - -struct CallData; -class CallPolicy; - -struct NameData; -class NamePolicy; - -//A vector of elements in the expression. -//Names, operators, calls in the correct order. -//Need for determining variable use, variable modification, calls - -struct Token { - Token(unsigned int lineNumber, const std::string& token) - : lineNumber(lineNumber), token(token) { - } - unsigned int lineNumber; - std::string token; - friend std::ostream & operator<<(std::ostream & out, const Token & token); -}; - -struct ExpressionElement { - enum ExprType { NAME, OP, CALL, LITERAL}; - - ExprType type; - std::shared_ptr name; - std::shared_ptr token; - std::shared_ptr call; - ExpressionElement(ExprType t, std::shared_ptr item) : type(t), name(item) {}; - ExpressionElement(ExprType t, std::shared_ptr item) : type(t), token(item){}; - ExpressionElement(ExprType t, std::shared_ptr item) : type(t), call(item) {}; -}; - -struct ExpressionData { - - unsigned int lineNumber; - std::vector> expr; //All items in expression - - friend std::ostream & operator<<(std::ostream & out, const ExpressionData & ex); -}; - -class ExpressionPolicy : -public srcSAXEventDispatch::EventListener, -public srcSAXEventDispatch::PolicyDispatcher, -public srcSAXEventDispatch::PolicyListener { - -private: - ExpressionData data; - NamePolicy *namePolicy; - CallPolicy *callPolicy; - std::size_t exprDepth; - -public: - ExpressionPolicy(std::initializer_list listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - exprDepth(0), - namePolicy(nullptr), - callPolicy(nullptr) - { - InitializeExpressionPolicyHandlers(); - } - - ~ExpressionPolicy(); - -protected: - std::any DataInner() const override { return std::make_shared(data); } - - void NotifyWrite(const PolicyDispatcher * policy, srcSAXEventDispatch::srcSAXEventContext & ctx) override {} //doesn't use other parsers - - virtual void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override; - -private: - void InitializeExpressionPolicyHandlers(); - void CollectCallHandlers(); - void CollectNameHandlers(); - void CollectOtherHandlers(); -}; - -#endif diff --git a/src/policy_classes/ForPolicy.hpp b/src/policy_classes/ForPolicy.hpp new file mode 100644 index 0000000..ea8032e --- /dev/null +++ b/src/policy_classes/ForPolicy.hpp @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file ForPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_FOR_POLICY_HPP +#define INCLUDED_FOR_POLICY_HPP + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + class BlockPolicy; + struct BlockData; + + struct ForData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement> control; + DeltaElement> block; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + return control.ToString(operation); + } + }; + + class ForPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + ForData data; + + std::unique_ptr controlPolicy; + std::unique_ptr blockPolicy; + + public: + ForPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeForPolicyHandlers(); + } + + ~ForPolicy() {} + + protected: + std::any DataInner() const { return std::make_shared(data); } + + void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) { + if(typeid(ControlPolicy) == typeid(*policy)) { + data.control = DeltaElement(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(BlockPolicy) == typeid(*policy)) { + data.block = DeltaElement(ctx.diffStack.back().operation, policy->Data()); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + + ctx.dispatcher->RemoveListener(nullptr); + } + + void NotifyWrite(const PolicyDispatcher* policy, srcDispatch::srcSAXEventContext& ctx) {} // doesn't use other parsers + + private: + void InitializeForPolicyHandlers() { + using namespace srcDispatch; + + openEventMap[ParserState::forstmt] = [this](srcSAXEventContext& ctx) { + if(depth) return; + + depth = ctx.depth; + data = ForData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectControlHandlers(); + CollectBlockHandlers(); + }; + + // end of policy + closeEventMap[ParserState::forstmt] = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeForPolicyHandlers(); + }; + } + + void CollectControlHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::control] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!controlPolicy) { + controlPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(controlPolicy.get()); + }; + } + + void CollectBlockHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::block] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!blockPolicy) { + blockPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(blockPolicy.get()); + }; + } + }; + +} + +#endif diff --git a/src/policy_classes/FunctionCallPolicy.hpp b/src/policy_classes/FunctionCallPolicy.hpp deleted file mode 100644 index d1f37ee..0000000 --- a/src/policy_classes/FunctionCallPolicy.hpp +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file FunctionCallPolicy.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -/* - *Record current function being called - *Record argument names and positions - */ -#ifndef CALLPOLICY -#define CALLPOLICY -class FunctionCallPolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - /* - {CalledFunction1{arg1, line#}, {arg2, line#}, ..., {argn, line#}, - NestedCalledFunction1{arg1, line#},{arg2, line#}, ..., {argn, line#} - } - */ - public: - struct FunctionCallData{ - void clear(){ - fnName.clear(); - callargumentlist.clear(); - } - std::string fnName; - std::vector callargumentlist; - }; - ~FunctionCallPolicy(){} - FunctionCallPolicy(std::initializer_list listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners){ - InitializeEventHandlers(); - } - void Notify(const PolicyDispatcher * policy [[maybe_unused]], const srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} - void NotifyWrite(const PolicyDispatcher * policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers - protected: - std::any DataInner() const override { - return std::make_shared(data); - } - private: - FunctionCallData data; - std::string currentTypeName, currentCallName, currentModifier, currentSpecifier; - std::string fullFuncIdentifier; - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - - openEventMap[ParserState::argumentlist] = [this](srcSAXEventContext& ctx [[maybe_unused]]) { - data.callargumentlist.push_back("("); - data.callargumentlist.push_back(fullFuncIdentifier); - data.fnName = fullFuncIdentifier; - fullFuncIdentifier = ""; - }; - closeEventMap[ParserState::argumentlist] = [this](srcSAXEventContext& ctx){ - if(ctx.triggerField[ParserState::call] == 1){ //TODO: Fix - data.callargumentlist.push_back(")"); - NotifyAll(ctx); - data.clear(); - }else{ - data.callargumentlist.push_back(")"); - } - }; - - closeEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx [[maybe_unused]]){ - if(currentModifier == "*"){} - else if(currentModifier == "&"){} - }; - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx){ - if(ctx.IsOpen(ParserState::name) && ctx.IsGreaterThan(ParserState::call,ParserState::argumentlist) && ctx.IsClosed(ParserState::genericargumentlist)){ - data.fnName = ctx.currentToken; - fullFuncIdentifier += ctx.currentToken; - } - - if(ctx.And({ParserState::name, ParserState::argument, ParserState::argumentlist}) && ctx.IsEqualTo(ParserState::call,ParserState::argumentlist) && ctx.IsClosed(ParserState::genericargumentlist)){ - data.callargumentlist.push_back(ctx.currentToken); - } - - if(ctx.And({ParserState::literal, ParserState::argument, ParserState::argumentlist}) && ctx.IsEqualTo(ParserState::call,ParserState::argumentlist) && ctx.IsClosed(ParserState::genericargumentlist)){ - data.callargumentlist.push_back("*LITERAL*"); //Illegal c++ identifier as marker for literals - } - }; - } -}; -#endif \ No newline at end of file diff --git a/src/policy_classes/FunctionPolicy.hpp b/src/policy_classes/FunctionPolicy.hpp new file mode 100644 index 0000000..42603c7 --- /dev/null +++ b/src/policy_classes/FunctionPolicy.hpp @@ -0,0 +1,356 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file FunctionPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_FUNCTION_POLICY_HPP +#define INCLUDED_FUNCTION_POLICY_HPP + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace srcDispatch { + + struct FunctionData { + + enum FunctionType { CONSTRUCTOR, DESTRUCTOR, OPERATOR, FUNCTION }; + + /*** @todo fix */ + // std::vector> namespaces; + std::vector namespaces; + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + std::string language; + std::string filename; + + std::vector>> generics; + DeltaElement type; + DeltaElement accessSpecifier; + + std::vector>> leadingSpecifiers; + std::vector>> trailingSpecifiers; + + DeltaElement isDecl; + DeltaElement isPureVirtual; + DeltaElement isDelete; + + /*** @todo implement */ + std::set stereotypes; + + DeltaElement> returnType; + DeltaElement> name; + std::vector>> parameters; + std::vector>> memberInitList; + DeltaElement> block; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + + std::string signature; + + for(DeltaElement> specifier : leadingSpecifiers) { + if(specifier.IsOfOperation(operation)) { + signature += *specifier.GetOfOperation(operation) + ' '; + } + } + + signature += returnType.ToString(operation); + + if(returnType.IsOfOperation(operation)) { + signature += ' '; + } + + signature += name.ToString(operation); + + if(name.IsOfOperation(operation)) { + signature += '('; + } + + bool outputComma = false; + for (const DeltaElement>& parameter : parameters) { + bool outputRaw = parameter.IsOfOperation(operation); + if(outputRaw) { + if(outputComma) { + signature += ", "; + } + outputComma = true; + } + signature += parameter.ToString(operation); + } + + if(name.IsOfOperation(operation)) { + signature += ')'; + } + + for(DeltaElement> specifier : trailingSpecifiers) { + if(specifier.IsOfOperation(operation)) { + signature += ' ' + *specifier.GetOfOperation(operation); + } + } + + + if(isPureVirtual.IsOfOperation(operation) && isPureVirtual.GetOfOperation(operation)) { + signature += " = 0"; + } + + if(isDelete.IsOfOperation(operation) && isDelete.GetOfOperation(operation)) { + signature += " = delete"; + } + + if(isDecl.IsOfOperation(operation)) { + if(isDecl.GetOfOperation(operation)) { + signature += ';'; + } else { + signature += " {}"; + } + } + + return signature; + } + }; + + class FunctionPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + FunctionData data; + + bool beforeParameters; + + std::unique_ptr genericPolicy; + std::unique_ptr typePolicy; + std::unique_ptr namePolicy; + std::unique_ptr declPolicy; + std::unique_ptr callPolicy; + std::unique_ptr blockPolicy; + + public: + FunctionPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{}, beforeParameters(true) { + InitializeFunctionPolicyHandlers(); + } + + ~FunctionPolicy() {} + + protected: + std::any DataInner() const override { return std::make_shared(data); } + + virtual void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override { + if(typeid(GenericPolicy) == typeid(*policy)) { + data.generics.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(TypePolicy) == typeid(*policy)) { + data.returnType = DeltaElement(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(NamePolicy) == typeid(*policy)) { + data.name = DeltaElement(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(DeclPolicy) == typeid(*policy)) { + data.parameters.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(CallPolicy) == typeid(*policy)) { + data.memberInitList.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(BlockPolicy) == typeid(*policy)) { + data.block.Update(ctx.diffStack.back().operation, policy->Data()); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + + ctx.dispatcher->RemoveListenerDispatch(nullptr); + } + + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + private: + void InitializeFunctionPolicyHandlers() { + using namespace srcDispatch; + // start of policy + std::function startFunction = [this](srcSAXEventContext& ctx) { + if(depth) return; + + depth = ctx.depth; + data = FunctionData{}; + data.namespaces = ctx.currentNamespaces; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + data.language = ctx.currentFileLanguage; + data.filename = ctx.currentFilePath; + + std::map::const_iterator stereotype_attr_itr = ctx.attributes.find("stereotype"); + if(stereotype_attr_itr != ctx.attributes.end()) { + std::istringstream stereostring(stereotype_attr_itr->second); + data.stereotypes = std::set(std::istream_iterator(stereostring), std::istream_iterator()); + } + if(ctx.currentTag == "function" || ctx.currentTag == "function_decl") { + if(ctx.isOperator) { + data.type.Update(ctx.diffStack.back().operation, FunctionData::OPERATOR); + } else { + data.type.Update(ctx.diffStack.back().operation, FunctionData::FUNCTION); + } + } else if(ctx.currentTag == "constructor" || ctx.currentTag == "constructor_decl") { + data.type.Update(ctx.diffStack.back().operation, FunctionData::CONSTRUCTOR); + } else if(ctx.currentTag == "destructor" || ctx.currentTag == "destructor_decl") { + data.type.Update(ctx.diffStack.back().operation, FunctionData::DESTRUCTOR); + } + + data.isDecl.Update(ctx.diffStack.back().operation, ctx.currentTag == "function_decl" || ctx.currentTag == "constructor_decl" || ctx.currentTag == "destructor_decl"); + + CollectXMLAttributeHandlers(); + CollectGenericHandlers(); + CollectTypeHandlers(); + CollectNameHandlers(); + CollectParameterHandlers(); + CollectCallHandlers(); + CollectOtherHandlers(); + CollectBlockHandlers(); + }; + + // end of policy + std::function endFunction = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeFunctionPolicyHandlers(); + }; + + openEventMap[ParserState::function] = startFunction; + openEventMap[ParserState::functiondecl] = startFunction; + openEventMap[ParserState::constructor] = startFunction; + openEventMap[ParserState::constructordecl] = startFunction; + openEventMap[ParserState::destructor] = startFunction; + openEventMap[ParserState::destructordecl] = startFunction; + + closeEventMap[ParserState::function] = endFunction; + closeEventMap[ParserState::functiondecl] = endFunction; + closeEventMap[ParserState::constructor] = endFunction; + closeEventMap[ParserState::constructordecl] = endFunction; + closeEventMap[ParserState::destructor] = endFunction; + closeEventMap[ParserState::destructordecl] = endFunction; + } + + void CollectXMLAttributeHandlers() {} + + void CollectGenericHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::templates] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!genericPolicy) { + genericPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(genericPolicy.get()); + }; + } + + void CollectTypeHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::type] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!typePolicy) { + typePolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(typePolicy.get()); + }; + } + + void CollectNameHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!namePolicy) { + namePolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(namePolicy.get()); + }; + } + + void CollectParameterHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::parameterlist] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + openEventMap[ParserState::parameter] = [this](srcSAXEventContext& ctx) { + if(!declPolicy) { + declPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(declPolicy.get()); + }; + }; + + closeEventMap[ParserState::parameterlist] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + beforeParameters = false; + NopOpenEvents({ParserState::parameter}); + }; + } + + void CollectCallHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::call] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!callPolicy) { + callPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(callPolicy.get()); + }; + } + + void CollectOtherHandlers() { + using namespace srcDispatch; + closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(ctx.And({ParserState::specifier})) { + if(ctx.currentToken == "delete") { + data.isDelete.Update(ctx.diffStack.back().operation, true); + } else if(beforeParameters) { + data.leadingSpecifiers.emplace_back(ctx.diffStack.back().operation, std::make_shared(ctx.currentToken)); + } else { + data.trailingSpecifiers.emplace_back(ctx.diffStack.back().operation, std::make_shared(ctx.currentToken)); + } + } else if(ctx.And({ParserState::literal})) { + data.isPureVirtual.Update(ctx.diffStack.back().operation, true); + } + }; + } + + void CollectBlockHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::block] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!blockPolicy) { + blockPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(blockPolicy.get()); + }; + } + }; + +} + +#endif diff --git a/src/policy_classes/FunctionPolicySingleEvent.hpp b/src/policy_classes/FunctionPolicySingleEvent.hpp deleted file mode 100644 index d14b061..0000000 --- a/src/policy_classes/FunctionPolicySingleEvent.hpp +++ /dev/null @@ -1,321 +0,0 @@ -/** - * @file FunctionPolicySingleEvent.hpp - * - * MODIFIED FOR STEREOCODE - * - */ -#ifndef INCLUDED_FUNCTION_POLICY_SINGE_EVENT_HPP -#define INCLUDED_FUNCTION_POLICY_SINGE_EVENT_HPP - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -struct FunctionData { - enum FunctionType { CONSTRUCTOR, DESTURCTOR, OPERATOR, FUNCTION }; - - unsigned int lineNumber; - std::string language; - std::string filename; - FunctionType type; - std::shared_ptr returnType; - std::shared_ptr name; - std::vector> parameters; - std::vector> locals; //Local variables - std::vector> returnExpressions; //Expressions returned - std::vector> expressions; //All other exprs - std::set stereotypes; - - bool isVirtual; - bool isPureVirtual; - bool isConst; - bool isStatic; - bool isInline; - bool isFinal; - bool isOverride; - bool isConstExpr; - bool isDelete; - - std::string ToString() const { - std::string signature = name->ToString(); - signature += '('; - for(std::size_t pos = 0; pos < parameters.size(); ++pos) { - if (pos > 0) { - signature += ", "; - } - signature += parameters[pos]->type->ToString(); - } - signature += ')'; - if (isConst) { - signature += " const"; - } - return signature; - } - - friend std::ostream & operator<<(std::ostream & out, const FunctionData & functionData) { - if (functionData.returnType){ - out << *functionData.returnType << ' ' << *functionData.name; - } - out << '('; - for(std::size_t pos = 0; pos < functionData.parameters.size(); ++pos) { - if (pos != 0) - out << ", "; - out << *functionData.parameters[pos]; - } - out << ')'; - return out; - } -}; - - -class FunctionPolicy : -public srcSAXEventDispatch::EventListener, -public srcSAXEventDispatch::PolicyDispatcher, -public srcSAXEventDispatch::PolicyListener { - -private: - FunctionData data; - std::size_t functionDepth; - - TypePolicy *typePolicy; - NamePolicy *namePolicy; - ParamTypePolicy *paramPolicy; - DeclTypePolicy *declstmtPolicy; - ReturnPolicy *returnPolicy; - ExpressionPolicy *expressionPolicy; - -public: - FunctionPolicy(std::initializer_list listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - functionDepth(0), - typePolicy(nullptr), - namePolicy(nullptr), - paramPolicy(nullptr), - declstmtPolicy(nullptr), - expressionPolicy(nullptr), - returnPolicy(nullptr) { - InitializeFunctionPolicyHandlers(); - } - - ~FunctionPolicy() { - if (typePolicy) delete typePolicy; - if (namePolicy) delete namePolicy; - if (paramPolicy) delete paramPolicy; - if (declstmtPolicy) delete declstmtPolicy; - if (returnPolicy) delete returnPolicy; - if (expressionPolicy) delete expressionPolicy; - } - -protected: - std::any DataInner() const override { return std::make_shared(data); } - - void NotifyWrite(const PolicyDispatcher * policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers - - virtual void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - if (typeid(TypePolicy) == typeid(*policy)) { - data.returnType = policy->Data(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - } else if (typeid(NamePolicy) == typeid(*policy)) { - data.name = policy->Data(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - } else if (typeid(ParamTypePolicy) == typeid(*policy)) { - data.parameters.push_back(policy->Data()); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - } else if (typeid(DeclTypePolicy) == typeid(*policy)) { - std::shared_ptr>> decl_data = policy->Data>>(); - for(std::shared_ptr decl : *decl_data) - data.locals.push_back(decl); - decl_data->clear(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - } else if (typeid(ReturnPolicy) == typeid(*policy)) { - data.returnExpressions.push_back(policy->Data()); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - } else if (typeid(ExpressionPolicy) == typeid(*policy)) { - data.expressions.push_back(policy->Data()); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - } - } - -private: - void InitializeFunctionPolicyHandlers() { - using namespace srcSAXEventDispatch; - // start of policy - std::function startFunction = [this](srcSAXEventContext& ctx) { - if (!functionDepth) { - functionDepth = ctx.depth; - data = FunctionData{}; - data.lineNumber = ctx.currentLineNumber; - data.language = ctx.currentFileLanguage; - data.filename = ctx.currentFilePath; - std::map::const_iterator stereotype_attr_itr = ctx.attributes.find("stereotype"); - if (stereotype_attr_itr != ctx.attributes.end()){ - std::istringstream stereostring(stereotype_attr_itr->second); - data.stereotypes = std::set(std::istream_iterator(stereostring), std::istream_iterator()); - } - if (ctx.currentTag == "function" || ctx.currentTag == "function_decl") { - if (ctx.isOperator) - data.type = FunctionData::OPERATOR; - else - data.type = FunctionData::FUNCTION; - } else if (ctx.currentTag == "constructor" || ctx.currentTag == "constructor_decl") { - data.type = FunctionData::CONSTRUCTOR; - } else if (ctx.currentTag == "destructor" || ctx.currentTag == "destructor_decl") { - data.type = FunctionData::DESTURCTOR; - } - - CollectXMLAttributeHandlers(); - CollectTypeHandlers(); - CollectNameHandlers(); - CollectParameterHandlers(); - CollectOtherHandlers(); - CollectDeclstmtHandlers(); - CollectReturnHandlers(); - CollectExpressionHandlers(); - } - }; - - // end of policy - std::function endFunction = [this](srcSAXEventContext& ctx) { - if (functionDepth && functionDepth == ctx.depth) { - functionDepth = 0; - NotifyAll(ctx); - InitializeFunctionPolicyHandlers(); - } - }; - - openEventMap[ParserState::function] = startFunction; - openEventMap[ParserState::functiondecl] = startFunction; - openEventMap[ParserState::constructor] = startFunction; - openEventMap[ParserState::constructordecl] = startFunction; - openEventMap[ParserState::destructor] = startFunction; - openEventMap[ParserState::destructordecl] = startFunction; - - closeEventMap[ParserState::function] = endFunction; - closeEventMap[ParserState::functiondecl] = endFunction; - closeEventMap[ParserState::constructor] = endFunction; - closeEventMap[ParserState::constructordecl] = endFunction; - closeEventMap[ParserState::destructor] = endFunction; - closeEventMap[ParserState::destructordecl] = endFunction; - } - - void CollectXMLAttributeHandlers() {} - - void CollectTypeHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::type] = [this](srcSAXEventContext& ctx) { - if (functionDepth && (functionDepth + 1) == ctx.depth) { - if (!typePolicy) typePolicy = new TypePolicy{this}; - ctx.dispatcher->AddListenerDispatch(typePolicy); - } - }; - } - - void CollectNameHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - if (functionDepth && (functionDepth + 1) == ctx.depth) { - if (!namePolicy) namePolicy = new NamePolicy{this}; - ctx.dispatcher->AddListenerDispatch(namePolicy); - } - }; - } - - void CollectParameterHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::parameterlist] = [this](srcSAXEventContext& ctx) { - if (functionDepth && (functionDepth + 1) == ctx.depth) { - openEventMap[ParserState::parameter] = [this](srcSAXEventContext& ctx) { - if (functionDepth && (functionDepth + 2) == ctx.depth) { - if (!paramPolicy) paramPolicy = new ParamTypePolicy{this}; - ctx.dispatcher->AddListenerDispatch(paramPolicy); - } - }; - } - }; - - closeEventMap[ParserState::parameterlist] = [this](srcSAXEventContext& ctx) { - if (functionDepth && (functionDepth + 1) == ctx.depth) { - NopOpenEvents({ParserState::parameter}); - } - }; - } - - void CollectReturnHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::returnstmt] = [this](srcSAXEventContext& ctx) { - if (!returnPolicy) returnPolicy = new ReturnPolicy{this}; - ctx.dispatcher->AddListenerDispatch(returnPolicy); - }; - } - - void CollectExpressionHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::expr] = [this](srcSAXEventContext& ctx) { - if (!expressionPolicy) expressionPolicy = new ExpressionPolicy{this}; - ctx.dispatcher->AddListenerDispatch(expressionPolicy); - }; - } - - void CollectOtherHandlers() { - using namespace srcSAXEventDispatch; - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - if (functionDepth && (functionDepth + 1) == ctx.depth) { - if (ctx.And({ParserState::specifier})) { - if (ctx.currentToken == "virtual") - data.isVirtual = true; - else if (ctx.currentToken == "static") - data.isStatic = true; - else if (ctx.currentToken == "const") - data.isConst = true; - else if (ctx.currentToken == "final") - data.isFinal = true; - else if (ctx.currentToken == "override") - data.isOverride = true; - else if (ctx.currentToken == "delete") - data.isDelete = true; - else if (ctx.currentToken == "inline") - data.isInline = true; - else if (ctx.currentToken == "constexpr") - data.isConstExpr = true; - } else if (ctx.And({ParserState::literal})) { - data.isPureVirtual = true; - } - } - }; - } - - /** @todo Will not work with local classes. */ - /** @todo May need to add optimization that ignores declaration statement initialization. */ - void CollectDeclstmtHandlers(){ - using namespace srcSAXEventDispatch; - openEventMap[ParserState::block] = [this](srcSAXEventContext& ctx) { - if (functionDepth && (functionDepth + 1) == ctx.depth) { - openEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx) { - if (!declstmtPolicy) declstmtPolicy = new DeclTypePolicy{this}; - ctx.dispatcher->AddListenerDispatch(declstmtPolicy); - }; - } - }; - - closeEventMap[ParserState::block] = [this](srcSAXEventContext& ctx) { - if (functionDepth && (functionDepth + 1) == ctx.depth) { - NopOpenEvents({ParserState::declstmt}); - } - }; - } - -}; - -#endif diff --git a/src/policy_classes/FunctionSignaturePolicy.hpp b/src/policy_classes/FunctionSignaturePolicy.hpp deleted file mode 100644 index ba047f4..0000000 --- a/src/policy_classes/FunctionSignaturePolicy.hpp +++ /dev/null @@ -1,180 +0,0 @@ -/** - * @file FunctionSignaturePolicy.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -#ifndef FUNCTIONSIGNATUREPOLICY -#define FUNCTIONSIGNATUREPOLICY -struct SignatureData{ - SignatureData():isConst{false}, constPointerReturn{false}, isMethod{false}, isStatic{false}, pointerToConstReturn{false}, - hasAliasedReturn{false}, hasSideEffect{false}, hasArrayReturn{false}{} - int lineNumber; - bool isConst; - bool isMethod; - bool isStatic; - std::string name; - bool hasArrayReturn; - bool hasSideEffect; - bool isConstructor; - bool hasAliasedReturn; - std::string returnType; - bool constPointerReturn; - bool pointerToConstReturn; - std::string sLexicalCategory; - std::string returnTypeModifier; - std::vector parameters; - std::string nameOfContainingFile; - std::string nameOfContainingClass; - std::vector functionNamespaces; - std::vector returnTypeNamespaces; - void clear(){ - name.clear(); - hasArrayReturn = false; - isConst = false; - isMethod = false; - isStatic = false; - returnType.clear(); - parameters.clear(); - hasSideEffect = false; - isConstructor = false; - sLexicalCategory.clear(); - hasAliasedReturn = false; - functionNamespaces.clear(); - returnTypeModifier.clear(); - constPointerReturn = false; - nameOfContainingFile.clear(); - returnTypeNamespaces.clear(); - pointerToConstReturn = false; - nameOfContainingClass.clear(); - } -}; -class FunctionSignaturePolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - ~FunctionSignaturePolicy(){} - FunctionSignaturePolicy(std::initializer_list listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners){ - currentArgPosition = 1; - parampolicy.AddListener(this); - InitializeEventHandlers(); - } - void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override { - paramdata = policy->Data(); - data.parameters.push_back(*paramdata); - } - void NotifyWrite(const PolicyDispatcher * policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers - protected: - std::any DataInner() const override { - return std::make_shared(data); - } - private: - bool seenModifier; - ParamTypePolicy parampolicy; - std::shared_ptr paramdata; - SignatureData data; - size_t currentArgPosition; - std::string currentTypeName, currentDeclName, currentModifier, currentSpecifier; - - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - openEventMap[ParserState::parameterlist] = [this](srcSAXEventContext& ctx) { - ctx.dispatcher->AddListener(¶mpolicy); - data.lineNumber = ctx.currentLineNumber; - }; - closeEventMap[ParserState::parameterlist] = [this](srcSAXEventContext& ctx){ - ctx.dispatcher->RemoveListener(¶mpolicy); - if(ctx.IsOpen(ParserState::classn)){ - data.isMethod = true; - data.nameOfContainingClass = ctx.currentClassName; - } - data.name = ctx.currentFunctionName; - - }; - - openEventMap[ParserState::function] = [this](srcSAXEventContext& ctx) { - data.lineNumber = ctx.currentLineNumber; - }; - - openEventMap[ParserState::index] = [this](srcSAXEventContext& ctx) { - if(ctx.IsOpen(ParserState::type) && ctx.Nor({ParserState::functionblock, ParserState::parameterlist, ParserState::declstmt})){ - data.hasArrayReturn = true; - } - }; - - openEventMap[ParserState::op] = [this](srcSAXEventContext& ctx){ - if(ctx.And({ParserState::type, ParserState::function}) && ctx.Nor({ParserState::parameterlist, ParserState::functionblock, ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist})){ - data.returnTypeNamespaces.push_back(ctx.currentToken); - } - if(ctx.IsOpen(ParserState::function) && ctx.Nor({ParserState::type, ParserState::parameterlist, ParserState::functionblock, ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist})){ - data.functionNamespaces.push_back(ctx.currentToken); - } - }; - - openEventMap[ParserState::functionblock] = [this](srcSAXEventContext& ctx) { - NotifyAll(ctx); - seenModifier = false; - data.clear(); - }; - - closeEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx) { - if(currentModifier == "*") { - if(ctx.And({ParserState::type, ParserState::function}) && ctx.IsClosed(ParserState::parameterlist)){ - seenModifier = true; - data.hasAliasedReturn = true; - } - } - else if(currentModifier == "&") {} - }; - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx){ - if(ctx.And({ParserState::name, ParserState::type, ParserState::function}) && ctx.Nor({ParserState::functionblock, ParserState::parameterlist, ParserState::genericargumentlist, ParserState::index})){ - data.returnType = ctx.currentToken; - } - if(ctx.And({ParserState::modifier, ParserState::type, ParserState::function}) && ctx.Nor({ParserState::parameterlist, ParserState::genericargumentlist})){ - data.returnTypeModifier = ctx.currentToken; - } - if(ctx.And({ParserState::specifier, ParserState::function}) && ctx.Nor({ParserState::parameterlist, ParserState::functionblock, ParserState::genericargumentlist})){ - currentSpecifier = ctx.currentToken; - } - if(ctx.And({ParserState::modifier, ParserState::function}) && ctx.Nor({ParserState::parameterlist, ParserState::functionblock, ParserState::genericargumentlist})){ - currentModifier = ctx.currentToken; - } - }; - - closeEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx) { - if(currentSpecifier == "const" && ctx.Nor({ParserState::parameterlist, ParserState::type})){ - data.isConst = true; - } - if(currentSpecifier == "const" && ctx.IsOpen(ParserState::function) && ctx.IsOpen(ParserState::type)){ - if(!seenModifier){ - data.pointerToConstReturn = true; - }else{ - data.constPointerReturn = true; - } - } - if(currentSpecifier == "static" && ctx.Nor({ParserState::parameterlist, ParserState::type})){ - data.isStatic = true; - } - currentSpecifier.clear(); - }; - } - -}; -#endif \ No newline at end of file diff --git a/src/policy_classes/GenericArgumentsPolicy.cpp b/src/policy_classes/GenericArgumentsPolicy.cpp new file mode 100644 index 0000000..b65f28f --- /dev/null +++ b/src/policy_classes/GenericArgumentsPolicy.cpp @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file GenericArgumentsPolicy.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#include +#include +#include + +#include + +namespace srcDispatch { + + std::string GenericArgumentsData::ToString(srcDispatch::DiffOperation operation) const { + + std::string str; + + bool hasArgument = false; + bool printComma = false; + for (const DeltaElement>& argument : arguments) { + + bool outputRaw = argument.IsOfOperation(operation); + if(outputRaw) { + if(printComma) { + str += ", "; + } + if(!hasArgument) { + str += "<"; + hasArgument = true; + } + printComma = true; + } + + str += argument.ToString(operation); + } + + if(hasArgument) { + str += '>'; + } + + return str; + } + + std::shared_ptr GenericArgumentsData::copyAs(srcDispatch::DiffOperation operation) const { + std::shared_ptr data = std::make_shared(); + data->startLineNumber = startLineNumber; + data->endLineNumber = endLineNumber; + + for (const DeltaElement>& argument : arguments) { + data->arguments.emplace_back(DeltaElement(operation, argument.GetElement()->copyAs(operation))); + } + + return data; + } + + GenericArgumentsPolicy::GenericArgumentsPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeGenericArgumentsPolicyHandlers(); + } + + GenericArgumentsPolicy::~GenericArgumentsPolicy() {} + + void GenericArgumentsPolicy::Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) { + if(typeid(NamePolicy) == typeid(*policy)) { + //data.arguments.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + std::shared_ptr nameData = policy->Data(); + ExpressionData exprData; + exprData.startLineNumber.Update(nameData->startLineNumber.GetOperation(), nameData->startLineNumber.GetElement()); + exprData.endLineNumber.Update(nameData->endLineNumber.GetOperation(), nameData->endLineNumber.GetElement()); + DeltaElement exprAny(ctx.diffStack.back().operation, nameData); + exprData.expr.emplace_back(exprAny); + data.arguments.push_back(DeltaElement(ctx.diffStack.back().operation, std::make_shared(exprData))); + } else if(typeid(ExpressionPolicy) == typeid(*policy)) { + data.arguments.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + ctx.dispatcher->RemoveListener(nullptr); + } + + std::any GenericArgumentsPolicy::DataInner() const { + return std::make_shared(data); + } + + void GenericArgumentsPolicy::InitializeGenericArgumentsPolicyHandlers() { + using namespace srcDispatch; + // start of policy + openEventMap[ParserState::genericargumentlist] = [this](srcSAXEventContext &ctx) { + if(depth) return; + + depth = ctx.depth; + data = GenericArgumentsData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectArgumentHandler(); + }; + + // end of policy + closeEventMap[ParserState::genericargumentlist] = [this](srcSAXEventContext &ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeGenericArgumentsPolicyHandlers(); + }; + + openEventMap[ParserState::genericparameterlist] = [this](srcSAXEventContext &ctx) { + if(depth) return; + + depth = ctx.depth; + data = GenericArgumentsData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectParameterHandler(); + }; + + closeEventMap[ParserState::genericparameterlist] = [this](srcSAXEventContext &ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeGenericArgumentsPolicyHandlers(); + }; + } + + void GenericArgumentsPolicy::CollectArgumentHandler() { + using namespace srcDispatch; + + openEventMap[ParserState::argument] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + openEventMap[ParserState::expr] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + if(!expressionPolicy) { + expressionPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(expressionPolicy.get()); + }; + + openEventMap[ParserState::name] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + if(!namePolicy) { + namePolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(namePolicy.get()); + }; + }; + + closeEventMap[ParserState::argument] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + NopOpenEvents({ParserState::expr, ParserState::name}); + }; + } + + void GenericArgumentsPolicy::CollectParameterHandler() { + using namespace srcDispatch; + + openEventMap[ParserState::parameter] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { + if(!namePolicy) { + namePolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(namePolicy.get()); + }; + }; + closeEventMap[ParserState::parameter] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + NopOpenEvents({ParserState::name}); + }; + } + +} diff --git a/src/policy_classes/GenericArgumentsPolicy.hpp b/src/policy_classes/GenericArgumentsPolicy.hpp new file mode 100644 index 0000000..2ecab49 --- /dev/null +++ b/src/policy_classes/GenericArgumentsPolicy.hpp @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file GenericArgumentsPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_GENERIC_ARGUMENTS_POLICY_HPP +#define INCLUDED_GENERIC_ARGUMENTS_POLICY_HPP + +#include +#include +#include + +namespace srcDispatch { + + class NamePolicy; + class ExpressionPolicy; + struct ExpressionData; + + struct GenericArgumentsData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + std::vector>> arguments; + + std::shared_ptr copyAs(srcDispatch::DiffOperation operation) const; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const; + }; + + class GenericArgumentsPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + + private: + GenericArgumentsData data; + + std::unique_ptr expressionPolicy; + std::unique_ptr namePolicy; + + public: + GenericArgumentsPolicy(std::initializer_list listeners); + ~GenericArgumentsPolicy(); + virtual void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override; + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + protected: + virtual std::any DataInner() const override; + + private: + void InitializeGenericArgumentsPolicyHandlers(); + void CollectArgumentHandler(); + void CollectParameterHandler(); + }; + +} + +#endif diff --git a/src/policy_classes/GenericPolicy.cpp b/src/policy_classes/GenericPolicy.cpp new file mode 100644 index 0000000..d4d7407 --- /dev/null +++ b/src/policy_classes/GenericPolicy.cpp @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file GenericPolicy.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#include +#include + +#include +#include + +#include + +namespace srcDispatch { + + std::string GenericData::ToString(srcDispatch::DiffOperation operation) const { + + std::string str; + + bool hasParameter = false; + bool printComma = false; + for (const DeltaElement>& parameter : parameters) { + + bool outputRaw = parameter.IsOfOperation(operation); + if(outputRaw) { + if(printComma) { + str += ", "; + } + if(!hasParameter) { + str += "template<"; + hasParameter = true; + } + printComma = true; + } + + str += parameter.ToString(operation); + } + + if(hasParameter) { + str += '>'; + } + + return str; + } + + GenericPolicy::GenericPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeGenericPolicyHandlers(); + } + + GenericPolicy::~GenericPolicy() {} + + void GenericPolicy::Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) { + if(typeid(DeclPolicy) == typeid(*policy)) { + data.parameters.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + ctx.dispatcher->RemoveListener(nullptr); + } + + std::any GenericPolicy::DataInner() const { + return std::make_shared(data); + } + + void GenericPolicy::InitializeGenericPolicyHandlers() { + using namespace srcDispatch; + // start of policy + openEventMap[ParserState::templates] = [this](srcSAXEventContext &ctx) { + if(depth) return; + + depth = ctx.depth; + data = GenericData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectParameterHandlers(); + }; + + // end of policy + closeEventMap[ParserState::templates] = [this](srcSAXEventContext &ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeGenericPolicyHandlers(); + }; + } + + void GenericPolicy::CollectParameterHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::parameterlist] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + openEventMap[ParserState::parameter] = [this](srcSAXEventContext& ctx) { + if(!declPolicy) { + declPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(declPolicy.get()); + }; + }; + + closeEventMap[ParserState::parameterlist] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + NopOpenEvents({ParserState::parameter}); + }; + } +} diff --git a/src/policy_classes/GenericPolicy.hpp b/src/policy_classes/GenericPolicy.hpp new file mode 100644 index 0000000..acb20c2 --- /dev/null +++ b/src/policy_classes/GenericPolicy.hpp @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file GenericPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_GENERIC_POLICY_HPP +#define INCLUDED_GENERIC_POLICY_HPP + +#include + +#include + + +namespace srcDispatch { + + class DeclPolicy; + struct DeclData; + + class NamePolicy; + + class ExpressionPolicy; + struct ExpressionData; + + struct GenericData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + std::vector>> parameters; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const; + }; + + class GenericPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + GenericData data; + + std::unique_ptr declPolicy; + + public: + GenericPolicy(std::initializer_list listeners); + ~GenericPolicy(); + virtual void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override; + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + protected: + virtual std::any DataInner() const override; + + private: + void InitializeGenericPolicyHandlers(); + void CollectParameterHandlers(); + }; + +} + +#endif diff --git a/src/policy_classes/GotoPolicy.hpp b/src/policy_classes/GotoPolicy.hpp new file mode 100644 index 0000000..58e7c22 --- /dev/null +++ b/src/policy_classes/GotoPolicy.hpp @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file GotoPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_GOTO_POLICY_HPP +#define INCLUDED_GOTO_POLICY_HPP + +#include +#include +#include +#include + +#include + +#include +#include +#include + +namespace srcDispatch { + + struct GotoData { + enum GotoType { GOTO, BREAK, CONTINUE }; + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement type; + DeltaElement> label; + }; + + // Collect the expression in the return + class GotoPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + private: + GotoData data; + + std::unique_ptr namePolicy; + + public: + GotoPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeGotoPolicyHandlers(); + } + + ~GotoPolicy() {} + + protected: + std::any DataInner() const override { return std::make_shared(data); } + + virtual void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override { + if(typeid(NamePolicy) == typeid(*policy)) { + data.label.Update(ctx.diffStack.back().operation, policy->Data()); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + + ctx.dispatcher->RemoveListenerDispatch(nullptr); + } + + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + private: + void InitializeGotoPolicyHandlers() { + using namespace srcDispatch; + // start of policy + std::function startGoto = [this](srcSAXEventContext& ctx) { + if(depth) return; + + depth = ctx.depth; + data = GotoData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + + if(ctx.currentTag == "break") { + data.type.Update(ctx.diffStack.back().operation, GotoData::BREAK); + } else if(ctx.currentTag == "continue") { + data.type.Update(ctx.diffStack.back().operation, GotoData::CONTINUE); + } else { + data.type.Update(ctx.diffStack.back().operation, GotoData::GOTO); + } + + CollectLabelHandlers(); + }; + + // end of policy + std::function endGoto = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return; + depth = 0; + NotifyAll(ctx); + InitializeGotoPolicyHandlers(); + }; + + openEventMap[ParserState::gotostmt] = startGoto; + openEventMap[ParserState::breakstmt] = startGoto; + openEventMap[ParserState::continuestmt] = startGoto; + + closeEventMap[ParserState::gotostmt] = endGoto; + closeEventMap[ParserState::breakstmt] = endGoto; + closeEventMap[ParserState::continuestmt] = endGoto; + } + + void CollectLabelHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!namePolicy) { + namePolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(namePolicy.get()); + }; + } + + }; + +} + +#endif diff --git a/src/policy_classes/IfPolicy.hpp b/src/policy_classes/IfPolicy.hpp new file mode 100644 index 0000000..89885c1 --- /dev/null +++ b/src/policy_classes/IfPolicy.hpp @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file IfPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_IF_POLICY_HPP +#define INCLUDED_IF_POLICY_HPP + +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + struct IfData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement> condition; + DeltaElement> block; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + return condition.ToString(operation); + } + }; + + class IfPolicy : public ConditionalPolicy { + public: + IfPolicy(std::initializer_list listeners) + : ConditionalPolicy(listeners) {} + }; + +} + +#endif diff --git a/src/policy_classes/IfStmtPolicy.hpp b/src/policy_classes/IfStmtPolicy.hpp new file mode 100644 index 0000000..f771d47 --- /dev/null +++ b/src/policy_classes/IfStmtPolicy.hpp @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file IfStmtPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_IF_STMT_POLICY_HPP +#define INCLUDED_IF_STMT_POLICY_HPP + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + struct IfStmtData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + std::vector> clauses; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + if(clauses.empty()) return ""; + + // Not sure how safe using GetElement is here + if(clauses.front().GetElement().type() != typeid(std::shared_ptr)) return ""; + + return clauses.front().ToString>(operation); + } + }; + + class IfStmtPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + IfStmtData data; + + std::unique_ptr ifPolicy; + std::unique_ptr elseIfPolicy; + std::unique_ptr elsePolicy; + + public: + IfStmtPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeIfStmtPolicyHandlers(); + } + + ~IfStmtPolicy() {} + + protected: + std::any DataInner() const { return std::make_shared(data); } + + void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) { + if(typeid(IfPolicy) == typeid(*policy)) { + data.clauses.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else if(typeid(ElseIfPolicy) == typeid(*policy)) { + data.clauses.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else if(typeid(ElsePolicy) == typeid(*policy)) { + data.clauses.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + + ctx.dispatcher->RemoveListener(nullptr); + } + + void NotifyWrite(const PolicyDispatcher* policy, srcDispatch::srcSAXEventContext& ctx) {} // doesn't use other parsers + + private: + void InitializeIfStmtPolicyHandlers() { + using namespace srcDispatch; + + openEventMap[ParserState::ifgroup] = [this](srcSAXEventContext& ctx) { + if(depth) return; + + depth = ctx.depth; + data = IfStmtData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectIfHandlers(); + CollectElseIfHandlers(); + CollectElseHandlers(); + }; + + // end of policy + closeEventMap[ParserState::ifgroup] = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeIfStmtPolicyHandlers(); + }; + } + + void CollectIfHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::ifstmt] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!ifPolicy) { + ifPolicy = make_unique_policy({this}); + } + + ctx.dispatcher->AddListenerDispatch(ifPolicy.get()); + }; + } + + void CollectElseIfHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::elseif] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!elseIfPolicy) { + elseIfPolicy = make_unique_policy({this}); + } + + ctx.dispatcher->AddListenerDispatch(elseIfPolicy.get()); + }; + } + + void CollectElseHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::elsestmt] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!elsePolicy) { + elsePolicy = make_unique_policy({this}); + } + + ctx.dispatcher->AddListenerDispatch(elsePolicy.get()); + }; + } + }; + +} + +#endif diff --git a/src/policy_classes/IncrPolicy.hpp b/src/policy_classes/IncrPolicy.hpp new file mode 100644 index 0000000..5978498 --- /dev/null +++ b/src/policy_classes/IncrPolicy.hpp @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file IncrPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_INCR_POLICY_HPP +#define INCLUDED_INCR_POLICY_HPP + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + struct IncrData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + std::vector>> exprs; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + if(exprs.empty()) return ""; + + std::string str; + bool printComma = false; + for(const DeltaElement>& expr : exprs) { + + bool outputRaw = expr.IsOfOperation(operation); + if(outputRaw) { + if(printComma) { + str += ", "; + } + printComma = true; + } + + str += expr.ToString(operation); + } + + return str; + } + }; + + class IncrPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + IncrData data; + + std::unique_ptr exprPolicy; + + public: + IncrPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeIncrPolicyHandlers(); + } + + ~IncrPolicy() {} + + protected: + std::any DataInner() const override { return std::make_shared(data); } + + void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override { + if(typeid(ExpressionPolicy) == typeid(*policy)) { + data.exprs.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + ctx.dispatcher->RemoveListener(nullptr); + } + + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + private: + void InitializeIncrPolicyHandlers() { + using namespace srcDispatch; + + openEventMap[ParserState::incr] = [this](srcSAXEventContext& ctx) { + if(depth) return; + + depth = ctx.depth; + data = IncrData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectExpressionHandlers(); + + }; + + // end of policy + closeEventMap[ParserState::incr] = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeIncrPolicyHandlers(); + }; + } + + void CollectExpressionHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::expr] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!exprPolicy) { + exprPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(exprPolicy.get()); + }; + } + }; + +} + +#endif diff --git a/src/policy_classes/InitPolicy.hpp b/src/policy_classes/InitPolicy.hpp new file mode 100644 index 0000000..7d66c0f --- /dev/null +++ b/src/policy_classes/InitPolicy.hpp @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file InitPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_INIT_POLICY_HPP +#define INCLUDED_INIT_POLICY_HPP + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + struct InitData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + std::vector> inits; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + if(inits.empty()) return ""; + + std::string str; + bool printComma = false; + for (const DeltaElement& init : inits) { + + bool outputRaw = init.IsOfOperation(operation); + if(outputRaw) { + if(printComma) { + str += ", "; + } + printComma = true; + } + + if(init.GetElement().type() == typeid(std::shared_ptr)) { + str += init.ToString>(operation); + } else { + str += init.ToString>(operation); + } + } + + return str; + } + }; + + class InitPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + InitData data; + + std::unique_ptr declPolicy; + std::unique_ptr exprPolicy; + + public: + InitPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeInitPolicyHandlers(); + } + + ~InitPolicy() {} + + protected: + std::any DataInner() const override { return std::make_shared(data); } + + void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override { + if(typeid(ExpressionPolicy) == typeid(*policy)) { + if(data.inits.size() && ctx.diffStack.back().isReplace && data.inits.back().GetElement().type() == typeid(std::shared_ptr)) { + data.inits.back().Update(ctx.diffStack.back().operation, policy->Data()); + } else { + data.inits.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } + } else if(typeid(DeclPolicy) == typeid(*policy)) { + // not sure how safe GetElement is here + srcDispatch::DiffOperation operation = ctx.diffStack.back().operation; + std::shared_ptr decl = policy->Data(); + if(data.inits.size() && data.inits.back().GetElement().type() == typeid(std::shared_ptr)) { + DeltaElement> typeData(operation, std::any_cast>(data.inits.back().GetElement())->type.GetElement()->copyAs(operation)); + decl->type = typeData; + decl->isStatic = std::any_cast>(data.inits.back().GetElement())->isStatic; + } + data.inits.emplace_back(operation, decl); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + ctx.dispatcher->RemoveListener(nullptr); + } + + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + private: + void InitializeInitPolicyHandlers() { + using namespace srcDispatch; + + openEventMap[ParserState::init] = [this](srcSAXEventContext& ctx) { + if(depth) return; + + depth = ctx.depth; + data = InitData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectExpressionHandlers(); + }; + + // end of policy + closeEventMap[ParserState::init] = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeInitPolicyHandlers(); + }; + } + + void CollectExpressionHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::decl] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!declPolicy) { + declPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(declPolicy.get()); + }; + + openEventMap[ParserState::expr] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!exprPolicy) { + exprPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(exprPolicy.get()); + }; + } + }; + +} + +#endif diff --git a/src/policy_classes/LabelPolicy.hpp b/src/policy_classes/LabelPolicy.hpp new file mode 100644 index 0000000..44c5171 --- /dev/null +++ b/src/policy_classes/LabelPolicy.hpp @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file LabelPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_LABEL_POLICY_HPP +#define INCLUDED_LABEL_POLICY_HPP + +#include +#include +#include +#include + +#include + +#include +#include +#include + +namespace srcDispatch { + + struct LabelData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement> name; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + return name.ToString(operation); + } + }; + + class LabelPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + LabelData data; + + std::unique_ptr namePolicy; + + public: + LabelPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeLabelPolicyHandlers(); + } + + ~LabelPolicy() {} + + protected: + std::any DataInner() const override { return std::make_shared(data); } + + virtual void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override { + if(typeid(NamePolicy) == typeid(*policy)) { + data.name.Update(ctx.diffStack.back().operation, policy->Data()); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + ctx.dispatcher->RemoveListener(nullptr); + } + + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + private: + void InitializeLabelPolicyHandlers() { + using namespace srcDispatch; + // start of policy + openEventMap[ParserState::label] = [this](srcSAXEventContext &ctx) { + if(depth) return; + + depth = ctx.depth; + data = LabelData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectNameHandlers(); + }; + + // end of policy + closeEventMap[ParserState::label] = [this](srcSAXEventContext &ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeLabelPolicyHandlers(); + }; + } + + void CollectNameHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::name] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + if(!namePolicy) { + namePolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(namePolicy.get()); + }; + } + }; + +} + +#endif diff --git a/src/policy_classes/LiteralPolicy.hpp b/src/policy_classes/LiteralPolicy.hpp new file mode 100644 index 0000000..d6a8721 --- /dev/null +++ b/src/policy_classes/LiteralPolicy.hpp @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file LiteralPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_LITERAL_POLICY_HPP +#define INCLUDED_LITERAL_POLICY_HPP + +#include +#include +#include +#include + +#include +#include + +namespace srcDispatch { + + struct LiteralData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement literal; + + std::shared_ptr copyAs(srcDispatch::DiffOperation operation) const { + std::shared_ptr data = std::make_shared(); + data->literal = DeltaElement(operation, literal.GetElement()); + return data; + } + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + return literal.ToString(operation); + } + }; + + class LiteralPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + LiteralData data; + + public: + LiteralPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeLiteralPolicyHandlers(); + } + + ~LiteralPolicy() {} + + protected: + std::any DataInner() const override { return std::make_shared(data); } + void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override {} + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + private: + void InitializeLiteralPolicyHandlers() { + using namespace srcDispatch; + + openEventMap[ParserState::literal] = [this](srcSAXEventContext& ctx) { + if(depth) return; + + depth = ctx.depth; + data = LiteralData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectTokenHandlers(); + }; + + // end of policy + closeEventMap[ParserState::literal] = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeLiteralPolicyHandlers(); + }; + } + + void CollectTokenHandlers() { + using namespace srcDispatch; + closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { + if(data.literal.GetOperation() == srcDispatch::NONE) { + bool isChange = (ctx.depth + 1) == ctx.diffStack.back().depth && ctx.diffStack.back().isReplace; + srcDispatch::DiffOperation operation = isChange? CHANGE : ctx.diffStack.back().operation; + data.literal = DeltaElement(operation); + } + + if( ctx.diffStack.back().operation == srcDispatch::COMMON + || ctx.diffStack.back().operation == srcDispatch::DELETE) { + data.literal.GetOriginal() += ctx.currentToken; + } else if(ctx.diffStack.back().operation == srcDispatch::INSERT) { + data.literal.GetModified() += ctx.currentToken; + } + }; + } + }; + +} + +#endif diff --git a/src/policy_classes/NamePolicy.cpp b/src/policy_classes/NamePolicy.cpp new file mode 100644 index 0000000..57d7fc1 --- /dev/null +++ b/src/policy_classes/NamePolicy.cpp @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file NamePolicy.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#include +#include +#include + +#include + +namespace srcDispatch { + + std::string NameData::SimpleName() const { + if(name) return name.ToString(); + if(names.empty()) throw std::logic_error("NameData is empty"); + + // Not sure how safe GetElement use is + assert(names.back().GetElement().type() == typeid(std::shared_ptr)); + return names.back().ToString>(); + } + + std::string NameData::ToString(srcDispatch::DiffOperation operation) const { + + std::string str = name.ToString(operation); + for (const DeltaElement& name_element : names) { + if(name_element.GetElement().type() == typeid(std::shared_ptr)) { + str += name_element.ToString>(operation); + } else { + str += name_element.ToString>(operation); + } + } + if(templateArgumentList) { + str += templateArgumentList.ToString(operation); + } + for (const DeltaElement>& index : indices) { + + bool outputRaw = index.IsOfOperation(operation); + if(outputRaw) { + str += '['; + } + + str += index.ToString(operation); + + if(outputRaw) { + str += ']'; + } + + } + + return str; + } + + std::shared_ptr NameData::copyAs(srcDispatch::DiffOperation operation) const { + std::shared_ptr data = std::make_shared(); + data->startLineNumber = startLineNumber; + data->endLineNumber = endLineNumber; + + if(name) { + data->name = DeltaElement(operation, name.GetElement()); + } + + for (const DeltaElement& name_element : names) { + DeltaElement nameAny; + if(name_element.GetElement().type() == typeid(std::shared_ptr)) { + nameAny = DeltaElement(operation, std::any_cast>(name_element)->copyAs(operation)); + } else { + nameAny = DeltaElement(operation, std::any_cast>(name_element)->copyAs(operation)); + } + data->names.emplace_back(nameAny); + } + + if(templateArgumentList) { + data->templateArgumentList = DeltaElement(operation, templateArgumentList.GetElement()->copyAs(operation)); + } + + for (const DeltaElement>& index : indices) { + data->indices.emplace_back(DeltaElement(operation, index.GetElement()->copyAs(operation))); + } + + return data; + } + + NamePolicy::~NamePolicy() {} + + void NamePolicy::Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) { + + if(typeid(NamePolicy) == typeid(*policy)) { + data.names.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else if(typeid(OperatorPolicy) == typeid(*policy)) { + data.names.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else if(typeid(GenericArgumentsPolicy) == typeid(*policy)) { + data.templateArgumentList = DeltaElement(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(ExpressionPolicy) == typeid(*policy)) { + data.indices.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + ctx.dispatcher->RemoveListener(nullptr); + } + + void NamePolicy::InitializeNamePolicyHandlers() { + using namespace srcDispatch; + + // start of policy + openEventMap[ParserState::name] = [this](srcSAXEventContext &ctx) { + if(!depth) { + depth = ctx.depth; + data = NameData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectOperatorsHandlers(); + CollectGenericArgumentsHandlers(); + CollectArrayIndicesHandlers(); + } else { + NopCloseEvents({ParserState::tokenstring}); + if(!namePolicy) { + namePolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(namePolicy.get()); + } + }; + + // end of policy + closeEventMap[ParserState::name] = [this](srcSAXEventContext &ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeNamePolicyHandlers(); + }; + + closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + if(data.name.GetOperation() == srcDispatch::NONE) { + bool isChange = (ctx.depth + 1) == ctx.diffStack.back().depth && ctx.diffStack.back().isReplace; + srcDispatch::DiffOperation operation = isChange? CHANGE : ctx.diffStack.back().operation; + data.name = DeltaElement(operation); + } + + if( ctx.diffStack.back().operation == srcDispatch::COMMON + || ctx.diffStack.back().operation == srcDispatch::DELETE) { + data.name.GetOriginal() += ctx.currentToken; + } else if(ctx.diffStack.back().operation == srcDispatch::INSERT) { + data.name.GetModified() += ctx.currentToken; + } + }; + } + + void NamePolicy::CollectOperatorsHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::op] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + if(!operatorPolicy) { + operatorPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(operatorPolicy.get()); + }; + } + + void NamePolicy::CollectGenericArgumentsHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::genericargumentlist] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + if(!templateArgumentListPolicy) { + templateArgumentListPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(templateArgumentListPolicy.get()); + }; + openEventMap[ParserState::genericparameterlist] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + if(!templateArgumentListPolicy) { + templateArgumentListPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(templateArgumentListPolicy.get()); + }; + } + + void NamePolicy::CollectArrayIndicesHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::index] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + openEventMap[ParserState::expr] = [this](srcSAXEventContext &ctx) { + if(!expressionPolicy) { + expressionPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(expressionPolicy.get()); + }; + }; + } + +} diff --git a/src/policy_classes/NamePolicy.hpp b/src/policy_classes/NamePolicy.hpp new file mode 100644 index 0000000..4047f44 --- /dev/null +++ b/src/policy_classes/NamePolicy.hpp @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file NamePolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_NAME_POLICY_HPP +#define INCLUDED_NAME_POLICY_HPP + +#include +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + class ExpressionPolicy; + struct ExpressionData; + + class GenericArgumentsPolicy; + struct GenericArgumentsData; + + struct NameData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement name; + std::vector> names; + DeltaElement> templateArgumentList; + std::vector>> indices; + + std::string SimpleName() const; + std::shared_ptr copyAs(srcDispatch::DiffOperation operation) const; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const; + }; + + class NamePolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + NameData data; + + std::unique_ptr namePolicy; + std::unique_ptr operatorPolicy; + std::unique_ptr templateArgumentListPolicy; + std::unique_ptr expressionPolicy; + + public: + NamePolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeNamePolicyHandlers(); + } + + ~NamePolicy(); + + protected: + std::any DataInner() const override { return std::make_shared(data); } + virtual void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override; + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + private: + void InitializeNamePolicyHandlers(); + void CollectOperatorsHandlers(); + void CollectGenericArgumentsHandlers(); + void CollectArrayIndicesHandlers(); + }; + +} + +#endif diff --git a/src/policy_classes/NamePolicySingleEvent.cpp b/src/policy_classes/NamePolicySingleEvent.cpp deleted file mode 100644 index ad16889..0000000 --- a/src/policy_classes/NamePolicySingleEvent.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/** - * @file NamePolicySingleEvent.cpp - * - * MODIFIED from srcSAXEventDispatcher - * This collects the expression in the index - * - */ -#include - -std::string NameData::SimpleName() const { - if (!name.empty()) - return name; - return names.back()->SimpleName(); -} - - -std::string NameData::ToString() const { - std::string str = name; - for(std::size_t pos = 0; pos < names.size(); ++pos) { - if (pos != 0) - str += ' '; - str += names[pos]->ToString(); - } - return str; -} - - -std::ostream & operator<<(std::ostream & out, const NameData & nameData) { - if (!nameData.name.empty()) { - out << nameData.name; - } - for (size_t pos = 0; pos < nameData.names.size(); ++pos) { - if (pos != 0) out << "::"; - out << (*nameData.names[pos]); - } - if (!nameData.templateArguments.empty()) { - out << '<'; - for(const std::shared_ptr arg : nameData.templateArguments) { - out << *arg; - } - out << '>'; - } - if (nameData.indices) { - out << '[' << *nameData.indices << ']'; - } - return out; -} - -NamePolicy::~NamePolicy() { - if (namePolicy) delete namePolicy; - if (expressionPolicy) delete expressionPolicy; - if (templateArgumentPolicy) delete templateArgumentPolicy; -} - - -void NamePolicy::Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) { - if (typeid(NamePolicy) == typeid(*policy)) { - data.names.push_back(policy->Data()); - ctx.dispatcher->RemoveListener(nullptr); - } else if (typeid(TemplateArgumentPolicy) == typeid(*policy)) { - data.templateArguments.push_back(policy->Data()); - ctx.dispatcher->RemoveListener(nullptr); - } else if (typeid(ExpressionPolicy) == typeid(*policy)) { - data.indices = policy->Data(); - ctx.dispatcher->RemoveListener(nullptr); - } - -} - - -void NamePolicy::InitializeNamePolicyHandlers() { - using namespace srcSAXEventDispatch; - // start of policy - openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - if (!nameDepth) { - nameDepth = ctx.depth; - data = NameData{}; - data.lineNumber = ctx.currentLineNumber; - CollectTemplateArgumentsHandlers(); - CollectArrayIndicesHandlers(); - } else if ((nameDepth + 1) == ctx.depth) { - NopCloseEvents({ParserState::tokenstring}); - if (!namePolicy) namePolicy = new NamePolicy{this}; - ctx.dispatcher->AddListenerDispatch(namePolicy); - } - }; - // end of policy - closeEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - if (nameDepth && nameDepth == ctx.depth) { - nameDepth = 0; - NotifyAll(ctx); - InitializeNamePolicyHandlers(); - } - }; - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - if (nameDepth && nameDepth == ctx.depth) { - data.name += ctx.currentToken; - } - }; -} - - -void NamePolicy::CollectTemplateArgumentsHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::genericargumentlist] = [this](srcSAXEventContext& ctx) { - if (nameDepth && (nameDepth + 1) == ctx.depth) { - openEventMap[ParserState::argument] = [this](srcSAXEventContext& ctx) { - if (nameDepth && (nameDepth + 2) == ctx.depth) { - if (!templateArgumentPolicy) templateArgumentPolicy = new TemplateArgumentPolicy{this}; - ctx.dispatcher->AddListenerDispatch(templateArgumentPolicy); - } - }; - } - }; - closeEventMap[ParserState::genericargumentlist] = [this](srcSAXEventContext& ctx) { - if (nameDepth && (nameDepth + 1) == ctx.depth) { - NopOpenEvents({ParserState::argument}); - } - }; -} - - -void NamePolicy::CollectArrayIndicesHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::index] = [this](srcSAXEventContext& ctx) { - if(!expressionPolicy) expressionPolicy = new ExpressionPolicy{this}; - ctx.dispatcher->AddListenerDispatch(expressionPolicy); - }; -} - diff --git a/src/policy_classes/NamePolicySingleEvent.hpp b/src/policy_classes/NamePolicySingleEvent.hpp deleted file mode 100644 index 039cc1e..0000000 --- a/src/policy_classes/NamePolicySingleEvent.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @file NamePolicySingleEvent.hpp - * - * MODIFIED from srcSAXEventDispatcher - * This collects the expression in the index - * - */ -#ifndef INCLUDED_NAME_POLICY_SINGLE_EVENT_HPP -#define INCLUDED_NAME_POLICY_SINGLE_EVENT_HPP - -#include - -#include -#include - -#include -#include -#include - -struct ExpressionData; -class ExpressionPolicy; - -struct TemplateArgumentData; -class TemplateArgumentPolicy; - - -struct NameData { - - unsigned int lineNumber; - std::string name; - std::vector> names; - std::vector> templateArguments; - std::shared_ptr indices; - - std::string SimpleName() const; - std::string ToString() const; - friend std::ostream & operator<<(std::ostream & out, const NameData & nameData); -}; - - -class NamePolicy : -public srcSAXEventDispatch::EventListener, -public srcSAXEventDispatch::PolicyDispatcher, -public srcSAXEventDispatch::PolicyListener { - -private: - NameData data; - std::size_t nameDepth; - NamePolicy *namePolicy; - TemplateArgumentPolicy *templateArgumentPolicy; - ExpressionPolicy *expressionPolicy; - -public: - NamePolicy(std::initializer_list listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - nameDepth(0), - namePolicy(nullptr), - expressionPolicy(nullptr), - templateArgumentPolicy(nullptr) { - InitializeNamePolicyHandlers(); - } - - ~NamePolicy(); - -protected: - - std::any DataInner() const override { return std::make_shared(data); } - virtual void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override; - void NotifyWrite(const PolicyDispatcher * policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers - -private: - void InitializeNamePolicyHandlers(); - void CollectTemplateArgumentsHandlers(); - void CollectArrayIndicesHandlers(); -}; - -#endif diff --git a/src/policy_classes/OperatorPolicy.hpp b/src/policy_classes/OperatorPolicy.hpp new file mode 100644 index 0000000..f509b1e --- /dev/null +++ b/src/policy_classes/OperatorPolicy.hpp @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file OperatorPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_OPERATOR_POLICY_HPP +#define INCLUDED_OPERATOR_POLICY_HPP + +#include +#include +#include +#include + +#include +#include + +namespace srcDispatch { + + struct OperatorData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement op; + + std::shared_ptr copyAs(srcDispatch::DiffOperation operation) const { + std::shared_ptr data = std::make_shared(); + data->op = DeltaElement(operation, op.GetElement()); + return data; + } + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + return op.ToString(operation); + } + }; + + class OperatorPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + OperatorData data; + + public: + OperatorPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeOperatorPolicyHandlers(); + } + + ~OperatorPolicy() {} + + protected: + std::any DataInner() const override { return std::make_shared(data); } + void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override {} + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + private: + void InitializeOperatorPolicyHandlers() { + using namespace srcDispatch; + + openEventMap[ParserState::op] = [this](srcSAXEventContext& ctx) { + if(depth) return; + + depth = ctx.depth; + data = OperatorData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectTokenHandlers(); + }; + + // end of policy + closeEventMap[ParserState::op] = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeOperatorPolicyHandlers(); + }; + } + + void CollectTokenHandlers() { + using namespace srcDispatch; + closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { + if(data.op.GetOperation() == srcDispatch::NONE) { + bool isChange = (ctx.depth + 1) == ctx.diffStack.back().depth && ctx.diffStack.back().isReplace; + srcDispatch::DiffOperation operation = isChange? CHANGE : ctx.diffStack.back().operation; + data.op = DeltaElement(operation); + } + + if( ctx.diffStack.back().operation == srcDispatch::COMMON + || ctx.diffStack.back().operation == srcDispatch::DELETE) { + data.op.GetOriginal() += ctx.currentToken; + } else if(ctx.diffStack.back().operation == srcDispatch::INSERT) { + data.op.GetModified() += ctx.currentToken; + } + }; + } + }; + +} + +#endif diff --git a/src/policy_classes/ParamTypePolicy.hpp b/src/policy_classes/ParamTypePolicy.hpp deleted file mode 100644 index 5be1090..0000000 --- a/src/policy_classes/ParamTypePolicy.hpp +++ /dev/null @@ -1,134 +0,0 @@ -/** - * @file ParamTypePolicy.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef INCLUDED_PARAM_TYPE_POLICY_HPP -#define INCLUDED_PARAM_TYPE_POLICY_HPP - -#include -#include -#include -#include -class ParamTypePolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - ParamTypePolicy(std::initializer_list listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners){ - InitializeEventHandlers(); - } - ~ParamTypePolicy(){} - - void Notify(const PolicyDispatcher * policy [[maybe_unused]], const srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} - void NotifyWrite(const PolicyDispatcher * policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers - protected: - std::any DataInner() const override { - return std::make_shared(data); - } - private: - DeclData data; - std::string currentTypeName, currentDeclName, currentModifier, currentSpecifier; - - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - openEventMap[ParserState::op] = [this](srcSAXEventContext& ctx){ - if(ctx.And({ParserState::type, ParserState::parameter}) && ctx.Nor({ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist})){ - data.namespaces.push_back(ctx.currentToken); - } - }; - - openEventMap[ParserState::index] = [this](srcSAXEventContext& ctx [[maybe_unused]]){ - data.usesSubscript = true; - }; - - closeEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx){ - if(ctx.IsOpen(ParserState::parameter)){ - if(currentModifier == "*"){ - data.isPointer = true; - } - else if(currentModifier == "&"){ - data.isReference = true; - } - } - }; - - closeEventMap[ParserState::decl] = [this](srcSAXEventContext& ctx){ - if(ctx.And({ParserState::parameter})){ - data.lineNumber = ctx.currentLineNumber; - data.nameOfIdentifier = currentDeclName; - } - }; - - closeEventMap[ParserState::type] = [this](srcSAXEventContext& ctx){ - if(ctx.And({ParserState::parameter})){ - data.nameOfType = currentTypeName; - currentTypeName.clear(); - } - }; - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx){ - //TODO: possibly, this if-statement is suppressing more than just unmarked whitespace. Investigate. - if(!(ctx.currentToken.empty() || ctx.currentToken[0] == ' ')){ - - if(ctx.And({ParserState::name, ParserState::type, ParserState::decl, ParserState::parameter}) && ctx.Nor({ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist, ParserState::index})){ - currentTypeName = ctx.currentToken; // parameter data type - } - if(ctx.And({ParserState::name, ParserState::decl, ParserState::parameter}) && - ctx.Nor({ParserState::type, ParserState::index/*skip array portion*/, ParserState::argumentlist/*skip init list portion*/, - ParserState::init, ParserState::specifier, ParserState::modifier, ParserState::genericargumentlist})){ - currentDeclName = ctx.currentToken; // parameter variable name - } - if(ctx.And({ParserState::specifier, ParserState::decl, ParserState::parameter})){ - currentSpecifier = ctx.currentToken; - } - if(ctx.And({ParserState::modifier, ParserState::type, ParserState::parameter})){ - currentModifier = ctx.currentToken; - } - } - }; - closeEventMap[ParserState::parameter] = [this](srcSAXEventContext& ctx){ - data.isParameter = true; - data.nameOfContainingFunction = ctx.currentFunctionName; - data.nameOfContainingFile = ctx.currentFilePath; - if (ctx.currentFileLanguage == "Java" && !data.isFinal){ - data.isReference = true; - } - NotifyAll(ctx); - data.clear(); - }; - closeEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx){ - if(ctx.IsOpen(ParserState::parameter)){ - if(currentSpecifier == "const"){ - if(data.isPointer){ - data.isConstAlias = true; - }else{ - data.isConstValue = true; - } - } - if(currentSpecifier == "final"){ - data.isFinal = true; - } - if(currentSpecifier == "static"){ - data.isStatic = true; - } - } - currentSpecifier.clear(); - }; - - } -}; - -#endif - diff --git a/src/policy_classes/ParamTypePolicySingleEvent.hpp b/src/policy_classes/ParamTypePolicySingleEvent.hpp deleted file mode 100644 index d945470..0000000 --- a/src/policy_classes/ParamTypePolicySingleEvent.hpp +++ /dev/null @@ -1,121 +0,0 @@ -/** - * @file ParamTypePolicySingleEvent.hpp - * - */ - -#ifndef INCLUDED_PARAM_TYPE_POLICY_SINGLE_EVENT_HPP -#define INCLUDED_PARAM_TYPE_POLICY_SINGLE_EVENT_HPP - - -#include - -#include -#include - -#include -#include - -struct ParamTypeData { - - unsigned int lineNumber; - std::shared_ptr type; - std::shared_ptr name; - - friend std::ostream & operator<<(std::ostream& out, const ParamTypeData& paramData) { - out << *paramData.type; - if (paramData.name) - out << ' ' << *paramData.name; - return out; - } -}; - - -class ParamTypePolicy : -public srcSAXEventDispatch::EventListener, -public srcSAXEventDispatch::PolicyDispatcher, -public srcSAXEventDispatch::PolicyListener { - -private: - ParamTypeData data; - std::size_t paramDepth; - TypePolicy* typePolicy; - NamePolicy* namePolicy; - -public: - ParamTypePolicy(std::initializer_list listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - paramDepth(0), - typePolicy(nullptr), - namePolicy(nullptr) { - - InitializeParamTypePolicyHandlers(); - } - - ~ParamTypePolicy() { - if (typePolicy) delete typePolicy; - if (namePolicy) delete namePolicy; - - } - -protected: - std::any DataInner() const override { return std::make_shared(data); } - - virtual void Notify(const PolicyDispatcher* policy, const srcSAXEventDispatch::srcSAXEventContext& ctx) override { - if (typeid(TypePolicy) == typeid(*policy)) { - data.type = policy->Data(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - } else if (typeid(NamePolicy) == typeid(*policy)) { - data.name = policy->Data(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - } - } - - void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} //doesn't use other parsers - -private: - void InitializeParamTypePolicyHandlers() { - using namespace srcSAXEventDispatch; - // start of policy - openEventMap[ParserState::parameter] = [this](srcSAXEventContext& ctx) { - if (!paramDepth) { - paramDepth = ctx.depth; - data = ParamTypeData{}; - data.lineNumber = ctx.currentLineNumber; - CollectTypeHandlers(); - CollectNameHandlers(); - } - }; - - // end of policy - closeEventMap[ParserState::parameter] = [this](srcSAXEventContext& ctx) { - if (paramDepth && paramDepth == ctx.depth) { - paramDepth = 0; - NotifyAll(ctx); - InitializeParamTypePolicyHandlers(); - } - }; - } - - void CollectTypeHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::type] = [this](srcSAXEventContext& ctx) { - if (paramDepth && (paramDepth + 2) == ctx.depth) { - if (!typePolicy) typePolicy = new TypePolicy{this}; - ctx.dispatcher->AddListenerDispatch(typePolicy); - } - }; - } - - void CollectNameHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - if (paramDepth && (paramDepth + 2) == ctx.depth) { - if (!namePolicy) namePolicy = new NamePolicy{this}; - ctx.dispatcher->AddListenerDispatch(namePolicy); - } - }; - } -}; - -#endif diff --git a/src/policy_classes/ReturnPolicy.hpp b/src/policy_classes/ReturnPolicy.hpp index 5f891d5..1bbb4e7 100644 --- a/src/policy_classes/ReturnPolicy.hpp +++ b/src/policy_classes/ReturnPolicy.hpp @@ -1,44 +1,51 @@ -#include -#include -#include -#include +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file ReturnPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_RETURN_POLICY_HPP +#define INCLUDED_RETURN_POLICY_HPP + +#include +#include +#include +#include +#include + +#include #include -#include -#ifndef RETURNPOLICY -#define RETURNPOLICY -class ReturnPolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - public: +#include - ReturnPolicy(std::initializer_list listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners){ - InitializeEventHandlers(); - } - ~ReturnPolicy(){} +namespace srcDispatch { - void Notify(const PolicyDispatcher * policy [[maybe_unused]], const srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} // doesn't use other parsers - void NotifyWrite(const PolicyDispatcher * policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} // doesn't use other parsers + struct ReturnData { - void ClearCollection() { returnUses.clear(); } + DeltaElement startLineNumber; + DeltaElement endLineNumber; - std::unordered_map>* GetReturnUses() { - return &returnUses; - } - protected: - std::any DataInner() const override {} - + DeltaElement> expr; + + template + friend class DeltaElement; private: - std::unordered_map> returnUses; // variablename | line number + std::string ToString(srcDispatch::DiffOperation operation) const { + return expr.ToString(operation); + } + }; + + // Collect the expression in the return + class ReturnPolicy : public ExprTypePolicy { + public: + ReturnPolicy(std::initializer_list listeners) + : ExprTypePolicy(listeners) { + } - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - - closeEventMap[ParserState::name] = [this](srcSAXEventContext &ctx) { - if(ctx.IsOpen({ParserState::returnstmt}) && ctx.IsClosed({ParserState::comment})){ - returnUses[ctx.currentToken].insert(ctx.currentLineNumber); + }; - NotifyAll(ctx); - } - }; +} - } -}; -#endif \ No newline at end of file +#endif diff --git a/src/policy_classes/ReturnPolicySingleEvent.hpp b/src/policy_classes/ReturnPolicySingleEvent.hpp deleted file mode 100644 index f5c1ba4..0000000 --- a/src/policy_classes/ReturnPolicySingleEvent.hpp +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @file ReturnPolicySingleEvent.hpp - * - * - */ -#ifndef INCLUDED_RETURN_POLICY_SINGLE_EVENT_HPP -#define INCLUDED_RETURN_POLICY_SINGLE_EVENT_HPP - -#include -#include -#include - -#include - -#include -#include -#include - - -// Collect the expression in the return -// -class ReturnPolicy : -public srcSAXEventDispatch::EventListener, -public srcSAXEventDispatch::PolicyDispatcher, -public srcSAXEventDispatch::PolicyListener { - -private: - std::shared_ptr data; - std::size_t returnDepth; - ExpressionPolicy* exprPolicy; - -public: - ReturnPolicy(std::initializer_list listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - returnDepth(0), - exprPolicy(nullptr) { - InitializeReturnPolicyHandlers(); - } - - ~ReturnPolicy() { - if (exprPolicy) delete exprPolicy; - } - -protected: - std::any DataInner() const override { return data; } - - virtual void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - if (typeid(ExpressionPolicy) == typeid(*policy)) { - data = policy->Data(); - ctx.dispatcher->RemoveListener(nullptr); - } - } - - void NotifyWrite(const PolicyDispatcher * policy, srcSAXEventDispatch::srcSAXEventContext & ctx) override {} //doesn't use other parsers - -private: - void InitializeReturnPolicyHandlers() { - using namespace srcSAXEventDispatch; - // start of policy - openEventMap[ParserState::returnstmt] = [this](srcSAXEventContext& ctx) { - if (!returnDepth) { - returnDepth = ctx.depth; - data = std::shared_ptr(); - CollectExpressionHandlers(); - } - }; - - // end of policy - closeEventMap[ParserState::returnstmt] = [this](srcSAXEventContext& ctx) { - if (returnDepth && returnDepth == ctx.depth) { - returnDepth = 0; - NotifyAll(ctx); - InitializeReturnPolicyHandlers(); - } - }; - } - - void CollectExpressionHandlers() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::expr] = [this](srcSAXEventContext& ctx) { - if (!exprPolicy) exprPolicy = new ExpressionPolicy{this}; - ctx.dispatcher->AddListenerDispatch(exprPolicy); - }; - } - -}; - -#endif diff --git a/src/policy_classes/SNLPolicy.hpp b/src/policy_classes/SNLPolicy.hpp deleted file mode 100644 index 5c6a651..0000000 --- a/src/policy_classes/SNLPolicy.hpp +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file SNLPolicy.hpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include - -#ifndef SOURCENLPOLICY -#define SOURCENLPOLICY -class SourceNLPolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - public: - struct SourceNLData{ - SourceNLData(){} - void clear(){ - category.clear(); - identifiername.clear(); - } - std::string category; - std::string identifiername; - }; - SourceNLData data; - ~SourceNLPolicy(){} - SourceNLPolicy(std::initializer_list listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners){ - InitializeEventHandlers(); - } - void Notify(const PolicyDispatcher * policy [[maybe_unused]], const srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers - void NotifyWrite(const PolicyDispatcher * policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers - protected: - void * DataInner() const override { - return new SourceNLData(data); - } - private: - std::string currentTypeName, currentDeclName, currentModifier, currentSpecifier; - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - closeEventMap[ParserState::snoun] = [this](srcSAXEventContext& ctx){ - //std::cerr< -#include -#include -#include -#include -#include - -#ifndef STEREOTYPEPOLICY -#define STEREOTYPEPOLICY -class StereotypePolicy : public srcSAXEventDispatch::EventListener, public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener { - public: - struct StereotypeData{ - StereotypeData() {} - void clear(){stereotypes.clear();} - std::vector stereotypes; - }; - ~StereotypePolicy(){} - StereotypePolicy(std::initializer_list listeners = {}): srcSAXEventDispatch::PolicyDispatcher(listeners){ - InitializeEventHandlers(); - } - void Notify(const PolicyDispatcher * policy [[maybe_unused]], const srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers - void NotifyWrite(const PolicyDispatcher * policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override {} //doesn't use other parsers - protected: - void * DataInner() const override { - return new StereotypeData(data); - } - private: - StereotypeData data; - std::string currentStereotype; - void InitializeEventHandlers(){ - using namespace srcSAXEventDispatch; - closeEventMap[ParserState::stereotype] = [this](srcSAXEventContext& ctx){ - std::string word; - for(char ch : currentStereotype){ - switch(ch){ - //it's a space, so push back stereotype and clear word - case ' ':{ - data.stereotypes.push_back(word); - word.clear(); - break; - } - //it's the end of the string, so push back whatever is in word - case 0:{ - data.stereotypes.push_back(word); - break; - } - //append ch to word and keep going - default:{ - if(std::isalnum(ch)){ - word+=ch; - } - break; - } - } - } - NotifyAll(ctx); - data.clear(); - }; - - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx){ - //TODO: possibly, this if-statement is suppressing more than just unmarked whitespace. Investigate. - if(!(ctx.currentToken.empty() || ctx.currentToken == " ")){ - if(ctx.IsOpen(ParserState::stereotype)){ - currentStereotype = ctx.currentToken; - } - } - }; - } -}; -#endif \ No newline at end of file diff --git a/src/policy_classes/SwitchPolicy.hpp b/src/policy_classes/SwitchPolicy.hpp new file mode 100644 index 0000000..910479a --- /dev/null +++ b/src/policy_classes/SwitchPolicy.hpp @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file SwitchPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_SWITCH_POLICY_HPP +#define INCLUDED_SWITCH_POLICY_HPP + +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + struct SwitchData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement> condition; + DeltaElement> block; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + return condition.ToString(operation); + } + }; + + class SwitchPolicy : public ConditionalPolicy { + public: + SwitchPolicy(std::initializer_list listeners) + : ConditionalPolicy(listeners) {} + }; + +} + +#endif diff --git a/src/policy_classes/TemplateArgumentPolicySingleEvent.cpp b/src/policy_classes/TemplateArgumentPolicySingleEvent.cpp deleted file mode 100644 index b2de4bb..0000000 --- a/src/policy_classes/TemplateArgumentPolicySingleEvent.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/** - * @file TemplateArgumentPolicySingleEvent.cpp - * - */ -#include - -std::ostream & operator<<(std::ostream & out, const TemplateArgumentData & argumentData) { - for(std::size_t pos = 0; pos < argumentData.data.size(); ++pos) { - if (pos != 0) - out << ' '; - const std::pair & element = argumentData.data[pos]; - if (element.second == TemplateArgumentData::NAME) - out << *std::any_cast>(element.first); - else if (element.second == TemplateArgumentData::POINTER) - out << '*'; - else if (element.second == TemplateArgumentData::REFERENCE) - out << '&'; - else if (element.second == TemplateArgumentData::RVALUE) - out << "&&"; - else - out << *std::any_cast>(element.first); - } - - return out; -} - -TemplateArgumentPolicy::TemplateArgumentPolicy(std::initializer_list listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - argumentDepth(0), - namePolicy(nullptr) { - InitializeTemplateArgumentPolicyHandlers(); -} - -TemplateArgumentPolicy::~TemplateArgumentPolicy() { - if (namePolicy) delete namePolicy; -} - -void TemplateArgumentPolicy::Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) { - data.data.back().first = policy->Data(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); -} - -void TemplateArgumentPolicy::NotifyWrite(const PolicyDispatcher * policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]){} - -std::any TemplateArgumentPolicy::DataInner() const { - return std::make_shared(data); -} - -void TemplateArgumentPolicy::InitializeTemplateArgumentPolicyHandlers() { - using namespace srcSAXEventDispatch; - // start of policy - openEventMap[ParserState::argument] = [this](srcSAXEventContext& ctx) { - if (!argumentDepth) { - argumentDepth = ctx.depth; - data = TemplateArgumentData{}; - data.lineNumber = ctx.currentLineNumber; - CollectNamesHandler(); - CollectOthersHandler(); - } - }; - - // end of policy - closeEventMap[ParserState::argument] = [this](srcSAXEventContext& ctx) { - if (argumentDepth && argumentDepth == ctx.depth) { - argumentDepth = 0; - NotifyAll(ctx); - InitializeTemplateArgumentPolicyHandlers(); - } - }; -} - -void TemplateArgumentPolicy::CollectNamesHandler() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - // C++ has depth of 2 others 1 - std::size_t elementStackSize = ctx.elementStack.size(); - if (argumentDepth && - (((argumentDepth + 2) == ctx.depth && elementStackSize > 1 && ctx.elementStack[elementStackSize - 2] == "expr") - || (argumentDepth + 1) == ctx.depth)) { - data.data.push_back(std::make_pair(nullptr, TemplateArgumentData::NAME)); - if (!namePolicy) namePolicy = new NamePolicy{this}; - ctx.dispatcher->AddListenerDispatch(namePolicy); - } - }; -} - -void TemplateArgumentPolicy::CollectOthersHandler() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::literal] = [this](srcSAXEventContext& ctx) { - // C++ has depth of 2 others 1 - std::size_t elementStackSize = ctx.elementStack.size(); - if (argumentDepth && - (((argumentDepth + 2) == ctx.depth && elementStackSize > 1 && ctx.elementStack[elementStackSize - 2] == "expr") - || (argumentDepth + 1) == ctx.depth)) { - data.data.push_back(std::make_pair(std::make_shared(), TemplateArgumentData::LITERAL)); - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - (*std::any_cast>(data.data.back().first)) += ctx.currentToken; - }; - } - }; - - closeEventMap[ParserState::literal] = [this](srcSAXEventContext& ctx) { - if (argumentDepth && (((argumentDepth + 2) == ctx.depth && ctx.elementStack.back() == "expr") - || (argumentDepth + 1) == ctx.depth)) { - NopCloseEvents({ParserState::tokenstring}); - } - }; - - openEventMap[ParserState::op] = [this](srcSAXEventContext& ctx) { - // C++ has depth of 2 others 1 - std::size_t elementStackSize = ctx.elementStack.size(); - if (argumentDepth && - (((argumentDepth + 2) == ctx.depth && elementStackSize > 1 && ctx.elementStack[elementStackSize - 2] == "expr") - || (argumentDepth + 1) == ctx.depth)) { - data.data.push_back(std::make_pair(new std::string(), TemplateArgumentData::OPERATOR)); - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - (*std::any_cast>(data.data.back().first)) += ctx.currentToken; - }; - } - }; - - closeEventMap[ParserState::op] = [this](srcSAXEventContext& ctx) { - if (argumentDepth && (((argumentDepth + 2) == ctx.depth && ctx.elementStack.back() == "expr") - || (argumentDepth + 1) == ctx.depth)) { - NopCloseEvents({ParserState::tokenstring}); - } - }; - - openEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx) { - // C++ has depth of 2 others 1 - std::size_t elementStackSize = ctx.elementStack.size(); - if (argumentDepth && (((argumentDepth + 2) == ctx.depth && elementStackSize > 1 && ctx.elementStack[elementStackSize - 2] == "expr") - || (argumentDepth + 1) == ctx.depth)) { - data.data.push_back(std::make_pair(nullptr, TemplateArgumentData::MODIFIER)); - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - if (ctx.currentToken == "*") - data.data.back().second = TemplateArgumentData::POINTER; - else if (ctx.currentToken == "&") - data.data.back().second = TemplateArgumentData::REFERENCE; - else if (ctx.currentToken == "&&") - data.data.back().second = TemplateArgumentData::RVALUE; - }; - } - }; - - closeEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx) { - if (argumentDepth && (((argumentDepth + 2) == ctx.depth && ctx.elementStack.back() == "expr") - || (argumentDepth + 1) == ctx.depth)) { - NopCloseEvents({ParserState::tokenstring}); - } - }; - - openEventMap[ParserState::call] = [this](srcSAXEventContext& ctx) { - // C++ has depth of 2 others 1 - std::size_t elementStackSize = ctx.elementStack.size(); - if (argumentDepth && (((argumentDepth + 2) == ctx.depth && elementStackSize > 1 && ctx.elementStack[elementStackSize - 2] == "expr") - || (argumentDepth + 1) == ctx.depth)) { - data.data.push_back(std::make_pair(new std::string(), TemplateArgumentData::CALL)); - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - (*std::any_cast>(data.data.back().first)) += ctx.currentToken; - }; - } - }; - - closeEventMap[ParserState::call] = [this](srcSAXEventContext& ctx) { - if (argumentDepth && (((argumentDepth + 2) == ctx.depth && ctx.elementStack.back() == "expr") - || (argumentDepth + 1) == ctx.depth)) { - NopCloseEvents({ParserState::tokenstring}); - } - }; -} diff --git a/src/policy_classes/TemplateArgumentPolicySingleEvent.hpp b/src/policy_classes/TemplateArgumentPolicySingleEvent.hpp deleted file mode 100644 index cf7b46d..0000000 --- a/src/policy_classes/TemplateArgumentPolicySingleEvent.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @file TemplateArgumentPolicySingleEvent.hpp - * - */ -#ifndef INCLUDED_TEMPLATE1_ARGUMENT_POLICY_SINGLE_EVENT_HPP -#define INCLUDED_TEMPLATE1_ARGUMENT_POLICY_SINGLE_EVENT_HPP - -#include -#include - -class NamePolicy; - - -struct TemplateArgumentData { - enum TemplateArgumentType { NAME, LITERAL, MODIFIER, POINTER, REFERENCE, RVALUE, OPERATOR, CALL }; - - unsigned int lineNumber; - std::vector> data; - friend std::ostream & operator<<(std::ostream & out, const TemplateArgumentData & argumentData); -}; - - -class TemplateArgumentPolicy : -public srcSAXEventDispatch::EventListener, -public srcSAXEventDispatch::PolicyDispatcher, -public srcSAXEventDispatch::PolicyListener { - -public: - TemplateArgumentPolicy(std::initializer_list listeners); - ~TemplateArgumentPolicy(); - virtual void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override; - virtual void NotifyWrite(const PolicyDispatcher * policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]) override; - -protected: - virtual std::any DataInner() const override; - -private: - void InitializeTemplateArgumentPolicyHandlers(); - void CollectNamesHandler(); - void CollectOthersHandler(); - -private: - TemplateArgumentData data; - std::size_t argumentDepth; - NamePolicy * namePolicy; - -}; - -#endif diff --git a/src/policy_classes/ThrowPolicy.hpp b/src/policy_classes/ThrowPolicy.hpp new file mode 100644 index 0000000..0206288 --- /dev/null +++ b/src/policy_classes/ThrowPolicy.hpp @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file ThrowPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_THROW_POLICY_HPP +#define INCLUDED_THROW_POLICY_HPP + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + struct ThrowData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement> expr; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + return expr.ToString(operation); + } + }; + + // Collect the expression in the return + class ThrowPolicy : public ExprTypePolicy { + public: + ThrowPolicy(std::initializer_list listeners) + : ExprTypePolicy(listeners) { + } + + }; + +} + +#endif diff --git a/src/policy_classes/TryPolicy.hpp b/src/policy_classes/TryPolicy.hpp new file mode 100644 index 0000000..5538387 --- /dev/null +++ b/src/policy_classes/TryPolicy.hpp @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file TryPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_TRY_POLICY_HPP +#define INCLUDED_TRY_POLICY_HPP + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + struct TryData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement> block; + std::vector> clauses; + }; + + class TryPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + TryData data; + + std::unique_ptr blockPolicy; + std::unique_ptr catchPolicy; + + public: + TryPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeTryPolicyHandlers(); + } + + ~TryPolicy() {} + + protected: + std::any DataInner() const { return std::make_shared(data); } + + void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) { + if(typeid(BlockPolicy) == typeid(*policy)) { + data.block.Update(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(CatchPolicy) == typeid(*policy)) { + data.clauses.push_back(DeltaElement(ctx.diffStack.back().operation, policy->Data())); + } else { + throw srcDispatch::PolicyError(std::string("Unhandled Policy '") + typeid(*policy).name() + '\''); + } + + ctx.dispatcher->RemoveListener(nullptr); + } + + void NotifyWrite(const PolicyDispatcher* policy, srcDispatch::srcSAXEventContext& ctx) {} // doesn't use other parsers + + private: + void InitializeTryPolicyHandlers() { + using namespace srcDispatch; + + openEventMap[ParserState::trystmt] = [this](srcSAXEventContext &ctx) { + if(depth) return; + + depth = ctx.depth; + data = TryData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectBlockHandlers(); + CollectCatchHandlers(); + }; + + // end of policy + closeEventMap[ParserState::trystmt] = [this](srcSAXEventContext &ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeTryPolicyHandlers(); + }; + } + + void CollectBlockHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::block] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + if(!blockPolicy) { + blockPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(blockPolicy.get()); + }; + } + + void CollectCatchHandlers() { + using namespace srcDispatch; + openEventMap[ParserState::catchstmt] = [this](srcSAXEventContext &ctx) { + if(!depth) return; + + if(!catchPolicy) { + catchPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(catchPolicy.get()); + }; + } + + }; + +} + +#endif diff --git a/src/policy_classes/TypePolicy.cpp b/src/policy_classes/TypePolicy.cpp new file mode 100644 index 0000000..e982742 --- /dev/null +++ b/src/policy_classes/TypePolicy.cpp @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file TypePolicy.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#include +#include +#include +#include + +namespace srcDispatch { + + std::string TypeData::ToString(srcDispatch::DiffOperation operation) const { + std::string str; + bool printSpace = false; + for (const std::pair, DeltaElement>& type : types) { + + bool outputRaw = type.second.IsOfOperation(operation); + if(outputRaw) { + if(printSpace) { + str += ' '; + } + printSpace = true; + } + + TypeData::TypeType outputsType = ((operation == srcDispatch::DELETE && type.second.HasOriginal()) || !type.second.HasModified())? type.second.GetOriginal() : type.second.GetModified(); + if(outputRaw && outputsType == TypeData::POINTER) { + str += '*'; + } else if(outputRaw && outputsType == TypeData::REFERENCE) { + str += '&'; + } else if(outputRaw && outputsType == TypeData::RVALUE) { + str += "&&"; + } else if(outputsType == TypeData::SPECIFIER) { + str += type.first.ToString>(operation); + } else if(outputsType == TypeData::TYPENAME) { + str += type.first.ToString>(operation); + } + + } + return str; + } + + std::shared_ptr TypeData::copyAs(srcDispatch::DiffOperation operation) const { + std::shared_ptr data = std::make_shared(); + data->startLineNumber = startLineNumber; + data->endLineNumber = endLineNumber; + + for(const std::pair, DeltaElement>& type : types) { + DeltaElement typeAny; + if(type.second.GetElement() == TypeData::SPECIFIER) { + typeAny = DeltaElement(operation, std::any_cast>(type.first)); + } else if(type.second.GetElement() == TypeData::TYPENAME) { + typeAny = DeltaElement(operation, std::any_cast>(type.first.GetElement())->copyAs(operation)); + } + data->types.emplace_back(typeAny, DeltaElement(operation, type.second.GetElement())); + } + return data; + } + + + TypePolicy::TypePolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), data{} { + InitializeTypePolicyHandlers(); + } + + TypePolicy::~TypePolicy() {} + + void TypePolicy::Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) { + data.types.push_back(std::make_pair(DeltaElement(ctx.diffStack.back().operation, policy->Data()), DeltaElement(ctx.diffStack.back().operation, TypeData::TYPENAME))); + ctx.dispatcher->RemoveListenerDispatch(nullptr); + } + + std::any TypePolicy::DataInner() const { + return std::make_shared(data); + } + + void TypePolicy::InitializeTypePolicyHandlers() { + using namespace srcDispatch; + // start of policy + openEventMap[ParserState::type] = [this](srcSAXEventContext& ctx) { + if(depth) return; + + depth = ctx.depth; + data = TypeData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + CollectNamesHandler(); + CollectModifersHandler(); + CollectSpecifiersHandler(); + }; + + // end of policy + closeEventMap[ParserState::type] = [this](srcSAXEventContext& ctx) { + if(!depth || depth != ctx.depth) return; + + depth = 0; + NotifyAll(ctx); + InitializeTypePolicyHandlers(); + }; + } + + void TypePolicy::CollectNamesHandler() { + using namespace srcDispatch; + openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + if(!namePolicy) { + namePolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(namePolicy.get()); + }; + } + + void TypePolicy::CollectModifersHandler() { + using namespace srcDispatch; + openEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx) + { + if(!depth) return; + + data.types.push_back(std::make_pair(DeltaElement(), DeltaElement(ctx.diffStack.back().operation, TypeData::NONE))); + closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { + TypeData::TypeType modifier = TypeData::NONE; + if(ctx.currentToken == "*") { + modifier = TypeData::POINTER; + } else if(ctx.currentToken == "&") { + modifier = TypeData::REFERENCE; + } else if(ctx.currentToken == "&&") { + modifier = TypeData::RVALUE; + } + + data.types.back().second.Update(ctx.diffStack.back().operation, modifier); + }; + }; + + closeEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + NopCloseEvents({ParserState::tokenstring}); + }; + } + + void TypePolicy::CollectSpecifiersHandler() { + using namespace srcDispatch; + openEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + data.types.push_back(std::make_pair(DeltaElement(ctx.diffStack.back().operation, std::make_shared("")), DeltaElement(ctx.diffStack.back().operation, TypeData::SPECIFIER))); + closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { + data.types.back().first.Append>(ctx.diffStack.back().operation, ctx.currentToken); + }; + }; + + closeEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx) { + if(!depth) return; + + NopCloseEvents({ParserState::tokenstring}); + }; + } + +} diff --git a/src/policy_classes/TypePolicy.hpp b/src/policy_classes/TypePolicy.hpp new file mode 100644 index 0000000..1900a14 --- /dev/null +++ b/src/policy_classes/TypePolicy.hpp @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file TypePolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_TYPE_POLICY_HPP +#define INCLUDED_TYPE_POLICY_HPP + +#include +#include +#include + +#include + +namespace srcDispatch { + + class NamePolicy; + + struct TypeData { + enum TypeType : int { TYPENAME, POINTER, REFERENCE, RVALUE, SPECIFIER, NONE }; + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + std::vector, DeltaElement>> types; + + std::shared_ptr copyAs(srcDispatch::DiffOperation operation) const; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const; + }; + + class TypePolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + private: + TypeData data; + + std::unique_ptr namePolicy; + + public: + TypePolicy(std::initializer_list listeners); + ~TypePolicy(); + virtual void Notify(const PolicyDispatcher* policy, const srcDispatch::srcSAXEventContext& ctx) override; + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + protected: + virtual std::any DataInner() const override; + + private: + void InitializeTypePolicyHandlers(); + void CollectNamesHandler(); + void CollectModifersHandler(); + void CollectSpecifiersHandler(); + }; +} + +#endif diff --git a/src/policy_classes/TypePolicySingleEvent.cpp b/src/policy_classes/TypePolicySingleEvent.cpp deleted file mode 100644 index 82c930e..0000000 --- a/src/policy_classes/TypePolicySingleEvent.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/** - * @file TypePolicySingleEvent.cpp - * - */ - -#include - -std::string TypeData::ToString() const { - std::string type_str; - for (std::size_t pos = 0; pos < types.size(); ++pos) { - if (pos != 0) type_str += ' '; - const std::pair & type = types[pos]; - if (type.second == TypeData::POINTER) - type_str += '*'; - else if (type.second == TypeData::REFERENCE) - type_str += '&'; - else if (type.second == TypeData::RVALUE) - type_str += "&&"; - else if (type.second == TypeData::SPECIFIER) - type_str += *std::any_cast>(type.first); - else if (type.second == TypeData::TYPENAME) - type_str += std::any_cast>(type.first)->ToString(); - } - return type_str; -} - -std::ostream & operator<<(std::ostream & out, const TypeData & typeData) { - //std::cerr << "TPSE\n"; - //std::cerr << "TPSE Size: " << typeData.types.empty() << '\n'; - //std::cerr << "TACO\n"; - for(std::size_t pos = 0; pos < typeData.types.size(); ++pos) { - //std::cerr << "TPSE2\n"; - if (pos != 0) out << ' '; - const std::pair & type = typeData.types[pos]; - if (type.second == TypeData::POINTER) - out << '*'; - else if (type.second == TypeData::REFERENCE) - out << '&'; - else if (type.second == TypeData::RVALUE) - out << "&&"; - else if (type.second == TypeData::SPECIFIER) - out << *std::any_cast>(type.first); - else if (type.second == TypeData::TYPENAME) - out << *std::any_cast>(type.first); - } - return out; -} - -TypePolicy::TypePolicy(std::initializer_list listeners) - : srcSAXEventDispatch::PolicyDispatcher(listeners), - data{}, - typeDepth(0), - namePolicy(nullptr) { - - InitializeTypePolicyHandlers(); -} - -TypePolicy::~TypePolicy(){ - if (namePolicy) delete namePolicy; -} - -void TypePolicy::Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) { - //this causes undefined behavior if types is empty - data.types.back().first = policy->Data(); - ctx.dispatcher->RemoveListenerDispatch(nullptr); -} - -void TypePolicy::NotifyWrite(const PolicyDispatcher * policy [[maybe_unused]], srcSAXEventDispatch::srcSAXEventContext & ctx [[maybe_unused]]){} - -std::any TypePolicy::DataInner() const { - return std::make_shared(data); -} - -void TypePolicy::InitializeTypePolicyHandlers() { - using namespace srcSAXEventDispatch; - // start of policy - openEventMap[ParserState::type] = [this](srcSAXEventContext& ctx) { - if (!typeDepth) { - typeDepth = ctx.depth; - data = TypeData{}; - data.lineNumber = ctx.currentLineNumber; - CollectNamesHandler(); - CollectModifersHandler(); - CollectSpecifiersHandler(); - } - }; - - // end of policy - closeEventMap[ParserState::type] = [this](srcSAXEventContext& ctx) { - if (typeDepth && typeDepth == ctx.depth) { - typeDepth = 0; - NotifyAll(ctx); - InitializeTypePolicyHandlers(); - } - }; -} - -void TypePolicy::CollectNamesHandler() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::name] = [this](srcSAXEventContext& ctx) { - if (typeDepth && (typeDepth + 1) == ctx.depth) { - data.types.push_back(std::make_pair(nullptr, TypeData::TYPENAME)); - if (!namePolicy) namePolicy = new NamePolicy{this}; - ctx.dispatcher->AddListenerDispatch(namePolicy); - } - }; -} - -void TypePolicy::CollectModifersHandler() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx) { - if (typeDepth && (typeDepth + 1) == ctx.depth) { - data.types.push_back(std::make_pair(nullptr, TypeData::NONE)); - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - if (ctx.currentToken == "*") - data.types.back().second = TypeData::POINTER; - else if (ctx.currentToken == "&") - data.types.back().second = TypeData::REFERENCE; - else if (ctx.currentToken == "&&") - data.types.back().second = TypeData::RVALUE; - }; - } - }; - - closeEventMap[ParserState::modifier] = [this](srcSAXEventContext& ctx) { - if (typeDepth && (typeDepth + 1) == ctx.depth) { - NopCloseEvents({ParserState::tokenstring}); - } - }; -} - -void TypePolicy::CollectSpecifiersHandler() { - using namespace srcSAXEventDispatch; - openEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx) { - if (typeDepth && (typeDepth + 1) == ctx.depth) { - data.types.push_back(std::make_pair(std::make_shared(""), TypeData::SPECIFIER)); - closeEventMap[ParserState::tokenstring] = [this](srcSAXEventContext& ctx) { - (*std::any_cast>(data.types.back().first)) += ctx.currentToken; - }; - } - }; - - closeEventMap[ParserState::specifier] = [this](srcSAXEventContext& ctx) { - if (typeDepth && (typeDepth + 1) == ctx.depth) { - NopCloseEvents({ParserState::tokenstring}); - } - }; -} diff --git a/src/policy_classes/TypePolicySingleEvent.hpp b/src/policy_classes/TypePolicySingleEvent.hpp deleted file mode 100644 index 186d97a..0000000 --- a/src/policy_classes/TypePolicySingleEvent.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @file TypePolicySingleEvent.hpp - * - */ -#ifndef INCLUDED_TYPE1_POLICY_SINGLE_EVENT_HPP -#define INCLUDED_TYPE1_POLICY_SINGLE_EVENT_HPP - -#include - -#include - -#include - -class NamePolicy; - - -struct TypeData { - enum TypeType { TYPENAME, POINTER, REFERENCE, RVALUE, SPECIFIER, NONE }; - - unsigned int lineNumber; - std::vector> types; - std::string ToString() const; - friend std::ostream & operator<<(std::ostream & out, const TypeData & typeData); -}; - - -class TypePolicy : -public srcSAXEventDispatch::EventListener, -public srcSAXEventDispatch::PolicyDispatcher, -public srcSAXEventDispatch::PolicyListener { - -private: - TypeData data; - std::size_t typeDepth; - NamePolicy * namePolicy; - -public: - TypePolicy(std::initializer_list listeners); - ~TypePolicy(); - virtual void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override; - virtual void NotifyWrite(const PolicyDispatcher * policy, srcSAXEventDispatch::srcSAXEventContext & ctx) override; - -protected: - virtual std::any DataInner() const override; - -private: - void InitializeTypePolicyHandlers(); - void CollectNamesHandler(); - void CollectModifersHandler(); - void CollectSpecifiersHandler(); - -}; - -#endif diff --git a/src/policy_classes/UnitPolicy.hpp b/src/policy_classes/UnitPolicy.hpp new file mode 100644 index 0000000..5e361d8 --- /dev/null +++ b/src/policy_classes/UnitPolicy.hpp @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file UnitPolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + * + * Policy for srcDispatch + * Listens for both classes and functions + * Calls the ClassPolicy for class + * Calls the FunctionPolicy for function + * + */ +#ifndef INCLUDED_UNIT_POLICY_HPP +#define INCLUDED_UNIT_POLICY_HPP + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace srcDispatch { + + struct UnitData { + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + std::vector>> classInfo; + std::vector>> functionInfo; + std::vector>> declStmtInfo; + }; + + class UnitPolicy : + public srcDispatch::EventListener, + public srcDispatch::PolicyDispatcher, + public srcDispatch::PolicyListener { + + public: + static const std::size_t MAX_DEPTH = (std::size_t)-1; + + UnitData data; + std::size_t unitDepth; + + std::unique_ptr declStmtPolicy; + std::unique_ptr functionPolicy; + std::unique_ptr classPolicy; + + public: + UnitPolicy(std::initializer_list listeners) + : srcDispatch::PolicyDispatcher(listeners), unitDepth(MAX_DEPTH) { + InitializeUnitPolicyHandlers(); + } + + ~UnitPolicy() {} + + void Notify(const srcDispatch::PolicyDispatcher* policy, + const srcDispatch::srcSAXEventContext& ctx) override { + // Save class and function information + if(typeid(ClassPolicy) == typeid(*policy)) { + srcDispatch::DiffOperation operation = ctx.diffStack.back().isConvert? srcDispatch::COMMON : ctx.diffStack.back().operation; + data.classInfo.emplace_back(operation, policy->Data()); + } else if(typeid(FunctionPolicy) == typeid(*policy)) { + data.functionInfo.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } else if(typeid(DeclStmtPolicy) == typeid(*policy)) { + data.declStmtInfo.emplace_back(ctx.diffStack.back().operation, policy->Data()); + } + ctx.dispatcher->RemoveListenerDispatch(nullptr); + } + + void NotifyWrite(const PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + protected: + std::any DataInner() const override { return std::make_shared(data); } + + private: + void InitializeUnitPolicyHandlers() { + using namespace srcDispatch; + + openEventMap[ParserState::unit] = [this](srcSAXEventContext& ctx) { + if(unitDepth == MAX_DEPTH && (ctx.isArchive || ctx.depth > 0)) { + unitDepth = ctx.depth; + data = UnitData{}; + data.startLineNumber = ctx.startLineNumber; + data.endLineNumber = ctx.endLineNumber; + } + }; + + closeEventMap[ParserState::unit] = [this](srcSAXEventContext& ctx) { + if(unitDepth != ctx.depth) return; + + unitDepth = MAX_DEPTH; + NotifyAll(ctx); + }; + + // start of policy + std::function startClassPolicy = [this](srcSAXEventContext& ctx) { + if(depth == MAX_DEPTH) return; + + if(!classPolicy) { + classPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(classPolicy.get()); + }; + + openEventMap[ParserState::classn] = startClassPolicy; + openEventMap[ParserState::structn] = startClassPolicy; + + // end of policy + std::function endClassPolicy = [](srcSAXEventContext& ctx) {}; + + closeEventMap[ParserState::classn] = endClassPolicy; + closeEventMap[ParserState::structn] = endClassPolicy; + + // start function of policy + std::function startFunction = [this](srcSAXEventContext& ctx) { + if(depth == MAX_DEPTH) return; + + if(!functionPolicy) { + functionPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(functionPolicy.get()); + }; + + openEventMap[ParserState::function] = startFunction; + openEventMap[ParserState::functiondecl] = startFunction; + openEventMap[ParserState::constructor] = startFunction; + openEventMap[ParserState::constructordecl] = startFunction; + openEventMap[ParserState::destructor] = startFunction; + openEventMap[ParserState::destructordecl] = startFunction; + + // end of policy + std::function endFunction = [](srcSAXEventContext& ctx) {}; + + closeEventMap[ParserState::function] = endFunction; + closeEventMap[ParserState::functiondecl] = endFunction; + closeEventMap[ParserState::constructor] = endFunction; + closeEventMap[ParserState::constructordecl] = endFunction; + closeEventMap[ParserState::destructor] = endFunction; + closeEventMap[ParserState::destructordecl] = endFunction; + + openEventMap[ParserState::declstmt] = [this](srcSAXEventContext& ctx) { + if(depth == MAX_DEPTH) return; + + if(!declStmtPolicy) { + declStmtPolicy = make_unique_policy({this}); + } + ctx.dispatcher->AddListenerDispatch(declStmtPolicy.get()); + }; + + closeEventMap[ParserState::declstmt] = [](srcSAXEventContext& ctx) {}; + } + }; + +} + +#endif diff --git a/src/policy_classes/UnitPolicySingleEvent.hpp b/src/policy_classes/UnitPolicySingleEvent.hpp deleted file mode 100644 index 7f53578..0000000 --- a/src/policy_classes/UnitPolicySingleEvent.hpp +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Policy for srcSAXEventDispatcher - * Listens for both classes and functions - * Calls the ClassPolicySingleEvent for class - * Calls the FunctionPolicySingleEvent for function - * - */ -#ifndef INCLUDED_UNIT_POLICY_HPP -#define INCLUDED_UNIT_POLICY_HPP - -#include - -#include -#include - -#include -#include -#include -#include -#include - - -class UnitPolicySingleEvent : - public srcSAXEventDispatch::EventListener, - public srcSAXEventDispatch::PolicyDispatcher, - public srcSAXEventDispatch::PolicyListener { - -public: - FunctionPolicy *functionPolicy; - ClassPolicy *classPolicy; - -public: - UnitPolicySingleEvent(std::initializer_list listeners) : - srcSAXEventDispatch::PolicyDispatcher(listeners), - functionPolicy(nullptr), - classPolicy(nullptr) { - InitializeUnitPolicyHandlers(); - } - - ~UnitPolicySingleEvent() { - if(functionPolicy) delete functionPolicy; - if(classPolicy) delete classPolicy; - } - - void NotifyWrite(const PolicyDispatcher * policy, srcSAXEventDispatch::srcSAXEventContext & ctx) override {} //doesn't use other parsers - - void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - // Assumes at least one lister which should always be one - policyListeners.back()->Notify(policy, ctx); - ctx.dispatcher->RemoveListenerDispatch(nullptr); - } - -protected: - std::any DataInner() const override { return std::any(); } - -private: - void InitializeUnitPolicyHandlers() { - using namespace srcSAXEventDispatch; - - // start of policy - std::function startClassPolicy = [this](srcSAXEventContext& ctx) { - if(!classPolicy) classPolicy = new ClassPolicy{this}; - ctx.dispatcher->AddListenerDispatch(classPolicy); - }; - - // end of policy - std::function endClassPolicy = [this](srcSAXEventContext& ctx) { - }; - - openEventMap[ParserState::classn] = startClassPolicy; - closeEventMap[ParserState::classn] = endClassPolicy; - openEventMap[ParserState::structn] = startClassPolicy; - closeEventMap[ParserState::structn] = endClassPolicy; - - // start function of policy - std::function startFunction = [this](srcSAXEventContext& ctx) { - if(!functionPolicy) functionPolicy = new FunctionPolicy{this}; - ctx.dispatcher->AddListenerDispatch(functionPolicy); - }; - - // end of policy - std::function endFunction = [this](srcSAXEventContext& ctx) { - }; - - openEventMap[ParserState::function] = startFunction; - openEventMap[ParserState::functiondecl] = startFunction; - openEventMap[ParserState::constructor] = startFunction; - openEventMap[ParserState::constructordecl] = startFunction; - openEventMap[ParserState::destructor] = startFunction; - openEventMap[ParserState::destructordecl] = startFunction; - - closeEventMap[ParserState::function] = endFunction; - closeEventMap[ParserState::functiondecl] = endFunction; - closeEventMap[ParserState::constructor] = endFunction; - closeEventMap[ParserState::constructordecl] = endFunction; - closeEventMap[ParserState::destructor] = endFunction; - closeEventMap[ParserState::destructordecl] = endFunction; - - } -}; - -#endif diff --git a/src/policy_classes/WhilePolicy.hpp b/src/policy_classes/WhilePolicy.hpp new file mode 100644 index 0000000..f7da257 --- /dev/null +++ b/src/policy_classes/WhilePolicy.hpp @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file WhilePolicy.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_WHILE_POLICY_HPP +#define INCLUDED_WHILE_POLICY_HPP + +#include +#include +#include + +#include +#include +#include + +namespace srcDispatch { + + struct WhileData { + + DeltaElement startLineNumber; + DeltaElement endLineNumber; + + DeltaElement> condition; + DeltaElement> block; + + template + friend class DeltaElement; + private: + std::string ToString(srcDispatch::DiffOperation operation) const { + return condition.ToString(operation); + } + }; + + class WhilePolicy : public ConditionalPolicy { + public: + WhilePolicy(std::initializer_list listeners) + : ConditionalPolicy(listeners) {} + }; + +} + +#endif diff --git a/srcSAX b/srcSAX index d4e394e..93cbbee 160000 --- a/srcSAX +++ b/srcSAX @@ -1 +1 @@ -Subproject commit d4e394e2aa20b583492748f8daec5ec64fc9d536 +Subproject commit 93cbbee89957ea1dc8c744c72b7a835016ad0fd3 diff --git a/test/.DS_Store b/test/.DS_Store new file mode 100644 index 0000000..1cbbab5 Binary files /dev/null and b/test/.DS_Store differ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..d4cf8f0 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,40 @@ +## +# CMakeLists.txt +# +# Copyright (C) 2025-2025 srcML, LLC. (www.srcML.org) +# +# This file is part of the srcDispatch. +# +# The srcDispatch is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# The srcDispatch is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the srcDispatch; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +find_package(LibXml2 REQUIRED) +find_package(Boost REQUIRED) + +include_directories(util) + +macro(add_unit_test TEST_FILE) + + get_filename_component(TEST_NAME_WITH_EXTENSION ${TEST_FILE} NAME) + string(FIND ${TEST_NAME_WITH_EXTENSION} "." EXTENSION_BEGIN) + string(SUBSTRING ${TEST_NAME_WITH_EXTENSION} 0 ${EXTENSION_BEGIN} TEST_NAME) + + add_executable(${TEST_NAME} ${TEST_FILE}) + target_link_libraries(${TEST_NAME} $ $ LibXml2::LibXml2 Boost::boost ${ARGN}) + add_test(NAME ${TEST_NAME} COMMAND $) + set_target_properties(${TEST_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +endmacro() + +add_subdirectory(suite) diff --git a/CMake/srcsax_event_dispatch_install.cmake b/test/suite/CMakeLists.txt similarity index 53% rename from CMake/srcsax_event_dispatch_install.cmake rename to test/suite/CMakeLists.txt index 221b69b..5de2770 100644 --- a/CMake/srcsax_event_dispatch_install.cmake +++ b/test/suite/CMakeLists.txt @@ -1,25 +1,26 @@ ## -# srcsax_event_dispatch_install.cmake +# CMakeLists.txt # -# Copyright (C) 2016-2018 srcML, LLC. (www.srcML.org) +# Copyright (C) 2025-2025 srcML, LLC. (www.srcML.org) # -# This file is part of the srcSAXEventDispatch. +# This file is part of the srcDiffDispatch. # -# The srcSAXEventDispatch is free software; you can redistribute it and/or modify +# The srcDiffDispatch is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # -# The srcSAXEventDispatch is distributed in the hope that it will be useful, +# The srcDiffDispatch is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with the srcSAXEventDispatch; if not, write to the Free Software +# along with the srcDiffDispatch; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -if(NOT WIN32) - set(CMAKE_INSTALL_PREFIX "/usr/local/") -endif() +file(GLOB TESTS *.cpp) +foreach(TEST IN ITEMS ${TESTS}) + add_unit_test(${TEST}) +endforeach() diff --git a/test/suite/testCall.cpp b/test/suite/testCall.cpp new file mode 100644 index 0000000..28a777e --- /dev/null +++ b/test/suite/testCall.cpp @@ -0,0 +1,389 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testCall.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE call tests +#include + +#include + +#include +#include +#include + +// Define test data +namespace data = boost::unit_test; + +BOOST_AUTO_TEST_CASE(call_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { f(); }", "void foo() { f(); }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ExprStmtData& stmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(stmt.expr.IsCommon()); + BOOST_TEST(stmt.expr->expr.size() == 1); + BOOST_TEST(stmt.expr->expr.at(0).IsCommon()); + + const srcDispatch::CallData& call = *std::any_cast>(stmt.expr->expr.at(0).GetElement()); + BOOST_TEST(call.name.ToString() == "f"); + BOOST_TEST(call.arguments.size() == 0); + BOOST_TEST(stmt.expr->expr.at(0).ToString>() == "f()"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "f()"); + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(call_insert_stmt) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { f(); }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + const srcDispatch::ExprStmtData& stmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(stmt.expr.IsInsert()); + BOOST_TEST(stmt.expr->expr.size() == 1); + BOOST_TEST(stmt.expr->expr.at(0).IsInsert()); + + const srcDispatch::CallData& call = *std::any_cast>(stmt.expr->expr.at(0).GetElement()); + BOOST_TEST(call.name.ToString() == "|f"); + BOOST_TEST(call.arguments.size() == 0); + BOOST_TEST(stmt.expr->expr.at(0).ToString>() == "|f()"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "|f()"); + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(call_delete_stmt) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { f(); }", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::ExprStmtData& stmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(stmt.expr.IsDelete()); + BOOST_TEST(stmt.expr->expr.size() == 1); + BOOST_TEST(stmt.expr->expr.at(0).IsDelete()); + + const srcDispatch::CallData& call = *std::any_cast>(stmt.expr->expr.at(0).GetElement()); + BOOST_TEST(call.name.ToString() == "f|"); + BOOST_TEST(call.arguments.size() == 0); + BOOST_TEST(stmt.expr->expr.at(0).ToString>() == "f()|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "f()|"); + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(call_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { a = b; }", "void foo() { a = b + f(); }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ExprStmtData& stmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(stmt.expr.IsCommon()); + BOOST_TEST(stmt.expr->expr.size() == 5); + BOOST_TEST(stmt.expr->expr.at(0).IsCommon()); + BOOST_TEST(stmt.expr->expr.at(1).IsCommon()); + BOOST_TEST(stmt.expr->expr.at(2).IsCommon()); + BOOST_TEST(stmt.expr->expr.at(3).IsInsert()); + BOOST_TEST(stmt.expr->expr.at(4).IsInsert()); + + const srcDispatch::CallData& call = *std::any_cast>(stmt.expr->expr.at(4).GetElement()); + BOOST_TEST(call.name.ToString() == "|f"); + BOOST_TEST(call.arguments.size() == 0); + BOOST_TEST(stmt.expr->expr.at(4).ToString>() == "|f()"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "a = b|a = b + f()"); + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(call_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { a = b + f(); }", "void foo() { a = b; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ExprStmtData& stmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(stmt.expr.IsCommon()); + BOOST_TEST(stmt.expr->expr.size() == 5); + BOOST_TEST(stmt.expr->expr.at(0).IsCommon()); + BOOST_TEST(stmt.expr->expr.at(1).IsCommon()); + BOOST_TEST(stmt.expr->expr.at(2).IsCommon()); + BOOST_TEST(stmt.expr->expr.at(3).IsDelete()); + BOOST_TEST(stmt.expr->expr.at(4).IsDelete()); + + const srcDispatch::CallData& call = *std::any_cast>(stmt.expr->expr.at(4).GetElement()); + BOOST_TEST(call.name.ToString() == "f|"); + BOOST_TEST(call.arguments.size() == 0); + BOOST_TEST(stmt.expr->expr.at(4).ToString>() == "f()|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "a = b + f()|a = b"); + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +// args +BOOST_AUTO_TEST_CASE(call_arg_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { f(a); }", "void foo() { f(a); }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ExprStmtData& stmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(stmt.expr.IsCommon()); + BOOST_TEST(stmt.expr->expr.size() == 1); + BOOST_TEST(stmt.expr->expr.at(0).IsCommon()); + + const srcDispatch::CallData& call = *std::any_cast>(stmt.expr->expr.at(0).GetElement()); + BOOST_TEST(call.name.ToString() == "f"); + BOOST_TEST(call.arguments.size() == 1); + BOOST_TEST(call.arguments.at(0).IsCommon()); + BOOST_TEST(call.arguments.at(0).ToString() == "a"); + BOOST_TEST(stmt.expr->expr.at(0).ToString>() == "f(a)"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "f(a)"); + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(call_arg_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { f(); }", "void foo() { f(a); }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ExprStmtData& stmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(stmt.expr.IsCommon()); + BOOST_TEST(stmt.expr->expr.size() == 1); + BOOST_TEST(stmt.expr->expr.at(0).IsCommon()); + + const srcDispatch::CallData& call = *std::any_cast>(stmt.expr->expr.at(0).GetElement()); + BOOST_TEST(call.name.ToString() == "f"); + BOOST_TEST(call.arguments.size() == 1); + BOOST_TEST(call.arguments.at(0).IsInsert()); + BOOST_TEST(call.arguments.at(0).ToString() == "|a"); + BOOST_TEST(stmt.expr->expr.at(0).ToString>() == "f()|f(a)"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "f()|f(a)"); + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(call_arg_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { f(a); }", "void foo() { f(); }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ExprStmtData& stmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(stmt.expr.IsCommon()); + BOOST_TEST(stmt.expr->expr.size() == 1); + BOOST_TEST(stmt.expr->expr.at(0).IsCommon()); + + const srcDispatch::CallData& call = *std::any_cast>(stmt.expr->expr.at(0).GetElement()); + BOOST_TEST(call.name.ToString() == "f"); + BOOST_TEST(call.arguments.size() == 1); + BOOST_TEST(call.arguments.at(0).IsDelete()); + BOOST_TEST(call.arguments.at(0).ToString() == "a|"); + BOOST_TEST(stmt.expr->expr.at(0).ToString>() == "f(a)|f()"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "f(a)|f()"); + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(call_arg_insert_front) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { f(a); }", "void foo() { f(0, a); }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ExprStmtData& stmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(stmt.expr.IsCommon()); + BOOST_TEST(stmt.expr->expr.size() == 1); + BOOST_TEST(stmt.expr->expr.at(0).IsCommon()); + + const srcDispatch::CallData& call = *std::any_cast>(stmt.expr->expr.at(0).GetElement()); + BOOST_TEST(call.name.ToString() == "f"); + BOOST_TEST(call.arguments.size() == 2); + BOOST_TEST(call.arguments.at(0).IsInsert()); + BOOST_TEST(call.arguments.at(0).ToString() == "|0"); + BOOST_TEST(call.arguments.at(1).IsCommon()); + BOOST_TEST(call.arguments.at(1).ToString() == "a"); + BOOST_TEST(stmt.expr->expr.at(0).ToString>() == "f(a)|f(0, a)"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "f(a)|f(0, a)"); + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(call_arg_insert_back) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { f(a); }", "void foo() { f(a, b + 1); }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ExprStmtData& stmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(stmt.expr.IsCommon()); + BOOST_TEST(stmt.expr->expr.size() == 1); + BOOST_TEST(stmt.expr->expr.at(0).IsCommon()); + + const srcDispatch::CallData& call = *std::any_cast>(stmt.expr->expr.at(0).GetElement()); + BOOST_TEST(call.name.ToString() == "f"); + BOOST_TEST(call.arguments.size() == 2); + BOOST_TEST(call.arguments.at(0).IsCommon()); + BOOST_TEST(call.arguments.at(0).ToString() == "a"); + BOOST_TEST(call.arguments.at(1).IsInsert()); + BOOST_TEST(call.arguments.at(1).ToString() == "|b + 1"); + BOOST_TEST(stmt.expr->expr.at(0).ToString>() == "f(a)|f(a, b + 1)"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "f(a)|f(a, b + 1)"); + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + + + +BOOST_AUTO_TEST_CASE(call_arg_delete_front) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { f(0, a); }", "void foo() { f(a); }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ExprStmtData& stmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(stmt.expr.IsCommon()); + BOOST_TEST(stmt.expr->expr.size() == 1); + BOOST_TEST(stmt.expr->expr.at(0).IsCommon()); + + const srcDispatch::CallData& call = *std::any_cast>(stmt.expr->expr.at(0).GetElement()); + BOOST_TEST(call.name.ToString() == "f"); + BOOST_TEST(call.arguments.size() == 2); + BOOST_TEST(call.arguments.at(0).IsDelete()); + BOOST_TEST(call.arguments.at(0).ToString() == "0|"); + BOOST_TEST(call.arguments.at(1).IsCommon()); + BOOST_TEST(call.arguments.at(1).ToString() == "a"); + BOOST_TEST(stmt.expr->expr.at(0).ToString>() == "f(0, a)|f(a)"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "f(0, a)|f(a)"); + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(call_arg_delete_back) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { f(a, b + 1); }", "void foo() { f(a); }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ExprStmtData& stmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(stmt.expr.IsCommon()); + BOOST_TEST(stmt.expr->expr.size() == 1); + BOOST_TEST(stmt.expr->expr.at(0).IsCommon()); + + const srcDispatch::CallData& call = *std::any_cast>(stmt.expr->expr.at(0).GetElement()); + BOOST_TEST(call.name.ToString() == "f"); + BOOST_TEST(call.arguments.size() == 2); + BOOST_TEST(call.arguments.at(0).IsCommon()); + BOOST_TEST(call.arguments.at(0).ToString() == "a"); + BOOST_TEST(call.arguments.at(1).IsDelete()); + BOOST_TEST(call.arguments.at(1).ToString() == "b + 1|"); + BOOST_TEST(stmt.expr->expr.at(0).ToString>() == "f(a, b + 1)|f(a)"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "f(a, b + 1)|f(a)"); + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testCase.cpp b/test/suite/testCase.cpp new file mode 100644 index 0000000..8b2ba8e --- /dev/null +++ b/test/suite/testCase.cpp @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testCase.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE case_expr tests +#include + +#include + +#include +#include +#include + +#include + +// Define test data +namespace data = boost::unit_test; + +BOOST_AUTO_TEST_CASE(block_common_case) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { switch(1) { case foo; } }", "void foo() { switch(1) { case foo: }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + + const srcDispatch::SwitchData& switchData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(switchData.block.IsCommon()); + BOOST_TEST(switchData.block->statements.size() == 0); + + BOOST_TEST(switchData.block->cases.size() == 1); + BOOST_TEST(switchData.block->cases.at(0).IsCommon()); + BOOST_TEST(switchData.block->cases.at(0)->expr.IsCommon()); + BOOST_TEST(switchData.block->cases.at(0)->expr->expr.size() == 1); + BOOST_TEST(switchData.block->cases.at(0)->expr->expr.at(0).IsCommon()); + BOOST_TEST(switchData.block->cases.at(0).ToString() == "foo"); + + BOOST_TEST(switchData.block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_insert_case) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { switch(1) {} }", "void foo() { switch(1) { case foo: }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + + const srcDispatch::SwitchData& switchData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(switchData.block.IsCommon()); + BOOST_TEST(switchData.block->statements.size() == 0); + + BOOST_TEST(switchData.block->cases.size() == 1); + BOOST_TEST(switchData.block->cases.at(0).IsInsert()); + BOOST_TEST(switchData.block->cases.at(0)->expr.IsInsert()); + BOOST_TEST(switchData.block->cases.at(0)->expr->expr.size() == 1); + BOOST_TEST(switchData.block->cases.at(0)->expr->expr.at(0).IsInsert()); + BOOST_TEST(switchData.block->cases.at(0).ToString() == "|foo"); + + BOOST_TEST(switchData.block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_delete_case) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { switch(1) { case foo: } }", "void foo() { switch(1) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + + const srcDispatch::SwitchData& switchData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(switchData.block.IsCommon()); + BOOST_TEST(switchData.block->statements.size() == 0); + + BOOST_TEST(switchData.block->cases.size() == 1); + BOOST_TEST(switchData.block->cases.at(0).IsDelete()); + BOOST_TEST(switchData.block->cases.at(0)->expr.IsDelete()); + BOOST_TEST(switchData.block->cases.at(0)->expr->expr.size() == 1); + BOOST_TEST(switchData.block->cases.at(0)->expr->expr.at(0).IsDelete()); + BOOST_TEST(switchData.block->cases.at(0).ToString() == "foo|"); + + BOOST_TEST(switchData.block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_case_rename) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { switch(1) { case foo: } }", "void foo() { switch(1) { case bar: } }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + + const srcDispatch::SwitchData& switchData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(switchData.block.IsCommon()); + BOOST_TEST(switchData.block->statements.size() == 0); + + BOOST_TEST(switchData.block->cases.size() == 1); + BOOST_TEST(switchData.block->cases.at(0).IsCommon()); + BOOST_TEST(switchData.block->cases.at(0)->expr.IsCommon()); + BOOST_TEST(switchData.block->cases.at(0)->expr->expr.size() == 1); + BOOST_TEST(switchData.block->cases.at(0)->expr->expr.at(0).IsCommon()); + BOOST_TEST(std::any_cast>(switchData.block->cases.at(0)->expr->expr.at(0).GetElement())->name.IsChange()); + BOOST_TEST(switchData.block->cases.at(0).ToString() == "foo|bar"); + + BOOST_TEST(switchData.block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_case_expr_replace) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { switch(1) { case 0: } }", "void foo() { switch(1) { case foo: } }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + + const srcDispatch::SwitchData& switchData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(switchData.block.IsCommon()); + BOOST_TEST(switchData.block->statements.size() == 0); + + BOOST_TEST(switchData.block->cases.size() == 1); + BOOST_TEST(switchData.block->cases.at(0).IsCommon()); + BOOST_TEST(switchData.block->cases.at(0)->expr.IsChange()); + BOOST_TEST(switchData.block->cases.at(0)->expr.GetOriginal()->expr.size() == 1); + BOOST_TEST(switchData.block->cases.at(0)->expr.GetOriginal()->expr.at(0).IsDelete()); + BOOST_TEST(switchData.block->cases.at(0)->expr.GetModified()->expr.size() == 1); + BOOST_TEST(switchData.block->cases.at(0)->expr.GetModified()->expr.at(0).IsInsert()); + BOOST_TEST(switchData.block->cases.at(0).ToString() == "0|foo"); + + BOOST_TEST(switchData.block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testClass.cpp b/test/suite/testClass.cpp new file mode 100644 index 0000000..6274918 --- /dev/null +++ b/test/suite/testClass.cpp @@ -0,0 +1,3124 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testClass.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE class_and_struct tests +#include + +#include + +#include +#include +#include + +// Define test data +namespace data = boost::unit_test; + +// Do I need to collect class decl? + +BOOST_AUTO_TEST_CASE(class_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo {};", "class foo {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(struct_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"struct foo {};", "struct bar {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::STRUCT); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo|bar"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"", "class foo {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsInsert()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsInsert()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsInsert()); + BOOST_TEST(classData->name.ToString() == "|foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo {};", ""}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsDelete()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsDelete()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsDelete()); + BOOST_TEST(classData->name.ToString() == "foo|"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_rename) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo {};", "class bar {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo|bar"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +// parents +BOOST_AUTO_TEST_CASE(class_parent_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo : bar {};", "class foo : bar {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.size() == 1); + BOOST_TEST(classData->parents.at(0). IsCommon()); + BOOST_TEST(classData->parents.at(0)->name); + BOOST_TEST(classData->parents.at(0)->name.IsCommon()); + BOOST_TEST(classData->parents.at(0)->name.ToString() == "bar"); + BOOST_TEST(!classData->parents.at(0)->isVirtual); + BOOST_TEST(!classData->parents.at(0)->accessSpecifier); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_parent_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo {};", "class foo : bar {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.size() == 1); + BOOST_TEST(classData->parents.at(0).IsInsert()); + BOOST_TEST(classData->parents.at(0)->name); + BOOST_TEST(classData->parents.at(0)->name.IsInsert()); + BOOST_TEST(classData->parents.at(0)->name.ToString() == "|bar"); + BOOST_TEST(!classData->parents.at(0)->isVirtual); + BOOST_TEST(!classData->parents.at(0)->accessSpecifier); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_parent_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo : bar {};", "class foo {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.size() == 1); + BOOST_TEST(classData->parents.at(0).IsDelete()); + BOOST_TEST(classData->parents.at(0)->name); + BOOST_TEST(classData->parents.at(0)->name.IsDelete()); + BOOST_TEST(classData->parents.at(0)->name.ToString() == "bar|"); + BOOST_TEST(!classData->parents.at(0)->isVirtual); + BOOST_TEST(!classData->parents.at(0)->accessSpecifier); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_parent_rename) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo : public bar {};", "class foo : public foobar {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.size() == 1); + BOOST_TEST(classData->parents.at(0).IsCommon()); + BOOST_TEST(classData->parents.at(0)->name); + BOOST_TEST(classData->parents.at(0)->name.IsCommon()); + BOOST_TEST(classData->parents.at(0)->name.ToString() == "bar|foobar"); + BOOST_TEST(!classData->parents.at(0)->isVirtual); + BOOST_TEST(bool(classData->parents.at(0)->accessSpecifier)); + BOOST_TEST(classData->parents.at(0)->accessSpecifier.IsCommon()); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_parent_common_access) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo : public bar {};", "class foo : public bar {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.size() == 1); + BOOST_TEST(classData->parents.at(0).IsCommon()); + BOOST_TEST(classData->parents.at(0)->name); + BOOST_TEST(classData->parents.at(0)->name.IsCommon()); + BOOST_TEST(classData->parents.at(0)->name.ToString() == "bar"); + BOOST_TEST(!classData->parents.at(0)->isVirtual); + BOOST_TEST(bool(classData->parents.at(0)->accessSpecifier)); + BOOST_TEST(classData->parents.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->parents.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_parent_insert_access) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo : bar {};", "class foo : public bar {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.size() == 1); + BOOST_TEST(classData->parents.at(0).IsCommon()); + BOOST_TEST(classData->parents.at(0)->name); + BOOST_TEST(classData->parents.at(0)->name.IsCommon()); + BOOST_TEST(classData->parents.at(0)->name.ToString() == "bar"); + BOOST_TEST(!classData->parents.at(0)->isVirtual); + BOOST_TEST(bool(classData->parents.at(0)->accessSpecifier)); + BOOST_TEST(classData->parents.at(0)->accessSpecifier.IsInsert()); + BOOST_TEST(classData->parents.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_parent_delete_access) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo : public bar {};", "class foo : bar {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.size() == 1); + BOOST_TEST(classData->parents.at(0).IsCommon()); + BOOST_TEST(classData->parents.at(0)->name); + BOOST_TEST(classData->parents.at(0)->name.IsCommon()); + BOOST_TEST(classData->parents.at(0)->name.ToString() == "bar"); + BOOST_TEST(!classData->parents.at(0)->isVirtual); + BOOST_TEST(bool(classData->parents.at(0)->accessSpecifier)); + BOOST_TEST(classData->parents.at(0)->accessSpecifier.IsDelete()); + BOOST_TEST(classData->parents.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_parent_change_access) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo : public bar {};", "class foo : private bar {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.size() == 1); + BOOST_TEST(classData->parents.at(0).IsCommon()); + BOOST_TEST(classData->parents.at(0)->name); + BOOST_TEST(classData->parents.at(0)->name.IsCommon()); + BOOST_TEST(classData->parents.at(0)->name.ToString() == "bar"); + BOOST_TEST(!classData->parents.at(0)->isVirtual); + BOOST_TEST(bool(classData->parents.at(0)->accessSpecifier)); + BOOST_TEST(classData->parents.at(0)->accessSpecifier.IsChange()); + BOOST_TEST(classData->parents.at(0)->accessSpecifier.GetOriginal() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->parents.at(0)->accessSpecifier.GetModified() == AccessSpecifier::PRIVATE); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_parent_common_virtual) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo : virtual bar {};", "class foo : virtual bar {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.size() == 1); + BOOST_TEST(classData->parents.at(0).IsCommon()); + BOOST_TEST(classData->parents.at(0)->name); + BOOST_TEST(classData->parents.at(0)->name.IsCommon()); + BOOST_TEST(classData->parents.at(0)->name.ToString() == "bar"); + BOOST_TEST(bool(classData->parents.at(0)->isVirtual)); + BOOST_TEST(classData->parents.at(0)->isVirtual.IsCommon()); + BOOST_TEST(!classData->parents.at(0)->accessSpecifier); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_parent_insert_virtual) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo : bar {};", "class foo : virtual bar {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.size() == 1); + BOOST_TEST(classData->parents.at(0).IsCommon()); + BOOST_TEST(classData->parents.at(0)->name); + BOOST_TEST(classData->parents.at(0)->name.IsCommon()); + BOOST_TEST(classData->parents.at(0)->name.ToString() == "bar"); + BOOST_TEST(bool(classData->parents.at(0)->isVirtual)); + BOOST_TEST(classData->parents.at(0)->isVirtual.IsInsert()); + BOOST_TEST(!classData->parents.at(0)->accessSpecifier); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_parent_delete_virtual) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo : virtual bar {};", "class foo : bar {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.size() == 1); + BOOST_TEST(classData->parents.at(0).IsCommon()); + BOOST_TEST(classData->parents.at(0)->name); + BOOST_TEST(classData->parents.at(0)->name.IsCommon()); + BOOST_TEST(classData->parents.at(0)->name.ToString() == "bar"); + BOOST_TEST(bool(classData->parents.at(0)->isVirtual)); + BOOST_TEST(classData->parents.at(0)->isVirtual.IsDelete()); + BOOST_TEST(!classData->parents.at(0)->accessSpecifier); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_parent_replace) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo : bar {};", "class foo : foobar {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.size() == 2); + + BOOST_TEST(classData->parents.at(0).IsDelete()); + BOOST_TEST(classData->parents.at(0)->name); + BOOST_TEST(classData->parents.at(0)->name.IsDelete()); + BOOST_TEST(classData->parents.at(0)->name.ToString() == "bar|"); + BOOST_TEST(!classData->parents.at(0)->isVirtual); + BOOST_TEST(!classData->parents.at(0)->accessSpecifier); + + BOOST_TEST(classData->parents.at(1).IsInsert()); + BOOST_TEST(classData->parents.at(1)->name); + BOOST_TEST(classData->parents.at(1)->name.IsInsert()); + BOOST_TEST(classData->parents.at(1)->name.ToString() == "|foobar"); + BOOST_TEST(!classData->parents.at(1)->isVirtual); + BOOST_TEST(!classData->parents.at(1)->accessSpecifier); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +// fields +BOOST_AUTO_TEST_CASE(class_fields_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { int i; };", "class foo { int i; };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.size() == 1); + BOOST_TEST(classData->fields.at(0).IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.size() == 1); + BOOST_TEST(classData->fields.at(0)->decls.at(0).IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->fields.at(0).ToString() == "int i"); + + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_fields_private) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: int i; };", "class foo { private: int i; };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.size() == 1); + BOOST_TEST(classData->fields.at(0).IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.size() == 1); + BOOST_TEST(classData->fields.at(0)->decls.at(0).IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->fields.at(0).ToString() == "int i"); + + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_fields_private_default) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { int i; };", "class foo { private: int i; };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.size() == 1); + BOOST_TEST(classData->fields.at(0).IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.size() == 1); + BOOST_TEST(classData->fields.at(0)->decls.at(0).IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->fields.at(0).ToString() == "int i"); + + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_fields_public) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: int i; };", "class foo { public: int i; };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.size() == 1); + BOOST_TEST(classData->fields.at(0).IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.size() == 1); + BOOST_TEST(classData->fields.at(0)->decls.at(0).IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->fields.at(0).ToString() == "int i"); + + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_fields_protected) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { protected: int i; };", "class foo { protected: int i; };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.size() == 1); + BOOST_TEST(classData->fields.at(0).IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.size() == 1); + BOOST_TEST(classData->fields.at(0)->decls.at(0).IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PROTECTED); + BOOST_TEST(classData->fields.at(0).ToString() == "int i"); + + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_fields_access_change) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: int i; };", "class foo { protected: int i; };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.size() == 1); + BOOST_TEST(classData->fields.at(0).IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.size() == 1); + BOOST_TEST(classData->fields.at(0)->decls.at(0).IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.IsChange()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.GetOriginal() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.GetModified() == AccessSpecifier::PROTECTED); + BOOST_TEST(classData->fields.at(0).ToString() == "int i"); + + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_fields_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: };", "class foo { private: int i; };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.size() == 1); + BOOST_TEST(classData->fields.at(0).IsInsert()); + BOOST_TEST(classData->fields.at(0)->decls.size() == 1); + BOOST_TEST(classData->fields.at(0)->decls.at(0).IsInsert()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->fields.at(0).ToString() == "|int i"); + + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_fields_insert_with_access) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: };", "class foo { private: int i; };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.size() == 1); + BOOST_TEST(classData->fields.at(0).IsInsert()); + BOOST_TEST(classData->fields.at(0)->decls.size() == 1); + BOOST_TEST(classData->fields.at(0)->decls.at(0).IsInsert()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.IsInsert()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->fields.at(0).ToString() == "|int i"); + + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_fields_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: int i; };", "class foo { private: };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.size() == 1); + BOOST_TEST(classData->fields.at(0).IsDelete()); + BOOST_TEST(classData->fields.at(0)->decls.size() == 1); + BOOST_TEST(classData->fields.at(0)->decls.at(0).IsDelete()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->fields.at(0).ToString() == "int i|"); + + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_fields_delete_with_access) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: int i; };", "class foo { private: };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.size() == 1); + BOOST_TEST(classData->fields.at(0).IsDelete()); + BOOST_TEST(classData->fields.at(0)->decls.size() == 1); + BOOST_TEST(classData->fields.at(0)->decls.at(0).IsDelete()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.IsDelete()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->fields.at(0).ToString() == "int i|"); + + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_fields_replace) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: int i; };", "class foo { private: double d; };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.size() == 2); + BOOST_TEST(classData->fields.at(0).IsDelete()); + BOOST_TEST(classData->fields.at(0)->decls.size() == 1); + BOOST_TEST(classData->fields.at(0)->decls.at(0).IsDelete()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->fields.at(0).ToString() == "int i|"); + + BOOST_TEST(classData->fields.at(1).IsInsert()); + BOOST_TEST(classData->fields.at(1)->decls.size() == 1); + BOOST_TEST(classData->fields.at(1)->decls.at(0).IsInsert()); + BOOST_TEST(classData->fields.at(1)->decls.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->fields.at(1)->decls.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->fields.at(1).ToString() == "|double d"); + + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_fields_replace_with_namespace) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: int i; };", "class foo { private: double d; };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.size() == 2); + BOOST_TEST(classData->fields.at(0).IsDelete()); + BOOST_TEST(classData->fields.at(0)->decls.size() == 1); + BOOST_TEST(classData->fields.at(0)->decls.at(0).IsDelete()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.IsDelete()); + BOOST_TEST(classData->fields.at(0)->decls.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->fields.at(0).ToString() == "int i|"); + + BOOST_TEST(classData->fields.at(1).IsInsert()); + BOOST_TEST(classData->fields.at(1)->decls.size() == 1); + BOOST_TEST(classData->fields.at(1)->decls.at(0).IsInsert()); + BOOST_TEST(classData->fields.at(1)->decls.at(0)->accessSpecifier.IsInsert()); + BOOST_TEST(classData->fields.at(1)->decls.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->fields.at(1).ToString() == "|double d"); + + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +// constructor +BOOST_AUTO_TEST_CASE(class_constructors_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { foo() {} };", "class foo { foo() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->constructors.size() == 1); + BOOST_TEST(classData->constructors.at(0).IsCommon()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->constructors.at(0).ToString() == "foo() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_constructors_private) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: foo() {} };", "class foo { private: foo() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->constructors.size() == 1); + BOOST_TEST(classData->constructors.at(0).IsCommon()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->constructors.at(0).ToString() == "foo() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_constructors_private_default) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { foo() {} };", "class foo { private: foo() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->constructors.size() == 1); + BOOST_TEST(classData->constructors.at(0).IsCommon()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->constructors.at(0).ToString() == "foo() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_constructors_public) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: foo() {} };", "class foo { public: foo() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->constructors.size() == 1); + BOOST_TEST(classData->constructors.at(0).IsCommon()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->constructors.at(0).ToString() == "foo() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_constructors_protected) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { protected: foo() {} };", "class foo { protected: foo() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->constructors.size() == 1); + BOOST_TEST(classData->constructors.at(0).IsCommon()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PROTECTED); + BOOST_TEST(classData->constructors.at(0).ToString() == "foo() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_constructors_access_change) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: foo() {} };", "class foo { protected: foo() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->constructors.size() == 1); + BOOST_TEST(classData->constructors.at(0).IsCommon()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.IsChange()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.GetOriginal() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.GetModified() == AccessSpecifier::PROTECTED); + BOOST_TEST(classData->constructors.at(0).ToString() == "foo() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_constructors_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: };", "class foo { private: foo() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->constructors.size() == 1); + BOOST_TEST(classData->constructors.at(0).IsInsert()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->constructors.at(0).ToString() == "|foo() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_constructors_insert_with_access) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: };", "class foo { private: foo() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->constructors.size() == 1); + BOOST_TEST(classData->constructors.at(0).IsInsert()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.IsInsert()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->constructors.at(0).ToString() == "|foo() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_constructors_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: foo() {} };", "class foo { private: };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->constructors.size() == 1); + BOOST_TEST(classData->constructors.at(0).IsDelete()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->constructors.at(0).ToString() == "foo() {}|"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_constructors_delete_with_access) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: foo() {} };", "class foo { private: };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->constructors.size() == 1); + BOOST_TEST(classData->constructors.at(0).IsDelete()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.IsDelete()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->constructors.at(0).ToString() == "foo() {}|"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_constructors_replace) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: foo() { ab; } public: void f() { c; d; } };", "class bar { private: bar() { b; } public: void f() { c; d; } };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo|bar"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->constructors.size() == 2); + BOOST_TEST(classData->constructors.at(0).IsDelete()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->constructors.at(0).ToString() == "foo() {}|"); + + BOOST_TEST(classData->constructors.at(1).IsInsert()); + BOOST_TEST(classData->constructors.at(1)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->constructors.at(1)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->constructors.at(1).ToString() == "|bar() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_constructors_replace_with_namespace) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: foo() { a; } public: void f() { c + d + e + f; } };", "class bar { private: bar() { a; } public: void f() { c + d + e + f; } };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo|bar"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->constructors.size() == 2); + BOOST_TEST(classData->constructors.at(0).IsDelete()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.IsDelete()); + BOOST_TEST(classData->constructors.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->constructors.at(0).ToString() == "foo() {}|"); + + BOOST_TEST(classData->constructors.at(1).IsInsert()); + BOOST_TEST(classData->constructors.at(1)->accessSpecifier.IsInsert()); + BOOST_TEST(classData->constructors.at(1)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->constructors.at(1).ToString() == "|bar() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +// destructor +BOOST_AUTO_TEST_CASE(class_destructors_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { ~foo() {} };", "class foo { ~foo() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->destructor); + BOOST_TEST(classData->destructor.IsCommon()); + BOOST_TEST(classData->destructor->accessSpecifier.IsCommon()); + BOOST_TEST(classData->destructor->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->destructor.ToString() == "~foo() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_destructors_private) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: ~foo() {} };", "class foo { private: ~foo() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->destructor); + BOOST_TEST(classData->destructor.IsCommon()); + BOOST_TEST(classData->destructor->accessSpecifier.IsCommon()); + BOOST_TEST(classData->destructor->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->destructor.ToString() == "~foo() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_destructors_private_default) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { ~foo() {} };", "class foo { private: ~foo() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->destructor); + BOOST_TEST(classData->destructor.IsCommon()); + BOOST_TEST(classData->destructor->accessSpecifier.IsCommon()); + BOOST_TEST(classData->destructor->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->destructor.ToString() == "~foo() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_destructors_public) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: ~foo() {} };", "class foo { public: ~foo() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->destructor); + BOOST_TEST(classData->destructor.IsCommon()); + BOOST_TEST(classData->destructor->accessSpecifier.IsCommon()); + BOOST_TEST(classData->destructor->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->destructor.ToString() == "~foo() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_destructors_protected) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { protected: ~foo() {} };", "class foo { protected: ~foo() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->destructor); + BOOST_TEST(classData->destructor.IsCommon()); + BOOST_TEST(classData->destructor->accessSpecifier.IsCommon()); + BOOST_TEST(classData->destructor->accessSpecifier.GetElement() == AccessSpecifier::PROTECTED); + BOOST_TEST(classData->destructor.ToString() == "~foo() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_destructors_access_change) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: ~foo() {} };", "class foo { protected: ~foo() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->destructor); + BOOST_TEST(classData->destructor.IsCommon()); + BOOST_TEST(classData->destructor->accessSpecifier.IsChange()); + BOOST_TEST(classData->destructor->accessSpecifier.GetOriginal() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->destructor->accessSpecifier.GetModified() == AccessSpecifier::PROTECTED); + BOOST_TEST(classData->destructor.ToString() == "~foo() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_destructors_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: };", "class foo { private: ~foo() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->destructor); + BOOST_TEST(classData->destructor.IsInsert()); + BOOST_TEST(classData->destructor->accessSpecifier.IsCommon()); + BOOST_TEST(classData->destructor->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->destructor.ToString() == "|~foo() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_destructors_insert_with_access) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: };", "class foo { private: ~foo() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->destructor); + BOOST_TEST(classData->destructor.IsInsert()); + BOOST_TEST(classData->destructor->accessSpecifier.IsInsert()); + BOOST_TEST(classData->destructor->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->destructor.ToString() == "|~foo() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_destructors_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: ~foo() {} };", "class foo { private: };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->destructor); + BOOST_TEST(classData->destructor.IsDelete()); + BOOST_TEST(classData->destructor->accessSpecifier.IsCommon()); + BOOST_TEST(classData->destructor->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->destructor.ToString() == "~foo() {}|"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_destructors_delete_with_access) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: ~foo() {} };", "class foo { private: };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->destructor); + BOOST_TEST(classData->destructor.IsDelete()); + BOOST_TEST(classData->destructor->accessSpecifier.IsDelete()); + BOOST_TEST(classData->destructor->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->destructor.ToString() == "~foo() {}|"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_destructors_replace) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: ~foo() { ab; } public: void f() { c; d; } };", "class bar { private: ~bar() { b; } public: void f() { c; d; } };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo|bar"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->destructor); + BOOST_TEST(classData->destructor.IsChange()); + BOOST_TEST(classData->destructor->accessSpecifier.IsCommon()); + BOOST_TEST(classData->destructor->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->destructor.ToString() == "~foo() {}|~bar() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_destructors_replace_with_namespace) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: ~foo() { a; } public: void f() { c + d + e + f; } };", "class bar { private: ~bar() { a; } public: void f() { c + d + e + f; } };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo|bar"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->destructor); + BOOST_TEST(classData->destructor.IsChange()); + BOOST_TEST(classData->destructor.GetOriginal()->accessSpecifier.GetOriginal() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->destructor.GetModified()->accessSpecifier.GetModified() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->destructor.ToString() == "~foo() {}|~bar() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_destructors_replace_with_convert_namespace) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: ~foo() {} void f(int c, double d, long e, float f) { c + d + e + f; } };", "class bar { private: ~bar() { delete a; } void f(int c, double d, long e, float f) { c + d + e + f; } };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo|bar"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->destructor); + BOOST_TEST(classData->destructor.IsChange()); + BOOST_TEST(classData->destructor->accessSpecifier.IsChange()); + BOOST_TEST(classData->destructor->accessSpecifier.GetOriginal() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->destructor->accessSpecifier.GetModified() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->destructor.ToString() == "~foo() {}|~bar() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +// operators +BOOST_AUTO_TEST_CASE(class_operators_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { bool operator==() {} };", "class foo { bool operator==() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->operators.size() == 1); + BOOST_TEST(classData->operators.at(0).IsCommon()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->operators.at(0).ToString() == "bool operator==() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_operators_private) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: bool operator==() {} };", "class foo { private: bool operator==() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->operators.size() == 1); + BOOST_TEST(classData->operators.at(0).IsCommon()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->operators.at(0).ToString() == "bool operator==() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_operators_private_default) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { bool operator==() {} };", "class foo { private: bool operator==() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->operators.size() == 1); + BOOST_TEST(classData->operators.at(0).IsCommon()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->operators.at(0).ToString() == "bool operator==() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_operators_public) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: bool operator==() {} };", "class foo { public: bool operator==() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->operators.size() == 1); + BOOST_TEST(classData->operators.at(0).IsCommon()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->operators.at(0).ToString() == "bool operator==() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_operators_protected) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { protected: bool operator==() {} };", "class foo { protected: bool operator==() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->operators.size() == 1); + BOOST_TEST(classData->operators.at(0).IsCommon()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PROTECTED); + BOOST_TEST(classData->operators.at(0).ToString() == "bool operator==() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_operators_access_change) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: bool operator==() {} };", "class foo { protected: bool operator==() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->operators.size() == 1); + BOOST_TEST(classData->operators.at(0).IsCommon()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.IsChange()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.GetOriginal() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.GetModified() == AccessSpecifier::PROTECTED); + BOOST_TEST(classData->operators.at(0).ToString() == "bool operator==() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_operators_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: };", "class foo { private: bool operator==() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->operators.size() == 1); + BOOST_TEST(classData->operators.at(0).IsInsert()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->operators.at(0).ToString() == "|bool operator==() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_operators_insert_with_access) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: };", "class foo { private: bool operator==() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->operators.size() == 1); + BOOST_TEST(classData->operators.at(0).IsInsert()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.IsInsert()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->operators.at(0).ToString() == "|bool operator==() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_operators_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: bool operator==() {} };", "class foo { private: };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->operators.size() == 1); + BOOST_TEST(classData->operators.at(0).IsDelete()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->operators.at(0).ToString() == "bool operator==() {}|"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_operators_delete_with_access) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: bool operator==() {} };", "class foo { private: };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->operators.size() == 1); + BOOST_TEST(classData->operators.at(0).IsDelete()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.IsDelete()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->operators.at(0).ToString() == "bool operator==() {}|"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_operators_replace) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: bool operator==(int b) { return std::max(b - a, 0); } };", "class foo { private: bool operator!=(const object& that) { return *this != that; } };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->operators.size() == 2); + BOOST_TEST(classData->operators.at(0).IsDelete()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->operators.at(0).ToString() == "bool operator==(int b) {}|"); + + BOOST_TEST(classData->operators.at(1).IsInsert()); + BOOST_TEST(classData->operators.at(1)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->operators.at(1)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->operators.at(1).ToString() == "|bool operator!=(const object & that) {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_operators_replace_with_namespace) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: bool operator==(int b) { return std::max(b - a, 0); } };", "class foo { private: bool operator!=(const object& that) { return *this != that; } };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->operators.size() == 2); + BOOST_TEST(classData->operators.at(0).IsDelete()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.IsDelete()); + BOOST_TEST(classData->operators.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->operators.at(0).ToString() == "bool operator==(int b) {}|"); + + BOOST_TEST(classData->operators.at(1).IsInsert()); + BOOST_TEST(classData->operators.at(1)->accessSpecifier.IsInsert()); + BOOST_TEST(classData->operators.at(1)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->operators.at(1).ToString() == "|bool operator!=(const object & that) {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +// methods +BOOST_AUTO_TEST_CASE(class_methods_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { void f() {} };", "class foo { void f() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->methods.at(0).IsCommon()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->methods.at(0).ToString() == "void f() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_methods_private) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: void f() {} };", "class foo { private: void f() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->methods.at(0).IsCommon()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->methods.at(0).ToString() == "void f() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_methods_private_default) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { void f() {} };", "class foo { private: void f() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->methods.at(0).IsCommon()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->methods.at(0).ToString() == "void f() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_methods_public) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: void f() {} };", "class foo { public: void f() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->methods.at(0).IsCommon()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->methods.at(0).ToString() == "void f() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_methods_protected) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { protected: void f() {} };", "class foo { protected: void f() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->methods.at(0).IsCommon()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PROTECTED); + BOOST_TEST(classData->methods.at(0).ToString() == "void f() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_methods_access_change) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: void f() {} };", "class foo { protected: void f() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->methods.at(0).IsCommon()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.IsChange()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.GetOriginal() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.GetModified() == AccessSpecifier::PROTECTED); + BOOST_TEST(classData->methods.at(0).ToString() == "void f() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_methods_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: };", "class foo { private: void f() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->methods.at(0).IsInsert()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->methods.at(0).ToString() == "|void f() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_methods_insert_with_access) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: };", "class foo { private: void f() {} };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->methods.at(0).IsInsert()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.IsInsert()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->methods.at(0).ToString() == "|void f() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_methods_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: void f() {} };", "class foo { private: };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->methods.at(0).IsDelete()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->methods.at(0).ToString() == "void f() {}|"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_methods_delete_with_access) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: void f() {} };", "class foo { private: };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->methods.at(0).IsDelete()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.IsDelete()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->methods.at(0).ToString() == "void f() {}|"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_methods_replace) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { private: void f() { a; } };", "class foo { private: int g() { b; } };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->methods.size() == 2); + BOOST_TEST(classData->methods.at(0).IsDelete()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->methods.at(0).ToString() == "void f() {}|"); + + BOOST_TEST(classData->methods.at(1).IsInsert()); + BOOST_TEST(classData->methods.at(1)->accessSpecifier.IsCommon()); + BOOST_TEST(classData->methods.at(1)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->methods.at(1).ToString() == "|int g() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_methods_replace_with_namespace) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { public: void f() { a; } };", "class foo { private: int g() { b; } };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->methods.size() == 2); + BOOST_TEST(classData->methods.at(0).IsDelete()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.IsDelete()); + BOOST_TEST(classData->methods.at(0)->accessSpecifier.GetElement() == AccessSpecifier::PUBLIC); + BOOST_TEST(classData->methods.at(0).ToString() == "void f() {}|"); + + BOOST_TEST(classData->methods.at(1).IsInsert()); + BOOST_TEST(classData->methods.at(1)->accessSpecifier.IsInsert()); + BOOST_TEST(classData->methods.at(1)->accessSpecifier.GetElement() == AccessSpecifier::PRIVATE); + BOOST_TEST(classData->methods.at(1).ToString() == "|int g() {}"); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +// abstract +BOOST_AUTO_TEST_CASE(class_is_abstract) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { virtual void f() = 0; };", "class foo { virtual void f() = 0; };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(classData->isAbstract); + BOOST_TEST(classData->isAbstract.IsCommon()); + BOOST_TEST(classData->isAbstract.GetElement()); +} + +BOOST_AUTO_TEST_CASE(class_becomes_abstract) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { };", "class foo { virtual void f() = 0; };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(classData->isAbstract); + BOOST_TEST(classData->isAbstract.IsInsert()); + BOOST_TEST(classData->isAbstract.GetElement()); +} + +BOOST_AUTO_TEST_CASE(class_was_abstract) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo { virtual void f() = 0; };", "class foo { };"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.size() == 1); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(classData->isAbstract); + BOOST_TEST(classData->isAbstract.IsDelete()); + BOOST_TEST(classData->isAbstract.GetElement()); +} + +// generic +BOOST_AUTO_TEST_CASE(class_is_generic) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template class foo {};", "template class foo {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.size() == 1); + BOOST_TEST(classData->generics.at(0).IsCommon()); + BOOST_TEST(classData->generics.at(0).ToString() == "template"); + + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_becomes_generic) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo {};", "template class foo {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.size() == 1); + BOOST_TEST(classData->generics.at(0).IsInsert()); + BOOST_TEST(classData->generics.at(0).ToString() == "|template"); + + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(class_was_generic) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template class foo {};", "class foo {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.size() == 1); + BOOST_TEST(classData->generics.at(0).IsDelete()); + BOOST_TEST(classData->generics.at(0).ToString() == "template|"); + + BOOST_TEST(classData->type.IsCommon()); + BOOST_TEST(classData->type.GetElement() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); + +} + +// Inner Classes diff --git a/test/suite/testClassConvert.cpp b/test/suite/testClassConvert.cpp new file mode 100644 index 0000000..2c5dae7 --- /dev/null +++ b/test/suite/testClassConvert.cpp @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testClassConvert.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE class type convert tests +#include + +#include + +#include +#include +#include + +// Define test data +namespace data = boost::unit_test; + +// Do I need to collect class decl? + +BOOST_AUTO_TEST_CASE(class_to_struct) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"class foo {};", "struct foo {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsChange()); + BOOST_TEST(classData->type.GetOriginal() == srcDispatch::ClassData::CLASS); + BOOST_TEST(classData->type.GetModified() == srcDispatch::ClassData::STRUCT); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +BOOST_AUTO_TEST_CASE(struct_to_class) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"struct foo {};", "class foo {};"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 1); + + const srcDispatch::DeltaElement>& classData = runner.GetClassInfo().at(0); + BOOST_TEST(classData.IsCommon()); + + BOOST_TEST(classData->generics.empty()); + BOOST_TEST(classData->type.IsChange()); + BOOST_TEST(classData->type.GetOriginal() == srcDispatch::ClassData::STRUCT); + BOOST_TEST(classData->type.GetModified() == srcDispatch::ClassData::CLASS); + + BOOST_TEST(classData->name.IsCommon()); + BOOST_TEST(classData->name.ToString() == "foo"); + + BOOST_TEST(classData->parents.empty()); + + BOOST_TEST(classData->fields.empty()); + BOOST_TEST(classData->constructors.empty()); + BOOST_TEST(!classData->destructor); + BOOST_TEST(classData->operators.empty()); + BOOST_TEST(classData->methods.empty()); + BOOST_TEST(classData->innerClasses.empty()); + + BOOST_TEST(!classData->isAbstract); +} + +// inner/local class convert diff --git a/test/suite/testCondition.cpp b/test/suite/testCondition.cpp new file mode 100644 index 0000000..3a33893 --- /dev/null +++ b/test/suite/testCondition.cpp @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testCondition.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE condition tests +#include + +#include + +#include +#include +#include + +#include + +// Define test data +namespace data = boost::unit_test; + +// condition decl +BOOST_AUTO_TEST_CASE(decl_condition_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { while(int i = 1) {} }", "void foo() { while(int i = 1) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::WhileData& whileData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(whileData.condition); + BOOST_TEST(whileData.condition.IsCommon()); + BOOST_TEST(whileData.condition->conditions.size() == 1); + BOOST_TEST(whileData.condition->conditions.at(0).IsCommon()); + + BOOST_TEST(whileData.condition->conditions.at(0).ToString>() == "int i = 1"); + BOOST_TEST(whileData.condition.ToString() == "int i = 1"); + + BOOST_TEST(whileData.block.IsCommon()); + BOOST_TEST(whileData.block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(decl_condition_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { while(int i = 1) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + const srcDispatch::WhileData& whileData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(whileData.condition); + BOOST_TEST(whileData.condition.IsInsert()); + BOOST_TEST(whileData.condition->conditions.size() == 1); + BOOST_TEST(whileData.condition->conditions.at(0).IsInsert()); + BOOST_TEST(whileData.condition->conditions.at(0).ToString>() == "|int i = 1"); + BOOST_TEST(whileData.condition.ToString() == "|int i = 1"); + + BOOST_TEST(whileData.block.IsInsert()); + BOOST_TEST(whileData.block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "|int i = 1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(decl_condition_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { while(int i = 1) {} }", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::WhileData& whileData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(whileData.condition); + BOOST_TEST(whileData.condition.IsDelete()); + BOOST_TEST(whileData.condition->conditions.size() == 1); + BOOST_TEST(whileData.condition->conditions.at(0).IsDelete()); + BOOST_TEST(whileData.condition->conditions.at(0).ToString>() == "int i = 1|"); + BOOST_TEST(whileData.condition.ToString() == "int i = 1|"); + + BOOST_TEST(whileData.block.IsDelete()); + BOOST_TEST(whileData.block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 1|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(decl_condition_replace) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { while(int i = 1) {} }", "void foo() { while(double d = 1.0) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::WhileData& whileData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(whileData.condition); + BOOST_TEST(whileData.condition.IsCommon()); + BOOST_TEST(whileData.condition->conditions.size() == 2); + BOOST_TEST(whileData.condition->conditions.at(0).IsDelete()); + BOOST_TEST(whileData.condition->conditions.at(0).ToString>() == "int i = 1|"); + BOOST_TEST(whileData.condition->conditions.at(1).IsInsert()); + BOOST_TEST(whileData.condition->conditions.at(1).ToString>() == "|double d = 1.0"); + BOOST_TEST(whileData.condition.ToString() == "int i = 1|double d = 1.0"); + + BOOST_TEST(whileData.block.IsCommon()); + BOOST_TEST(whileData.block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 1|double d = 1.0"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(decl_condition_modify) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { while(int i = 1) {} }", "void foo() { while(int i = 2) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::WhileData& whileData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(whileData.condition); + BOOST_TEST(whileData.condition.IsCommon()); + BOOST_TEST(whileData.condition->conditions.size() == 1); + BOOST_TEST(whileData.condition->conditions.at(0).IsCommon()); + BOOST_TEST(whileData.condition->conditions.at(0).ToString>() == "int i = 1|int i = 2"); + BOOST_TEST(whileData.condition.ToString() == "int i = 1|int i = 2"); + + BOOST_TEST(whileData.block.IsCommon()); + BOOST_TEST(whileData.block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 1|int i = 2"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testConditionalConvert.cpp b/test/suite/testConditionalConvert.cpp new file mode 100644 index 0000000..2125054 --- /dev/null +++ b/test/suite/testConditionalConvert.cpp @@ -0,0 +1,363 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testConditionalConvert.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE conditional convert tests +#include + +#include + +#include +#include +#include + +#include +#include +#include + +// Define test data +namespace data = boost::unit_test; + +BOOST_AUTO_TEST_CASE(if_to_while) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { if(1) {} }", "void foo() { while(1) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsChange()); + + const srcDispatch::IfStmtData& ifData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetOriginal()); + BOOST_TEST(ifData.clauses.size() == 1); + + const srcDispatch::IfData& ifClause = *std::any_cast>(ifData.clauses.at(0).GetElement()); + BOOST_TEST(ifData.clauses.at(0).IsDelete()); + BOOST_TEST(ifClause.condition.IsCommon()); + BOOST_TEST(ifClause.condition->conditions.size() == 1); + BOOST_TEST(ifClause.condition->conditions.at(0).IsCommon()); + BOOST_TEST(ifClause.condition.ToString() == "1"); + BOOST_TEST(ifClause.block.IsCommon()); + BOOST_TEST(ifClause.block->statements.size() == 0); + + const srcDispatch::WhileData& whileData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetModified()); + BOOST_TEST(whileData.condition); + BOOST_TEST(whileData.condition.IsCommon()); + BOOST_TEST(whileData.condition->conditions.size() == 1); + BOOST_TEST(whileData.condition->conditions.at(0).IsCommon()); + BOOST_TEST(whileData.condition.ToString() == "1"); + BOOST_TEST(whileData.block.IsCommon()); + BOOST_TEST(whileData.block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(while_to_if) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { while(1) {} }", "void foo() { if(1) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsChange()); + + const srcDispatch::WhileData& whileData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetOriginal()); + BOOST_TEST(whileData.condition); + BOOST_TEST(whileData.condition.IsCommon()); + BOOST_TEST(whileData.condition->conditions.size() == 1); + BOOST_TEST(whileData.condition->conditions.at(0).IsCommon()); + BOOST_TEST(whileData.condition.ToString() == "1"); + BOOST_TEST(whileData.block.IsCommon()); + BOOST_TEST(whileData.block->statements.size() == 0); + + const srcDispatch::IfStmtData& ifData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetModified()); + BOOST_TEST(ifData.clauses.size() == 1); + + const srcDispatch::IfData& ifClause = *std::any_cast>(ifData.clauses.at(0).GetElement()); + BOOST_TEST(ifData.clauses.at(0).IsInsert()); + BOOST_TEST(ifClause.condition.IsCommon()); + BOOST_TEST(ifClause.condition->conditions.size() == 1); + BOOST_TEST(ifClause.condition->conditions.at(0).IsCommon()); + BOOST_TEST(ifClause.condition.ToString() == "1"); + BOOST_TEST(ifClause.block.IsCommon()); + BOOST_TEST(ifClause.block->statements.size() == 0); + + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(while_to_if_with_convert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { while(1) { while(2) {} } }", "void foo() { if(1) { if(2) {} } }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsChange()); + + const srcDispatch::WhileData& whileData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetOriginal()); + BOOST_TEST(whileData.condition); + BOOST_TEST(whileData.condition.IsCommon()); + BOOST_TEST(whileData.condition->conditions.size() == 1); + BOOST_TEST(whileData.condition->conditions.at(0).IsCommon()); + BOOST_TEST(whileData.condition.ToString() == "1"); + + const srcDispatch::IfStmtData& ifData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetModified()); + BOOST_TEST(ifData.clauses.size() == 1); + + const srcDispatch::IfData& ifClause = *std::any_cast>(ifData.clauses.at(0).GetElement()); + BOOST_TEST(ifData.clauses.at(0).IsInsert()); + BOOST_TEST(ifClause.condition.IsCommon()); + BOOST_TEST(ifClause.condition->conditions.size() == 1); + BOOST_TEST(ifClause.condition->conditions.at(0).IsCommon()); + BOOST_TEST(ifClause.condition.ToString() == "1"); + BOOST_TEST(ifClause.block.IsCommon()); + BOOST_TEST(ifClause.block->statements.size() == 1); + + BOOST_TEST(whileData.block.IsCommon()); + BOOST_TEST(whileData.block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(if_to_for) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { if(i < 10) { sum += i; } }", "void foo() { for(int i = 0; i < 10; ++i) { sum += i; } }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsChange()); + + const srcDispatch::IfStmtData& ifData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetOriginal()); + BOOST_TEST(ifData.clauses.size() == 1); + + const srcDispatch::IfData& ifClause = *std::any_cast>(ifData.clauses.at(0).GetElement()); + BOOST_TEST(ifData.clauses.at(0).IsDelete()); + BOOST_TEST(ifClause.condition.IsCommon()); + BOOST_TEST(ifClause.condition->conditions.size() == 1); + BOOST_TEST(ifClause.condition->conditions.at(0).IsCommon()); + BOOST_TEST(ifClause.condition.ToString() == "i < 10"); + BOOST_TEST(ifClause.block.IsCommon()); + BOOST_TEST(ifClause.block->statements.size() == 1); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetModified()); + BOOST_TEST(forData.control); + BOOST_TEST(forData.control.IsInsert()); + + BOOST_TEST(forData.control->init.IsInsert()); + BOOST_TEST(forData.control->init.ToString() == "|int i = 0"); + + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 10"); + + BOOST_TEST(forData.control->incr.IsInsert()); + BOOST_TEST(forData.control->incr.ToString() == "|++ i"); + + BOOST_TEST(forData.control.ToString(srcDispatch::INSERT) == "int i = 0; i < 10; ++ i"); + + BOOST_TEST(forData.block.IsCommon()); + BOOST_TEST(forData.block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(for_to_if) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0; i < 10; ++i) { sum += i; } }", "void foo() { if(i < 10) { sum += i; } }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsChange()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetOriginal()); + BOOST_TEST(forData.control); + BOOST_TEST(forData.control.IsDelete()); + + BOOST_TEST(forData.control->init.IsDelete()); + BOOST_TEST(forData.control->init.ToString() == "int i = 0|"); + + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 10"); + + BOOST_TEST(forData.control->incr.IsDelete()); + BOOST_TEST(forData.control->incr.ToString() == "++ i|"); + + BOOST_TEST(forData.control.ToString(srcDispatch::DELETE) == "int i = 0; i < 10; ++ i"); + + BOOST_TEST(forData.block.IsCommon()); + BOOST_TEST(forData.block->statements.size() == 1); + + const srcDispatch::IfStmtData& ifData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetModified()); + BOOST_TEST(ifData.clauses.size() == 1); + + const srcDispatch::IfData& ifClause = *std::any_cast>(ifData.clauses.at(0).GetElement()); + BOOST_TEST(ifData.clauses.at(0).IsInsert()); + BOOST_TEST(ifClause.condition.IsCommon()); + BOOST_TEST(ifClause.condition->conditions.size() == 1); + BOOST_TEST(ifClause.condition->conditions.at(0).IsCommon()); + BOOST_TEST(ifClause.condition.ToString() == "i < 10"); + BOOST_TEST(ifClause.block.IsCommon()); + BOOST_TEST(ifClause.block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(while_to_for) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { while(i < 10) { sum += i; } }", "void foo() { for(int i = 0; i < 10; ++i) { sum += i; } }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsChange()); + + const srcDispatch::WhileData& whileData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetOriginal()); + BOOST_TEST(whileData.condition.IsCommon()); + BOOST_TEST(whileData.condition->conditions.size() == 1); + BOOST_TEST(whileData.condition->conditions.at(0).IsCommon()); + BOOST_TEST(whileData.condition.ToString() == "i < 10"); + BOOST_TEST(whileData.block.IsCommon()); + BOOST_TEST(whileData.block->statements.size() == 1); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetModified()); + BOOST_TEST(forData.control); + BOOST_TEST(forData.control.IsInsert()); + + BOOST_TEST(forData.control->init.IsInsert()); + BOOST_TEST(forData.control->init.ToString() == "|int i = 0"); + + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 10"); + + BOOST_TEST(forData.control->incr.IsInsert()); + BOOST_TEST(forData.control->incr.ToString() == "|++ i"); + + BOOST_TEST(forData.control.ToString(srcDispatch::INSERT) == "int i = 0; i < 10; ++ i"); + + BOOST_TEST(forData.block.IsCommon()); + BOOST_TEST(forData.block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(for_to_while) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0; i < 10; ++i) { sum += i; } }", "void foo() { while(i < 10) { sum += i; } }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsChange()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetOriginal()); + BOOST_TEST(forData.control); + BOOST_TEST(forData.control.IsDelete()); + + BOOST_TEST(forData.control->init.IsDelete()); + BOOST_TEST(forData.control->init.ToString() == "int i = 0|"); + + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 10"); + + BOOST_TEST(forData.control->incr.IsDelete()); + BOOST_TEST(forData.control->incr.ToString() == "++ i|"); + + BOOST_TEST(forData.control.ToString(srcDispatch::DELETE) == "int i = 0; i < 10; ++ i"); + + BOOST_TEST(forData.block.IsCommon()); + BOOST_TEST(forData.block->statements.size() == 1); + + const srcDispatch::WhileData& whileData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetModified()); + BOOST_TEST(whileData.condition.IsCommon()); + BOOST_TEST(whileData.condition->conditions.size() == 1); + BOOST_TEST(whileData.condition->conditions.at(0).IsCommon()); + BOOST_TEST(whileData.condition.ToString() == "i < 10"); + BOOST_TEST(whileData.block.IsCommon()); + BOOST_TEST(whileData.block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testControl.cpp b/test/suite/testControl.cpp new file mode 100644 index 0000000..670097b --- /dev/null +++ b/test/suite/testControl.cpp @@ -0,0 +1,1427 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testControl.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE control tests +#include + +#include + +#include +#include +#include + +#include + +// Define test data +namespace data = boost::unit_test; + +BOOST_AUTO_TEST_CASE(block_common_control) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0; 1; ++i) {} }", "void foo() { for(int i = 0; 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 1); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0; 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_control) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0; i < 1; ++i) {} }", "void foo() { for(int i = 1; i < 2; ++j) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 1); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0|int i = 1"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1|i < 2"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i|++ j"); + BOOST_TEST(forData.control->incr.ToString() == "++ i|++ j"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0; i < 1; ++ i|int i = 1; i < 2; ++ j"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_expr_init_control_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(i = 0; i < 1; ++i) {} }", "void foo() { for(i = 0; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 1); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "i = 0"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "i = 0; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_expr_init_control_minor_change) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(i = 0; i < 1; ++i) {} }", "void foo() { for(i = 1; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 1); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "i = 0|i = 1"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "i = 0; i < 1; ++ i|i = 1; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_expr_init_control_replace) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(i = 0; i < 1; ++i) {} }", "void foo() { for(j = 1; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 1); + BOOST_TEST(forData.control->init->inits.at(0).IsChange()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "i = 0|j = 1"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "i = 0; i < 1; ++ i|j = 1; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_expr_init_control_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(; i < 1; ++i) {} }", "void foo() { for(i = 0; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 1); + BOOST_TEST(forData.control->init->inits.at(0).IsInsert()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "|i = 0"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "; i < 1; ++ i|i = 0; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_expr_init_control_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(i = 0; i < 1; ++i) {} }", "void foo() { for(; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 1); + BOOST_TEST(forData.control->init->inits.at(0).IsDelete()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "i = 0|"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "i = 0; i < 1; ++ i|; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_decl_init_control_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(; i < 1; ++i) {} }", "void foo() { for(int i = 0; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 1); + BOOST_TEST(forData.control->init->inits.at(0).IsInsert()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "|int i = 0"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "; i < 1; ++ i|int i = 0; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_decl_init_control_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0; i < 1; ++i) {} }", "void foo() { for(; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 1); + BOOST_TEST(forData.control->init->inits.at(0).IsDelete()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0|"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0; i < 1; ++ i|; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_init_control_decl_to_expr) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0; i < 1; ++i) {} }", "void foo() { for(i = 0; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 2); + BOOST_TEST(forData.control->init->inits.at(0).IsDelete()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0|"); + BOOST_TEST(forData.control->init->inits.at(1).IsInsert()); + BOOST_TEST(forData.control->init->inits.at(1).ToString>() == "|i = 0"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0; i < 1; ++ i|i = 0; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_init_control_expr_to_decl) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(i = 0; i < 1; ++i) {} }", "void foo() { for(int i = 0; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 2); + BOOST_TEST(forData.control->init->inits.at(0).IsDelete()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "i = 0|"); + BOOST_TEST(forData.control->init->inits.at(1).IsInsert()); + BOOST_TEST(forData.control->init->inits.at(1).ToString>() == "|int i = 0"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "i = 0; i < 1; ++ i|int i = 0; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_init_control_multi_decl) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0, j = 1; i < 1; ++i) {} }", "void foo() { for(int i = 0, j = 1; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 2); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0"); + BOOST_TEST(forData.control->init->inits.at(1).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(1).ToString>() == "int j = 1"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0, int j = 1; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_init_control_multi_decl_insert_front) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int j = 1; i < 1; ++i) {} }", "void foo() { for(int i = 0, j = 1; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 2); + BOOST_TEST(forData.control->init->inits.at(0).IsInsert()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "|int i = 0"); + BOOST_TEST(forData.control->init->inits.at(1).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(1).ToString>() == "int j = 1"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int j = 1; i < 1; ++ i|int i = 0, int j = 1; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_init_control_multi_decl_insert_back) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0; i < 1; ++i) {} }", "void foo() { for(int i = 0, j = 1; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 2); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0"); + BOOST_TEST(forData.control->init->inits.at(1).IsInsert()); + BOOST_TEST(forData.control->init->inits.at(1).ToString>() == "|int j = 1"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0; i < 1; ++ i|int i = 0, int j = 1; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_init_control_multi_decl_insert_middle) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0, k = 2; i < 1; ++i) {} }", "void foo() { for(int i = 0, j = 1, k = 2; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 3); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0"); + BOOST_TEST(forData.control->init->inits.at(1).IsInsert()); + BOOST_TEST(forData.control->init->inits.at(1).ToString>() == "|int j = 1"); + BOOST_TEST(forData.control->init->inits.at(2).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(2).ToString>() == "int k = 2"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0, int k = 2; i < 1; ++ i|int i = 0, int j = 1, int k = 2; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_init_control_multi_decl_delete_front) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0, j = 1; i < 1; ++i) {} }", "void foo() { for(int j = 1; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 2); + BOOST_TEST(forData.control->init->inits.at(0).IsDelete()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0|"); + BOOST_TEST(forData.control->init->inits.at(1).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(1).ToString>() == "int j = 1"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0, int j = 1; i < 1; ++ i|int j = 1; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_init_control_multi_decl_delete_back) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0, j = 1; i < 1; ++i) {} }", "void foo() { for(int i = 0; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 2); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0"); + BOOST_TEST(forData.control->init->inits.at(1).IsDelete()); + BOOST_TEST(forData.control->init->inits.at(1).ToString>() == "int j = 1|"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0, int j = 1; i < 1; ++ i|int i = 0; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +// multi decl +BOOST_AUTO_TEST_CASE(block_init_control_multi_decl_delete_middle) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0, j = 1, k = 2; i < 1; ++i) {} }", "void foo() { for(int i = 0, k = 2; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 3); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0"); + BOOST_TEST(forData.control->init->inits.at(1).IsDelete()); + BOOST_TEST(forData.control->init->inits.at(1).ToString>() == "int j = 1|"); + BOOST_TEST(forData.control->init->inits.at(2).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(2).ToString>() == "int k = 2"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0, int j = 1, int k = 2; i < 1; ++ i|int i = 0, int k = 2; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +// multi expr +BOOST_AUTO_TEST_CASE(block_init_control_multi_expr) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(i = 0, j = 1; i < 1; ++i) {} }", "void foo() { for(i = 0, j = 1; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 2); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "i = 0"); + BOOST_TEST(forData.control->init->inits.at(1).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(1).ToString>() == "j = 1"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "i = 0, j = 1; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_init_control_multi_expr_insert_front) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(j = 1; i < 1; ++i) {} }", "void foo() { for(i = 0, j = 1; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 2); + BOOST_TEST(forData.control->init->inits.at(0).IsInsert()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "|i = 0"); + BOOST_TEST(forData.control->init->inits.at(1).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(1).ToString>() == "j = 1"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "j = 1; i < 1; ++ i|i = 0, j = 1; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_init_control_multi_expr_insert_back) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(i = 0; i < 1; ++i) {} }", "void foo() { for(i = 0, j = 1; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 2); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "i = 0"); + BOOST_TEST(forData.control->init->inits.at(1).IsInsert()); + BOOST_TEST(forData.control->init->inits.at(1).ToString>() == "|j = 1"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "i = 0; i < 1; ++ i|i = 0, j = 1; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_init_control_multi_expr_insert_middle) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(i = 0, k = 2; i < 1; ++i) {} }", "void foo() { for(i = 0, j = 1, k = 2; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 3); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "i = 0"); + BOOST_TEST(forData.control->init->inits.at(1).IsInsert()); + BOOST_TEST(forData.control->init->inits.at(1).ToString>() == "|j = 1"); + BOOST_TEST(forData.control->init->inits.at(2).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(2).ToString>() == "k = 2"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "i = 0, k = 2; i < 1; ++ i|i = 0, j = 1, k = 2; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_init_control_multi_expr_delete_front) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(i = 0, j = 1; i < 1; ++i) {} }", "void foo() { for(j = 1; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 2); + BOOST_TEST(forData.control->init->inits.at(0).IsDelete()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "i = 0|"); + BOOST_TEST(forData.control->init->inits.at(1).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(1).ToString>() == "j = 1"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "i = 0, j = 1; i < 1; ++ i|j = 1; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_init_control_multi_expr_delete_back) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(i = 0, j = 1; i < 1; ++i) {} }", "void foo() { for(i = 0; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 2); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "i = 0"); + BOOST_TEST(forData.control->init->inits.at(1).IsDelete()); + BOOST_TEST(forData.control->init->inits.at(1).ToString>() == "j = 1|"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "i = 0, j = 1; i < 1; ++ i|i = 0; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_init_control_multi_expr_delete_middle) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(i = 0, j = 1, k = 2; i < 1; ++i) {} }", "void foo() { for(i = 0, k = 2; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 3); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "i = 0"); + BOOST_TEST(forData.control->init->inits.at(1).IsDelete()); + BOOST_TEST(forData.control->init->inits.at(1).ToString>() == "j = 1|"); + BOOST_TEST(forData.control->init->inits.at(2).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(2).ToString>() == "k = 2"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 1); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr.ToString() == "++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "i = 0, j = 1, k = 2; i < 1; ++ i|i = 0, k = 2; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +// multi incr +BOOST_AUTO_TEST_CASE(block_incr_control_multi_expr) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0; i < 1; ++i, --j) {} }", "void foo() { for(int i = 0; i < 1; ++i, --j) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 1); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 2); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr->exprs.at(1).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(1).ToString() == "-- j"); + BOOST_TEST(forData.control->incr.ToString() == "++ i, -- j"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0; i < 1; ++ i, -- j"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_incr_control_multi_expr_insert_front) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0; i < 1; --j) {} }", "void foo() { for(int i = 0; i < 1; ++i, --j) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 1); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 2); + BOOST_TEST(forData.control->incr->exprs.at(0).IsInsert()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "|++ i"); + BOOST_TEST(forData.control->incr->exprs.at(1).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(1).ToString() == "-- j"); + BOOST_TEST(forData.control->incr.ToString() == "-- j|++ i, -- j"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0; i < 1; -- j|int i = 0; i < 1; ++ i, -- j"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_incr_control_multi_expr_insert_back) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0; i < 1; ++i) {} }", "void foo() { for(int i = 0; i < 1; ++i, --j) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 1); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 2); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr->exprs.at(1).IsInsert()); + BOOST_TEST(forData.control->incr->exprs.at(1).ToString() == "|-- j"); + BOOST_TEST(forData.control->incr.ToString() == "++ i|++ i, -- j"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0; i < 1; ++ i|int i = 0; i < 1; ++ i, -- j"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_incr_control_multi_expr_insert_middle) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0; i < 1; ++i, k /= 2) {} }", "void foo() { for(int i = 0; i < 1; ++i, --j, k /= 2) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 1); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 3); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr->exprs.at(1).IsInsert()); + BOOST_TEST(forData.control->incr->exprs.at(1).ToString() == "|-- j"); + BOOST_TEST(forData.control->incr->exprs.at(2).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(2).ToString() == "k /= 2"); + BOOST_TEST(forData.control->incr.ToString() == "++ i, k /= 2|++ i, -- j, k /= 2"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0; i < 1; ++ i, k /= 2|int i = 0; i < 1; ++ i, -- j, k /= 2"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_incr_control_multi_expr_delete_front) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0; i < 1; ++i, --j) {} }", "void foo() { for(int i = 0; i < 1; --j) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 1); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 2); + BOOST_TEST(forData.control->incr->exprs.at(0).IsDelete()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i|"); + BOOST_TEST(forData.control->incr->exprs.at(1).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(1).ToString() == "-- j"); + BOOST_TEST(forData.control->incr.ToString() == "++ i, -- j|-- j"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0; i < 1; ++ i, -- j|int i = 0; i < 1; -- j"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_incr_control_multi_expr_delete_back) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0; i < 1; ++i, --j) {} }", "void foo() { for(int i = 0; i < 1; ++i) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 1); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 2); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr->exprs.at(1).IsDelete()); + BOOST_TEST(forData.control->incr->exprs.at(1).ToString() == "-- j|"); + BOOST_TEST(forData.control->incr.ToString() == "++ i, -- j|++ i"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0; i < 1; ++ i, -- j|int i = 0; i < 1; ++ i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_incr_control_multi_expr_delete_middle) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(int i = 0; i < 1; ++i, --j, k /= 2) {} }", "void foo() { for(int i = 0; i < 1; ++i, k /= 2) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 1); + BOOST_TEST(forData.control->init->inits.at(0).IsCommon()); + BOOST_TEST(forData.control->init->inits.at(0).ToString>() == "int i = 0"); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition->conditions.size() == 1); + BOOST_TEST(forData.control->condition->conditions.at(0).IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "i < 1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 3); + BOOST_TEST(forData.control->incr->exprs.at(0).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(0).ToString() == "++ i"); + BOOST_TEST(forData.control->incr->exprs.at(1).IsDelete()); + BOOST_TEST(forData.control->incr->exprs.at(1).ToString() == "-- j|"); + BOOST_TEST(forData.control->incr->exprs.at(2).IsCommon()); + BOOST_TEST(forData.control->incr->exprs.at(2).ToString() == "k /= 2"); + BOOST_TEST(forData.control->incr.ToString() == "++ i, -- j, k /= 2|++ i, k /= 2"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i = 0; i < 1; ++ i, -- j, k /= 2|int i = 0; i < 1; ++ i, k /= 2"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testDecl.cpp b/test/suite/testDecl.cpp new file mode 100644 index 0000000..00744bd --- /dev/null +++ b/test/suite/testDecl.cpp @@ -0,0 +1,1241 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testDecl.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE decl tests +#include + +#include + +#include +#include +#include + +// Define test data +namespace data = boost::unit_test; + +// templated (not arg but def) + +BOOST_AUTO_TEST_CASE(decl_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"type a = 0;", "type a = 0;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.ToString() == "0"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "type a = 0"); +} + +BOOST_AUTO_TEST_CASE(decl_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"", "type a = 0;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "|type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "|a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "|a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.ToString() == "|0"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "|type a = 0"); +} + +BOOST_AUTO_TEST_CASE(decl_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"type a = 0;", ""}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type|"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a|"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a|"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.ToString() == "0|"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "type a = 0|"); +} + +BOOST_AUTO_TEST_CASE(name_rename) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"type a = 0;", "type b = 0;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsChange()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a|b"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.GetOriginal() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.GetModified() == "b"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.ToString() == "0"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "type a = 0|type b = 0"); +} + +BOOST_AUTO_TEST_CASE(type_rename) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"foo a;", "bar a;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->name.IsChange()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "foo|bar"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "foo a|bar a"); +} + +BOOST_AUTO_TEST_CASE(type_rename_two) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"foo a;", "foo* a;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 2); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->name.IsCommon()); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).second.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).second.GetElement() == srcDispatch::TypeData::TypeType::POINTER); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).first); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "foo|foo *"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "foo a|foo * a"); +} + +BOOST_AUTO_TEST_CASE(decl_init_literal_change) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"type a = 0;", "type a = 1;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.IsChange()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.GetOriginal()->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.GetModified()->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.GetOriginal()->expr.at(0).IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.GetModified()->expr.at(0).IsInsert()); + + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.GetOriginal()->expr.at(0).GetOriginal())->literal.IsDelete()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.GetModified()->expr.at(0).GetModified())->literal.IsInsert()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.GetOriginal()->expr.at(0).GetOriginal())->literal.ToString() == "0|"); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.GetModified()->expr.at(0).GetModified())->literal.ToString() == "|1"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "type a = 0|type a = 1"); +} + +BOOST_AUTO_TEST_CASE(init_literal_change_2) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"type a(0);", "type a = 1;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0).IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0)->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0)->expr.at(0).IsDelete()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0)->expr.at(0).GetOriginal())->literal.ToString() == "0|"); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0)->expr.at(0).GetOriginal())->literal.IsDelete()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0)->expr.at(0).GetOriginal())->literal.ToString() == "0|"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.at(0).IsInsert()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.at(0).GetModified())->literal.IsInsert()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.at(0).GetModified())->literal.ToString() == "|1"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "type a(0)|type a = 1"); +} + +BOOST_AUTO_TEST_CASE(init_literal_change_3) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"type a{0};", "type a = 1;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0).IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0)->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0)->expr.at(0).IsDelete()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0)->expr.at(0).GetOriginal())->literal.ToString() == "0|"); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0)->expr.at(0).GetOriginal())->literal.IsDelete()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0)->expr.at(0).GetOriginal())->literal.ToString() == "0|"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.at(0).IsInsert()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.at(0).GetModified())->literal.IsInsert()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.at(0).GetModified())->literal.ToString() == "|1"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "type a(0)|type a = 1"); +} + +BOOST_AUTO_TEST_CASE(name_only_match) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"type* a(0);", "typePtr a = 1;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 2); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->name.IsChange()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.ToString>() == "type|typePtr"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).second.IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).second.GetElement() == srcDispatch::TypeData::TypeType::POINTER); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type *|typePtr"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0).IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0)->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0)->expr.at(0).IsDelete()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0)->expr.at(0).GetOriginal())->literal.ToString() == "0|"); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0)->expr.at(0).GetOriginal())->literal.IsDelete()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->arguments.at(0)->expr.at(0).GetOriginal())->literal.ToString() == "0|"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.at(0).IsInsert()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.at(0).GetModified())->literal.IsInsert()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.at(0).GetModified())->literal.ToString() == "|1"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "type * a(0)|typePtr a = 1"); +} + +BOOST_AUTO_TEST_CASE(comma_separated_decl) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"type a = 0, b = 1, c = 2;", "type a = 0, c = 2, d = 3;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 4); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.ToString() == "0"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1).IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1)->generics.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1)->type->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1)->type.ToString() == "type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1)->name.IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1)->name->name.IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1)->name.ToString() == "b|"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1)->name->name.ToString() == "b|"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1)->init.IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1)->init.ToString() == "1|"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2)->generics.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2)->type->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2)->type.ToString() == "type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2)->name.ToString() == "c"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2)->name->name.ToString() == "c"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2)->init.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2)->init.ToString() == "2"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(3).IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(3)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(3)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(3)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(3)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(3)->type->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(3)->type.ToString() == "type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(3)->name.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(3)->name->name.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(3)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(3)->name.ToString() == "|d"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(3)->name->name.ToString() == "|d"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(3)->init.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(3)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(3)->init.ToString() == "|3"); + + // a little weird as type is shared, so always in common + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).ToString() == "type a = 0"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(1).ToString() == "type b = 1|type"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(2).ToString() == "type c = 2"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(3).ToString() == "type|type d = 3"); +} + +// compound name +BOOST_AUTO_TEST_CASE(decl_compound_name_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"std::string str = \"\";", "std::string str = \"\";"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + + BOOST_TEST(!std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->name); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.size() == 3); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first).IsCommon()); + + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0)).IsCommon()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement())->names.size() == 0); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement())->name.IsCommon()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement())->name.ToString() == "std"); + + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(1)).IsCommon()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(1).GetElement())->op.IsCommon()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(1).GetElement())->op.ToString() == "::"); + + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(2)).IsCommon()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(2).GetElement())->names.size() == 0); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(2).GetElement())->name.IsCommon()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(2).GetElement())->name.ToString() == "string"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.ToString>() == "std::string"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "std::string"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "str"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "str"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.ToString() == "\"\""); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "std::string str = \"\""); +} + +BOOST_AUTO_TEST_CASE(decl_compound_name_change) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"std::string str = \"\";", "std::wstring str = \"\";"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + + BOOST_TEST(!std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->name); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.size() == 3); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first).IsCommon()); + + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0)).IsCommon()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement())->names.size() == 0); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement())->name.IsCommon()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement())->name.ToString() == "std"); + + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(1)).IsCommon()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(1).GetElement())->op.IsCommon()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(1).GetElement())->op.ToString() == "::"); + + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(2)).IsCommon()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(2).GetElement())->names.size() == 0); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(2).GetElement())->name.IsChange()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(2).GetElement())->name.ToString() == "string|wstring"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.ToString>() == "std::string|std::wstring"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "std::string|std::wstring"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "str"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "str"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.ToString() == "\"\""); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "std::string str = \"\"|std::wstring str = \"\""); +} + +BOOST_AUTO_TEST_CASE(decl_simple_to_complex_name) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"string str = \"\";", "std::string str = \"\";"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsInsert()); + + BOOST_TEST(!std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->name); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.size() == 3); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first).IsInsert()); + + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0)).IsInsert()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement())->names.size() == 0); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement())->name.IsInsert()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement())->name.ToString() == "|std"); + + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(1)).IsInsert()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(1).GetElement())->op.IsInsert()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(1).GetElement())->op.ToString() == "|::"); + + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(2)).IsCommon()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(2).GetElement())->names.size() == 0); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(2).GetElement())->name.IsCommon()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(2).GetElement())->name.ToString() == "string"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.ToString>() == "string|std::string"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "string|std::string"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "str"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "str"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.ToString() == "\"\""); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "string str = \"\"|std::string str = \"\""); +} + +// specifier test +BOOST_AUTO_TEST_CASE(decl_add_specifier) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"type a = 0;", "const type a = 0;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 2); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::SPECIFIER); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.ToString>() == "|const"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).first.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).first.ToString>() == "type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type|const type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.ToString() == "0"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "type a = 0|const type a = 0"); +} + +// specifier test +BOOST_AUTO_TEST_CASE(decl_remove_specifier) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"const type a = 0;", "type a = 0;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 2); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::SPECIFIER); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.ToString>() == "const|"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).first.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).first.ToString>() == "type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "const type|type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.ToString() == "0"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "const type a = 0|type a = 0"); +} + +// specifier test +BOOST_AUTO_TEST_CASE(decl_change_specifier) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"static type a = 0;", "const type a = 0;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 3); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::SPECIFIER); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.ToString>() == "static|"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).second.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).second.GetElement() == srcDispatch::TypeData::TypeType::SPECIFIER); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).first.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).first.ToString>() == "|const"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(2).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(2).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(2).first.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(2).first.ToString>() == "type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "static type|const type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.ToString() == "0"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "static type a = 0|const type a = 0"); +} + +// modifier change test +BOOST_AUTO_TEST_CASE(decl_modifier_change) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"type* a;", "type& a;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 2); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.ToString>() == "type"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).second.IsChange()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).second.GetOriginal() == srcDispatch::TypeData::TypeType::POINTER); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(1).second.GetModified() == srcDispatch::TypeData::TypeType::REFERENCE); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type *|type &"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "type * a|type & a"); +} + +// templated name +BOOST_AUTO_TEST_CASE(decl_template_argument_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"type a;", "type a;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + + BOOST_TEST(!std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->name); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.size() == 1); + BOOST_TEST(std::any_cast>( + std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement() + )->name.IsCommon() + ); + BOOST_TEST(std::any_cast>( + std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement() + )->name.ToString() == "type" + ); + + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList.IsCommon()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.size() == 1); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0).IsCommon()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0).ToString() == "arg"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "type a"); +} + +BOOST_AUTO_TEST_CASE(decl_template_argument_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"type a;", "type a;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsInsert()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsInsert()); + + BOOST_TEST(!std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->name); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.size() == 1); + BOOST_TEST(std::any_cast>( + std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement() + )->name.IsCommon() + ); + BOOST_TEST(std::any_cast>( + std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement() + )->name.ToString() == "type" + ); + + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList.IsInsert()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.size() == 1); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0).IsInsert()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0).ToString() == "|arg"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type|type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "type a|type a"); +} + +BOOST_AUTO_TEST_CASE(decl_template_argument_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"type a;", "type a;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsDelete()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsDelete()); + + BOOST_TEST(!std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->name); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.size() == 1); + BOOST_TEST(std::any_cast>( + std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement() + )->name.IsCommon() + ); + BOOST_TEST(std::any_cast>( + std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement() + )->name.ToString() == "type" + ); + + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList.IsDelete()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.size() == 1); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0).IsDelete()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0).ToString() == "arg|"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type|type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "type a|type a"); +} + +BOOST_AUTO_TEST_CASE(decl_template_argument_insert_arg) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"type a;", "type a;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + + BOOST_TEST(!std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->name); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.size() == 1); + BOOST_TEST(std::any_cast>( + std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement() + )->name.IsCommon() + ); + BOOST_TEST(std::any_cast>( + std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement() + )->name.ToString() == "type" + ); + + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList.IsCommon()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.size() == 2); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0).IsCommon()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0).ToString() == "foo"); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(1).IsInsert()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(1).ToString() == "|bar"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type|type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "type a|type a"); +} + +BOOST_AUTO_TEST_CASE(decl_template_argument_delete_arg) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"type a;", "type a;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + + BOOST_TEST(!std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->name); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.size() == 1); + BOOST_TEST(std::any_cast>( + std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement() + )->name.IsCommon() + ); + BOOST_TEST(std::any_cast>( + std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement() + )->name.ToString() == "type" + ); + + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList.IsCommon()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.size() == 2); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0).IsDelete()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0).ToString() == "foo|"); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(1).IsCommon()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(1).ToString() == "bar"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type|type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "type a|type a"); +} + +BOOST_AUTO_TEST_CASE(decl_template_argument_change_arg) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"type a;", "type a;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 0); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + + BOOST_TEST(!std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->name); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.size() == 1); + BOOST_TEST(std::any_cast>( + std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement() + )->name.IsCommon() + ); + BOOST_TEST(std::any_cast>( + std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->names.at(0).GetElement() + )->name.ToString() == "type" + ); + + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList.IsCommon()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.size() == 1); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0).IsCommon()); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0)->expr.size() == 1); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0)->expr.at(0).IsCommon()); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0)->expr.at(0).GetElement() + )->names.size() == 0 + ); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0)->expr.at(0).GetElement() + )->name.IsChange() + ); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0)->expr.at(0).GetElement() + )->name.GetOriginal() == "foo" + ); + BOOST_TEST(std::any_cast>( + std::any_cast>( + runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0)->expr.at(0).GetElement() + )->name.GetModified() == "bar" + ); + BOOST_TEST(std::any_cast>(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.GetElement())->templateArgumentList->arguments.at(0).ToString() == "foo|bar"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type|type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "type a|type a"); +} + +// templated +BOOST_AUTO_TEST_CASE(decl_template_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template type a = 0;", "template type a = 0;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 1); + BOOST_TEST(runner.GetFunctionInfo().size() == 0); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.at(0).IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->generics.at(0).ToString() == "template"); + BOOST_TEST(!runner.GetDeclStmtInfo().at(0)->decls.at(0)->accessSpecifier); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->type.ToString() == "type"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name.ToString() == "a"); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->name->name.ToString() == "a"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.IsCommon()); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init->expr.size() == 1); + BOOST_TEST(runner.GetDeclStmtInfo().at(0)->decls.at(0)->init.ToString() == "0"); + + BOOST_TEST(runner.GetDeclStmtInfo().at(0).ToString() == "type a = 0"); +} diff --git a/test/suite/testDeclStmt.cpp b/test/suite/testDeclStmt.cpp new file mode 100644 index 0000000..8c3cc94 --- /dev/null +++ b/test/suite/testDeclStmt.cpp @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testDeclStmt.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE decl_stmt tests +#include + +#include + +#include +#include +#include + +// Define test data +namespace data = boost::unit_test; + +BOOST_AUTO_TEST_CASE(block_common_decl_stmt) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { int i; }", "void foo() { int i; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "int i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_insert_decl_stmt) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { foo bar; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "|foo bar"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_delete_decl_stmt) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { foo bar; }", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "foo bar|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_replace_decl_stmt) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { foo f; }", "void foo() { bar b; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 2); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "foo f|"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(1).IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(1).ToString>() == "|bar b"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testDo.cpp b/test/suite/testDo.cpp new file mode 100644 index 0000000..5601dd4 --- /dev/null +++ b/test/suite/testDo.cpp @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testDo.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE do_stmt tests +#include + +#include + +#include +#include +#include + +#include + +// Define test data +namespace data = boost::unit_test; + +BOOST_AUTO_TEST_CASE(block_change_common_do) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { do {} while(1); }", "void foo() { do {} while(1); }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_insert_do) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { do {} while(1);"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + const srcDispatch::DoData& doData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(doData.condition); + BOOST_TEST(doData.condition.IsInsert()); + BOOST_TEST(doData.condition->conditions.size() == 1); + BOOST_TEST(doData.condition->conditions.at(0).IsInsert()); + + const srcDispatch::ExpressionData& expr = *std::any_cast>(doData.condition->conditions.at(0).GetElement()); + BOOST_TEST(expr.expr.size() == 1); + BOOST_TEST(expr.expr.at(0).IsInsert()); + BOOST_TEST(std::any_cast>(expr.expr.at(0).GetElement())->literal.GetElement() == "1"); + BOOST_TEST(std::any_cast>(expr.expr.at(0).GetElement())->literal.ToString() == "|1"); + BOOST_TEST(expr.expr.at(0).ToString>() == "|1"); + BOOST_TEST(doData.condition->conditions.at(0).ToString>() == "|1"); + BOOST_TEST(doData.condition.ToString() == "|1"); + + BOOST_TEST(doData.block.IsInsert()); + BOOST_TEST(doData.block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "|1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_delete_do) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { do {} while(1);", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::DoData& doData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(doData.condition); + BOOST_TEST(doData.condition.IsDelete()); + BOOST_TEST(doData.condition->conditions.size() == 1); + BOOST_TEST(doData.condition->conditions.at(0).IsDelete()); + + const srcDispatch::ExpressionData& expr = *std::any_cast>(doData.condition->conditions.at(0).GetElement()); + BOOST_TEST(expr.expr.size() == 1); + BOOST_TEST(expr.expr.at(0).IsDelete()); + BOOST_TEST(std::any_cast>(expr.expr.at(0).GetElement())->literal.GetElement() == "1"); + BOOST_TEST(std::any_cast>(expr.expr.at(0).GetElement())->literal.ToString() == "1|"); + BOOST_TEST(expr.expr.at(0).ToString>() == "1|"); + BOOST_TEST(doData.condition->conditions.at(0).ToString>() == "1|"); + BOOST_TEST(doData.condition.ToString() == "1|"); + + BOOST_TEST(doData.block.IsDelete()); + BOOST_TEST(doData.block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_replace_do) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { do { a; } while(1); }", "void foo() { do { b; } while(2); }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 2); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::DoData& deletedData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(deletedData.condition.IsDelete()); + BOOST_TEST(deletedData.block.IsDelete()); + BOOST_TEST(deletedData.block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(1).IsInsert()); + + const srcDispatch::DoData& insertedData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(1).GetElement()); + BOOST_TEST(insertedData.condition.IsInsert()); + BOOST_TEST(insertedData.block.IsInsert()); + BOOST_TEST(insertedData.block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(1).ToString>() == "|2"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testExprConvert.cpp b/test/suite/testExprConvert.cpp new file mode 100644 index 0000000..fb51bd8 --- /dev/null +++ b/test/suite/testExprConvert.cpp @@ -0,0 +1,268 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testExprConvert.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE expr convert tests +#include + +#include + +#include +#include +#include + +#include +#include +#include + +// Define test data +namespace data = boost::unit_test; + +BOOST_AUTO_TEST_CASE(decl_to_expr) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { int i = 0; }", "void foo() { 0; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsChange()); + + const srcDispatch::DeclStmtData& declStmtData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetOriginal()); + BOOST_TEST(declStmtData.decls.size() == 1); + BOOST_TEST(declStmtData.decls.at(0).IsDelete()); + BOOST_TEST(declStmtData.decls.at(0)->type.IsDelete()); + BOOST_TEST(declStmtData.decls.at(0)->type.ToString() == "int|"); + BOOST_TEST(declStmtData.decls.at(0)->name.IsDelete()); + BOOST_TEST(declStmtData.decls.at(0)->name.ToString() == "i|"); + BOOST_TEST(declStmtData.decls.at(0)->init.IsCommon()); + BOOST_TEST(declStmtData.decls.at(0)->init->expr.size() == 1); + BOOST_TEST(declStmtData.decls.at(0)->init->expr.at(0).IsCommon()); + BOOST_TEST(declStmtData.decls.at(0)->init->expr.at(0).ToString>() == "0"); + BOOST_TEST(declStmtData.decls.at(0)->init.ToString() == "0"); + BOOST_TEST(declStmtData.decls.at(0).ToString(srcDispatch::DELETE) == "int i = 0"); + + const srcDispatch::ExprStmtData& exprStmtData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetModified()); + BOOST_TEST(exprStmtData.expr.IsCommon()); + BOOST_TEST(exprStmtData.expr->expr.size() == 1); + BOOST_TEST(exprStmtData.expr->expr.at(0).IsCommon()); + BOOST_TEST(exprStmtData.expr->expr.at(0).ToString>() == "0"); + BOOST_TEST(exprStmtData.expr.ToString() == "0"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(expr_to_decl) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { 0; }", "void foo() { int i = 0; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsChange()); + + const srcDispatch::ExprStmtData& exprStmtData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetOriginal()); + BOOST_TEST(exprStmtData.expr.IsCommon()); + BOOST_TEST(exprStmtData.expr->expr.size() == 1); + BOOST_TEST(exprStmtData.expr->expr.at(0).IsCommon()); + BOOST_TEST(exprStmtData.expr->expr.at(0).ToString>() == "0"); + BOOST_TEST(exprStmtData.expr.ToString() == "0"); + + const srcDispatch::DeclStmtData& declStmtData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetModified()); + BOOST_TEST(declStmtData.decls.size() == 1); + BOOST_TEST(declStmtData.decls.at(0).IsInsert()); + BOOST_TEST(declStmtData.decls.at(0)->type.IsInsert()); + BOOST_TEST(declStmtData.decls.at(0)->type.ToString() == "|int"); + BOOST_TEST(declStmtData.decls.at(0)->name.IsInsert()); + BOOST_TEST(declStmtData.decls.at(0)->name.ToString() == "|i"); + BOOST_TEST(declStmtData.decls.at(0)->init.IsCommon()); + BOOST_TEST(declStmtData.decls.at(0)->init->expr.size() == 1); + BOOST_TEST(declStmtData.decls.at(0)->init->expr.at(0).IsCommon()); + BOOST_TEST(declStmtData.decls.at(0)->init->expr.at(0).ToString>() == "0"); + BOOST_TEST(declStmtData.decls.at(0)->init.ToString() == "0"); + BOOST_TEST(declStmtData.decls.at(0).ToString(srcDispatch::INSERT) == "int i = 0"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(expr_to_return) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { 0; }", "void foo() { return 0; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsChange()); + + const srcDispatch::ExprStmtData& exprStmtData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetOriginal()); + BOOST_TEST(exprStmtData.expr.IsCommon()); + BOOST_TEST(exprStmtData.expr->expr.size() == 1); + BOOST_TEST(exprStmtData.expr->expr.at(0).IsCommon()); + BOOST_TEST(exprStmtData.expr->expr.at(0).ToString>() == "0"); + BOOST_TEST(exprStmtData.expr.ToString() == "0"); + + const srcDispatch::ReturnData& returnData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetModified()); + BOOST_TEST(returnData.expr.IsCommon()); + BOOST_TEST(returnData.expr->expr.size() == 1); + BOOST_TEST(returnData.expr->expr.at(0).IsCommon()); + BOOST_TEST(returnData.expr->expr.at(0).ToString>() == "0"); + BOOST_TEST(returnData.expr.ToString() == "0"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(return_to_expr) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { return 0; }", "void foo() { 0; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsChange()); + + const srcDispatch::ReturnData& returnData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetOriginal()); + BOOST_TEST(returnData.expr.IsCommon()); + BOOST_TEST(returnData.expr->expr.size() == 1); + BOOST_TEST(returnData.expr->expr.at(0).IsCommon()); + BOOST_TEST(returnData.expr->expr.at(0).ToString>() == "0"); + BOOST_TEST(returnData.expr.ToString() == "0"); + + const srcDispatch::ExprStmtData& exprStmtData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetModified()); + BOOST_TEST(exprStmtData.expr.IsCommon()); + BOOST_TEST(exprStmtData.expr->expr.size() == 1); + BOOST_TEST(exprStmtData.expr->expr.at(0).IsCommon()); + BOOST_TEST(exprStmtData.expr->expr.at(0).ToString>() == "0"); + BOOST_TEST(exprStmtData.expr.ToString() == "0"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(decl_to_return) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { int i = 0; }", "void foo() { return 0; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsChange()); + + const srcDispatch::DeclStmtData& declStmtData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetOriginal()); + BOOST_TEST(declStmtData.decls.size() == 1); + BOOST_TEST(declStmtData.decls.at(0).IsDelete()); + BOOST_TEST(declStmtData.decls.at(0)->type.IsDelete()); + BOOST_TEST(declStmtData.decls.at(0)->type.ToString() == "int|"); + BOOST_TEST(declStmtData.decls.at(0)->name.IsDelete()); + BOOST_TEST(declStmtData.decls.at(0)->name.ToString() == "i|"); + BOOST_TEST(declStmtData.decls.at(0)->init.IsCommon()); + BOOST_TEST(declStmtData.decls.at(0)->init->expr.size() == 1); + BOOST_TEST(declStmtData.decls.at(0)->init->expr.at(0).IsCommon()); + BOOST_TEST(declStmtData.decls.at(0)->init->expr.at(0).ToString>() == "0"); + BOOST_TEST(declStmtData.decls.at(0)->init.ToString() == "0"); + BOOST_TEST(declStmtData.decls.at(0).ToString(srcDispatch::DELETE) == "int i = 0"); + + const srcDispatch::ReturnData& returnData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetModified()); + BOOST_TEST(returnData.expr.IsCommon()); + BOOST_TEST(returnData.expr->expr.size() == 1); + BOOST_TEST(returnData.expr->expr.at(0).IsCommon()); + BOOST_TEST(returnData.expr->expr.at(0).ToString>() == "0"); + BOOST_TEST(returnData.expr.ToString() == "0"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(return_to_decl) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { return 0; }", "void foo() { int i = 0; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsChange()); + + const srcDispatch::ReturnData& returnData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetOriginal()); + BOOST_TEST(returnData.expr.IsCommon()); + BOOST_TEST(returnData.expr->expr.size() == 1); + BOOST_TEST(returnData.expr->expr.at(0).IsCommon()); + BOOST_TEST(returnData.expr->expr.at(0).ToString>() == "0"); + BOOST_TEST(returnData.expr.ToString() == "0"); + + const srcDispatch::DeclStmtData& declStmtData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetModified()); + BOOST_TEST(declStmtData.decls.size() == 1); + BOOST_TEST(declStmtData.decls.at(0).IsInsert()); + BOOST_TEST(declStmtData.decls.at(0)->type.IsInsert()); + BOOST_TEST(declStmtData.decls.at(0)->type.ToString() == "|int"); + BOOST_TEST(declStmtData.decls.at(0)->name.IsInsert()); + BOOST_TEST(declStmtData.decls.at(0)->name.ToString() == "|i"); + BOOST_TEST(declStmtData.decls.at(0)->init.IsCommon()); + BOOST_TEST(declStmtData.decls.at(0)->init->expr.size() == 1); + BOOST_TEST(declStmtData.decls.at(0)->init->expr.at(0).IsCommon()); + BOOST_TEST(declStmtData.decls.at(0)->init->expr.at(0).ToString>() == "0"); + BOOST_TEST(declStmtData.decls.at(0)->init.ToString() == "0"); + BOOST_TEST(declStmtData.decls.at(0).ToString(srcDispatch::INSERT) == "int i = 0"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testExprStmt.cpp b/test/suite/testExprStmt.cpp new file mode 100644 index 0000000..747b2a5 --- /dev/null +++ b/test/suite/testExprStmt.cpp @@ -0,0 +1,185 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testExprStmt.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE expr_stmt tests +#include + +#include + +#include +#include +#include + +// Define test data +namespace data = boost::unit_test; + +BOOST_AUTO_TEST_CASE(block_change_common_expr_stmt) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { a; }", "void foo() { a; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "a"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_insert_expr_stmt) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { a; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + const srcDispatch::ExprStmtData& expr = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(expr.expr); + BOOST_TEST(expr.expr.IsInsert()); + BOOST_TEST(expr.expr->expr.size() == 1); + BOOST_TEST(expr.expr->expr.at(0).IsInsert()); + BOOST_TEST(std::any_cast>(expr.expr->expr.at(0).GetElement())->name.IsInsert()); + BOOST_TEST(expr.expr->expr.at(0).ToString>() == "|a"); + BOOST_TEST(expr.expr.ToString() == "|a"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "|a"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_delete_expr_stmt) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { a; }", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::ExprStmtData& expr = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(expr.expr); + BOOST_TEST(expr.expr.IsDelete()); + BOOST_TEST(expr.expr->expr.size() == 1); + BOOST_TEST(expr.expr->expr.at(0).IsDelete()); + BOOST_TEST(std::any_cast>(expr.expr->expr.at(0).GetElement())->name.IsDelete()); + BOOST_TEST(expr.expr->expr.at(0).ToString>() == "a|"); + BOOST_TEST(expr.expr.ToString() == "a|"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "a|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_expr_stmt) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { a - b; }", "void foo() { a + b; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ExprStmtData& expr = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(expr.expr); + BOOST_TEST(expr.expr.IsCommon()); + BOOST_TEST(expr.expr->expr.size() == 3); + BOOST_TEST(expr.expr->expr.at(0).IsCommon()); + BOOST_TEST(expr.expr->expr.at(0).ToString>() == "a"); + BOOST_TEST(expr.expr->expr.at(1).IsCommon()); + BOOST_TEST(std::any_cast>(expr.expr->expr.at(1).GetElement())->op.IsChange()); + BOOST_TEST(std::any_cast>(expr.expr->expr.at(1).GetElement())->op.ToString() == "-|+"); + BOOST_TEST(expr.expr->expr.at(1).ToString>() == "-|+"); + BOOST_TEST(expr.expr->expr.at(2).IsCommon()); + BOOST_TEST(expr.expr->expr.at(2).ToString>() == "b"); + BOOST_TEST(expr.expr.ToString() == "a - b|a + b"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "a - b|a + b"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_replace_expr_stmt) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { a; }", "void foo() { b; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 2); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::ExprStmtData& deletedExpr = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(deletedExpr.expr); + BOOST_TEST(deletedExpr.expr.IsDelete()); + BOOST_TEST(deletedExpr.expr->expr.size() == 1); + BOOST_TEST(deletedExpr.expr->expr.at(0).IsDelete()); + BOOST_TEST(std::any_cast>(deletedExpr.expr->expr.at(0).GetElement())->name.IsDelete()); + BOOST_TEST(deletedExpr.expr->expr.at(0).ToString>() == "a|"); + BOOST_TEST(deletedExpr.expr.ToString() == "a|"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "a|"); + + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(1).IsInsert()); + + const srcDispatch::ExprStmtData& insertedExpr = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(1).GetElement()); + BOOST_TEST(insertedExpr.expr); + BOOST_TEST(insertedExpr.expr.IsInsert()); + BOOST_TEST(insertedExpr.expr->expr.size() == 1); + BOOST_TEST(insertedExpr.expr->expr.at(0).IsInsert()); + BOOST_TEST(std::any_cast>(insertedExpr.expr->expr.at(0).GetElement())->name.IsInsert()); + BOOST_TEST(insertedExpr.expr->expr.at(0).ToString>() == "|b"); + BOOST_TEST(insertedExpr.expr.ToString() == "|b"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(1).ToString>() == "|b"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testFor.cpp b/test/suite/testFor.cpp new file mode 100644 index 0000000..556936a --- /dev/null +++ b/test/suite/testFor.cpp @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testFor.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE for_stmt tests +#include + +#include + +#include +#include +#include + +#include + +// Define test data +namespace data = boost::unit_test; + +// // for and control +BOOST_AUTO_TEST_CASE(block_common_for) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(; 1; ) {} }", "void foo() { for(; 1; ) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsCommon()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsCommon()); + BOOST_TEST(forData.control->init->inits.size() == 0); + BOOST_TEST(forData.control->condition.IsCommon()); + BOOST_TEST(forData.control->condition.ToString() == "1"); + BOOST_TEST(forData.control->incr.IsCommon()); + BOOST_TEST(forData.control->incr->exprs.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "; 1; "); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_insert_for) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { for(; 1; ) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsInsert()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsInsert()); + BOOST_TEST(forData.control->init->inits.size() == 0); + BOOST_TEST(forData.control->condition.IsInsert()); + BOOST_TEST(forData.control->condition.ToString() == "|1"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsInsert()); + BOOST_TEST(forData.control->incr->exprs.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "|; 1; "); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_delete_for) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { for(; 1; ) {} }", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::ForData& forData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(forData.control.IsDelete()); + BOOST_TEST(forData.control->init); + BOOST_TEST(forData.control->init.IsDelete()); + BOOST_TEST(forData.control->init->inits.size() == 0); + BOOST_TEST(forData.control->condition.IsDelete()); + BOOST_TEST(forData.control->condition.ToString() == "1|"); + BOOST_TEST(forData.control->incr); + BOOST_TEST(forData.control->incr.IsDelete()); + BOOST_TEST(forData.control->incr->exprs.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "; 1; |"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testFunction.cpp b/test/suite/testFunction.cpp new file mode 100644 index 0000000..f601640 --- /dev/null +++ b/test/suite/testFunction.cpp @@ -0,0 +1,1182 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testFunction.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE function tests +#include + +#include + +#include +#include +#include + +// Define test data +namespace data = boost::unit_test; + +BOOST_AUTO_TEST_CASE(function_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(function_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "|void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "|foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "|foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "|void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(function_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", ""}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo|"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}|"); +} + +BOOST_AUTO_TEST_CASE(function_name_change) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void bar() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsChange()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo|bar"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.GetOriginal() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.GetModified() == "bar"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}|void bar() {}"); +} + +BOOST_AUTO_TEST_CASE(function_return_type_change) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "int foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(std::any_cast>(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.GetElement())->name.IsChange()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void|int"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}|int foo() {}"); +} + +BOOST_AUTO_TEST_CASE(function_add_parameter) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo(int i) {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0).IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type->types.at(0).second.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type->types.at(0).first.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type.ToString() == "|int"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->name.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->name.ToString() == "|i"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}|void foo(int i) {}"); +} + +BOOST_AUTO_TEST_CASE(function_remove_parameter) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo(double d) {}", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0).IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type->types.at(0).second.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type->types.at(0).first.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type.ToString() == "double|"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->name.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->name.ToString() == "d|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo(double d) {}|void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(function_parameter_type_change) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo(double d) {}", "void foo(int d) {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type->types.at(0).first.IsCommon()); + BOOST_TEST(std::any_cast>(runner.GetFunctionInfo().at(0)->parameters.at(0)->type->types.at(0).first.GetElement())->name.IsChange()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type.ToString() == "double|int"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->name.ToString() == "d"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo(double d) {}|void foo(int d) {}"); +} + +BOOST_AUTO_TEST_CASE(function_parameter_name_change) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo(double d) {}", "void foo(double num) {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type.ToString() == "double"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->name->name.IsChange()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->name.ToString() == "d|num"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo(double d) {}|void foo(double num) {}"); +} + +BOOST_AUTO_TEST_CASE(function_parameter_multi_change) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo(int i, double d) {}", "void foo(double d, long l) {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 3); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0).IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type->types.at(0).second.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type->types.at(0).first.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->type.ToString() == "int|"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->name.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(0)->name.ToString() == "i|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(1).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(1)->type.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(1)->type->types.at(0).first.IsCommon()); + BOOST_TEST(std::any_cast>(runner.GetFunctionInfo().at(0)->parameters.at(1)->type->types.at(0).first.GetElement())->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(1)->type.ToString() == "double"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(1)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(1)->name.ToString() == "d"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(2).IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(2)->type.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(2)->type->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(2)->type->types.at(0).second.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(2)->type->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(2)->type->types.at(0).first.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(2)->type.ToString() == "|long"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(2)->name.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.at(2)->name.ToString() == "|l"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo(int i, double d) {}|void foo(double d, long l) {}"); +} + +// decl to def +BOOST_AUTO_TEST_CASE(function_decl_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo();", "void foo();"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->block); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo();"); +} + +// specifiers +BOOST_AUTO_TEST_CASE(function_specifier_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo();", "void foo() const;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.at(0).IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.at(0).ToString() == "|const"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->block); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo();|void foo() const;"); +} + +BOOST_AUTO_TEST_CASE(function_specifier_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() const;", "void foo();"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.at(0).IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.at(0).ToString() == "const|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->block); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() const;|void foo();"); +} + +BOOST_AUTO_TEST_CASE(function_pure_virtual_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo();", "void foo() = 0;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(runner.GetFunctionInfo().at(0)->isPureVirtual.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->isPureVirtual.GetElement()); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->block); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo();|void foo() = 0;"); +} + +BOOST_AUTO_TEST_CASE(function_pure_virtual_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() = 0;", "void foo();"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(runner.GetFunctionInfo().at(0)->isPureVirtual.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->isPureVirtual.GetElement()); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->block); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() = 0;|void foo();"); +} + +BOOST_AUTO_TEST_CASE(function_pure_delete_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo();", "void foo() = delete;"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->isDelete); + BOOST_TEST(runner.GetFunctionInfo().at(0)->isDelete.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->isDelete.GetElement()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->block); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo();|void foo() = delete;"); +} + +BOOST_AUTO_TEST_CASE(function_pure_delete_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() = delete;", "void foo();"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(runner.GetFunctionInfo().at(0)->isDelete); + BOOST_TEST(runner.GetFunctionInfo().at(0)->isDelete.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->isDelete.GetElement()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->block); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() = delete;|void foo();"); +} + +// block +BOOST_AUTO_TEST_CASE(function_block_insert_expr_stmt) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { a; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + const srcDispatch::ExprStmtData& expr = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(expr.expr); + BOOST_TEST(expr.expr.IsInsert()); + BOOST_TEST(expr.expr->expr.size() == 1); + BOOST_TEST(expr.expr->expr.at(0).IsInsert()); + BOOST_TEST(std::any_cast>(expr.expr->expr.at(0).GetElement())->name.IsInsert()); + BOOST_TEST(expr.expr->expr.at(0).ToString>() == "|a"); + BOOST_TEST(expr.expr.ToString() == "|a"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "|a"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +// operator +BOOST_AUTO_TEST_CASE(function_operator_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"bool operator==() {}", "bool operator==() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::OPERATOR); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "bool"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "operator=="); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "operator"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "bool operator==() {}"); +} + +BOOST_AUTO_TEST_CASE(function_operator_common_decl) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"bool operator==();", "bool operator==();"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::OPERATOR); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "bool"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "operator=="); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "operator"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->block); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "bool operator==();"); +} + +BOOST_AUTO_TEST_CASE(function_operator_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"", "bool operator==() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::OPERATOR); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "|bool"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "|operator=="); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "|operator"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "|bool operator==() {}"); +} + +BOOST_AUTO_TEST_CASE(function_operator_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"bool operator==() {}", ""}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::OPERATOR); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "bool|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "operator==|"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "operator|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "bool operator==() {}|"); +} + +BOOST_AUTO_TEST_CASE(function_operator_type) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"operator bool() {}", "operator bool() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.empty()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::OPERATOR); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->returnType); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "operator bool"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "operator "); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "operator bool() {}"); +} + +// template function +BOOST_AUTO_TEST_CASE(function_template_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template void foo() {}", "template void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "template"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(function_template_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "template void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "|template"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(function_template_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template void foo() {}", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "template|"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(!runner.GetFunctionInfo().at(0)->accessSpecifier); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isPureVirtual); + BOOST_TEST(!runner.GetFunctionInfo().at(0)->isDelete); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->leadingSpecifiers.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->trailingSpecifiers.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).second.GetElement() == srcDispatch::TypeData::TypeType::TYPENAME); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType->types.at(0).first.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->returnType.ToString() == "void"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->names.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name.ToString() == "foo"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->name->name.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->parameters.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +// decl to defn (add to srcDiff first) diff --git a/test/suite/testGoto.cpp b/test/suite/testGoto.cpp new file mode 100644 index 0000000..4398115 --- /dev/null +++ b/test/suite/testGoto.cpp @@ -0,0 +1,323 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testGoto.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE goto_stmts tests +#include + +#include + +#include +#include +#include + +#include + +// Define test data +namespace data = boost::unit_test; + +// goto/break/continue +BOOST_AUTO_TEST_CASE(block_change_common_break) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { break; }", "void foo() { break; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::GotoData& gotoData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(gotoData.type.IsCommon()); + BOOST_TEST(gotoData.type.GetElement() == srcDispatch::GotoData::BREAK); + BOOST_TEST(!gotoData.label); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_insert_break) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { break; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + const srcDispatch::GotoData& gotoData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(gotoData.type.IsInsert()); + BOOST_TEST(gotoData.type.GetElement() == srcDispatch::GotoData::BREAK); + BOOST_TEST(!gotoData.label); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_delete_break) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { break; }", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::GotoData& gotoData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(gotoData.type.IsDelete()); + BOOST_TEST(gotoData.type.GetElement() == srcDispatch::GotoData::BREAK); + BOOST_TEST(!gotoData.label); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_common_continue) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { continue; }", "void foo() { continue; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::GotoData& gotoData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(gotoData.type.IsCommon()); + BOOST_TEST(gotoData.type.GetElement() == srcDispatch::GotoData::CONTINUE); + BOOST_TEST(!gotoData.label); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_insert_continue) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { continue; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + const srcDispatch::GotoData& gotoData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(gotoData.type.IsInsert()); + BOOST_TEST(gotoData.type.GetElement() == srcDispatch::GotoData::CONTINUE); + BOOST_TEST(!gotoData.label); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_delete_continue) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { continue; }", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::GotoData& gotoData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(gotoData.type.IsDelete()); + BOOST_TEST(gotoData.type.GetElement() == srcDispatch::GotoData::CONTINUE); + BOOST_TEST(!gotoData.label); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_common_goto) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { goto; }", "void foo() { goto; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::GotoData& gotoData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(gotoData.type.IsCommon()); + BOOST_TEST(gotoData.type.GetElement() == srcDispatch::GotoData::GOTO); + BOOST_TEST(!gotoData.label); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_insert_goto) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { goto; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + const srcDispatch::GotoData& gotoData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(gotoData.type.IsInsert()); + BOOST_TEST(gotoData.type.GetElement() == srcDispatch::GotoData::GOTO); + BOOST_TEST(!gotoData.label); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_delete_goto) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { goto; }", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::GotoData& gotoData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(gotoData.type.IsDelete()); + BOOST_TEST(gotoData.type.GetElement() == srcDispatch::GotoData::GOTO); + BOOST_TEST(!gotoData.label); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_common_label_goto) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { goto foo; }", "void foo() { goto foo; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::GotoData& gotoData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(gotoData.type.IsCommon()); + BOOST_TEST(gotoData.type.GetElement() == srcDispatch::GotoData::GOTO); + BOOST_TEST(gotoData.label.IsCommon()); + BOOST_TEST(gotoData.label.ToString() == "foo"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_rename_label_goto) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { goto foo; }", "void foo() { goto bar; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::GotoData& gotoData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + + BOOST_TEST(gotoData.type.IsCommon()); + BOOST_TEST(gotoData.type.GetElement() == srcDispatch::GotoData::GOTO); + BOOST_TEST(gotoData.label.IsCommon()); + BOOST_TEST(gotoData.label->name.IsChange()); + BOOST_TEST(gotoData.label.ToString() == "foo|bar"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testIfStmt.cpp b/test/suite/testIfStmt.cpp new file mode 100644 index 0000000..cde6a29 --- /dev/null +++ b/test/suite/testIfStmt.cpp @@ -0,0 +1,478 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testIfStmt.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE if_stmt tests +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +// Define test data +namespace data = boost::unit_test; + +BOOST_AUTO_TEST_CASE(block_change_common_if_stmt) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { if(1) {} }", "void foo() { if(1) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_insert_if_stmt) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { if(1) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + const srcDispatch::IfStmtData& ifStmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(ifStmt.clauses.size() == 1); + BOOST_TEST(ifStmt.clauses.at(0).IsInsert()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.IsInsert()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.ToString() == "|1"); + BOOST_TEST(ifStmt.clauses.at(0).ToString>() == "|1"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "|1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_delete_if_stmt) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { if(1) {} }", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::IfStmtData& ifStmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(ifStmt.clauses.size() == 1); + BOOST_TEST(ifStmt.clauses.at(0).IsDelete()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.IsDelete()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.ToString() == "1|"); + BOOST_TEST(ifStmt.clauses.at(0).ToString>() == "1|"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_condition_if_stmt) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { if(1) {} }", "void foo() { if(2) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::IfStmtData& ifStmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(ifStmt.clauses.size() == 1); + BOOST_TEST(ifStmt.clauses.at(0).IsCommon()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.IsCommon()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.ToString() == "1|2"); + BOOST_TEST(ifStmt.clauses.at(0).ToString>() == "1|2"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1|2"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_common_elseif) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { if(1) {} else if(2) {} }", "void foo() { if(1) {} else if(2) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::IfStmtData& ifStmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(ifStmt.clauses.size() == 2); + + BOOST_TEST(ifStmt.clauses.at(0).IsCommon()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.IsCommon()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.ToString() == "1"); + BOOST_TEST(ifStmt.clauses.at(0).ToString>() == "1"); + + BOOST_TEST(ifStmt.clauses.at(1).IsCommon()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(1).GetElement())->condition.IsCommon()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(1).GetElement())->condition.ToString() == "2"); + BOOST_TEST(ifStmt.clauses.at(1).ToString>() == "2"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_insert_elseif_whole) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { if(1) {} else if(2) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + const srcDispatch::IfStmtData& ifStmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(ifStmt.clauses.size() == 2); + + BOOST_TEST(ifStmt.clauses.at(0).IsInsert()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.IsInsert()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.ToString() == "|1"); + BOOST_TEST(ifStmt.clauses.at(0).ToString>() == "|1"); + + BOOST_TEST(ifStmt.clauses.at(1).IsInsert()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(1).GetElement())->condition.IsInsert()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(1).GetElement())->condition.ToString() == "|2"); + BOOST_TEST(ifStmt.clauses.at(1).ToString>() == "|2"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "|1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_delete_elseif_whole) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {if(1) {} else if(2) {} }", "void foo() { }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::IfStmtData& ifStmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(ifStmt.clauses.size() == 2); + + BOOST_TEST(ifStmt.clauses.at(0).IsDelete()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.IsDelete()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.ToString() == "1|"); + BOOST_TEST(ifStmt.clauses.at(0).ToString>() == "1|"); + + BOOST_TEST(ifStmt.clauses.at(1).IsDelete()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(1).GetElement())->condition.IsDelete()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(1).GetElement())->condition.ToString() == "2|"); + BOOST_TEST(ifStmt.clauses.at(1).ToString>() == "2|"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_insert_elseif) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { if(1) {} }", "void foo() { if(1) {} else if(2) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::IfStmtData& ifStmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(ifStmt.clauses.size() == 2); + + BOOST_TEST(ifStmt.clauses.at(0).IsCommon()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.IsCommon()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.ToString() == "1"); + BOOST_TEST(ifStmt.clauses.at(0).ToString>() == "1"); + + BOOST_TEST(ifStmt.clauses.at(1).IsInsert()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(1).GetElement())->condition.IsInsert()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(1).GetElement())->condition.ToString() == "|2"); + BOOST_TEST(ifStmt.clauses.at(1).ToString>() == "|2"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_delete_elseif) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { if(1) {} else if(2) {} }", "void foo() { if(1) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::IfStmtData& ifStmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(ifStmt.clauses.size() == 2); + + BOOST_TEST(ifStmt.clauses.at(0).IsCommon()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.IsCommon()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.ToString() == "1"); + BOOST_TEST(ifStmt.clauses.at(0).ToString>() == "1"); + + BOOST_TEST(ifStmt.clauses.at(1).IsDelete()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(1).GetElement())->condition.IsDelete()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(1).GetElement())->condition.ToString() == "2|"); + BOOST_TEST(ifStmt.clauses.at(1).ToString>() == "2|"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_common_else) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { if(1) {} else {} }", "void foo() { if(1) {} else {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::IfStmtData& ifStmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(ifStmt.clauses.size() == 2); + + BOOST_TEST(ifStmt.clauses.at(0).IsCommon()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.IsCommon()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.ToString() == "1"); + BOOST_TEST(ifStmt.clauses.at(0).ToString>() == "1"); + + BOOST_TEST(ifStmt.clauses.at(1).IsCommon()); + BOOST_TEST(!std::any_cast>(ifStmt.clauses.at(1).GetElement())->condition); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_insert_else_whole) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { if(1) {} else {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + const srcDispatch::IfStmtData& ifStmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(ifStmt.clauses.size() == 2); + + BOOST_TEST(ifStmt.clauses.at(0).IsInsert()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.IsInsert()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.ToString() == "|1"); + BOOST_TEST(ifStmt.clauses.at(0).ToString>() == "|1"); + + BOOST_TEST(ifStmt.clauses.at(1).IsInsert()); + BOOST_TEST(!std::any_cast>(ifStmt.clauses.at(1).GetElement())->condition); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "|1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_delete_else_whole) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {if(1) {} else {} }", "void foo() { }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::IfStmtData& ifStmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(ifStmt.clauses.size() == 2); + + BOOST_TEST(ifStmt.clauses.at(0).IsDelete()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.IsDelete()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.ToString() == "1|"); + BOOST_TEST(ifStmt.clauses.at(0).ToString>() == "1|"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1|"); + + BOOST_TEST(ifStmt.clauses.at(1).IsDelete()); + BOOST_TEST(!std::any_cast>(ifStmt.clauses.at(1).GetElement())->condition); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_insert_else) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { if(1) {} }", "void foo() { if(1) {} else {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::IfStmtData& ifStmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(ifStmt.clauses.size() == 2); + + BOOST_TEST(ifStmt.clauses.at(0).IsCommon()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.IsCommon()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.ToString() == "1"); + BOOST_TEST(ifStmt.clauses.at(0).ToString>() == "1"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1"); + + BOOST_TEST(ifStmt.clauses.at(1).IsInsert()); + BOOST_TEST(!std::any_cast>(ifStmt.clauses.at(1).GetElement())->condition); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_delete_else) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { if(1) {} else {} }", "void foo() { if(1) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::IfStmtData& ifStmt = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(ifStmt.clauses.size() == 2); + + BOOST_TEST(ifStmt.clauses.at(0).IsCommon()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.IsCommon()); + BOOST_TEST(std::any_cast>(ifStmt.clauses.at(0).GetElement())->condition.ToString() == "1"); + BOOST_TEST(ifStmt.clauses.at(0).ToString>() == "1"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1"); + + BOOST_TEST(ifStmt.clauses.at(1).IsDelete()); + BOOST_TEST(!std::any_cast>(ifStmt.clauses.at(1).GetElement())->condition); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testLabel.cpp b/test/suite/testLabel.cpp new file mode 100644 index 0000000..2463b4d --- /dev/null +++ b/test/suite/testLabel.cpp @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testLabel.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE label tests +#include + +#include + +#include +#include +#include + +// Define test data +namespace data = boost::unit_test; + +BOOST_AUTO_TEST_CASE(block_common_label) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { label: }", "void foo() { label: }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.at(0)->name.ToString() == "label"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_insert_label) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { label: }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.at(0).IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.at(0)->name.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.at(0)->name.ToString() == "|label"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_delete_label) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { label: }", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.at(0).IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.at(0)->name.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.at(0)->name.ToString() == "label|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_replace_label) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { foo: }", "void foo() { bar: }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 2); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.at(0).IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.at(0)->name.IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.at(0)->name.ToString() == "foo|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.at(1).IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.at(1)->name.IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.at(1)->name.ToString() == "|bar"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testReturn.cpp b/test/suite/testReturn.cpp new file mode 100644 index 0000000..c154dbb --- /dev/null +++ b/test/suite/testReturn.cpp @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testReturn.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE return_stmt tests +#include + +#include + +#include +#include +#include + +// Define test data +namespace data = boost::unit_test; + +BOOST_AUTO_TEST_CASE(block_change_common_return) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { return 0; }", "void foo() { return 0; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "0"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_insert_return) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { return a; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + const srcDispatch::ReturnData& returnData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(returnData.expr); + BOOST_TEST(returnData.expr.IsInsert()); + BOOST_TEST(returnData.expr->expr.size() == 1); + BOOST_TEST(returnData.expr->expr.at(0).IsInsert()); + BOOST_TEST(std::any_cast>(returnData.expr->expr.at(0).GetElement())->name.IsInsert()); + BOOST_TEST(returnData.expr->expr.at(0).ToString>() == "|a"); + BOOST_TEST(returnData.expr.ToString() == "|a"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "|a"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_delete_return) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { return a; }", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::ReturnData& returnData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(returnData.expr); + BOOST_TEST(returnData.expr.IsDelete()); + BOOST_TEST(returnData.expr->expr.size() == 1); + BOOST_TEST(returnData.expr->expr.at(0).IsDelete()); + BOOST_TEST(std::any_cast>(returnData.expr->expr.at(0).GetElement())->name.IsDelete()); + BOOST_TEST(returnData.expr->expr.at(0).ToString>() == "a|"); + BOOST_TEST(returnData.expr.ToString() == "a|"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "a|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_return) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { return a - b; }", "void foo() { return a + b; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ReturnData& returnData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(returnData.expr); + BOOST_TEST(returnData.expr.IsCommon()); + BOOST_TEST(returnData.expr->expr.size() == 3); + BOOST_TEST(returnData.expr->expr.at(0).IsCommon()); + BOOST_TEST(returnData.expr->expr.at(0).ToString>() == "a"); + BOOST_TEST(returnData.expr->expr.at(1).IsCommon()); + BOOST_TEST(std::any_cast>(returnData.expr->expr.at(1).GetElement())->op.IsChange()); + BOOST_TEST(std::any_cast>(returnData.expr->expr.at(1).GetElement())->op.ToString() == "-|+"); + BOOST_TEST(returnData.expr->expr.at(1).ToString>() == "-|+"); + BOOST_TEST(returnData.expr->expr.at(2).IsCommon()); + BOOST_TEST(returnData.expr->expr.at(2).ToString>() == "b"); + BOOST_TEST(returnData.expr.ToString() == "a - b|a + b"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "a - b|a + b"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_return_expr) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { return a; }", "void foo() { return b; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ReturnData& returnData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(returnData.expr); + BOOST_TEST(returnData.expr.IsCommon()); + BOOST_TEST(returnData.expr->expr.size() == 1); + BOOST_TEST(returnData.expr->expr.at(0).IsCommon()); + BOOST_TEST(std::any_cast>(returnData.expr->expr.at(0).GetElement())->name.IsChange()); + BOOST_TEST(returnData.expr->expr.at(0).ToString>() == "a|b"); + BOOST_TEST(returnData.expr.ToString() == "a|b"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "a|b"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_whole_return) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { return 0; }", "void foo() { return a; }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ReturnData& returnData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(returnData.expr); + BOOST_TEST(returnData.expr.IsChange()); + + BOOST_TEST(returnData.expr.GetOriginal()->expr.size() == 1); + BOOST_TEST(returnData.expr.GetOriginal()->expr.at(0).IsDelete()); + BOOST_TEST(returnData.expr.GetOriginal()->expr.at(0).IsDelete()); + BOOST_TEST(std::any_cast>(returnData.expr.GetOriginal()->expr.at(0).GetElement())->literal.IsDelete()); + BOOST_TEST(std::any_cast>(returnData.expr.GetOriginal()->expr.at(0).GetElement())->literal.ToString() == "0|"); + BOOST_TEST(returnData.expr.GetOriginal()->expr.at(0).ToString>() == "0|"); + + BOOST_TEST(returnData.expr.GetModified()->expr.size() == 1); + BOOST_TEST(returnData.expr.GetModified()->expr.at(0).IsInsert()); + BOOST_TEST(returnData.expr.GetModified()->expr.at(0).IsInsert()); + BOOST_TEST(std::any_cast>(returnData.expr.GetModified()->expr.at(0).GetElement())->name.IsInsert()); + BOOST_TEST(std::any_cast>(returnData.expr.GetModified()->expr.at(0).GetElement())->name.ToString() == "|a"); + BOOST_TEST(returnData.expr.GetModified()->expr.at(0).ToString>() == "|a"); + + BOOST_TEST(returnData.expr.ToString() == "0|a"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "0|a"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testSwitch.cpp b/test/suite/testSwitch.cpp new file mode 100644 index 0000000..267492d --- /dev/null +++ b/test/suite/testSwitch.cpp @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testSwitch.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE switch_stmt tests +#include + +#include + +#include +#include +#include + +#include + +// Define test data +namespace data = boost::unit_test; + +// switch +BOOST_AUTO_TEST_CASE(block_change_common_switch) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { switch(1) {} }", "void foo() { switch(1) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_insert_switch) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { switch(1) {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + const srcDispatch::SwitchData& switchData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(switchData.condition); + BOOST_TEST(switchData.condition.IsInsert()); + BOOST_TEST(switchData.condition->conditions.size() == 1); + BOOST_TEST(switchData.condition->conditions.at(0).IsInsert()); + + const srcDispatch::ExpressionData& expr = *std::any_cast>(switchData.condition->conditions.at(0).GetElement()); + BOOST_TEST(expr.expr.size() == 1); + BOOST_TEST(expr.expr.at(0).IsInsert()); + BOOST_TEST(std::any_cast>(expr.expr.at(0).GetElement())->literal.GetElement() == "1"); + BOOST_TEST(std::any_cast>(expr.expr.at(0).GetElement())->literal.ToString() == "|1"); + BOOST_TEST(expr.expr.at(0).ToString>() == "|1"); + BOOST_TEST(switchData.condition->conditions.at(0).ToString>() == "|1"); + BOOST_TEST(switchData.condition.ToString() == "|1"); + + BOOST_TEST(switchData.block.IsInsert()); + BOOST_TEST(switchData.block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "|1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_delete_switch) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { switch(1) {}", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::SwitchData& switchData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(switchData.condition); + BOOST_TEST(switchData.condition.IsDelete()); + BOOST_TEST(switchData.condition->conditions.size() == 1); + BOOST_TEST(switchData.condition->conditions.at(0).IsDelete()); + + const srcDispatch::ExpressionData& expr = *std::any_cast>(switchData.condition->conditions.at(0).GetElement()); + BOOST_TEST(expr.expr.size() == 1); + BOOST_TEST(expr.expr.at(0).IsDelete()); + BOOST_TEST(std::any_cast>(expr.expr.at(0).GetElement())->literal.GetElement() == "1"); + BOOST_TEST(std::any_cast>(expr.expr.at(0).GetElement())->literal.ToString() == "1|"); + BOOST_TEST(expr.expr.at(0).ToString>() == "1|"); + BOOST_TEST(switchData.condition->conditions.at(0).ToString>() == "1|"); + BOOST_TEST(switchData.condition.ToString() == "1|"); + + BOOST_TEST(switchData.block.IsDelete()); + BOOST_TEST(switchData.block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_replace_switch) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { switch(1) { default: a; } }", "void foo() { switch(2) { default: b; } }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 2); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::SwitchData& deletedData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(deletedData.condition.IsDelete()); + BOOST_TEST(deletedData.block.IsDelete()); + BOOST_TEST(deletedData.block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(1).IsInsert()); + + const srcDispatch::SwitchData& insertedData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(1).GetElement()); + BOOST_TEST(insertedData.condition.IsInsert()); + BOOST_TEST(insertedData.block.IsInsert()); + BOOST_TEST(insertedData.block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(1).ToString>() == "|2"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testTemplate.cpp b/test/suite/testTemplate.cpp new file mode 100644 index 0000000..b1c5bae --- /dev/null +++ b/test/suite/testTemplate.cpp @@ -0,0 +1,335 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testFunction.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE template tests +#include + +#include + +#include +#include +#include + +// Define test data +namespace data = boost::unit_test; + +BOOST_AUTO_TEST_CASE(template_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template void foo() {}", "template void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "template"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(template_insert_front) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template void func() {}", "template template void func() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 2); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "|template"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(1).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(1).ToString() == "template"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void func() {}"); +} + +BOOST_AUTO_TEST_CASE(template_insert_back) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template void func() {}", "template template void func() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 2); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "template"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(1).IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(1).ToString() == "|template"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void func() {}"); +} + +BOOST_AUTO_TEST_CASE(template_delete_front) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template template void func() {}", "template void func() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 2); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "template|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(1).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(1).ToString() == "template"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void func() {}"); +} + +BOOST_AUTO_TEST_CASE(template_delete_back) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template template void func() {}", "template void func() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 2); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "template"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(1).IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(1).ToString() == "template|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void func() {}"); +} + +BOOST_AUTO_TEST_CASE(template_insert_parameter_front) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template void foo() {}", "template void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.size() == 2); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0).IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(1).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "template|template"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(template_insert_parameter_back) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template void foo() {}", "template void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.size() == 2); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(1).IsInsert()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "template|template"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(template_delete_parameter_front) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template void foo() {}", "template void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.size() == 2); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0).IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(1).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "template|template"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(template_delete_parameter_back) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template void foo() {}", "template void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.size() == 2); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(1).IsDelete()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "template|template"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(template_modify_parameter_type) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template void foo() {}", "template void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0)->type.ToString() == "typename|class"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0)->name.ToString() == "type"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0).ToString() == "typename type|class type"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "template|template"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(template_modify_parameter_name) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template void foo() {}", "template void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0)->type.ToString() == "typename"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0)->name.ToString() == "type|T"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0).ToString() == "typename type|typename T"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "template|template"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(template_modify_parameter_init) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template void foo() {}", "template void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0)->type.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0)->type.ToString() == "typename"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0)->name.IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0)->name.ToString() == "type"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0)->parameters.at(0).ToString() == "typename type|typename type = object"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "template|template"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(template_common_int) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template void foo() {}", "template void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "template"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(template_common_int_insert_init) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"template void foo() {}", "template void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).IsCommon()); + BOOST_TEST(runner.GetFunctionInfo().at(0)->generics.at(0).ToString() == "template|template"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->type.GetElement() == srcDispatch::FunctionData::FUNCTION); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testThrow.cpp b/test/suite/testThrow.cpp new file mode 100644 index 0000000..87a89ab --- /dev/null +++ b/test/suite/testThrow.cpp @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testThrow.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE throw_stmt tests +#include + +#include + +#include +#include +#include + +// Define test data +namespace data = boost::unit_test; + +BOOST_AUTO_TEST_CASE(block_change_common_throw) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { throw std::string(); }", "void foo() { throw std::string(); }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "std::string()"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_insert_throw) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { throw Exception(); }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + const srcDispatch::ThrowData& throwData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(throwData.expr); + BOOST_TEST(throwData.expr.IsInsert()); + BOOST_TEST(throwData.expr->expr.size() == 1); + BOOST_TEST(throwData.expr->expr.at(0).IsInsert()); + BOOST_TEST(std::any_cast>(throwData.expr->expr.at(0).GetElement())->name.IsInsert()); + BOOST_TEST(throwData.expr->expr.at(0).ToString>() == "|Exception()"); + BOOST_TEST(throwData.expr.ToString() == "|Exception()"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "|Exception()"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_delete_throw) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { throw Exception(); }", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::ThrowData& throwData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(throwData.expr); + BOOST_TEST(throwData.expr.IsDelete()); + BOOST_TEST(throwData.expr->expr.size() == 1); + BOOST_TEST(throwData.expr->expr.at(0).IsDelete()); + BOOST_TEST(std::any_cast>(throwData.expr->expr.at(0).GetElement())->name.IsDelete()); + BOOST_TEST(throwData.expr->expr.at(0).ToString>() == "Exception()|"); + BOOST_TEST(throwData.expr.ToString() == "Exception()|"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "Exception()|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_throw) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { throw std::string(); }", "void foo() { throw Exception(); }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::ThrowData& throwData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(throwData.expr); + BOOST_TEST(throwData.expr.IsChange()); + BOOST_TEST(throwData.expr.GetOriginal()->expr.size() == 1); + BOOST_TEST(throwData.expr.GetOriginal()->expr.at(0).IsDelete()); + BOOST_TEST(throwData.expr.GetOriginal()->expr.at(0).ToString>() == "std::string()|"); + BOOST_TEST(throwData.expr.GetModified()->expr.size() == 1); + BOOST_TEST(throwData.expr.GetModified()->expr.at(0).IsInsert()); + BOOST_TEST(throwData.expr.GetModified()->expr.at(0).ToString>() == "|Exception()"); + BOOST_TEST(throwData.expr.ToString() == "std::string()|Exception()"); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "std::string()|Exception()"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} \ No newline at end of file diff --git a/test/suite/testTry.cpp b/test/suite/testTry.cpp new file mode 100644 index 0000000..2b1738d --- /dev/null +++ b/test/suite/testTry.cpp @@ -0,0 +1,509 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testIfStmt.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE try_catch tests +#include + +#include + +#include +#include +#include + +#include +#include + +// Define test data +namespace data = boost::unit_test; + +BOOST_AUTO_TEST_CASE(try_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { try {} }", "void foo() { try {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).OriginalType().name() == typeid(std::shared_ptr).name()); + BOOST_TEST(bool(std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement())->block)); + BOOST_TEST(bool(std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement())->block.IsCommon())); + BOOST_TEST(std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement())->clauses.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(try_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { try {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ModifiedType().name() == typeid(std::shared_ptr).name()); + BOOST_TEST(bool(std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement())->block)); + BOOST_TEST(bool(std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement())->block.IsInsert())); + BOOST_TEST(std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement())->clauses.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(try_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { try {} }", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).OriginalType().name() == typeid(std::shared_ptr).name()); + BOOST_TEST(bool(std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement())->block)); + BOOST_TEST(bool(std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement())->block.IsDelete())); + BOOST_TEST(std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement())->clauses.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(catch_common) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { try {} catch() {} }", "void foo() { try {} catch() {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).OriginalType().name() == typeid(std::shared_ptr).name()); + + const srcDispatch::TryData& tryData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(bool(tryData.block)); + BOOST_TEST(bool(tryData.block.IsCommon())); + + BOOST_TEST(tryData.clauses.size() == 1); + BOOST_TEST(tryData.clauses.at(0).IsCommon()); + + const srcDispatch::CatchData& catchData = *std::any_cast>(tryData.clauses.at(0).GetElement()); + BOOST_TEST(catchData.parameters.size() == 0); + BOOST_TEST(catchData.block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(catch_insert) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { try {} }", "void foo() { try {} catch() {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).OriginalType().name() == typeid(std::shared_ptr).name()); + + const srcDispatch::TryData& tryData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(bool(tryData.block)); + BOOST_TEST(bool(tryData.block.IsCommon())); + + BOOST_TEST(tryData.clauses.size() == 1); + BOOST_TEST(tryData.clauses.at(0).IsInsert()); + + const srcDispatch::CatchData& catchData = *std::any_cast>(tryData.clauses.at(0).GetElement()); + BOOST_TEST(catchData.parameters.size() == 0); + BOOST_TEST(catchData.block.IsInsert()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(catch_delete) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { try {} catch() {} }", "void foo() { try {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).OriginalType().name() == typeid(std::shared_ptr).name()); + + const srcDispatch::TryData& tryData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(bool(tryData.block)); + BOOST_TEST(bool(tryData.block.IsCommon())); + + BOOST_TEST(tryData.clauses.size() == 1); + BOOST_TEST(tryData.clauses.at(0).IsDelete()); + + const srcDispatch::CatchData& catchData = *std::any_cast>(tryData.clauses.at(0).GetElement()); + BOOST_TEST(catchData.parameters.size() == 0); + BOOST_TEST(catchData.block.IsDelete()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(catch_common_param) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { try {} catch(Exception e) {} }", "void foo() { try {} catch(Exception e) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).OriginalType().name() == typeid(std::shared_ptr).name()); + + const srcDispatch::TryData& tryData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(bool(tryData.block)); + BOOST_TEST(bool(tryData.block.IsCommon())); + + BOOST_TEST(tryData.clauses.size() == 1); + BOOST_TEST(tryData.clauses.at(0).IsCommon()); + + const srcDispatch::CatchData& catchData = *std::any_cast>(tryData.clauses.at(0).GetElement()); + BOOST_TEST(catchData.parameters.size() == 1); + BOOST_TEST(catchData.parameters.at(0).IsCommon()); + BOOST_TEST(catchData.parameters.at(0).ToString() == "Exception e"); + + BOOST_TEST(catchData.block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(catch_insert_param) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { try {} catch() {} }", "void foo() { try {} catch(Exception e) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).OriginalType().name() == typeid(std::shared_ptr).name()); + + const srcDispatch::TryData& tryData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(bool(tryData.block)); + BOOST_TEST(bool(tryData.block.IsCommon())); + + BOOST_TEST(tryData.clauses.size() == 1); + BOOST_TEST(tryData.clauses.at(0).IsCommon()); + + const srcDispatch::CatchData& catchData = *std::any_cast>(tryData.clauses.at(0).GetElement()); + BOOST_TEST(catchData.parameters.size() == 1); + BOOST_TEST(catchData.parameters.at(0).IsInsert()); + BOOST_TEST(catchData.parameters.at(0).ToString() == "|Exception e"); + + BOOST_TEST(catchData.block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(catch_delete_param) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { try {} catch(Exception e) {} }", "void foo() { try {} catch() {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).OriginalType().name() == typeid(std::shared_ptr).name()); + + const srcDispatch::TryData& tryData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(bool(tryData.block)); + BOOST_TEST(bool(tryData.block.IsCommon())); + + BOOST_TEST(tryData.clauses.size() == 1); + BOOST_TEST(tryData.clauses.at(0).IsCommon()); + + const srcDispatch::CatchData& catchData = *std::any_cast>(tryData.clauses.at(0).GetElement()); + BOOST_TEST(catchData.parameters.size() == 1); + BOOST_TEST(catchData.parameters.at(0).IsDelete()); + BOOST_TEST(catchData.parameters.at(0).ToString() == "Exception e|"); + + BOOST_TEST(catchData.block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(catch_common_param_insert_front) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { try {} catch(Exception e) {} }", "void foo() { try {} catch(foo bar, Exception e) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).OriginalType().name() == typeid(std::shared_ptr).name()); + + const srcDispatch::TryData& tryData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(bool(tryData.block)); + BOOST_TEST(bool(tryData.block.IsCommon())); + + BOOST_TEST(tryData.clauses.size() == 1); + BOOST_TEST(tryData.clauses.at(0).IsCommon()); + + const srcDispatch::CatchData& catchData = *std::any_cast>(tryData.clauses.at(0).GetElement()); + BOOST_TEST(catchData.parameters.size() == 2); + BOOST_TEST(catchData.parameters.at(0).IsInsert()); + BOOST_TEST(catchData.parameters.at(0).ToString() == "|foo bar"); + BOOST_TEST(catchData.parameters.at(1).IsCommon()); + BOOST_TEST(catchData.parameters.at(1).ToString() == "Exception e"); + + BOOST_TEST(catchData.block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(catch_common_param_insert_back) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { try {} catch(Exception e) {} }", "void foo() { try {} catch(Exception e, foo bar) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).OriginalType().name() == typeid(std::shared_ptr).name()); + + const srcDispatch::TryData& tryData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(bool(tryData.block)); + BOOST_TEST(bool(tryData.block.IsCommon())); + + BOOST_TEST(tryData.clauses.size() == 1); + BOOST_TEST(tryData.clauses.at(0).IsCommon()); + + const srcDispatch::CatchData& catchData = *std::any_cast>(tryData.clauses.at(0).GetElement()); + BOOST_TEST(catchData.parameters.size() == 2); + BOOST_TEST(catchData.parameters.at(0).IsCommon()); + BOOST_TEST(catchData.parameters.at(0).ToString() == "Exception e"); + BOOST_TEST(catchData.parameters.at(1).IsInsert()); + BOOST_TEST(catchData.parameters.at(1).ToString() == "|foo bar"); + + BOOST_TEST(catchData.block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(catch_common_param_delete_front) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { try {} catch(foo bar, Exception e) {} }", "void foo() { try {} catch(Exception e) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).OriginalType().name() == typeid(std::shared_ptr).name()); + + const srcDispatch::TryData& tryData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(bool(tryData.block)); + BOOST_TEST(bool(tryData.block.IsCommon())); + + BOOST_TEST(tryData.clauses.size() == 1); + BOOST_TEST(tryData.clauses.at(0).IsCommon()); + + const srcDispatch::CatchData& catchData = *std::any_cast>(tryData.clauses.at(0).GetElement()); + BOOST_TEST(catchData.parameters.size() == 2); + BOOST_TEST(catchData.parameters.at(0).IsDelete()); + BOOST_TEST(catchData.parameters.at(0).ToString() == "foo bar|"); + BOOST_TEST(catchData.parameters.at(1).IsCommon()); + BOOST_TEST(catchData.parameters.at(1).ToString() == "Exception e"); + + BOOST_TEST(catchData.block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(catch_common_param_delete_back) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { try {} catch(Exception e, foo bar) {} }", "void foo() { try {} catch(Exception e) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).OriginalType().name() == typeid(std::shared_ptr).name()); + + const srcDispatch::TryData& tryData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(bool(tryData.block)); + BOOST_TEST(bool(tryData.block.IsCommon())); + + BOOST_TEST(tryData.clauses.size() == 1); + BOOST_TEST(tryData.clauses.at(0).IsCommon()); + + const srcDispatch::CatchData& catchData = *std::any_cast>(tryData.clauses.at(0).GetElement()); + BOOST_TEST(catchData.parameters.size() == 2); + BOOST_TEST(catchData.parameters.at(0).IsCommon()); + BOOST_TEST(catchData.parameters.at(0).ToString() == "Exception e"); + BOOST_TEST(catchData.parameters.at(1).IsDelete()); + BOOST_TEST(catchData.parameters.at(1).ToString() == "foo bar|"); + + BOOST_TEST(catchData.block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(catch_common_param_replace) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { try {} catch(std::string str) {} }", "void foo() { try {} catch(Exception e) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).OriginalType().name() == typeid(std::shared_ptr).name()); + + const srcDispatch::TryData& tryData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(bool(tryData.block)); + BOOST_TEST(bool(tryData.block.IsCommon())); + + BOOST_TEST(tryData.clauses.size() == 1); + BOOST_TEST(tryData.clauses.at(0).IsCommon()); + + const srcDispatch::CatchData& catchData = *std::any_cast>(tryData.clauses.at(0).GetElement()); + BOOST_TEST(catchData.parameters.size() == 2); + BOOST_TEST(catchData.parameters.at(0).IsDelete()); + BOOST_TEST(catchData.parameters.at(0).ToString() == "std::string str|"); + BOOST_TEST(catchData.parameters.at(1).IsInsert()); + BOOST_TEST(catchData.parameters.at(1).ToString() == "|Exception e"); + + BOOST_TEST(catchData.block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} diff --git a/test/suite/testWhile.cpp b/test/suite/testWhile.cpp new file mode 100644 index 0000000..e4b84e2 --- /dev/null +++ b/test/suite/testWhile.cpp @@ -0,0 +1,225 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file testWhile.cpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the srcDiff Infrastructure. + */ + +#define BOOST_TEST_MODULE while_stmt tests +#include + +#include + +#include +#include +#include + +#include + +// Define test data +namespace data = boost::unit_test; + +BOOST_AUTO_TEST_CASE(block_common_while) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { while(1) {} }", "void foo() { while(1) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::WhileData& whileData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(whileData.condition); + BOOST_TEST(whileData.condition.IsCommon()); + BOOST_TEST(whileData.condition->conditions.size() == 1); + BOOST_TEST(whileData.condition->conditions.at(0).IsCommon()); + + const srcDispatch::ExpressionData& expr = *std::any_cast>(whileData.condition->conditions.at(0).GetElement()); + BOOST_TEST(expr.expr.size() == 1); + BOOST_TEST(expr.expr.at(0).IsCommon()); + BOOST_TEST(std::any_cast>(expr.expr.at(0).GetElement())->literal.GetElement() == "1"); + BOOST_TEST(std::any_cast>(expr.expr.at(0).GetElement())->literal.ToString() == "1"); + BOOST_TEST(expr.expr.at(0).ToString>() == "1"); + BOOST_TEST(whileData.condition->conditions.at(0).ToString>() == "1"); + BOOST_TEST(whileData.condition.ToString() == "1"); + + BOOST_TEST(whileData.block.IsCommon()); + BOOST_TEST(whileData.block->statements.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_insert_while) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() {}", "void foo() { while(1) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsInsert()); + + const srcDispatch::WhileData& whileData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(whileData.condition); + BOOST_TEST(whileData.condition.IsInsert()); + BOOST_TEST(whileData.condition->conditions.size() == 1); + BOOST_TEST(whileData.condition->conditions.at(0).IsInsert()); + + const srcDispatch::ExpressionData& expr = *std::any_cast>(whileData.condition->conditions.at(0).GetElement()); + BOOST_TEST(expr.expr.size() == 1); + BOOST_TEST(expr.expr.at(0).IsInsert()); + BOOST_TEST(std::any_cast>(expr.expr.at(0).GetElement())->literal.GetElement() == "1"); + BOOST_TEST(std::any_cast>(expr.expr.at(0).GetElement())->literal.ToString() == "|1"); + BOOST_TEST(expr.expr.at(0).ToString>() == "|1"); + BOOST_TEST(whileData.condition->conditions.at(0).ToString>() == "|1"); + BOOST_TEST(whileData.condition.ToString() == "|1"); + + BOOST_TEST(whileData.block.IsInsert()); + BOOST_TEST(whileData.block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "|1"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_delete_while) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { while(1) {}", "void foo() {}"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::WhileData& whileData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(whileData.condition); + BOOST_TEST(whileData.condition.IsDelete()); + BOOST_TEST(whileData.condition->conditions.size() == 1); + BOOST_TEST(whileData.condition->conditions.at(0).IsDelete()); + + const srcDispatch::ExpressionData& expr = *std::any_cast>(whileData.condition->conditions.at(0).GetElement()); + BOOST_TEST(expr.expr.size() == 1); + BOOST_TEST(expr.expr.at(0).IsDelete()); + BOOST_TEST(std::any_cast>(expr.expr.at(0).GetElement())->literal.GetElement() == "1"); + BOOST_TEST(std::any_cast>(expr.expr.at(0).GetElement())->literal.ToString() == "1|"); + BOOST_TEST(expr.expr.at(0).ToString>() == "1|"); + BOOST_TEST(whileData.condition->conditions.at(0).ToString>() == "1|"); + BOOST_TEST(whileData.condition.ToString() == "1|"); + + BOOST_TEST(whileData.block.IsDelete()); + BOOST_TEST(whileData.block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_change_condition_expr_while) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { while(1) {}", "void foo() { while(2) {} }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsCommon()); + + const srcDispatch::WhileData& whileData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(whileData.condition); + BOOST_TEST(whileData.condition.IsCommon()); + BOOST_TEST(whileData.condition->conditions.size() == 1); + BOOST_TEST(whileData.condition->conditions.at(0).IsChange()); + + const srcDispatch::ExpressionData& originalExpr = *std::any_cast>(whileData.condition->conditions.at(0).GetOriginal()); + BOOST_TEST(originalExpr.expr.size() == 1); + BOOST_TEST(originalExpr.expr.at(0).IsDelete()); + BOOST_TEST(originalExpr.expr.at(0).IsDelete()); + BOOST_TEST(originalExpr.expr.at(0).ToString>() == "1|"); + + const srcDispatch::ExpressionData& modifiedExpr = *std::any_cast>(whileData.condition->conditions.at(0).GetModified()); + BOOST_TEST(modifiedExpr.expr.size() == 1); + BOOST_TEST(modifiedExpr.expr.at(0).IsInsert()); + BOOST_TEST(modifiedExpr.expr.at(0).IsInsert()); + BOOST_TEST(modifiedExpr.expr.at(0).ToString>() == "|2"); + + BOOST_TEST(whileData.condition->conditions.at(0).ToString>() == "1|2"); + BOOST_TEST(whileData.condition.ToString() == "1|2"); + + BOOST_TEST(whileData.block.IsCommon()); + BOOST_TEST(whileData.block->statements.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1|2"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + +BOOST_AUTO_TEST_CASE(block_replace_while) { + + srcDispatch::DispatchRunner runner; + runner.RunDispatcher({{"void foo() { while(1) { a; }", "void foo() { while(2) { b; } }"}}); + + BOOST_TEST(runner.GetDeclStmtInfo().size() == 0); + BOOST_TEST(runner.GetFunctionInfo().size() == 1); + BOOST_TEST(runner.GetClassInfo().size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block.IsCommon()); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.size() == 2); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).IsDelete()); + + const srcDispatch::WhileData& deletedData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(0).GetElement()); + BOOST_TEST(deletedData.condition.IsDelete()); + BOOST_TEST(deletedData.block.IsDelete()); + BOOST_TEST(deletedData.block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(0).ToString>() == "1|"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(1).IsInsert()); + + const srcDispatch::WhileData& insertedData = *std::any_cast>(runner.GetFunctionInfo().at(0)->block->statements.at(1).GetElement()); + BOOST_TEST(insertedData.condition.IsInsert()); + BOOST_TEST(insertedData.block.IsInsert()); + BOOST_TEST(insertedData.block->statements.size() == 1); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->statements.at(1).ToString>() == "|2"); + + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->labels.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->cases.size() == 0); + BOOST_TEST(runner.GetFunctionInfo().at(0)->block->blocks.size() == 0); + + BOOST_TEST(runner.GetFunctionInfo().at(0).ToString() == "void foo() {}"); +} + diff --git a/test/util/DispatchRunner.hpp b/test/util/DispatchRunner.hpp new file mode 100644 index 0000000..2d35c99 --- /dev/null +++ b/test/util/DispatchRunner.hpp @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-3.0-only +/** + * @file DispatchRunner.hpp + * + * @copyright Copyright (C) 2025-2025 SDML (www.srcML.org) + * + * This file is part of the Dispatch Infrastructure. + */ + +#ifndef INCLUDED_DISPATCH_RUNNER_HPP +#define INCLUDED_DISPATCH_RUNNER_HPP + +#include +#include +#include + +#include +#include + +#include +#include + +namespace srcDispatch { + +typedef std::pair SourcePair; + +class DispatchRunner : public srcDispatch::PolicyListener { +private: + + void writeFile(const std::string& filename, const std::string& contents) { + std::ofstream file(filename); + file << contents; + } + + std::string readDiffFile() { + std::ifstream srcDiffFile("srcdiff.xml", std::ios::ate); + std::size_t size = srcDiffFile.tellg(); + srcDiffFile.seekg(0); + + std::string srcDiffStr(size, '\0'); + srcDiffFile.read(&srcDiffStr[0], size); + return srcDiffStr; + } + + std::string srcDiff(const std::string& original, const std::string& modified) { + + writeFile("original.cpp", original); + writeFile("modified.cpp", modified); + + std::system("srcdiff original.cpp modified.cpp -o srcdiff.xml"); + + std::string srcDiffStr = readDiffFile(); + + std::remove("original.cpp"); + std::remove("modified.cpp"); + std::remove("srcdiff.xml"); + + return srcDiffStr; + } + + std::string srcDiff(const std::vector& sourcePairs) { + + std::filesystem::create_directory("original"); + std::filesystem::create_directory("modified"); + + int pairNum = 0; + for(const SourcePair& pair : sourcePairs) { + std::string numStr = std::to_string(pairNum); + writeFile("original/file" + numStr + ".cpp", pair.first); + writeFile("modified/file" + numStr + ".cpp", pair.second); + ++pairNum; + } + + std::system("srcdiff original modified -o srcdiff.xml"); + + std::string srcDiffStr = readDiffFile(); + + std::filesystem::remove_all("original"); + std::filesystem::remove_all("modified"); + std::remove("srcdiff.xml"); + + return srcDiffStr; + } + + std::shared_ptr unit; + +public: + DispatchRunner() {} + + const std::vector>>& GetClassInfo() const { + return unit->classInfo; + } + + const std::vector>>& GetFunctionInfo() const { + return unit->functionInfo; + } + + const std::vector>>& GetDeclStmtInfo() const { + return unit->declStmtInfo; + } + + void Notify(const srcDispatch::PolicyDispatcher * policy, + const srcDispatch::srcSAXEventContext & ctx) override { + unit = policy->Data(); + } + + void NotifyWrite(const srcDispatch::PolicyDispatcher* policy [[maybe_unused]], srcDispatch::srcSAXEventContext& ctx [[maybe_unused]]) override {} + + void RunDispatcher(const std::vector& sourcePairs) { + + std::string srcDiffStr; + if(sourcePairs.size() == 1) { + srcDiffStr = srcDiff(sourcePairs.at(0).first, sourcePairs.at(0).second); + } else { + srcDiffStr = srcDiff(sourcePairs); + } + + try { + srcSAXController control(srcDiffStr); + srcDispatch::srcDispatcher dispatch(this); + control.parse(&dispatch); //Start parsing + } catch(SAXError error) { + std::cerr << error.message; + exit(1); + } + } + + +}; + +} + +#endif \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt deleted file mode 100644 index 93302b3..0000000 --- a/tests/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -## -# CMakeLists.txt -# -# Copyright (C) 2016-2018 srcML, LLC. (www.srcML.org) -# -# This file is part of the srcSAXEventDispatch. -# -# The srcSAXEventDispatch is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# The srcSAXEventDispatch is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with the srcSAXEventDispatch; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -file( GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Test* ) -include_directories(${DISPATCH_INCLUDE_DIR}) -message(${SOURCES}) - -add_definitions("-std=c++11") - -find_package(LibXml2 REQUIRED) - -foreach( testsourcefile ${SOURCES} ) - string( REPLACE ".cpp" "" testname ${testsourcefile} ) - get_filename_component(file ${testsourcefile} NAME_WE) - add_executable( ${file} EXCLUDE_FROM_ALL ${testsourcefile} ) - target_link_libraries( ${file} srcsaxeventdispatch srcsax_static srcml ${DISPATCH_LIBRARIES} LibXml2::LibXml2) -endforeach( testsourcefile ${SOURCES} ) diff --git a/tests/TestCallPolicy.cpp b/tests/TestCallPolicy.cpp deleted file mode 100644 index 9c0bebe..0000000 --- a/tests/TestCallPolicy.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -std::string StringToSrcML(std::string str){ - struct srcml_archive* archive; - struct srcml_unit* unit; - size_t size = 0; - - char *ch = new char[str.size()]; - - archive = srcml_archive_create(); - srcml_archive_enable_option(archive, SRCML_OPTION_POSITION); - srcml_archive_write_open_memory(archive, &ch, &size); - - unit = srcml_unit_create(archive); - srcml_unit_set_language(unit, SRCML_LANGUAGE_CXX); - srcml_unit_set_filename(unit, "testsrcType.cpp"); - - srcml_unit_parse_memory(unit, str.c_str(), str.size()); - srcml_archive_write_unit(archive, unit); - - srcml_unit_free(unit); - srcml_archive_close(archive); - srcml_archive_free(archive); - //TrimFromEnd(ch, size); - return std::string(ch); -} - -class TestCalls : public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - ~TestCalls(){} - TestCalls(std::initializer_list listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners){} - void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - calldata = *policy->Data(); - datatotest.push_back(calldata); - for(auto it : calldata.callargumentlist){ - std::cerr< datatotest; - -}; - -int main(int argc, char** filename){ - std::string codestr = "void foo(){foo(bar, baz, 2 + bin(dep, pep(1+blep)), beep);}"; - std::string srcmlstr = StringToSrcML(codestr); - - TestCalls calldata; - srcSAXController control(srcmlstr); - srcSAXEventDispatch::srcSAXEventDispatcher handler{&calldata}; - control.parse(&handler); //Start parsing - calldata.RunTest(); -} diff --git a/tests/TestClassPolicy.cpp b/tests/TestClassPolicy.cpp deleted file mode 100644 index f1d2a36..0000000 --- a/tests/TestClassPolicy.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include -#include -#include -#include -#include - -std::string StringToSrcML(std::string str){ - struct srcml_archive* archive; - struct srcml_unit* unit; - size_t size = 0; - - char * ch; - - archive = srcml_archive_create(); - srcml_archive_enable_option(archive, SRCML_OPTION_POSITION); - srcml_archive_write_open_memory(archive, &ch, &size); - - unit = srcml_unit_create(archive); - srcml_unit_set_language(unit, SRCML_LANGUAGE_CXX); - srcml_unit_set_filename(unit, "testsrcType.cpp"); - - srcml_unit_parse_memory(unit, str.c_str(), str.size()); - srcml_archive_write_unit(archive, unit); - - srcml_unit_free(unit); - srcml_archive_close(archive); - srcml_archive_free(archive); - - std::string srcml; - srcml.append(ch, size); - - return srcml; -} - -class TestClassPolicy : public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - - ~TestClassPolicy() { } - - TestClassPolicy(std::initializer_list listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners) { } - - void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - datatotest = *policy->Data>(); - } - - void RunTest(){ - assert(datatotest[0].className == "foo_data"); - assert(datatotest[0].members[0].nameOfIdentifier == "z"); - assert(datatotest[0].members[1].nameOfIdentifier == "y"); - - assert(datatotest[1].className == "foo"); - assert(datatotest[1].members[0].nameOfIdentifier == "x"); - assert(datatotest[1].methods[0].name == "Print"); - } - protected: - - void * DataInner() const override { - return (void*)0; - } - - private: - - ClassPolicy classpolicy; - ClassPolicy::ClassData classdata; - std::vector datatotest; - -}; - -int main(int argc, char** filename){ - std::string codestr = "class foo { \n public: \n void Print() { }; \n int x; \n struct foo_data { \n int z; \n int y; \n }; \n };"; - std::string srcmlstr = StringToSrcML(codestr); - - try { - TestClassPolicy classdata; - srcSAXController control(srcmlstr); - srcSAXEventDispatch::srcSAXEventDispatcher handler { &classdata }; - control.parse(&handler); //Start parsing - classdata.RunTest(); - } catch(SAXError e) { - std::cerr << e.message; - } -} diff --git a/tests/TestDecleTypePolicy.cpp b/tests/TestDecleTypePolicy.cpp deleted file mode 100644 index 09aef75..0000000 --- a/tests/TestDecleTypePolicy.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -std::string StringToSrcML(std::string str){ - struct srcml_archive* archive; - struct srcml_unit* unit; - size_t size = 0; - - char *ch = 0; - - archive = srcml_archive_create(); - srcml_archive_enable_option(archive, SRCML_OPTION_POSITION); - srcml_archive_write_open_memory(archive, &ch, &size); - - unit = srcml_unit_create(archive); - srcml_unit_set_language(unit, SRCML_LANGUAGE_CXX); - srcml_unit_set_filename(unit, "testsrcType.cpp"); - - srcml_unit_parse_memory(unit, str.c_str(), str.size()); - srcml_archive_write_unit(archive, unit); - - srcml_unit_free(unit); - srcml_archive_close(archive); - srcml_archive_free(archive); - - return std::string(ch); -} - -class TestDeclType : public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - ~TestDeclType(){} - TestDeclType(std::initializer_list listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners){} - void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - decltypedata = *policy->Data(); - datatotest.push_back(decltypedata); - } - void NotifyWrite(const PolicyDispatcher * policy, srcSAXEventDispatch::srcSAXEventContext & ctx) override {} - void RunTest(){ - assert(datatotest.size() == 6); - assert(datatotest[0].nameOfType == "int"); - assert(datatotest[0].nameOfIdentifier == "abc"); - assert(datatotest[0].lineNumber == 1); - assert(datatotest[0].isConstValue == false); - assert(datatotest[0].isConstAlias == false); - assert(datatotest[0].isReference == true); - assert(datatotest[0].isPointer == false); - assert(datatotest[0].isStatic == false); - assert(datatotest[0].namespaces.empty()); - assert(datatotest[0].isClassMember == true); - assert(datatotest[0].nameOfContainingClass == "testclass"); - assert(datatotest[0].nameOfContainingFunction == ""); - assert(datatotest[0].nameOfContainingFile == "testsrcType.cpp"); - - assert(datatotest[1].nameOfType == "Object"); - assert(datatotest[1].nameOfIdentifier == "onetwothree"); - assert(datatotest[1].lineNumber == 1); - assert(datatotest[1].isConstValue == false); - assert(datatotest[1].isConstAlias == false); - assert(datatotest[1].isReference == false); - assert(datatotest[1].isPointer == false); - assert(datatotest[1].isStatic == false); - assert(datatotest[1].namespaces.empty()); - assert(datatotest[1].nameOfContainingClass == "testclass"); - assert(datatotest[1].nameOfContainingFunction == ""); - assert(datatotest[1].nameOfContainingFile == "testsrcType.cpp"); - - assert(datatotest[2].nameOfType == "Object"); - assert(datatotest[2].nameOfIdentifier == "DoReiMe"); - assert(datatotest[2].lineNumber == 1); - assert(datatotest[2].isConstValue == false); - assert(datatotest[2].isConstAlias == false); - assert(datatotest[2].isReference == false); - assert(datatotest[2].isPointer == true); - assert(datatotest[2].isStatic == true); - assert(datatotest[2].namespaces.empty()); - assert(datatotest[2].nameOfContainingClass == ""); - assert(datatotest[2].nameOfContainingFunction == "foo"); - assert(datatotest[2].nameOfContainingFile == "testsrcType.cpp"); - - assert(datatotest[3].nameOfType == "Object"); - assert(datatotest[3].nameOfIdentifier == "aybeecee"); - assert(datatotest[3].lineNumber == 1); - assert(datatotest[3].isConstAlias == true); - assert(datatotest[3].isConstValue == true); - assert(datatotest[3].isReference == false); - assert(datatotest[3].isPointer == true); - assert(datatotest[3].isStatic == false); - assert(datatotest[3].namespaces.empty()); - assert(datatotest[3].nameOfContainingClass == ""); - assert(datatotest[3].nameOfContainingFunction == "foo"); - assert(datatotest[3].nameOfContainingFile == "testsrcType.cpp"); - - assert(datatotest[4].nameOfType == "vector"); - assert(datatotest[4].nameOfIdentifier == "spaces"); - assert(datatotest[4].lineNumber == 2); - assert(datatotest[4].isConstValue == false); - assert(datatotest[4].isConstAlias == false); - assert(datatotest[4].isReference == false); - assert(datatotest[4].isPointer == false); - assert(datatotest[4].isStatic == false); - assert(datatotest[4].namespaces.size() == 2); - assert(datatotest[4].nameOfContainingClass == ""); - assert(datatotest[4].nameOfContainingFunction == "foo"); - assert(datatotest[4].nameOfContainingFile == "testsrcType.cpp"); - - assert(datatotest[5].nameOfType == "int"); - assert(datatotest[5].nameOfIdentifier == "ab"); - assert(datatotest[5].lineNumber == 2); - assert(datatotest[5].isConstValue == false); - assert(datatotest[5].isConstAlias == true); - assert(datatotest[5].isReference == false); - assert(datatotest[5].isPointer == true); - assert(datatotest[5].isStatic == false); - assert(datatotest[5].namespaces.empty()); - assert(datatotest[5].isClassMember == false); - assert(datatotest[5].usesSubscript == true); - assert(datatotest[5].nameOfContainingClass == ""); - assert(datatotest[5].nameOfContainingFunction == ""); - assert(datatotest[5].nameOfContainingFile == "testsrcType.cpp"); - - //assert(datatotest[5].nameOfType == ""); - //std::cerr<<"Msg: "< datatotest; -}; - -int main(int argc, char** filename){ - std::string codestr = "class testclass {int& abc; Object onetwothree; void foo(){static Object* DoReiMe; const Object* const aybeecee;\n nlp::std::vector spaces;} testclass(int i){}}; int* const ab[5];"; - std::string srcmlstr = StringToSrcML(codestr); - - TestDeclType decltypedata; - srcSAXController control(srcmlstr); - srcSAXEventDispatch::srcSAXEventDispatcher handler {&decltypedata}; - control.parse(&handler); //Start parsing - decltypedata.RunTest(); -} \ No newline at end of file diff --git a/tests/TestExpr.cpp b/tests/TestExpr.cpp deleted file mode 100644 index 97d7240..0000000 --- a/tests/TestExpr.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -std::string StringToSrcML(std::string str){ - struct srcml_archive* archive; - struct srcml_unit* unit; - size_t size = 0; - - char *ch = 0; - - archive = srcml_archive_create(); - srcml_archive_enable_option(archive, SRCML_OPTION_POSITION); - srcml_archive_write_open_memory(archive, &ch, &size); - - unit = srcml_unit_create(archive); - srcml_unit_set_language(unit, SRCML_LANGUAGE_CXX); - srcml_unit_set_filename(unit, "testsrcType.cpp"); - - srcml_unit_parse_memory(unit, str.c_str(), str.size()); - srcml_archive_write_unit(archive, unit); - - srcml_unit_free(unit); - srcml_archive_close(archive); - srcml_archive_free(archive); - ch[size-1] = 0; - return std::string(ch); -} - -class TestExpr : public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - ~TestExpr(){} - TestExpr(std::initializer_list listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners){} - void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - exprdata = *policy->Data(); - datatotest.push_back(exprdata); - } - void NotifyWrite(const PolicyDispatcher * policy, srcSAXEventDispatch::srcSAXEventContext & ctx) override { - } - void RunTest(){ - - } - protected: - void * DataInner() const override { - return (void*)0; //To silence the warning - } - private: - ExprPolicy::ExprDataSet exprdata; - std::vector datatotest; -}; - -int main(int argc, char** filename){ - std::string codestr = "void foo(){j = 0; \nk = 1; \ndoreme = 5; \nabc = abc + 0;\n i = j + k;\n foo(abc+doreme);}"; - std::string srcmlstr = StringToSrcML(codestr); - std::cerr< handler {&exprdata}; - control.parse(&handler); //Start parsing - exprdata.RunTest(); -} \ No newline at end of file diff --git a/tests/TestFnSignaturePolicy.cpp b/tests/TestFnSignaturePolicy.cpp deleted file mode 100644 index 38565c8..0000000 --- a/tests/TestFnSignaturePolicy.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -std::string StringToSrcML(std::string str){ - struct srcml_archive* archive; - struct srcml_unit* unit; - size_t size = 0; - - char *ch = 0; - - archive = srcml_archive_create(); - srcml_archive_enable_option(archive, SRCML_OPTION_POSITION); - srcml_archive_write_open_memory(archive, &ch, &size); - - unit = srcml_unit_create(archive); - srcml_unit_set_language(unit, SRCML_LANGUAGE_CXX); - srcml_unit_set_filename(unit, "testsrcType.cpp"); - - srcml_unit_parse_memory(unit, str.c_str(), str.size()); - srcml_archive_write_unit(archive, unit); - - srcml_unit_free(unit); - srcml_archive_close(archive); - srcml_archive_free(archive); - ch[size] = 0; - return std::string(ch); -} - -class TestFunctionSignature : public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - ~TestFunctionSignature(){} - TestFunctionSignature(std::initializer_list listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners){} - void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - signaturedata = *policy->Data(); - datatotest.push_back(signaturedata); - } - void NotifyWrite(const PolicyDispatcher * policy, srcSAXEventDispatch::srcSAXEventContext & ctx) override {} - void RunTest(){ - - assert(datatotest.size() == 5); - assert(datatotest[0].returnType == "void"); - assert(datatotest[0].name== "foo"); - assert(datatotest[0].returnTypeModifier == std::string()); - assert(datatotest[0].lineNumber == 1); - assert(datatotest[0].isConst == false); - assert(datatotest[0].isMethod == false); - assert(datatotest[0].isStatic == false); - assert(datatotest[0].parameters.size() == 4); - assert(datatotest[0].returnTypeNamespaces.size() == 0); - assert(datatotest[0].functionNamespaces.size() == 0); - assert(datatotest[0].pointerToConstReturn == false); - assert(datatotest[0].constPointerReturn == false); - assert(datatotest[0].hasAliasedReturn == false); - - assert(datatotest[1].returnType == "void"); - assert(datatotest[1].name== "bar"); - assert(datatotest[1].returnTypeModifier == std::string()); - assert(datatotest[1].lineNumber == 2); - assert(datatotest[1].isConst == false); - assert(datatotest[1].isMethod == false); - assert(datatotest[1].isStatic == true); - assert(datatotest[1].parameters.size() == 4); - assert(datatotest[1].returnTypeNamespaces.size() == 0); - assert(datatotest[1].functionNamespaces.size() == 0); - assert(datatotest[1].pointerToConstReturn == false); - assert(datatotest[1].constPointerReturn == false); - assert(datatotest[1].hasAliasedReturn == false); - - assert(datatotest[2].returnType == "int"); - assert(datatotest[2].name== "bloo"); - assert(datatotest[2].returnTypeModifier == "*"); - assert(datatotest[2].lineNumber == 3); - assert(datatotest[2].isConst == false); - assert(datatotest[2].isMethod == false); - assert(datatotest[2].isStatic == false); - assert(datatotest[2].parameters.size() == 4); - assert(datatotest[2].returnTypeNamespaces.size() == 0); - assert(datatotest[2].functionNamespaces.size() == 0); - assert(datatotest[2].pointerToConstReturn == false); - assert(datatotest[2].constPointerReturn == false); - assert(datatotest[2].hasAliasedReturn == true); - - assert(datatotest[3].returnType == "void"); - assert(datatotest[3].name== "bleep"); - assert(datatotest[3].returnTypeModifier == std::string()); - assert(datatotest[3].lineNumber == 4); - assert(datatotest[3].isConst == true); - assert(datatotest[3].isMethod == true); - assert(datatotest[3].isStatic == false); - assert(datatotest[3].parameters.size() == 4); - assert(datatotest[3].returnTypeNamespaces.size() == 0); - assert(datatotest[3].functionNamespaces.size() == 0); - assert(datatotest[3].pointerToConstReturn == false); - assert(datatotest[3].constPointerReturn == false); - assert(datatotest[3].hasAliasedReturn == false); - assert(datatotest[3].nameOfContainingClass == "testclass"); - - assert(datatotest[4].returnType == "object"); - assert(datatotest[4].name== "bloo"); - assert(datatotest[4].returnTypeModifier == "*"); - assert(datatotest[4].lineNumber == 5); - assert(datatotest[4].isConst == false); - assert(datatotest[4].isMethod == false); - assert(datatotest[4].isStatic == true); - assert(datatotest[4].parameters.size() == 3); - assert(datatotest[4].returnTypeNamespaces.size() == 2); - assert(datatotest[4].functionNamespaces.size() == 1); - assert(datatotest[4].pointerToConstReturn == true); - assert(datatotest[4].constPointerReturn == true); - assert(datatotest[4].hasAliasedReturn == true); - - } - protected: - void * DataInner() const override { - return (void*)0; //To silence the warning - } - private: - SignatureData signaturedata; - std::vector datatotest; -}; - -int main(int argc, char** filename){ - std::string codestr = "void foo(int abc, Object onetwothree, Object* DoReiMe, const Object* aybeecee){}\n" - "static void bar(int abc, Object onetwothree, Object* DoReiMe, const Object* aybeecee){}\n" - "int* bloo(int abc, Object onetwothree, Object* DoReiMe, const Object* aybeecee){}\n" - "class testclass{void bleep(int abc, Object onetwothree, Object* DoReiMe, const Object* aybeecee)const{}};\n" - "static const GameDes::std::object* const std::bloo(Object onetwothree, Object* DoReiMe, const Object* aybeecee){}"; - std::string srcmlstr = StringToSrcML(codestr); - - TestFunctionSignature sigData; - srcSAXController control(srcmlstr); - srcSAXEventDispatch::srcSAXEventDispatcher handler {&sigData}; - control.parse(&handler); //Start parsing - sigData.RunTest(); -} \ No newline at end of file diff --git a/tests/TestParamTypePolicy.cpp b/tests/TestParamTypePolicy.cpp deleted file mode 100644 index 4972b26..0000000 --- a/tests/TestParamTypePolicy.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/** - * @file TestParamTypePolicy.cpp - * - * @copyright Copyright (C) 2013-2014 SDML (www.srcML.org) - * - * The srcML Toolkit is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The srcML Toolkit is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the srcML Toolkit; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -#include -#include -#include -std::string StringToSrcML(std::string str){ - struct srcml_archive* archive; - struct srcml_unit* unit; - size_t size = 0; - - char *ch = 0; - - archive = srcml_archive_create(); - srcml_archive_enable_option(archive, SRCML_OPTION_POSITION); - srcml_archive_write_open_memory(archive, &ch, &size); - - unit = srcml_unit_create(archive); - srcml_unit_set_language(unit, SRCML_LANGUAGE_CXX); - srcml_unit_set_filename(unit, "testsrcType.cpp"); - - srcml_unit_parse_memory(unit, str.c_str(), str.size()); - srcml_archive_write_unit(archive, unit); - - srcml_unit_free(unit); - srcml_archive_close(archive); - srcml_archive_free(archive); - ch[size] = 0; - return std::string(ch); -} - -class TestParamType : public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - ~TestParamType(){} - TestParamType(std::initializer_list listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners){} - void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - paramdata = *policy->Data(); - datatotest.push_back(paramdata); - } - void NotifyWrite(const PolicyDispatcher * policy, srcSAXEventDispatch::srcSAXEventContext & ctx) override{ - - } - void RunTest(){ - assert(datatotest.size() == 6); - assert(datatotest[0].nameOfType == "int"); - assert(datatotest[0].nameOfIdentifier == "abc"); - assert(datatotest[0].lineNumber == 1); - assert(datatotest[0].isConstValue == false); - assert(datatotest[0].isConstAlias == false); - assert(datatotest[0].isReference == true); - assert(datatotest[0].isPointer == false); - assert(datatotest[0].isStatic == false); - assert(datatotest[0].namespaces.empty()); - - assert(datatotest[1].nameOfType == "Object"); - assert(datatotest[1].nameOfIdentifier == "onetwothree"); - assert(datatotest[1].lineNumber == 1); - assert(datatotest[1].isConstValue == false); - assert(datatotest[1].isConstAlias == false); - assert(datatotest[1].isReference == false); - assert(datatotest[1].isPointer == false); - assert(datatotest[1].isStatic == false); - assert(datatotest[1].namespaces.empty()); - - assert(datatotest[2].nameOfType == "Object"); - assert(datatotest[2].nameOfIdentifier == "DoReiMe"); - assert(datatotest[2].lineNumber == 1); - assert(datatotest[2].isConstValue == false); - assert(datatotest[2].isConstAlias == false); - assert(datatotest[2].isReference == false); - assert(datatotest[2].isPointer == true); - assert(datatotest[2].isStatic == true); - assert(datatotest[2].namespaces.empty()); - - assert(datatotest[3].nameOfType == "Object"); - assert(datatotest[3].nameOfIdentifier == "aybeecee"); - assert(datatotest[3].lineNumber == 1); - assert(datatotest[3].isConstValue == true); - assert(datatotest[3].isConstAlias == true); - assert(datatotest[3].isReference == false); - assert(datatotest[3].isPointer == true); - assert(datatotest[3].isStatic == false); - assert(datatotest[3].namespaces.empty()); - - assert(datatotest[4].nameOfType == "vector"); - assert(datatotest[4].nameOfIdentifier == "spaces"); - assert(datatotest[4].lineNumber == 1); - assert(datatotest[4].isConstValue == false); - assert(datatotest[4].isConstAlias == false); - assert(datatotest[4].isReference == false); - assert(datatotest[4].isPointer == false); - assert(datatotest[4].isStatic == false); - assert(datatotest[4].namespaces.size() == 1); - - assert(datatotest[5].nameOfType == "int"); - assert(datatotest[5].nameOfIdentifier == "ab"); - assert(datatotest[5].lineNumber == 1); - assert(datatotest[5].isConstValue == false); - assert(datatotest[5].isConstAlias == true); - assert(datatotest[5].isReference == false); - assert(datatotest[5].isPointer == true); - assert(datatotest[5].isStatic == false); - assert(datatotest[5].namespaces.empty()); - assert(datatotest[5].isClassMember == false); - assert(datatotest[5].usesSubscript == true); - } - protected: - void * DataInner() const override { - return (void*)0; //To silence the warning - } - private: - - ParamTypePolicy parampolicy; - DeclData paramdata; - std::vector datatotest; -}; - -int main(int argc, char** filename){ - std::string codestr = "void foo(int& abc, Object onetwothree, static Object* DoReiMe, const Object* const aybeecee, std::vector spaces, int* const ab[5]){}"; - std::string srcmlstr = StringToSrcML(codestr); - - TestParamType paramData; - srcSAXController control(srcmlstr); - srcSAXEventDispatch::srcSAXEventDispatcher handler {¶mData}; - control.parse(&handler); //Start parsing - paramData.RunTest(); -} \ No newline at end of file diff --git a/tests/TestSNLPolicy.cpp b/tests/TestSNLPolicy.cpp deleted file mode 100644 index 57c9c7f..0000000 --- a/tests/TestSNLPolicy.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -std::string filetostring (const std::string file){ - std::ifstream t(file); - std::string str; - - t.seekg(0, std::ios::end); - str.reserve(t.tellg()); - t.seekg(0, std::ios::beg); - - str.assign((std::istreambuf_iterator(t)), - std::istreambuf_iterator()); - return str; -} -std::string StringToSrcML(std::string str){ - struct srcml_archive* archive; - struct srcml_unit* unit; - size_t size = 0; - - char *ch = 0; - - archive = srcml_archive_create(); - srcml_archive_enable_option(archive, SRCML_OPTION_POSITION); - srcml_archive_write_open_memory(archive, &ch, &size); - - unit = srcml_unit_create(archive); - srcml_unit_set_language(unit, SRCML_LANGUAGE_CXX); - srcml_unit_set_filename(unit, "testsrcType.cpp"); - - srcml_unit_parse_memory(unit, str.c_str(), str.size()); - srcml_archive_write_unit(archive, unit); - - srcml_unit_free(unit); - srcml_archive_close(archive); - srcml_archive_free(archive); - ch[size] = 0; - return std::string(ch); -} - -class TestSNLPolicy : public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - ~TestSNLPolicy(){} - TestSNLPolicy(std::initializer_list listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners){} - void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - sourcenlpdata = *policy->Data(); - for(auto data : sourcenlpdata.nlsetmap){ - std::cerr< handler {&decltypedata}; - control.parse(&handler); //Start parsing -} \ No newline at end of file diff --git a/tests/TestSrcSlicePolicy.cpp b/tests/TestSrcSlicePolicy.cpp deleted file mode 100644 index 5ad21ba..0000000 --- a/tests/TestSrcSlicePolicy.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -std::string StringToSrcML(std::string str){ - struct srcml_archive* archive; - struct srcml_unit* unit; - size_t size = 0; - - char *ch = 0; - - archive = srcml_archive_create(); - srcml_archive_enable_option(archive, SRCML_OPTION_POSITION); - srcml_archive_write_open_memory(archive, &ch, &size); - - unit = srcml_unit_create(archive); - srcml_unit_set_language(unit, SRCML_LANGUAGE_CXX); - srcml_unit_set_filename(unit, "testsrcType.cpp"); - - srcml_unit_parse_memory(unit, str.c_str(), str.size()); - srcml_archive_write_unit(archive, unit); - - srcml_unit_free(unit); - srcml_archive_close(archive); - srcml_archive_free(archive); - ch[size] = 0; - return std::string(ch); -} - -class TestSrcSlice : public srcSAXEventDispatch::PolicyDispatcher, public srcSAXEventDispatch::PolicyListener{ - public: - ~TestSrcSlice(){} - TestSrcSlice(std::initializer_list listeners = {}) : srcSAXEventDispatch::PolicyDispatcher(listeners){} - void Notify(const PolicyDispatcher * policy, const srcSAXEventDispatch::srcSAXEventContext & ctx) override { - decltypedata = *policy->Data(); - datatotest.push_back(decltypedata); - } - void RunTest(){ - assert(datatotest.size() == 5); - assert(datatotest[0].nameoftype == "int"); - assert(datatotest[0].nameofidentifier == "abc"); - assert(datatotest[0].linenumber == 1); - assert(datatotest[0].isConst == false); - assert(datatotest[0].isReference == true); - assert(datatotest[0].isPointer == false); - assert(datatotest[0].isStatic == false); - assert(datatotest[0].namespaces.empty()); - - assert(datatotest[1].nameoftype == "Object"); - assert(datatotest[1].nameofidentifier == "onetwothree"); - assert(datatotest[1].linenumber == 1); - assert(datatotest[1].isConst == false); - assert(datatotest[1].isReference == false); - assert(datatotest[1].isPointer == false); - assert(datatotest[1].isStatic == false); - assert(datatotest[1].namespaces.empty()); - - assert(datatotest[2].nameoftype == "Object"); - assert(datatotest[2].nameofidentifier == "DoReiMe"); - assert(datatotest[2].linenumber == 1); - assert(datatotest[2].isConst == false); - assert(datatotest[2].isReference == false); - assert(datatotest[2].isPointer == true); - assert(datatotest[2].isStatic == true); - assert(datatotest[2].namespaces.empty()); - - assert(datatotest[3].nameoftype == "Object"); - assert(datatotest[3].nameofidentifier == "aybeecee"); - assert(datatotest[3].linenumber == 1); - assert(datatotest[3].isConst == true); - assert(datatotest[3].isReference == false); - assert(datatotest[3].isPointer == true); - assert(datatotest[3].isStatic == false); - assert(datatotest[3].namespaces.empty()); - - assert(datatotest[4].nameoftype == "vector"); - assert(datatotest[4].nameofidentifier == "spaces"); - assert(datatotest[4].linenumber == 2); - assert(datatotest[4].isConst == false); - assert(datatotest[4].isReference == false); - assert(datatotest[4].isPointer == false); - assert(datatotest[4].isStatic == false); - assert(datatotest[4].namespaces.size() == 2); - } - protected: - void * DataInner() const override { - return (void*)0; //To silence the warning - } - private: - - srcSlicePolicy declpolicy; - srcSlicePolicy::DeclTypeData decltypedata; - std::vector datatotest; -}; - -int main(int argc, char** filename){ - std::string codestr = "void foo(){int& abc; Object onetwothree; static Object* DoReiMe; const Object* aybeecee;\n nlp::std::vector spaces;}"; - std::string srcmlstr = StringToSrcML(codestr); - - TestSrcSlice decltypedata; - srcSAXController control(srcmlstr); - srcSAXEventDispatch::srcSAXEventDispatcher handler {&decltypedata}; - control.parse(&handler); //Start parsing - decltypedata.RunTest(); -} \ No newline at end of file