diff --git a/libs/main/code/picodeparser.cpp b/libs/main/code/picodeparser.cpp index 4c0ca331..20cf80e2 100644 --- a/libs/main/code/picodeparser.cpp +++ b/libs/main/code/picodeparser.cpp @@ -19,6 +19,8 @@ #include "picodeparser.h" +#include "piliterals_string.h" + PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const { PIStringList arg_vals; @@ -454,7 +456,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { cur_namespace += pfc.takeCWord() + s_ns; ccmn = pfc.takeRange('{', '}'); // piCout << "namespace" << cur_namespace; - parseClass(0, ccmn, true); + parseClass(nullptr, ccmn, true); cur_namespace = prev_namespace; continue; } @@ -483,8 +485,8 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { continue; } ccmn = pfc.left(dind) + s_bo + pfc.mid(dind).takeRange('{', '}') + s_bc; - pfc.remove(0, ccmn.size()); - parseClass(0, ccmn, false); + pfc.remove(0, ccmn.size() - 2); + parseClass(nullptr, ccmn, false); continue; } if (pfc.left(4) == s_enum) { @@ -499,17 +501,59 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { meta << smeta; } // piCout << "pfc E" << cur_namespace << "," << tmp; - parseEnum(0, cur_namespace + tmp, pfc.takeRange('{', '}'), meta); + parseEnum(nullptr, cur_namespace + tmp, pfc.takeRange('{', '}'), meta); pfc.takeSymbol(); continue; } if (pfc.left(7) == s_typedef) { pfc.cutLeft(7); - typedefs << parseTypedef(pfc.takeLeft(pfc.find(';'))); - if (typedefs.back().first.isEmpty()) - typedefs.pop_back(); - else - root_.typedefs << typedefs.back(); + PIString typedef_type = pfc.takeCWord(); + if (typedef_type == s_class || typedef_type == s_struct || typedef_type == s_union) { + int dind = pfc.find('{', 0), find = pfc.find(';', 0); + if (dind < 0 && find < 0) { + pfc.cutLeft(6); + continue; + } + if (dind < 0 || find < dind) { + pfc.cutLeft(find + 1); + continue; + } + PIString cname = pfc.left(dind); + ccmn = cname + s_bo + pfc.mid(dind).takeRange('{', '}') + s_bc; + pfc.remove(0, ccmn.size() - 3); + if (cname.trimmed().isEmpty()) { + cname = pfc.takeCWord(); + ccmn.prepend(cname); + } + ccmn.prepend(typedef_type + " "_a); + parseClass(nullptr, ccmn, false); + } else if (typedef_type == s_enum) { + tmp = pfc.takeCWord(); + pfc.trim(); + MetaMap meta = maybeMeta(pfc); + if (tmp == s_class || tmp == s_struct) { + tmp = pfc.takeCWord(); + pfc.trim(); + MetaMap smeta = maybeMeta(pfc); + meta << smeta; + } + ccmn = pfc.takeRange('{', '}'); + if (tmp.isEmpty()) { + tmp = pfc.takeCWord(); + } + // piCout << "pfc E" << cur_namespace << "," << tmp; + parseEnum(nullptr, cur_namespace + tmp, ccmn, meta); + } else { + pfc.prepend(typedef_type); + } + PIString last = pfc.takeLeft(pfc.find(';')).trim(); + if (last.isNotEmpty()) { + typedefs << parseTypedef(last); + if (typedefs.back().first.isEmpty()) + typedefs.pop_back(); + else + root_.typedefs << typedefs.back(); + } pfc.takeSymbol(); continue; } @@ -570,7 +614,6 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) bool has_name = !cn.isEmpty(); if (cn.isEmpty()) cn = PIStringAscii("'; // piCout << "found " << typename_ << cn; - if (cn.isEmpty()) return nullptr; Entity * e = new Entity(); e->meta = meta; e->name = cur_namespace + cn; @@ -584,7 +627,7 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) } -void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) { +PICodeParser::Entity * PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) { static const PIString s_ns = PIStringAscii("::"); static const PIString s_public = PIStringAscii("public"); static const PIString s_protected = PIStringAscii("protected"); @@ -599,7 +642,7 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) static const PIString s_template = PIStringAscii("template"); Visibility prev_vis = cur_def_vis; int dind = fc.find('{'), find = fc.find(';'), end = 0; - if (dind < 0 && find < 0) return; + if (dind < 0 && find < 0) return nullptr; // piCout << "parse class <****\n" << fc << "\n****>"; Entity * ce = parent; if (!is_namespace) { @@ -650,11 +693,31 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) fc.takeSymbol(); continue; } - tmp = fc.takeLeft(fc.find('{')); - stmp = fc.takeRange('{', '}'); - fc.takeSymbol(); - stmp = cw + ' ' + tmp + '{' + stmp + '}'; - parseClass(ce, stmp, false); + tmp = fc.takeLeft(fc.find('{')); + stmp = fc.takeRange('{', '}'); + stmp = cw + ' ' + tmp + '{' + stmp + '}'; + auto new_entity = parseClass(ce, stmp, false); + // piCout << "!!! > \"" << fc << "\""; + PIStringList vars; + PIString var; + do { + var = fc.takeCWord(); + if (var.isNotEmpty()) vars << var; + if (fc.takeSymbol() == ";") break; + } while (var.isNotEmpty()); + if (new_entity) { + if (vars.isNotEmpty()) { + ce->children.removeAll(new_entity); + Member me; + me.visibility = cur_def_vis; + me.type = new_entity->name; + for (const auto & v: vars) { + me.name = v; + ce->members << me; + } + } + } + // piCout << "!!! <" << vars; continue; } if (cw == s_enum) { @@ -710,6 +773,7 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) } cur_def_vis = prev_vis; cur_namespace = prev_namespace; + return ce; } @@ -766,7 +830,7 @@ bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc PICodeParser::Typedef PICodeParser::parseTypedef(PIString fc) { - // piCout << "parse typedef" << fc; + // piCout << "parse typedef \"" << fc << "\""; Typedef td; fc.replaceAll('\t', ' '); diff --git a/libs/main/code/picodeparser.h b/libs/main/code/picodeparser.h index e9aea9e6..33cc543c 100644 --- a/libs/main/code/picodeparser.h +++ b/libs/main/code/picodeparser.h @@ -164,7 +164,7 @@ private: bool parseFileContent(PIString & fc, bool main); bool parseDirective(PIString d); Entity * parseClassDeclaration(const PIString & fc); - void parseClass(Entity * parent, PIString & fc, bool is_namespace); + Entity * parseClass(Entity * parent, PIString & fc, bool is_namespace); MetaMap parseMeta(PIString & fc); bool parseEnum(Entity * parent, const PIString & name, PIString fc, const MetaMap & meta); Typedef parseTypedef(PIString fc);