mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-07-26 18:00:38 +00:00
fix(parser): report unclosed multiline comments (#924)
* fix(parser): report unclosed multiline comments * chore: make multi line comment variable names clearer --------- Co-authored-by: Jan Laupetin <[email protected]>
This commit is contained in:
@@ -1,9 +1,12 @@
|
|||||||
#include "CommentRemovingStreamProxy.h"
|
#include "CommentRemovingStreamProxy.h"
|
||||||
|
|
||||||
|
#include "Parsing/ParsingException.h"
|
||||||
|
|
||||||
CommentRemovingStreamProxy::CommentRemovingStreamProxy(IParserLineStream* stream)
|
CommentRemovingStreamProxy::CommentRemovingStreamProxy(IParserLineStream* stream)
|
||||||
: m_stream(stream),
|
: m_stream(stream),
|
||||||
m_inside_multi_line_comment(false),
|
m_inside_multi_line_comment(false),
|
||||||
m_next_line_is_comment(false)
|
m_next_line_is_comment(false),
|
||||||
|
m_multi_line_comment_pos_in_start_line(0u)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11,13 +14,20 @@ ParserLine CommentRemovingStreamProxy::NextLine()
|
|||||||
{
|
{
|
||||||
auto line = m_stream->NextLine();
|
auto line = m_stream->NextLine();
|
||||||
|
|
||||||
|
if (line.IsEof() && m_inside_multi_line_comment)
|
||||||
|
{
|
||||||
|
throw ParsingException(
|
||||||
|
TokenPos(*m_multi_line_comment_start_line.m_filename, m_multi_line_comment_start_line.m_line_number, m_multi_line_comment_pos_in_start_line + 1u),
|
||||||
|
"Unclosed multi-line comment");
|
||||||
|
}
|
||||||
|
|
||||||
if (m_next_line_is_comment)
|
if (m_next_line_is_comment)
|
||||||
{
|
{
|
||||||
m_next_line_is_comment = !line.m_line.empty() && line.m_line[line.m_line.size() - 1] == '\\';
|
m_next_line_is_comment = !line.m_line.empty() && line.m_line[line.m_line.size() - 1] == '\\';
|
||||||
return ParserLine(line.m_filename, line.m_line_number, std::string());
|
return ParserLine(line.m_filename, line.m_line_number, std::string());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto multiLineCommentStart = 0u;
|
auto multiLineCommentStartInCurrentLine = 0u;
|
||||||
auto inString = false;
|
auto inString = false;
|
||||||
auto isEscaped = false;
|
auto isEscaped = false;
|
||||||
for (auto i = 0u; i < line.m_line.size(); i++)
|
for (auto i = 0u; i < line.m_line.size(); i++)
|
||||||
@@ -28,9 +38,9 @@ ParserLine CommentRemovingStreamProxy::NextLine()
|
|||||||
{
|
{
|
||||||
if (c == '*' && i + 1 < line.m_line.size() && line.m_line[i + 1] == '/')
|
if (c == '*' && i + 1 < line.m_line.size() && line.m_line[i + 1] == '/')
|
||||||
{
|
{
|
||||||
line.m_line.erase(multiLineCommentStart, i + 2 - multiLineCommentStart);
|
line.m_line.erase(multiLineCommentStartInCurrentLine, i + 2 - multiLineCommentStartInCurrentLine);
|
||||||
i = multiLineCommentStart - 1;
|
i = multiLineCommentStartInCurrentLine - 1;
|
||||||
multiLineCommentStart = 0;
|
multiLineCommentStartInCurrentLine = 0;
|
||||||
m_inside_multi_line_comment = false;
|
m_inside_multi_line_comment = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,8 +65,10 @@ ParserLine CommentRemovingStreamProxy::NextLine()
|
|||||||
|
|
||||||
if (c1 == '*')
|
if (c1 == '*')
|
||||||
{
|
{
|
||||||
multiLineCommentStart = i;
|
multiLineCommentStartInCurrentLine = i;
|
||||||
m_inside_multi_line_comment = true;
|
m_inside_multi_line_comment = true;
|
||||||
|
m_multi_line_comment_start_line = line;
|
||||||
|
m_multi_line_comment_pos_in_start_line = i;
|
||||||
}
|
}
|
||||||
else if (c1 == '/')
|
else if (c1 == '/')
|
||||||
{
|
{
|
||||||
@@ -69,7 +81,7 @@ ParserLine CommentRemovingStreamProxy::NextLine()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_inside_multi_line_comment)
|
if (m_inside_multi_line_comment)
|
||||||
line.m_line.erase(multiLineCommentStart);
|
line.m_line.erase(multiLineCommentStartInCurrentLine);
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ class CommentRemovingStreamProxy final : public IParserLineStream
|
|||||||
IParserLineStream* const m_stream;
|
IParserLineStream* const m_stream;
|
||||||
bool m_inside_multi_line_comment;
|
bool m_inside_multi_line_comment;
|
||||||
bool m_next_line_is_comment;
|
bool m_next_line_is_comment;
|
||||||
|
ParserLine m_multi_line_comment_start_line;
|
||||||
|
size_t m_multi_line_comment_pos_in_start_line;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CommentRemovingStreamProxy(IParserLineStream* stream);
|
explicit CommentRemovingStreamProxy(IParserLineStream* stream);
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
|
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
|
||||||
#include "Parsing/Mock/MockParserLineStream.h"
|
#include "Parsing/Mock/MockParserLineStream.h"
|
||||||
|
#include "Parsing/ParsingException.h"
|
||||||
|
|
||||||
#include <catch2/catch_test_macros.hpp>
|
#include <catch2/catch_test_macros.hpp>
|
||||||
#include <catch2/generators/catch_generators.hpp>
|
#include <catch2/generators/catch_generators.hpp>
|
||||||
|
#include <catch2/matchers/catch_matchers_exception.hpp>
|
||||||
|
#include <catch2/matchers/catch_matchers_string.hpp>
|
||||||
|
|
||||||
|
using namespace Catch::Matchers;
|
||||||
|
|
||||||
namespace test::parsing::impl::comment_removing_stream_proxy
|
namespace test::parsing::impl::comment_removing_stream_proxy
|
||||||
{
|
{
|
||||||
@@ -192,6 +197,19 @@ namespace test::parsing::impl::comment_removing_stream_proxy
|
|||||||
REQUIRE(proxy.Eof());
|
REQUIRE(proxy.Eof());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("CommentRemovingStreamProxy: Unclosed multiline comment at end of file throws an error", "[parsing][parsingstream]")
|
||||||
|
{
|
||||||
|
const std::vector<std::string> lines{"before /* comment", "still comment"};
|
||||||
|
|
||||||
|
MockParserLineStream mockStream(lines);
|
||||||
|
CommentRemovingStreamProxy proxy(&mockStream);
|
||||||
|
|
||||||
|
REQUIRE(proxy.NextLine().m_line == "before ");
|
||||||
|
REQUIRE(proxy.NextLine().m_line.empty());
|
||||||
|
REQUIRE_THROWS_MATCHES(
|
||||||
|
proxy.NextLine(), ParsingException, MessageMatches(ContainsSubstring("L1:8") && ContainsSubstring("Unclosed multi-line comment")));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("CommentRemovingStreamProxy: Can have multiple comment blocks in one line", "[parsing][parsingstream]")
|
TEST_CASE("CommentRemovingStreamProxy: Can have multiple comment blocks in one line", "[parsing][parsingstream]")
|
||||||
{
|
{
|
||||||
const std::vector<std::string> lines{
|
const std::vector<std::string> lines{
|
||||||
|
|||||||
Reference in New Issue
Block a user