diff options
| author | Li Jin <dragon-fly@qq.com> | 2026-02-24 00:18:48 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2026-02-24 00:18:48 +0800 |
| commit | e2d35caf96f1330db11316cccb0b6289d56ac662 (patch) | |
| tree | e846ceed68028e7678418d2b8c6f4a7a7f7baf41 /src | |
| parent | 1d450f59ab482906eedcd3cab4fea28327613592 (diff) | |
| download | yuescript-e2d35caf96f1330db11316cccb0b6289d56ac662.tar.gz yuescript-e2d35caf96f1330db11316cccb0b6289d56ac662.tar.bz2 yuescript-e2d35caf96f1330db11316cccb0b6289d56ac662.zip | |
Fixed comma position in class members with line number comments. Fixed issue #240.
Diffstat (limited to 'src')
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 84 |
1 files changed, 45 insertions, 39 deletions
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 92bf561..840ef3e 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
| @@ -78,7 +78,7 @@ static std::unordered_set<std::string> Metamethods = { | |||
| 78 | "close"s // Lua 5.4 | 78 | "close"s // Lua 5.4 |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | const std::string_view version = "0.33.1"sv; | 81 | const std::string_view version = "0.33.2"sv; |
| 82 | const std::string_view extension = "yue"sv; | 82 | const std::string_view extension = "yue"sv; |
| 83 | 83 | ||
| 84 | class CompileError : public std::logic_error { | 84 | class CompileError : public std::logic_error { |
| @@ -9955,9 +9955,11 @@ private: | |||
| 9955 | auto baseVar = getUnusedName("_base_"sv); | 9955 | auto baseVar = getUnusedName("_base_"sv); |
| 9956 | addToScope(baseVar); | 9956 | addToScope(baseVar); |
| 9957 | temp.push_back(indent() + "local "s + baseVar + " = "s); | 9957 | temp.push_back(indent() + "local "s + baseVar + " = "s); |
| 9958 | str_list builtins; | 9958 | using ClassMemberEntry = std::tuple<std::string, std::string, bool>; |
| 9959 | std::vector<std::pair<std::string, bool>> baseEntries; | 9959 | std::list<ClassMemberEntry> builtinFields; |
| 9960 | str_list statements; | 9960 | std::list<ClassMemberEntry> classFields; |
| 9961 | std::list<ClassMemberEntry> commentOrEmpty; | ||
| 9962 | str_list initStatements; | ||
| 9961 | if (body) { | 9963 | if (body) { |
| 9962 | std::list<ClassMember> members; | 9964 | std::list<ClassMember> members; |
| 9963 | for (auto content : classDecl->body->contents.objects()) { | 9965 | for (auto content : classDecl->body->contents.objects()) { |
| @@ -9969,11 +9971,19 @@ private: | |||
| 9969 | for (; it != members.end(); ++it) { | 9971 | for (; it != members.end(); ++it) { |
| 9970 | auto& member = *it; | 9972 | auto& member = *it; |
| 9971 | if (member.type == MemType::Property) { | 9973 | if (member.type == MemType::Property) { |
| 9972 | statements.push_back(indent() + member.item + nl(content)); | 9974 | initStatements.push_back(indent() + member.item + nl(content)); |
| 9973 | } else if (member.type == MemType::Builtin) { | 9975 | } else if (member.type == MemType::Builtin) { |
| 9974 | builtins.push_back((builtins.empty() ? Empty : ',' + nl(member.node)) + indent(1) + member.item); | 9976 | if (!commentOrEmpty.empty()) { |
| 9977 | builtinFields.insert(builtinFields.end(), commentOrEmpty.begin(), commentOrEmpty.end()); | ||
| 9978 | commentOrEmpty.clear(); | ||
| 9979 | } | ||
| 9980 | builtinFields.emplace_back(indent(1) + member.item, nl(member.node), false); | ||
| 9975 | } else { | 9981 | } else { |
| 9976 | baseEntries.emplace_back(indent(1) + member.item + nl(member.node), true); | 9982 | if (!commentOrEmpty.empty()) { |
| 9983 | classFields.insert(classFields.end(), commentOrEmpty.begin(), commentOrEmpty.end()); | ||
| 9984 | commentOrEmpty.clear(); | ||
| 9985 | } | ||
| 9986 | classFields.emplace_back(indent(1) + member.item, nl(member.node), false); | ||
| 9977 | } | 9987 | } |
| 9978 | } | 9988 | } |
| 9979 | break; | 9989 | break; |
| @@ -9981,13 +9991,13 @@ private: | |||
| 9981 | case id<YueComment_t>(): { | 9991 | case id<YueComment_t>(): { |
| 9982 | if (_config.reserveComment) { | 9992 | if (_config.reserveComment) { |
| 9983 | auto comment = static_cast<YueComment_t*>(content); | 9993 | auto comment = static_cast<YueComment_t*>(content); |
| 9984 | baseEntries.emplace_back(indent(1) + comment->to_string(&_config) + '\n', false); | 9994 | commentOrEmpty.emplace_back(indent(1) + comment->to_string(&_config), "\n"s, true); |
| 9985 | } | 9995 | } |
| 9986 | break; | 9996 | break; |
| 9987 | } | 9997 | } |
| 9988 | case id<EmptyLine_t>(): { | 9998 | case id<EmptyLine_t>(): { |
| 9989 | if (_config.reserveComment) { | 9999 | if (_config.reserveComment) { |
| 9990 | baseEntries.emplace_back("\n"s, false); | 10000 | commentOrEmpty.emplace_back(Empty, "\n"s, true); |
| 9991 | } | 10001 | } |
| 9992 | break; | 10002 | break; |
| 9993 | } | 10003 | } |
| @@ -10002,37 +10012,23 @@ private: | |||
| 10002 | forceAddToScope("self"s); | 10012 | forceAddToScope("self"s); |
| 10003 | for (auto stmt_ : block->statementOrComments.objects()) { | 10013 | for (auto stmt_ : block->statementOrComments.objects()) { |
| 10004 | if (auto stmt = ast_cast<Statement_t>(stmt_)) { | 10014 | if (auto stmt = ast_cast<Statement_t>(stmt_)) { |
| 10005 | transformStatement(stmt, statements); | 10015 | transformStatement(stmt, initStatements); |
| 10006 | } | 10016 | } |
| 10007 | } | 10017 | } |
| 10008 | if (!baseEntries.empty()) { | 10018 | if (!classFields.empty()) { |
| 10009 | temp.back() += '{' + nl(body); | 10019 | temp.back() += '{' + nl(body); |
| 10010 | int lastValue = -1; | 10020 | str_list fieldItems; |
| 10011 | for (int i = static_cast<int>(baseEntries.size()) - 1; i >= 0; --i) { | 10021 | for (auto& field : classFields) { |
| 10012 | if (baseEntries[i].second) { | 10022 | auto [item, newLine, isComment] = std::move(field); |
| 10013 | lastValue = i; | 10023 | bool isLast = &field == &classFields.back(); |
| 10014 | break; | 10024 | bool needComma = !isLast && !isComment; |
| 10015 | } | 10025 | if (needComma) { |
| 10016 | } | 10026 | fieldItems.emplace_back(item + ',' + newLine); |
| 10017 | str_list baseItems; | 10027 | } else { |
| 10018 | for (int i = 0; i < static_cast<int>(baseEntries.size()); ++i) { | 10028 | fieldItems.emplace_back(item + newLine); |
| 10019 | auto item = baseEntries[i].first; | ||
| 10020 | if (baseEntries[i].second && i != lastValue) { | ||
| 10021 | auto pos = item.rfind('\n'); | ||
| 10022 | if (pos != std::string::npos) { | ||
| 10023 | auto comment = item.rfind("-- "); | ||
| 10024 | if (comment != std::string::npos && comment < pos) { | ||
| 10025 | item.insert(comment - 1, ","); | ||
| 10026 | } else { | ||
| 10027 | item.insert(pos, ","); | ||
| 10028 | } | ||
| 10029 | } else { | ||
| 10030 | item.push_back(','); | ||
| 10031 | } | ||
| 10032 | } | 10029 | } |
| 10033 | baseItems.push_back(std::move(item)); | ||
| 10034 | } | 10030 | } |
| 10035 | temp.push_back(join(baseItems)); | 10031 | temp.push_back(join(fieldItems)); |
| 10036 | temp.push_back(indent() + '}' + nl(body)); | 10032 | temp.push_back(indent() + '}' + nl(body)); |
| 10037 | } else { | 10033 | } else { |
| 10038 | temp.back() += "{ }"s + nl(body); | 10034 | temp.back() += "{ }"s + nl(body); |
| @@ -10074,8 +10070,18 @@ private: | |||
| 10074 | _buf << indent() << "setmetatable("sv << baseVar << ", "sv << parentVar << ".__base)"sv << nl(classDecl); | 10070 | _buf << indent() << "setmetatable("sv << baseVar << ", "sv << parentVar << ".__base)"sv << nl(classDecl); |
| 10075 | } | 10071 | } |
| 10076 | _buf << indent() << classVar << " = "sv << globalVar("setmetatable"sv, classDecl, AccessType::Read) << "({"sv << nl(classDecl); | 10072 | _buf << indent() << classVar << " = "sv << globalVar("setmetatable"sv, classDecl, AccessType::Read) << "({"sv << nl(classDecl); |
| 10077 | if (!builtins.empty()) { | 10073 | if (!builtinFields.empty()) { |
| 10078 | _buf << join(builtins) << ',' << nl(classDecl); | 10074 | str_list builtinItems; |
| 10075 | for (auto& field : builtinFields) { | ||
| 10076 | auto [item, newLine, isComment] = std::move(field); | ||
| 10077 | bool needComma = !isComment; | ||
| 10078 | if (needComma) { | ||
| 10079 | builtinItems.emplace_back(item + ',' + newLine); | ||
| 10080 | } else { | ||
| 10081 | builtinItems.emplace_back(item + newLine); | ||
| 10082 | } | ||
| 10083 | } | ||
| 10084 | _buf << join(builtinItems); | ||
| 10079 | } else { | 10085 | } else { |
| 10080 | if (extend) { | 10086 | if (extend) { |
| 10081 | _buf << indent(1) << "__init = function(self, ...)"sv << nl(classDecl); | 10087 | _buf << indent(1) << "__init = function(self, ...)"sv << nl(classDecl); |
| @@ -10122,10 +10128,10 @@ private: | |||
| 10122 | _buf << indent(1) << "end"sv << nl(classDecl); | 10128 | _buf << indent(1) << "end"sv << nl(classDecl); |
| 10123 | _buf << indent() << "})"sv << nl(classDecl); | 10129 | _buf << indent() << "})"sv << nl(classDecl); |
| 10124 | _buf << indent() << baseVar << ".__class = "sv << classVar << nl(classDecl); | 10130 | _buf << indent() << baseVar << ".__class = "sv << classVar << nl(classDecl); |
| 10125 | if (!statements.empty()) { | 10131 | if (!initStatements.empty()) { |
| 10126 | _buf << indent() << "local self = "sv << classVar << ';' << nl(classDecl); | 10132 | _buf << indent() << "local self = "sv << classVar << ';' << nl(classDecl); |
| 10127 | } | 10133 | } |
| 10128 | _buf << join(statements); | 10134 | _buf << join(initStatements); |
| 10129 | if (extend) { | 10135 | if (extend) { |
| 10130 | _buf << indent() << "if "sv << parentVar << ".__inherited then"sv << nl(classDecl); | 10136 | _buf << indent() << "if "sv << parentVar << ".__inherited then"sv << nl(classDecl); |
| 10131 | _buf << indent(1) << parentVar << ".__inherited("sv << parentVar << ", "sv << classVar << ")"sv << nl(classDecl); | 10137 | _buf << indent(1) << parentVar << ".__inherited("sv << parentVar << ", "sv << classVar << ")"sv << nl(classDecl); |
