mirror of
https://github.com/logos-co/logos-cpp-sdk.git
synced 2026-08-31 17:51:07 +00:00
parse adjacent method comments to populate description
This commit is contained in:
@@ -257,6 +257,11 @@ ImplParseResult parseImplHeader(const QString& headerPath,
|
||||
State state = LookingForClass;
|
||||
int braceDepth = 0;
|
||||
|
||||
// Accumulates doc-comment lines adjacent to a method so the doc comment
|
||||
// becomes the method's description. Reset on any blank / non-comment line.
|
||||
QStringList pendingDoc;
|
||||
bool inBlockComment = false;
|
||||
|
||||
QRegularExpression classRe("\\bclass\\s+" + QRegularExpression::escape(className) + "\\b");
|
||||
QRegularExpression accessRe("^\\s*(public|private|protected)\\s*:");
|
||||
QRegularExpression eventsRe("^\\s*logos_events\\s*:");
|
||||
@@ -280,6 +285,18 @@ ImplParseResult parseImplHeader(const QString& headerPath,
|
||||
case InPublic:
|
||||
case InPrivate:
|
||||
case InLogosEvents:
|
||||
// Inside a multi-line /** ... */ doc-comment block: capture its
|
||||
// text (skip brace counting — comments don't affect scope).
|
||||
if (inBlockComment) {
|
||||
QString t = line;
|
||||
int end = t.indexOf("*/");
|
||||
if (end >= 0) { t = t.left(end); inBlockComment = false; }
|
||||
t.remove(QRegularExpression(R"(^\*+\s?)"));
|
||||
t = t.trimmed();
|
||||
if (!t.isEmpty()) pendingDoc.append(t);
|
||||
break;
|
||||
}
|
||||
|
||||
for (QChar c : line) {
|
||||
if (c == '{') braceDepth++;
|
||||
else if (c == '}') braceDepth--;
|
||||
@@ -297,6 +314,7 @@ ImplParseResult parseImplHeader(const QString& headerPath,
|
||||
// token we recognise here.)
|
||||
if (eventsRe.match(line).hasMatch()) {
|
||||
state = InLogosEvents;
|
||||
pendingDoc.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -306,22 +324,51 @@ ImplParseResult parseImplHeader(const QString& headerPath,
|
||||
QString spec = am.captured(1);
|
||||
if (spec == "public") state = InPublic;
|
||||
else state = InPrivate;
|
||||
pendingDoc.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Skip noise & non-declarations in any section.
|
||||
if (line.isEmpty() || line.startsWith("//") || line.startsWith("#")
|
||||
|| line.startsWith("/*") || line.startsWith("*"))
|
||||
// Only doc comments (/// or /** ... */ / /*! ... */) accumulate as
|
||||
// the pending description for the next method. Plain // and /*
|
||||
// comments are ignored but leave pending doc intact; blank /
|
||||
// preprocessor lines reset it so only *adjacent* comments attach.
|
||||
if (line.startsWith("///")) {
|
||||
QString text = line.mid(3);
|
||||
if (text.startsWith('<')) text = text.mid(1); // ///< trailing form
|
||||
text = text.trimmed();
|
||||
if (!text.isEmpty()) pendingDoc.append(text);
|
||||
break;
|
||||
}
|
||||
if (line.startsWith("/**") || line.startsWith("/*!")) {
|
||||
QString text = line.mid(3);
|
||||
int end = text.indexOf("*/");
|
||||
if (end >= 0) text = text.left(end);
|
||||
else inBlockComment = true;
|
||||
text.remove(QRegularExpression(R"(^\*+\s?)"));
|
||||
text = text.trimmed();
|
||||
if (!text.isEmpty()) pendingDoc.append(text);
|
||||
break;
|
||||
}
|
||||
if (line.startsWith("//") || line.startsWith("/*") || line.startsWith("*")) {
|
||||
break; // non-doc comment: ignore, keep pending doc
|
||||
}
|
||||
if (line.isEmpty() || line.startsWith("#")) {
|
||||
pendingDoc.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ctorDtorRe.match(line).hasMatch())
|
||||
if (ctorDtorRe.match(line).hasMatch()) {
|
||||
pendingDoc.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
if (line.startsWith("typedef") || line.startsWith("using")
|
||||
|| line.startsWith("friend") || line.startsWith("enum")
|
||||
|| line.startsWith("struct"))
|
||||
|| line.startsWith("struct")) {
|
||||
pendingDoc.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
if (state == InLogosEvents) {
|
||||
// Inside `logos_events:` — every bare prototype is an event.
|
||||
@@ -338,10 +385,11 @@ ImplParseResult parseImplHeader(const QString& headerPath,
|
||||
result.module.events.append(ed);
|
||||
}
|
||||
}
|
||||
pendingDoc.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
if (state != InPublic) break;
|
||||
if (state != InPublic) { pendingDoc.clear(); break; }
|
||||
|
||||
if (line.contains("std::function<")) {
|
||||
// A std::function member is not a method — skip it so the
|
||||
@@ -349,6 +397,7 @@ ImplParseResult parseImplHeader(const QString& headerPath,
|
||||
// parens in its type. (Events are declared in a typed
|
||||
// `logos_events:` section, parsed above — there is no longer
|
||||
// any special `std::function emitEvent` member to detect.)
|
||||
pendingDoc.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -356,9 +405,11 @@ ImplParseResult parseImplHeader(const QString& headerPath,
|
||||
QString decl = line.left(line.size() - 1).trimmed();
|
||||
MethodDecl md;
|
||||
if (parseMethodLine(decl, md)) {
|
||||
md.description = pendingDoc.join(' ').trimmed();
|
||||
result.module.methods.append(md);
|
||||
}
|
||||
}
|
||||
pendingDoc.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user