diff --git a/cxx-parser/__integration_test__/cxx_parser.integration.test.ts b/cxx-parser/__integration_test__/cxx_parser.integration.test.ts index 890a5d3..e511b3a 100644 --- a/cxx-parser/__integration_test__/cxx_parser.integration.test.ts +++ b/cxx-parser/__integration_test__/cxx_parser.integration.test.ts @@ -65,7 +65,8 @@ struct AAA { "is_const":false, "kind":100, "name":"int", - "source":"int" + "source":"int", + "template_arguments":[] } } ], diff --git a/cxx-parser/__tests__/unit_test/cxx_parser.test.ts b/cxx-parser/__tests__/unit_test/cxx_parser.test.ts index d7a23e1..4cc4b25 100644 --- a/cxx-parser/__tests__/unit_test/cxx_parser.test.ts +++ b/cxx-parser/__tests__/unit_test/cxx_parser.test.ts @@ -63,6 +63,7 @@ describe('cxx_parser', () => { kind: 101, name: 'Test', source: 'Test *', + template_arguments: [], }, }, ], @@ -137,6 +138,7 @@ describe('cxx_parser', () => { kind: 101, name: 'Test', source: 'Test *', + template_arguments: [], }, }, ], @@ -216,6 +218,7 @@ describe('cxx_parser', () => { kind: 101, name: 'Test', source: 'Test *', + template_arguments: [], }, }, ], diff --git a/cxx-parser/__tests__/unit_test/cxx_terra_node.test.ts b/cxx-parser/__tests__/unit_test/cxx_terra_node.test.ts new file mode 100644 index 0000000..d0a0d8a --- /dev/null +++ b/cxx-parser/__tests__/unit_test/cxx_terra_node.test.ts @@ -0,0 +1,23 @@ +import { SimpleType, SimpleTypeKind, cast } from '../../src'; + +describe('cast', () => { + it('case SimpleType', () => { + let astJsonContent = ` +{ + "__TYPE": "SimpleType", + "is_builtin_type": false, + "is_const": false, + "kind": 104, + "name": "Optional", + "source": "Optional", + "template_arguments": ["double"] +} +`; + let json = JSON.parse(astJsonContent); + let simpleType = cast(json) as unknown as SimpleType; + expect(simpleType.kind).toBe(SimpleTypeKind.template_t); + expect(simpleType.name).toBe('Optional'); + expect(simpleType.source).toBe('Optional'); + expect(simpleType.template_arguments).toEqual(['double']); + }); +}); diff --git a/cxx-parser/cxx/terra/include/terra.hpp b/cxx-parser/cxx/terra/include/terra.hpp index fc35430..02c6d26 100644 --- a/cxx-parser/cxx/terra/include/terra.hpp +++ b/cxx-parser/cxx/terra/include/terra.hpp @@ -65,12 +65,13 @@ namespace terra void to_simple_type(SimpleType &type, const cppast::cpp_type &cpp_type, bool recursion = false) { std::cout << "------------" << cppast::to_string(cpp_type) << " >> " << std::to_string((int)cpp_type.kind()) << "\n"; - if (!recursion) { + if (!recursion) + { type.name = cppast::to_string(cpp_type); type.source = cppast::to_string(cpp_type); type.kind = SimpleTypeKind::value_t; } - + switch (cpp_type.kind()) { case cppast::cpp_type_kind::builtin_t: @@ -155,14 +156,29 @@ namespace terra case cppast::cpp_type_kind::template_instantiation_t: { auto &cpp_template_instantiation_type = static_cast(cpp_type); - // if (cpp_template_instantiation_type.arguments().has_value()) { - // if (cpp_template_instantiation_type.arguments().value().size() == 1) { - // if (cpp_template_instantiation_type.arguments().value().begin()->type().has_value()) { - // to_simple_type(type, cpp_template_instantiation_type.arguments().value().begin()->type().value(), true); - // break; - // } - // } - // } + + type.name = cpp_template_instantiation_type.primary_template().name(); + + if (cpp_template_instantiation_type.arguments_exposed()) + { + for (auto &arg : cpp_template_instantiation_type.arguments().value()) + { + if (auto arg_type = arg.type()) + { + std::string arg_type_name = cppast::to_string(arg_type.value()); + type.template_arguments.push_back(arg_type_name); + std::cout << "template_instantiation_t argument: " << arg_type_name << "\n"; + } + } + } + else if (!cpp_template_instantiation_type.unexposed_arguments().empty()) + { + std::string arg_type_name = cpp_template_instantiation_type.unexposed_arguments(); + type.template_arguments.push_back(arg_type_name); + std::cout << "template_instantiation_t unexposed_arguments: " << arg_type_name << "\n"; + } + + type.source = cppast::to_string(cpp_type); type.kind = SimpleTypeKind::template_t; break; } @@ -181,7 +197,8 @@ namespace terra } } - void parse_base_node(BaseNode &base_node, const std::vector &namespaceList, const std::string &file_path, const cppast::cpp_entity &cpp_entity) { + void parse_base_node(BaseNode &base_node, const std::vector &namespaceList, const std::string &file_path, const cppast::cpp_entity &cpp_entity) + { base_node.name = std::string(cpp_entity.name()); base_node.namespaces = std::vector(namespaceList); base_node.file_path = std::string(file_path); @@ -190,7 +207,7 @@ namespace terra base_node.comment = parse_comment(cpp_entity); // base_node.source = cppast::to_string(cpp_entity); } - + // public cpp_entity, public cpp_variable_base, template void parse_parameter(Variable ¶meter, const std::vector &namespaceList, const std::string &file_path, const T &cpp_variable_base) @@ -219,7 +236,7 @@ namespace terra } } parameter.default_value = default_value; - + std::cout << "param type:" << parameter.type.name << " " << parameter.type.kind << " " << parameter.type.is_builtin_type << ", name:" << parameter.name << ", default value: " << parameter.default_value << "\n"; } @@ -237,7 +254,7 @@ namespace terra void parse_method(MemberFunction &method, const std::vector &namespaceList, const std::string &file_path, const cppast::cpp_member_function &cpp_member_function, std::string ¤t_access_specifier) { parse_base_node(method, namespaceList, file_path, cpp_member_function); - + method.is_virtual = cpp_member_function.is_virtual(); SimpleType return_type; to_simple_type(return_type, cpp_member_function.return_type()); @@ -316,7 +333,7 @@ namespace terra { TypeAlias type_alias; parse_base_node(type_alias, namespaceList, file_path, cpp_type_alias); - + SimpleType st; to_simple_type(st, cpp_type_alias.underlying_type()); type_alias.underlyingType = st; @@ -1020,6 +1037,7 @@ namespace terra json["kind"] = (int)node->kind; json["is_const"] = node->is_const; json["is_builtin_type"] = node->is_builtin_type; + json["template_arguments"] = node->template_arguments; } void MemberVariable2Json(MemberVariable *node, nlohmann::json &json) diff --git a/cxx-parser/cxx/terra/include/terra_node.hpp b/cxx-parser/cxx/terra/include/terra_node.hpp index 7116fb9..16f253c 100644 --- a/cxx-parser/cxx/terra/include/terra_node.hpp +++ b/cxx-parser/cxx/terra/include/terra_node.hpp @@ -87,6 +87,9 @@ namespace terra bool is_const = false; bool is_builtin_type = false; + /// @brief Only and maybe have values if the `kind == SimpleTypeKind::template_t` + std::vector template_arguments; + std::string GetTypeName() const { if (!name.empty()) diff --git a/cxx-parser/src/cxx_terra_node.ts b/cxx-parser/src/cxx_terra_node.ts index c9ef8fd..7e42704 100644 --- a/cxx-parser/src/cxx_terra_node.ts +++ b/cxx-parser/src/cxx_terra_node.ts @@ -32,6 +32,7 @@ export enum SimpleTypeKind { pointer_t = 101, reference_t = 102, array_t = 103, + template_t = 104, } export abstract class CXXTerraNode implements TerraNode { @@ -253,6 +254,7 @@ export class SimpleType extends CXXTerraNode { kind: SimpleTypeKind = SimpleTypeKind.value_t; is_const: boolean = false; is_builtin_type: boolean = false; + template_arguments: string[] = []; override get realName(): string { if (this.name) {