123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368 |
- #ifndef __CODE_GENERATOR_CODE_ANALYSIS_H__
- #define __CODE_GENERATOR_CODE_ANALYSIS_H__
- #if defined(_MSC_VER) && (_MSC_VER >= 1200)
- #pragma once
- #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
- #include <iostream>
- #include <filesystem>
- #include <regex>
- #include <fstream>
- #include "../robot/robotics/utils.hpp"
- using namespace robotics;
- struct file_info {
- /**
- * @brief 路径
- */
- std::string file_path;
- /**
- * @brief 代码
- */
- std::vector<std::string> content;
- /**
- * @brief 类型 0控制器 1实体类 2soap
- */
- int class_type = 0;
- };
- struct PropertyInfo {
- /**
- * @brief 类型名称
- */
- std::string type_name;
- /**
- * @brief 属性名称
- */
- std::string prop_name;
- /**
- * @brief json字段名称
- */
- std::string json_name;
- /**
- * @brief 数据库字段名称
- */
- std::string sql_name;
- /**
- * @brief excel字段名称
- */
- std::string excel_name;
- /**
- * @brief 不序列化json 默认false
- */
- bool no_json = false;
- /**
- * @brief 不创建数据库字段 默认false
- */
- bool no_sql = false;
- /**
- * @brief 不导出excel字段 默认false
- */
- bool no_excel = false;
- /**
- * @brief 字段索引
- */
- bool sql_key = false;
- /**
- * @brief 二进制序列化
- */
- bool no_archive = false;
- };
- struct ParameterInfo {
- /**
- * @brief 参数名称
- */
- std::string name;
- /**
- * @brief 参数类型
- */
- std::string type;
- /**
- * @brief 参数名称
- */
- std::string parameter_name;
- /**
- * @brief 类型名称
- */
- std::string argument_type = "robotics::v3::mvc::argument_type::Binary";
- /**
- * @brief 提取位置 QUERY Body Header
- */
- std::string from_storage_type = "robotics::v3::mvc::from_storage_type::QUERY";
- };
- struct MethodInfo {
- /**
- * @brief 身份验证
- */
- bool authen = true;
- /**
- * @brief 未登录跳转
- */
- std::string authen_jump;
- /**
- * @brief
- */
- std::string method = "robotics::v3::mvc::http_method::GET";
- /**
- * @brief
- */
- std::string content_type = "application/x-www-form-urlencoded";
- /**
- * @brief
- */
- std::string action_type;
- /**
- * @brief
- */
- std::string file_mapping;
- /**
- * @brief
- */
- std::string route;
- /**
- * @brief
- */
- std::string name;
- /**
- * @brief 函数签名
- */
- std::string signature;
- /**
- * @brief 参数
- */
- std::vector<ParameterInfo> parameters;
- };
- struct SoapParameterInfo {
- /**
- * @brief 类型
- */
- std::string type = "std::string";
- /**
- * @brief 参数类型
- */
- std::string argument_type = "robotics::v3::mvc::soap_argument_type::String";
- /**
- * @brief 参数名称
- */
- std::string parameter_name = "value";
- };
- struct soap_method_info {
- /**
- * @brief 方法名称
- */
- std::string name;
- /**
- * @brief 路由方法名称
- */
- std::string action_name;
- /**
- * @brief 函数签名
- */
- std::string signature;
- /**
- * @brief 参数
- */
- std::vector<SoapParameterInfo> parameters;
- };
- struct class_view_info {
- /**
- * @brief 0:控制器 1:实体类 2:soap
- */
- int class_type = 0;
- /**
- * @brief 是否是模板
- */
- bool is_template = false;
- /**
- * @brief 模板类型列表
- */
- std::vector<std::string> template_types;
- /**
- * @brief 模板参数列表
- */
- std::vector<std::string> template_parameters;
- /**
- * @brief 类名称
- */
- std::string class_name;
- /**
- * @brief 数据库表名称
- */
- std::string sql_table_name;
- /**
- * @brief 属性列表
- */
- std::vector<PropertyInfo> propertys;
- /**
- * @brief 控制器列表
- */
- std::vector<MethodInfo> methods;
- /**
- * @brief soap 方法列表
- */
- std::vector<soap_method_info> soap_methods;
- /**
- * @brief soap版本
- */
- std::string soap_version = "1.1";
- /**
- * @brief soap命名空间
- */
- std::string soap_namepsace = "http://tempuri.org/";
- /**
- * @brief soap路由
- */
- std::string soap_route;
- /**
- * @brief soap wsdl文件
- */
- std::string soap_wsdl;
- /**
- * @brief 头文件
- */
- std::string include;
- /**
- * @brief 反射
- */
- bool is_reflect = true;
- };
- class code_analysis_core {
- public:
- static std::vector<class_view_info> getClassView(std::filesystem::path path) {
- return code_analysis_core(path).getClassView();
- }
- protected:
- code_analysis_core(std::filesystem::path path) :
- _path(path) {
- }
- private:
- std::vector<class_view_info> getClassView() {
- std::vector<class_view_info> result;
- auto fileInfos = getiFileInfo();
- //控制器
- for (auto& it : fileInfos) {
- if (it.class_type != 0)
- continue;
- for (auto code : it.content) {
- std::regex pattern("class[ \r\n\t]{1,30}([a-zA-Z_0-9]{1,100})");
- std::smatch smatch;
- if (std::regex_search(code, smatch, pattern)) {
- if (smatch.size() == 2) {
- class_view_info add;
- add.include = it.file_path;
- add.class_type = 0;
- add.class_name = smatch[1];
- add.methods = getMethods(smatch.suffix());
- result.push_back(add);
- }
- }
- }
- }
- //实体类
- for (auto& it : fileInfos) {
- if (it.class_type != 1)
- continue;
- for (auto code : it.content) {
- //普通模板结构体
- {
- std::regex pattern("template[ \r\n\t]{0,30}<([\\s\\S]*?)>[ \r\n\t]{0,30}struct[ \r\n\t]{1,30}([a-zA-Z_0-9]{1,100})");
- std::smatch smatch;
- if (std::regex_search(code, smatch, pattern)) {
- if (smatch.size() == 3) {
- class_view_info add;
- add.include = it.file_path;
- add.class_type = 1;
- add.class_name = smatch[2];
- add.is_template = true;
- add.sql_table_name = smatch[2];
- auto templteTypeList = v3::utils::split(smatch[1], ",");
- for (auto& tempType : templteTypeList) {
- auto tempValue = v3::utils::split(tempType, " ");
- if (tempValue.size() == 2) {
- add.template_types.push_back(v3::utils::trim(tempValue[1]));
- }
- }
- add.propertys = getPropertys(smatch.suffix());
- result.push_back(add);
- code = smatch.suffix();
- }
- }
- }
- //带特性模板结构体
- {
- std::regex pattern("template[ \r\n\t]{0,30}<([\\s\\S]*?)>[ \r\n\t]{0,30}struct[ \r\n\t]{0,30}(\\[\\[[\\s\\S]*?\\]\\])[ \r\n\t]{0,30}([a-zA-Z_0-9]{1,100})[ \r\n\t]{0,30}\\{");
- std::smatch smatch;
- if (std::regex_search(code, smatch, pattern)) {
- if (smatch.size() == 4) {
- class_view_info add;
- add.include = it.file_path;
- add.class_type = 1;
- add.class_name = smatch[3];
- add.is_template = true;
- auto templteTypeList = v3::utils::split(smatch[1], ",");
- for (auto& tempType : templteTypeList) {
- auto tempValue = v3::utils::split(tempType, " ");
- if (tempValue.size() == 2) {
- add.template_types.push_back(v3::utils::trim(tempValue[1]));
- }
- }
- getTemplateParameter(smatch[2], add.template_types.size(), add);
- add.sql_table_name = add.sql_table_name.empty() ? add.class_name : add.sql_table_name;
- add.propertys = getPropertys("{" + smatch.suffix().str());
- result.push_back(add);
- code = smatch.suffix();
- }
- }
- }
- //普通结构体
- {
- std::regex pattern("struct[ \r\n\t]{1,30}([a-zA-Z_0-9]{1,100})");
- std::smatch smatch;
- if (std::regex_search(code, smatch, pattern)) {
- if (smatch.size() == 2) {
- class_view_info add;
- add.include = it.file_path;
- add.class_type = 1;
- add.class_name = smatch[1];
- add.sql_table_name = smatch[1];
- add.propertys = getPropertys(smatch.suffix());
- result.push_back(add);
- code = smatch.suffix();
- }
- }
- }
- //带反射特性结构体
- {
- std::regex pattern("struct[ \r\n\t]{0,30}\\[\\[NoReflect\\]\\][ \r\n\t]{0,30}([a-zA-Z_0-9]{1,100})");
- std::smatch smatch;
- if (std::regex_search(code, smatch, pattern)) {
- if (smatch.size() == 2) {
- class_view_info add;
- add.include = it.file_path;
- add.class_type = 1;
- add.class_name = smatch[1];
- add.sql_table_name = smatch[1].length() == 0 ? add.class_name : smatch[1];
- add.propertys = getPropertys(smatch.suffix());
- add.is_reflect = false;
- result.push_back(add);
- code = smatch.suffix();
- }
- }
- }
- //带数据库特性结构体
- {
- std::regex pattern("struct[ \r\n\t]{0,30}\\[\\[SqlTable\\(\"(.*?)\"\\)\\]\\][ \r\n\t]{0,30}([a-zA-Z_0-9]{1,100})");
- std::smatch smatch;
- if (std::regex_search(code, smatch, pattern)) {
- if (smatch.size() == 3) {
- class_view_info add;
- add.include = it.file_path;
- add.class_type = 1;
- add.class_name = smatch[2];
- add.sql_table_name = smatch[1].length() == 0 ? add.class_name : smatch[1];
- add.propertys = getPropertys(smatch.suffix());
- result.push_back(add);
- code = smatch.suffix();
- }
- }
- }
- //带数据库反射特性结构体
- {
- std::regex pattern("struct[ \r\n\t]{0,30}\\[\\[NoReflect\\]\\][ \r\n\t]{0,30}\\[\\[SqlTable\\(\"(.*?)\"\\)\\]\\][ \r\n\t]{0,30}([a-zA-Z_0-9]{1,100})");
- std::smatch smatch;
- if (std::regex_search(code, smatch, pattern)) {
- if (smatch.size() == 3) {
- class_view_info add;
- add.include = it.file_path;
- add.class_type = 1;
- add.class_name = smatch[2];
- add.sql_table_name = smatch[1].length() == 0 ? add.class_name : smatch[1];
- add.propertys = getPropertys(smatch.suffix());
- add.is_reflect = false;
- result.push_back(add);
- code = smatch.suffix();
- }
- }
- }
- }
- }
- //soap
- for (auto& it : fileInfos) {
- if (it.class_type != 2)
- continue;
- for (auto code : it.content) {
- std::regex pattern("class[ \r\n\t]{1,30}\\[\\[(.*?)\\]\\][ \r\n\t]{1,30}\\[\\[(.*?)\\]\\][ \r\n\t]{1,30}\\[\\[(.*?)\\]\\][ \r\n\t]{1,30}\\[\\[(.*?)\\]\\][ \r\n\t]{1,30}([a-zA-Z_0-9]{1,100})");
- std::smatch smatch;
- if (std::regex_search(code, smatch, pattern)) {
- if (smatch.size() == 6) {
- class_view_info add;
- add.include = it.file_path;
- add.class_type = 2;
- getSoapAttribute(smatch[1], add);
- getSoapAttribute(smatch[2], add);
- getSoapAttribute(smatch[3], add);
- getSoapAttribute(smatch[4], add);
- add.class_name = smatch[5];
- add.soap_methods = getSoapMethods(smatch.suffix());
- result.push_back(add);
- }
- }
- }
- }
- std::string rootPath = _path.string();
- rootPath = v3::utils::replace(rootPath, "\\", "/");
- if (rootPath[rootPath.size() - 1] != '/') {
- rootPath += "/";
- }
- for (auto& it : result) {
- it.include = v3::utils::replace(it.include, rootPath, "");
- }
- return result;
- }
- std::vector<file_info> getiFileInfo() {
- std::vector<file_info> result;
- auto controllerFiles = getControllerFiles();
- auto modelFiles = getModelsFiles();
- auto webServiceFiles = getWebServicesFiles();
- for (auto& item : controllerFiles) {
- file_info add;
- //获取代码
- std::string code = getCode(item);
- //剔除无用代码
- eliminateNotes(code);
- //
- add.class_type = 0;
- add.content = getStructContent(code);
- for (auto& it : add.content) {
- eliminateController(it);
- }
- add.file_path = v3::utils::replace(item.string(), "\\", "/");
- result.push_back(add);
- }
- for (auto& item : modelFiles) {
- file_info add;
- //获取代码
- std::string code = getCode(item);
- //剔除无用代码
- eliminateNotes(code);
- //
- add.class_type = 1;
- add.content = getStructContent(code);
- add.file_path = v3::utils::replace(item.string(), "\\", "/");
- result.push_back(add);
- }
- for (auto& item : webServiceFiles) {
- file_info add;
- //获取代码
- std::string code = getCode(item);
- //剔除无用代码
- eliminateNotes(code);
- //
- add.class_type = 2;
- add.content = getStructContent(code);
- for (auto& it : add.content) {
- eliminateWebService(it);
- }
- add.file_path = v3::utils::replace(item.string(), "\\", "/");
- result.push_back(add);
- }
- return result;
- }
- std::vector<std::filesystem::path> getControllerFiles() {
- std::filesystem::path controllersPath = _path;
- controllersPath /= "controllers";
- std::vector<std::filesystem::path> files;
- getFiles(controllersPath, { ".hpp" }, files);
- return files;
- }
- std::vector<std::filesystem::path> getModelsFiles() {
- std::filesystem::path modelsPath = _path;
- modelsPath /= "models";
- std::vector<std::filesystem::path> files;
- getFiles(modelsPath, { ".h" }, files);
- return files;
- }
- std::vector<std::filesystem::path> getWebServicesFiles() {
- std::filesystem::path webServicesPath = _path;
- webServicesPath /= "webservices";
- std::vector<std::filesystem::path> files;
- getFiles(webServicesPath, { ".hpp" }, files);
- return files;
- }
- void getFiles(std::filesystem::path path, std::vector<std::string> extension, std::vector<std::filesystem::path>& files)
- {
- if (!std::filesystem::is_directory(path)) {
- return;
- }
- for (auto& itr : std::filesystem::directory_iterator(path))
- {
- if (std::filesystem::is_directory(itr.status()))
- {
- getFiles(itr.path(), extension, files);
- }
- else
- {
- if (std::find(extension.begin(), extension.end(), itr.path().extension()) != extension.end()) {
- files.push_back(itr.path());
- }
- }
- }
- }
- std::string getCode(std::filesystem::path const& path) {
- std::ifstream file(path, std::ios::out);
- if (file.is_open()) {
- return std::string((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
- }
- return "";
- }
- void eliminateNotes(std::string& code) {
- std::vector<std::pair<std::string, std::string>> notes = {
- {"/*","*/"},
- {"//","\n"},
- {"#include","\n"},
- {"#pragma", "\n"},
- {"#ifndef", "\n"},
- {"#define", "\n"},
- {"#if", "\n"},
- {"#endif", "\n"}
- };
- for (auto& note : notes) {
- std::size_t begin = 0;
- std::size_t end = 0;
- while ((begin = code.find(note.first, begin)) != std::string::npos && (end = code.find(note.second, begin)) != std::string::npos) {
- if (begin > 0 && code[begin - 1] == ':') {
- begin += note.second.size();
- continue;
- }
- code.erase(begin, end - begin + note.second.size());
- }
- }
- }
- void eliminateController(std::string& code) {
- std::string tmpCode = code;
- std::regex pattern("WebResponse[ \r\n\t]{1,30}[a-zA-Z_0-9]{1,100}[ \r\n\t]{0,30}([a-zA-Z0-9\",\\[\\], \r\n\t:<>_\\(\\)]{0,500})");
- std::smatch smatch;
- while (std::regex_search(tmpCode, smatch, pattern)) {
- std::string value = smatch[0];
- std::size_t pos = code.find(value);
- if (pos == std::string::npos)
- break;
- pos += value.size();
- int begin = 0;
- int end = 0;
- for (std::size_t i = pos; i < code.size(); ++i) {
- if (code[i] == '"') {
- int tmpBegin = 0;
- for (std::size_t i1 = i; i1 < code.size(); ++i1) {
- if (code[i1] == '"') {
- tmpBegin++;
- }
- code.erase(i1, 1);
- i1--;
- if (tmpBegin == 2) {
- break;
- }
- }
- }
- if (code[i] == '{') {
- begin++;
- }
- else if (code[i] == '}') {
- end++;
- }
- code.erase(i, 1);
- i--;
- if (begin > 0 && end == begin) {
- code.insert(code.begin() + i, ';');
- break;
- }
- }
- tmpCode = smatch.suffix();
- }
- }
- void eliminateWebService(std::string& code) {
- std::string tmpCode = code;
- std::regex pattern("SoapResponse[ \r\n\t]{1,30}[a-zA-Z_0-9]{1,100}[ \r\n\t]{0,30}([a-zA-Z0-9\",\\[\\], \r\n\t:<>_\\(\\)]{0,500})");
- std::smatch smatch;
- while (std::regex_search(tmpCode, smatch, pattern)) {
- std::string value = smatch[0];
- std::size_t pos = code.find(value);
- if (pos == std::string::npos)
- break;
- pos += value.size();
- int begin = 0;
- int end = 0;
- for (std::size_t i = pos; i < code.size(); ++i) {
- if (code[i] == '"') {
- int tmpBegin = 0;
- for (std::size_t i1 = i; i1 < code.size(); ++i1) {
- if (code[i1] == '"') {
- tmpBegin++;
- }
- code.erase(i1, 1);
- i1--;
- if (tmpBegin == 2) {
- break;
- }
- }
- }
- if (code[i] == '{') {
- begin++;
- }
- else if (code[i] == '}') {
- end++;
- }
- code.erase(i, 1);
- i--;
- if (begin > 0 && end == begin) {
- code.insert(code.begin() + i, ';');
- break;
- }
- }
- tmpCode = smatch.suffix();
- }
- }
- std::vector<std::string> getStructContent(std::string code) {
- std::vector<std::string> result;
- auto func = [](std::string reg, std::string code) {
- std::vector<std::string> result;
- std::regex pattern(reg);
- std::smatch smatch;
- while (std::regex_search(code, smatch, pattern)) {
- std::string structContent = smatch[0];
- std::size_t pos = code.find(structContent);
- if (pos == std::string::npos)
- break;
- int begin = 0;
- int end = 0;
- std::string content;
- for (int i = pos; i < code.size(); ++i) {
- content += code[i];
- if (code[i] == '{') {
- begin++;
- }
- else if (code[i] == '}') {
- end++;
- }
- if (begin > 0 && begin == end) {
- break;
- }
- }
- result.push_back(content);
- code = smatch.suffix();
- }
- return result;
- };
- std::vector<std::string> regList;
- //普通模板结构体
- regList.push_back("template[ \r\n\t]{0,30}<[\\s\\S]*?>[ \r\n\t]{0,30}struct[ \r\n\t]{1,30}[a-zA-Z_0-9]{1,100}");
- //带特性模板结构体
- regList.push_back("template[ \r\n\t]{0,30}<[\\s\\S]*?>[ \r\n\t]{0,30}struct[ \r\n\t]{0,30}\\[\\[[\\s\\S]*?\\]\\][ \r\n\t]{0,30}[a-zA-Z_0-9]{1,100}[ \r\n\t]{0,30}\\{");
- //普通结构体
- regList.push_back("struct[ \r\n\t]{1,30}[a-zA-Z_0-9]{1,100}");
- //带特性结构体
- regList.push_back("struct[ \r\n\t]{0,30}\\[\\[NoReflect\\]\\][ \r\n\t]{0,30}[a-zA-Z_0-9]{1,100}");
- //带特性结构体
- regList.push_back("struct[ \r\n\t]{0,30}\\[\\[SqlTable\\(\".*?\"\\)\\]\\][ \r\n\t]{0,30}[a-zA-Z_0-9]{1,100}");
- //带特性结构体
- regList.push_back("struct[ \r\n\t]{0,30}\\[\\[NoReflect\\]\\][ \r\n\t]{0,30}\\[\\[SqlTable\\(\".*?\"\\)\\]\\][ \r\n\t]{0,30}[a-zA-Z_0-9]{1,100}");
- //控制器
- regList.push_back("class[ \r\n\t]{1,30}[a-zA-Z_0-9]{1,200}");
- //soap
- regList.push_back("class[ \r\n\t]{1,30}\\[\\[.*?\\]\\][ \r\n\t]{1,30}\\[\\[.*?\\]\\][ \r\n\t]{1,30}\\[\\[.*?\\]\\][ \r\n\t]{1,30}\\[\\[.*?\\]\\][ \r\n\t]{1,30}[a-zA-Z_0-9]{1,100}");
- std::string tmpCode = code;
- for (auto& it : regList) {
- auto values = func(it, tmpCode);
- for (auto& item : values) {
- std::size_t pos = 0;
- if ((pos = tmpCode.find(item)) != std::string::npos) {
- tmpCode.erase(pos, item.size());
- }
- }
- result.insert(result.end(), values.begin(), values.end());
- }
- return result;
- }
- void getTemplateParameter(std::string code, int count, class_view_info& result) {
- auto attributes = v3::utils::split(code, "]]");
- for (auto& it : attributes) {
- std::size_t begin = 0;
- std::size_t end = 0;
- //TemplateType
- if (it.find("TemplateType") != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
- std::string value = it.substr(begin, end - begin + 1);
- auto values = v3::utils::split(value, ",");
- if (values.size() != count)
- continue;
- std::vector<std::string> addItem;
- for (auto temp : values) {
- if ((begin = temp.find("\"")) != std::string::npos && (end = temp.rfind("\"")) != std::string::npos) {
- if (begin == end)
- continue;
- addItem.push_back(temp.substr(begin + 1, end - begin - 1));
- }
- }
- if (addItem.size() != count)
- continue;
- result.template_parameters.push_back(v3::utils::format("{}", v3::utils::join(addItem, ",")));
- }
- //SqlTable
- else if (it.find("SqlTable") != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
- result.sql_table_name = it.substr(begin + 1, end - begin - 1);
- }
- }
- }
- //获取属性
- std::vector<PropertyInfo> getPropertys(std::string code) {
- std::vector<PropertyInfo> result;
- code.erase(code.find("{"), 1);
- code.erase(code.rfind("}"), 1);
- std::vector<std::string> propertyCodes = v3::utils::split(code, ";");
- for (auto& prop : propertyCodes) {
- PropertyInfo add;
- //提取特性
- {
- std::regex pattern("\\[\\[(.*?)\\]\\]");
- std::smatch smatch;
- while (std::regex_search(prop, smatch, pattern)) {
- std::string attribute = smatch[1];
- std::string Json = "Json";
- std::string NoJson = "NoJson";
- std::string Sql = "Sql";
- std::string NoSql = "NoSql";
- std::string SqlKey = "SqlKey";
- std::string Excel = "Excel";
- std::string NoExcel = "NoExcel";
- std::string NoArchive = "NoArchive";
- if (attribute.size() > Json.size() && attribute.substr(0, Json.size()) == Json) {
- auto values = v3::utils::split(attribute, "\"");
- if (values.size() == 3) {
- add.json_name = values[1];
- std::size_t pos = values[2].find("false");
- add.no_json = pos != std::string::npos;
- }
- }
- else if (attribute.size() > NoJson.size() && attribute.substr(0, NoJson.size()) == NoJson) {
- attribute = v3::utils::to_upper(attribute);
- if (attribute.find("TRUE") != std::string::npos) {
- add.no_json = true;
- }
- }
- else if (attribute.size() > SqlKey.size() && attribute.substr(0, SqlKey.size()) == SqlKey) {
- attribute = v3::utils::to_upper(attribute);
- if (attribute.find("TRUE") != std::string::npos) {
- add.sql_key = true;
- }
- }
- else if (attribute.size() > Sql.size() && attribute.substr(0, Sql.size()) == Sql) {
- auto values = v3::utils::split(attribute, "\"");
- if (values.size() == 3) {
- add.sql_name = values[1];
- std::size_t pos = values[2].find("false");
- add.no_sql = pos != std::string::npos;
- }
- }
- else if (attribute.size() > NoSql.size() && attribute.substr(0, NoSql.size()) == NoSql) {
- attribute = v3::utils::to_upper(attribute);
- if (attribute.find("TRUE") != std::string::npos) {
- add.no_sql = true;
- }
- }
- else if (attribute.size() > Excel.size() && attribute.substr(0, Excel.size()) == Excel) {
- auto values = v3::utils::split(attribute, "\"");
- if (values.size() == 3) {
- add.excel_name = values[1];
- std::size_t pos = values[2].find("false");
- add.no_excel = pos != std::string::npos;
- }
- }
- else if (attribute.size() > NoExcel.size() && attribute.substr(0, NoExcel.size()) == NoExcel) {
- attribute = v3::utils::to_upper(attribute);
- if (attribute.find("TRUE") != std::string::npos) {
- add.no_excel = true;
- }
- }
- else if (attribute.size() > NoArchive.size() && attribute.substr(0, NoArchive.size()) == NoArchive) {
- attribute = v3::utils::to_upper(attribute);
- if (attribute.find("TRUE") != std::string::npos) {
- add.no_archive = true;
- }
- }
- prop = smatch.suffix();
- }
- }
- //提取属性
- {
- std::regex pattern("([a-zA-Z_0-9:<>]{1,100})[ \r\n\t]{1,30}([a-zA-Z_0-9]{1,100})");
- std::smatch smatch;
- if (std::regex_search(prop, smatch, pattern)) {
- if (smatch.size() == 3 &&
- ((smatch[1].str().find('<') != std::string::npos && smatch[1].str().find('>') != std::string::npos) ||
- (smatch[1].str().find('<') == std::string::npos && smatch[1].str().find('>') == std::string::npos))) {
- add.type_name = smatch[1];
- add.prop_name = smatch[2];
- add.json_name = add.json_name.empty() ? add.prop_name : add.json_name;
- add.sql_name = add.sql_name.empty() ? add.prop_name : add.sql_name;
- add.excel_name = add.excel_name.empty() ? add.prop_name : add.excel_name;
- result.push_back(add);
- }
- }
- }
- }
- return result;
- }
- //获取方法
- std::vector<MethodInfo> getMethods(std::string code) {
- std::vector<MethodInfo> result;
- std::vector<std::pair<std::string, std::string>> funcList;
- //提取方法列表
- {
- std::regex pattern("WebResponse[ \r\n\t]{1,30}[a-zA-Z_0-9]{1,100}[ \r\n\t]{0,30}\\([a-zA-Z0-9\",\\[\\], \r\n\t:<>_\\(\\)]{0,500}\\)");
- std::smatch smatch;
- while (std::regex_search(code, smatch, pattern)) {
- std::string value = smatch[0];
- std::size_t pos = code.find(value);
- if (pos == std::string::npos)
- break;
- if (pos > 0)
- pos--;
- std::string func;
- for (int i = pos; i >= 0; --i) {
- if (code[i] == ']') {
- int count = 0;
- for (; i >= 0; --i) {
- if (code[i] == '[')
- count++;
- func += code[i];
- if (count == 2) {
- i--;
- break;
- }
- }
- }
- if (!(code[i] == '\r' || code[i] == '\n' || code[i] == '\t' || code[i] == ' ')) {
- break;
- }
- }
- std::reverse(func.begin(), func.end());
- funcList.push_back(std::make_pair(value, func));
- code = smatch.suffix();
- }
- }
- for (auto& it : funcList) {
- MethodInfo add;
- //特性
- methodAttribute(it.second, add);
- methodParameter(it.first, add);
- result.push_back(add);
- }
- return result;
- }
- //提取特性
- void methodAttribute(std::string code, MethodInfo& result) {
- auto attributes = v3::utils::split(code, "]]");
- for (auto it : attributes) {
- std::size_t begin = 0;
- std::size_t end = 0;
- //[[ActionType("Page")]]
- if (it.find("[[ActionType") != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
- result.action_type = it.substr(begin + 1, end - begin - 1);
- }
- //[[Method("POST")]]
- if (it.find("[[Method") != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
- std::string value = it.substr(begin + 1, end - begin - 1);
- if (value == "GET") {
- result.method = "robotics::v3::mvc::http_method::GET";
- }
- else {
- result.method = "robotics::v3::mvc::http_method::POST";
- }
- }
- //[[Authen(false,"Home/Index")]]
- if (it.find("[[Authen") != std::string::npos && (begin = it.find("(")) != std::string::npos && (end = it.find(")")) != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
- if (it.find("false") != std::string::npos) {
- result.authen_jump = it.substr(begin + 1, end - begin - 1);
- result.authen = false;
- }
- else {
- result.authen_jump = it.substr(begin + 1, end - begin - 1);
- result.authen = true;
- }
- }
- //[[Authen(false)]]
- else if (it.find("[[Authen") != std::string::npos && (begin = it.find("(")) != std::string::npos && (end = it.find(")")) != std::string::npos) {
- std::string value = v3::utils::to_upper(it.substr(begin, end - begin + 1));
- result.authen = value.find("FALSE") == std::string::npos;
- }
- //[[Route("Account/Login")]]
- if (it.find("[[Route") != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
- result.route = it.substr(begin + 1, end - begin - 1);
- if (result.route.find('<') != std::string::npos) {
- }
- }
- //[[ContentType("application/x-www-form-urlencoded")]]
- if (it.find("[[ContentType") != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
- result.content_type = it.substr(begin + 1, end - begin - 1);
- }
- //[[FileMapping("Account/Index.html")]]
- if (it.find("[[FileMapping") != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
- result.file_mapping = it.substr(begin + 1, end - begin - 1);
- }
- }
- }
- //
- void methodParameter(std::string code, MethodInfo& result) {
- bool succ = false;
- std::string parameter;
- std::string funcName;
- //提取方法列表
- {
- std::regex pattern("WebResponse[ \r\n\t]{1,30}([a-zA-Z_0-9]{1,100})[ \r\n\t]{0,30}\\(([a-zA-Z0-9\",\\[\\], \r\n\t:<>_\\(\\)]{0,500})\\)");
- std::smatch smatch;
- if (std::regex_search(code, smatch, pattern)) {
- if (smatch.size() == 3) {
- succ = true;
- funcName = smatch[1];
- parameter = smatch[2];
- }
- }
- }
- if (!succ)return;
- std::vector<ParameterInfo> parameterValues;
- {
- auto parameters = v3::utils::split(parameter, ",");
- for (auto& it : parameters) {
- //带特性
- {
- std::regex pattern("\\[\\[(.*?)\\]\\][\r\n\t ]{0,30}([a-zA-Z_0-9<>:]{1,100})[\r\n\t ]{1,30}([a-zA-Z0-9_]{1,100})");
- std::smatch smatch;
- if (std::regex_search(it, smatch, pattern)) {
- if (smatch.size() == 4) {
- ParameterInfo add;
- std::string attribute = smatch[1];
- std::string paramType = smatch[2];
- std::string paramName = smatch[3];
- for (int i = 0; i < paramType.size(); ++i) {
- if (paramType[i] == ' ') {
- paramType.erase(i, 1);
- --i;
- }
- }
- parameterType(paramType, add);
- parameterAttribute(attribute, add);
- if (add.parameter_name.empty()) {
- add.parameter_name = paramName;
- }
- if (add.parameter_name == " ") {
- add.parameter_name = "";
- }
- add.name = paramName;
- add.type = paramType;
- parameterValues.push_back(add);
- continue;
- }
- }
- }
- //不带特性
- {
- std::regex pattern("([a-zA-Z_0-9<>:]{1,100})[\r\n\t ]{1,30}([a-zA-Z0-9_]{1,100})");
- std::smatch smatch;
- if (std::regex_search(it, smatch, pattern)) {
- if (smatch.size() == 3) {
- ParameterInfo add;
- std::string paramType = smatch[1];
- std::string paramName = smatch[2];
- for (int i = 0; i < paramType.size(); ++i) {
- if (paramType[i] == ' ') {
- paramType.erase(i, 1);
- --i;
- }
- }
- parameterType(paramType, add);
- add.name = paramName;
- add.type = paramType;
- add.parameter_name = paramName;
- parameterValues.push_back(add);
- continue;
- }
- }
- }
- }
- }
- result.parameters = parameterValues;
- std::string signature = "WebResponse({})";
- std::vector<std::string> tmpParams;
- for (auto& it : result.parameters) {
- tmpParams.push_back(it.type);
- }
- signature = v3::utils::format(signature, v3::utils::join(tmpParams, ","));
- result.signature = signature;
- result.name = funcName;
- }
- void parameterType(std::string code, ParameterInfo& parameter) {
- if (code == "robotics::v3::mvc::multipart_value" || code == "v3::mvc::multipart_value" || code == "mvc::multipart_value" || code == "multipart_value") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::Multipart";
- }
- else if (code == "int") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::Int";
- }
- else if (code == "std::uint64_t") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::Int64";
- }
- else if (code == "float") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::Float";
- }
- else if (code == "double") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::Double";
- }
- else if (code == "long") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::Long";
- }
- else if (code == "bool") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::Bool_";
- }
- else if (code == "std::string") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::String";
- }
- else if (code == "robotics::v3::datetime" || code == "v3::datetime" || code == "datetime") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::DateTime";
- }
- else if (code == "std::vector<std::uint8_t>") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::Binary";
- }
- else if (code == "std::vector<int>") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::VecInt";
- }
- else if (code == "std::vector<std::uint64_t>") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::VecInt64";
- }
- else if (code == "std::vector<float>") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::VecFloat";
- }
- else if (code == "std::vector<double>") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::VecDouble";
- }
- else if (code == "std::vector<long>") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::VecLong";
- }
- else if (code == "std::vector<bool>") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::VecBool";
- }
- else if (code == "std::vector<std::string>") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::VecString";
- }
- else if (code == "std::vector<robotics::v3::datetime>" || code == "std::vector<v3::datetime>" || code == "std::vector<datetime>") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::VecDateTime";
- }
- else if (code.size() > 12 && code.substr(0, 11) == "std::vector") {
- parameter.argument_type = "robotics::v3::mvc::argument_type::VecJson";
- }
- else {
- parameter.argument_type = "robotics::v3::mvc::argument_type::Json";
- }
- }
- void parameterAttribute(std::string code, ParameterInfo& parameter) {
- std::size_t begin = 0;
- std::size_t end = 0;
- //FromQuery
- if (code.find("FromQuery") != std::string::npos && (begin = code.find("\"")) != std::string::npos && (end = code.rfind("\"")) != std::string::npos) {
- parameter.from_storage_type = "robotics::v3::mvc::from_storage_type::QUERY";
- parameter.parameter_name = code.substr(begin + 1, end - begin - 1);
- }
- //FromBody
- else if (code.find("FromBody") != std::string::npos && (begin = code.find("\"")) != std::string::npos && (end = code.rfind("\"")) != std::string::npos) {
- parameter.from_storage_type = "robotics::v3::mvc::from_storage_type::BODY";
- parameter.parameter_name = code.substr(begin + 1, end - begin - 1);
- if (parameter.parameter_name.empty()) {
- parameter.parameter_name = " ";
- }
- }
- //FromHeader
- else if (code.find("FromHeader") != std::string::npos && (begin = code.find("\"")) != std::string::npos && (end = code.rfind("\"")) != std::string::npos) {
- parameter.from_storage_type = "robotics::v3::mvc::from_storage_type::HEADER";
- parameter.parameter_name = code.substr(begin + 1, end - begin - 1);
- }
- //FromUrl
- else if (code.find("FromUrl") != std::string::npos && (begin = code.find("\"")) != std::string::npos && (end = code.rfind("\"")) != std::string::npos) {
- parameter.from_storage_type = "robotics::v3::mvc::from_storage_type::URL";
- parameter.parameter_name = code.substr(begin + 1, end - begin - 1);
- }
- }
- void getSoapAttribute(std::string code, class_view_info& result) {
- std::size_t begin = 0;
- std::size_t end = 0;
- //Version
- if (code.find("Version") != std::string::npos && (begin = code.find("\"")) != std::string::npos && (end = code.rfind("\"")) != std::string::npos) {
- result.soap_version = code.substr(begin + 1, end - begin - 1);
- }
- //Namepsace
- else if (code.find("Namespace") != std::string::npos && (begin = code.find("\"")) != std::string::npos && (end = code.rfind("\"")) != std::string::npos) {
- result.soap_namepsace = code.substr(begin + 1, end - begin - 1);
- }
- //Route
- else if (code.find("Route") != std::string::npos && (begin = code.find("\"")) != std::string::npos && (end = code.rfind("\"")) != std::string::npos) {
- result.soap_route = code.substr(begin + 1, end - begin - 1);
- }
- //Wsdl
- else if (code.find("Wsdl") != std::string::npos && (begin = code.find("\"")) != std::string::npos && (end = code.rfind("\"")) != std::string::npos) {
- result.soap_wsdl = code.substr(begin + 1, end - begin - 1);
- }
- }
- std::vector<soap_method_info> getSoapMethods(std::string code) {
- std::vector<soap_method_info> result;
- std::vector<std::pair<std::string, std::string>> funcList;
- //提取方法列表
- {
- std::regex pattern("SoapResponse[ \r\n\t]{1,30}[a-zA-Z_0-9]{1,100}[ \r\n\t]{0,30}\\([a-zA-Z0-9\",\\[\\], \r\n\t:<>_\\(\\)]{0,500}\\)");
- std::smatch smatch;
- while (std::regex_search(code, smatch, pattern)) {
- std::string value = smatch[0];
- std::size_t pos = code.find(value);
- if (pos == std::string::npos)
- break;
- if (pos > 0)
- pos--;
- std::string func;
- for (int i = pos; i >= 0; --i) {
- if (code[i] == ']') {
- int count = 0;
- for (; i >= 0; --i) {
- if (code[i] == '[')
- count++;
- func += code[i];
- if (count == 2) {
- i--;
- break;
- }
- }
- }
- if (!(code[i] == '\r' || code[i] == '\n' || code[i] == '\t' || code[i] == ' ')) {
- break;
- }
- }
- std::reverse(func.begin(), func.end());
- funcList.push_back(std::make_pair(value, func));
- code = smatch.suffix();
- }
- }
- for (auto& it : funcList) {
- soap_method_info add;
- //特性
- soapMethodAttribute(it.second, add);
- soapMethodParameter(it.first, add);
- result.push_back(add);
- }
- return result;
- }
- void soapMethodAttribute(std::string code, soap_method_info& result) {
- auto attributes = v3::utils::split(code, "]]");
- for (auto it : attributes) {
- std::size_t begin = 0;
- std::size_t end = 0;
- //[[Method("get")]]
- if (it.find("Method") != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
- result.action_name = it.substr(begin + 1, end - begin - 1);
- }
- }
- }
- void soapMethodParameter(std::string code, soap_method_info& result) {
- std::regex pattern("SoapResponse[ \r\n\t]{1,30}([a-zA-Z_0-9]{1,100})[ \r\n\t]{0,30}\\(([a-zA-Z0-9\",\\[\\], \r\n\t:<>_\\(\\)]{0,500})\\)");
- std::smatch smatch;
- std::vector<SoapParameterInfo> parameterValues;
- while (std::regex_search(code, smatch, pattern)) {
- if (smatch.size() == 3) {
- result.name = smatch[1];
- if (result.action_name.empty()) {
- result.action_name = result.name;
- }
- auto parameters = v3::utils::split(smatch[2], ",");
- for (auto& it : parameters)
- {
- std::regex pattern1("([a-zA-Z_0-9<>:]{1,100})[\r\n\t ]{1,30}([a-zA-Z0-9_]{1,100})");
- std::smatch smatch1;
- if (std::regex_search(it, smatch1, pattern1)) {
- if (smatch1.size() == 3) {
- SoapParameterInfo add;
- std::string paramType = smatch1[1];
- std::string paramName = smatch1[2];
- for (int i = 0; i < paramType.size(); ++i) {
- if (paramType[i] == ' ') {
- paramType.erase(i, 1);
- --i;
- }
- }
- soapParameterType(paramType, add);
- add.parameter_name = paramName;
- add.type = paramType;
- parameterValues.push_back(add);
- continue;
- }
- }
- }
- }
- break;
- }
- result.parameters = parameterValues;
- std::string signature = "SoapResponse({})";
- std::vector<std::string> tmpParams;
- for (auto& it : result.parameters) {
- tmpParams.push_back(it.type);
- }
- signature = v3::utils::format(signature, v3::utils::join(tmpParams, ","));
- result.signature = signature;
- }
- void soapParameterType(std::string code, SoapParameterInfo& parameter) {
- if (code == "int") {
- parameter.argument_type = "robotics::v3::soap::soap_argument_type::Int";
- }
- else if (code == "std::uint64_t") {
- parameter.argument_type = "robotics::v3::soap::soap_argument_type::Int64";
- }
- else if (code == "float") {
- parameter.argument_type = "robotics::v3::soap::soap_argument_type::Float";
- }
- else if (code == "double") {
- parameter.argument_type = "robotics::v3::soap::soap_argument_type::Double";
- }
- else if (code == "long") {
- parameter.argument_type = "robotics::v3::soap::soap_argument_type::Long";
- }
- else if (code == "bool") {
- parameter.argument_type = "robotics::v3::soap::soap_argument_type::Bool_";
- }
- else if (code == "std::string") {
- parameter.argument_type = "robotics::v3::soap::soap_argument_type::String";
- }
- else if (code == "robotics::v3::datetime" || code == "v3::datetime" || code == "datetime") {
- parameter.argument_type = "robotics::v3::soap::soap_argument_type::DateTime";
- }
- else {
- parameter.argument_type = "robotics::v3::soap_argument_type::Json";
- }
- }
- private:
- std::filesystem::path _path;
- };
- #endif //!__CODE_GENERATOR_CODE_ANALYSIS_H__
|