From 13d01ed3f236d56006b1fbb84e30c712633819ac Mon Sep 17 00:00:00 2001 From: Kevin Traini Date: Wed, 29 Nov 2023 21:15:50 +0100 Subject: [PATCH 1/6] feat: Add AbstractPosition Part of #67 All position class must heritate from AbstractPosition class --- src/lib/ast/AST.h | 26 +++++++++++------------ src/lib/ast/AbstractExpression.cpp | 7 +++--- src/lib/ast/ArrayOperator.cpp | 4 ++-- src/lib/ast/AssignationOperator.cpp | 4 ++-- src/lib/ast/ClassicOperator.cpp | 4 ++-- src/lib/ast/FunctionOperator.cpp | 4 ++-- src/lib/message/DevWarning.cpp | 2 +- src/lib/message/DevWarning.h | 4 ++-- src/lib/message/Error.cpp | 2 +- src/lib/message/Error.h | 4 ++-- src/lib/utils/Position.h | 14 ++++++++++-- tests/unit/ast/AbstractExpressionTest.cpp | 2 +- tests/unit/grammar/ParserTest.cpp | 2 +- 13 files changed, 45 insertions(+), 34 deletions(-) diff --git a/src/lib/ast/AST.h b/src/lib/ast/AST.h index 03f59c64..9816538b 100644 --- a/src/lib/ast/AST.h +++ b/src/lib/ast/AST.h @@ -75,7 +75,7 @@ namespace filc::ast { public: virtual ~AbstractExpression(); - auto setPosition(filc::utils::Position *position) -> void; + auto setPosition(filc::utils::AbstractPosition *position) -> void; AbstractExpression(const AbstractExpression &other) = default; @@ -89,7 +89,7 @@ namespace filc::ast { auto setExported(bool exported) -> void; - [[nodiscard]] auto getPosition() const -> filc::utils::Position *; + [[nodiscard]] auto getPosition() const -> filc::utils::AbstractPosition *; [[nodiscard]] auto getExpressionType() const -> std::shared_ptr; @@ -107,7 +107,7 @@ namespace filc::ast { private: bool _exported{false}; - filc::utils::Position *_position{nullptr}; + filc::utils::AbstractPosition *_position{nullptr}; std::shared_ptr _expression_type; protected: @@ -446,12 +446,12 @@ namespace filc::ast { [[nodiscard]] virtual auto dumpPreLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr = 0; + filc::utils::AbstractPosition *position) const -> std::shared_ptr = 0; [[nodiscard]] virtual auto dumpPostLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr = 0; + filc::utils::AbstractPosition *position) const -> std::shared_ptr = 0; protected: Operator() = default; @@ -490,12 +490,12 @@ namespace filc::ast { [[nodiscard]] auto dumpPreLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr override; + filc::utils::AbstractPosition *position) const -> std::shared_ptr override; [[nodiscard]] auto dumpPostLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr override; + filc::utils::AbstractPosition *position) const -> std::shared_ptr override; private: OPERATOR _operator; @@ -514,12 +514,12 @@ namespace filc::ast { [[nodiscard]] auto dumpPreLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr override; + filc::utils::AbstractPosition *position) const -> std::shared_ptr override; [[nodiscard]] auto dumpPostLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr override; + filc::utils::AbstractPosition *position) const -> std::shared_ptr override; private: AbstractExpression *_expression; @@ -538,12 +538,12 @@ namespace filc::ast { [[nodiscard]] auto dumpPreLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr override; + filc::utils::AbstractPosition *position) const -> std::shared_ptr override; [[nodiscard]] auto dumpPostLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr override; + filc::utils::AbstractPosition *position) const -> std::shared_ptr override; private: std::vector _expressions; @@ -562,12 +562,12 @@ namespace filc::ast { [[nodiscard]] auto dumpPreLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr override; + filc::utils::AbstractPosition *position) const -> std::shared_ptr override; [[nodiscard]] auto dumpPostLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr override; + filc::utils::AbstractPosition *position) const -> std::shared_ptr override; private: Operator *_inner_operator; diff --git a/src/lib/ast/AbstractExpression.cpp b/src/lib/ast/AbstractExpression.cpp index bcb0ac72..fc59dd24 100644 --- a/src/lib/ast/AbstractExpression.cpp +++ b/src/lib/ast/AbstractExpression.cpp @@ -39,11 +39,11 @@ namespace filc::ast { _exported = exported; } - auto AbstractExpression::getPosition() const -> filc::utils::Position * { + auto AbstractExpression::getPosition() const -> filc::utils::AbstractPosition * { return _position; } - auto AbstractExpression::setPosition(filc::utils::Position *position) -> void { + auto AbstractExpression::setPosition(filc::utils::AbstractPosition *position) -> void { _position = position; } @@ -67,8 +67,9 @@ namespace filc::ast { auto AbstractExpression::addNameToEnvironment( filc::environment::Environment *environment) const -> void { + auto *position = dynamic_cast(getPosition()); auto name = filc::utils::joinString(filc::utils::splitString(environment->getModule(), '.'), "_") - + "_" + std::to_string(getPosition()->getLine()); + + "_" + std::to_string(position->getLine()); environment->addName(name, getExpressionType()); } diff --git a/src/lib/ast/ArrayOperator.cpp b/src/lib/ast/ArrayOperator.cpp index f3a5bebd..01a69177 100644 --- a/src/lib/ast/ArrayOperator.cpp +++ b/src/lib/ast/ArrayOperator.cpp @@ -43,7 +43,7 @@ namespace filc::ast { auto ArrayOperator::dumpPreLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr { + filc::utils::AbstractPosition *position) const -> std::shared_ptr { collector->addError(new filc::message::DevWarning( 3, position, @@ -56,7 +56,7 @@ namespace filc::ast { auto ArrayOperator::dumpPostLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr { + filc::utils::AbstractPosition *position) const -> std::shared_ptr { _expression->resolveType(environment, collector, nullptr); auto expression_type = _expression->getExpressionType(); if (expression_type == nullptr) { diff --git a/src/lib/ast/AssignationOperator.cpp b/src/lib/ast/AssignationOperator.cpp index a0c9dc47..fb8d679c 100644 --- a/src/lib/ast/AssignationOperator.cpp +++ b/src/lib/ast/AssignationOperator.cpp @@ -43,7 +43,7 @@ namespace filc::ast { auto AssignationOperator::dumpPreLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr { + filc::utils::AbstractPosition *position) const -> std::shared_ptr { collector->addError(new filc::message::DevWarning( 3, position, @@ -56,7 +56,7 @@ namespace filc::ast { auto AssignationOperator::dumpPostLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr { + filc::utils::AbstractPosition *position) const -> std::shared_ptr { collector->addError(new filc::message::DevWarning( 3, position, diff --git a/src/lib/ast/ClassicOperator.cpp b/src/lib/ast/ClassicOperator.cpp index 46d13df9..62e2d823 100644 --- a/src/lib/ast/ClassicOperator.cpp +++ b/src/lib/ast/ClassicOperator.cpp @@ -80,7 +80,7 @@ namespace filc::ast { auto ClassicOperator::dumpPreLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr { + filc::utils::AbstractPosition *position) const -> std::shared_ptr { auto ptr = std::make_shared(type); switch (_operator) { case PLUSPLUS: @@ -118,7 +118,7 @@ namespace filc::ast { auto ClassicOperator::dumpPostLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr { + filc::utils::AbstractPosition *position) const -> std::shared_ptr { auto ptr = std::make_shared(type); switch (_operator) { case PLUSPLUS: diff --git a/src/lib/ast/FunctionOperator.cpp b/src/lib/ast/FunctionOperator.cpp index f399776f..334c11f4 100644 --- a/src/lib/ast/FunctionOperator.cpp +++ b/src/lib/ast/FunctionOperator.cpp @@ -45,7 +45,7 @@ namespace filc::ast { auto FunctionOperator::dumpPreLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr { + filc::utils::AbstractPosition *position) const -> std::shared_ptr { collector->addError(new filc::message::DevWarning( 3, position, @@ -58,7 +58,7 @@ namespace filc::ast { auto FunctionOperator::dumpPostLambdaType(std::shared_ptr type, filc::environment::Environment *environment, filc::message::MessageCollector *collector, - filc::utils::Position *position) const -> std::shared_ptr { + filc::utils::AbstractPosition *position) const -> std::shared_ptr { std::vector> args_types; for (const auto &expression: _expressions) { expression->resolveType(environment, collector, nullptr); diff --git a/src/lib/message/DevWarning.cpp b/src/lib/message/DevWarning.cpp index 5fe57b24..83700c79 100644 --- a/src/lib/message/DevWarning.cpp +++ b/src/lib/message/DevWarning.cpp @@ -25,7 +25,7 @@ #include namespace filc::message { - DevWarning::DevWarning(unsigned int code, filc::utils::Position *position, std::string content) + DevWarning::DevWarning(unsigned int code, filc::utils::AbstractPosition *position, std::string content) : Message(ERROR, std::move(content)), _code(code), _position(position) {} auto DevWarning::print(std::ostream &out) -> std::ostream & { diff --git a/src/lib/message/DevWarning.h b/src/lib/message/DevWarning.h index b220a532..e50c3cec 100644 --- a/src/lib/message/DevWarning.h +++ b/src/lib/message/DevWarning.h @@ -30,13 +30,13 @@ namespace filc::message { class DevWarning final : public Message { public: - DevWarning(unsigned int code, filc::utils::Position *position, std::string content); + DevWarning(unsigned int code, filc::utils::AbstractPosition *position, std::string content); auto print(std::ostream &out) -> std::ostream & override; private: unsigned int _code; - filc::utils::Position *_position; + filc::utils::AbstractPosition *_position; }; } diff --git a/src/lib/message/Error.cpp b/src/lib/message/Error.cpp index b11924ad..7fce5f4c 100644 --- a/src/lib/message/Error.cpp +++ b/src/lib/message/Error.cpp @@ -36,7 +36,7 @@ namespace filc::message { return out; } - Error::Error(filc::message::LEVEL level, std::string content, filc::utils::Position *position) + Error::Error(filc::message::LEVEL level, std::string content, filc::utils::AbstractPosition *position) : Message(level, std::move(content)), _position(position) {} auto Error::print(std::ostream &out) -> std::ostream & { diff --git a/src/lib/message/Error.h b/src/lib/message/Error.h index e8598e3b..6808c76e 100644 --- a/src/lib/message/Error.h +++ b/src/lib/message/Error.h @@ -38,12 +38,12 @@ namespace filc::message { class Error final : public Message { public: - Error(LEVEL level, std::string content, filc::utils::Position *position); + Error(LEVEL level, std::string content, filc::utils::AbstractPosition *position); auto print(std::ostream &out) -> std::ostream & override; private: - filc::utils::Position *_position; + filc::utils::AbstractPosition *_position; }; } diff --git a/src/lib/utils/Position.h b/src/lib/utils/Position.h index 3a3f4e2d..44892b99 100644 --- a/src/lib/utils/Position.h +++ b/src/lib/utils/Position.h @@ -28,7 +28,17 @@ #include namespace filc::utils { - class Position final { + class AbstractPosition { + public: + [[nodiscard]] virtual auto dump(const std::string &color) const -> std::string = 0; + + virtual ~AbstractPosition() = default; + + protected: + AbstractPosition() = default; + }; + + class Position final : public AbstractPosition { public: Position(std::string filename, unsigned int line, unsigned int column); @@ -42,7 +52,7 @@ namespace filc::utils { [[nodiscard]] auto getContent() const -> std::string; - [[nodiscard]] auto dump(const std::string &color) const -> std::string; + [[nodiscard]] auto dump(const std::string &color) const -> std::string override; private: std::string _filename; diff --git a/tests/unit/ast/AbstractExpressionTest.cpp b/tests/unit/ast/AbstractExpressionTest.cpp index 88ee61f7..55bcc6e2 100644 --- a/tests/unit/ast/AbstractExpressionTest.cpp +++ b/tests/unit/ast/AbstractExpressionTest.cpp @@ -32,7 +32,7 @@ TEST(AbstractExpression, position) { ASSERT_EQ(nullptr, obj1.getPosition()); obj1.setPosition(new filc::utils::Position("test.fil", 1, 2)); - auto *position = obj1.getPosition(); + auto *position = dynamic_cast(obj1.getPosition()); ASSERT_STREQ("test.fil", position->getFilename().c_str()); ASSERT_EQ(1, position->getLine()); ASSERT_EQ(2, position->getColumn()); diff --git a/tests/unit/grammar/ParserTest.cpp b/tests/unit/grammar/ParserTest.cpp index 14c4b439..87775d67 100644 --- a/tests/unit/grammar/ParserTest.cpp +++ b/tests/unit/grammar/ParserTest.cpp @@ -58,7 +58,7 @@ TEST(Parser, position) { ASSERT_THAT(program->getExpressions(), SizeIs(1)); auto *expression = program->getExpressions()[0]; ASSERT_NE(nullptr, expression); - auto *position = expression->getPosition(); + auto *position = dynamic_cast(expression->getPosition()); ASSERT_STREQ(FIXTURES_PATH_GRAMMAR "/int1.fil", position->getFilename().c_str()); ASSERT_EQ(3, position->getLine()); ASSERT_EQ(0, position->getColumn()); From e65c7c5f9c393ea57ecb2dbdbd6c952ed903adac Mon Sep 17 00:00:00 2001 From: Kevin Traini Date: Wed, 29 Nov 2023 21:55:42 +0100 Subject: [PATCH 2/6] refactor: Position -> SimplePosition Part of #67 --- src/lib/FilCompiler.cpp | 2 +- src/lib/ast/AbstractExpression.cpp | 2 +- src/lib/ast/CharacterLiteral.cpp | 2 +- src/lib/ast/Identifier.cpp | 2 +- src/lib/grammar/FilParser.g4 | 82 +++++++++++------------ src/lib/message/Antlr4ErrorListener.cpp | 2 +- src/lib/utils/Position.cpp | 14 ++-- src/lib/utils/Position.h | 6 +- tests/unit/ast/AbstractExpressionTest.cpp | 4 +- tests/unit/grammar/ParserTest.cpp | 2 +- tests/unit/utils/PositionTest.cpp | 4 +- 11 files changed, 61 insertions(+), 61 deletions(-) diff --git a/src/lib/FilCompiler.cpp b/src/lib/FilCompiler.cpp index 40680ae6..9c0fe5f9 100644 --- a/src/lib/FilCompiler.cpp +++ b/src/lib/FilCompiler.cpp @@ -171,7 +171,7 @@ namespace filc { collector->addError( new filc::message::Error(filc::message::ERROR, "Module " + module_name + " not found", - new filc::utils::Position(program->getFilename(), 0, 0)) + new filc::utils::SimplePosition(program->getFilename(), 0, 0)) ); } } diff --git a/src/lib/ast/AbstractExpression.cpp b/src/lib/ast/AbstractExpression.cpp index fc59dd24..1f8393f1 100644 --- a/src/lib/ast/AbstractExpression.cpp +++ b/src/lib/ast/AbstractExpression.cpp @@ -67,7 +67,7 @@ namespace filc::ast { auto AbstractExpression::addNameToEnvironment( filc::environment::Environment *environment) const -> void { - auto *position = dynamic_cast(getPosition()); + auto *position = dynamic_cast(getPosition()); auto name = filc::utils::joinString(filc::utils::splitString(environment->getModule(), '.'), "_") + "_" + std::to_string(position->getLine()); environment->addName(name, getExpressionType()); diff --git a/src/lib/ast/CharacterLiteral.cpp b/src/lib/ast/CharacterLiteral.cpp index 4ae0d4e3..00d9a2f4 100644 --- a/src/lib/ast/CharacterLiteral.cpp +++ b/src/lib/ast/CharacterLiteral.cpp @@ -48,7 +48,7 @@ namespace filc::ast { if (token != nullptr) { filc::message::MessageCollector::getCollector()->addError(new filc::message::DevWarning( 2, - new filc::utils::Position(token), + new filc::utils::SimplePosition(token), "Lexer found a character that is not regular: " + snippet )); } diff --git a/src/lib/ast/Identifier.cpp b/src/lib/ast/Identifier.cpp index 165de101..abb11074 100644 --- a/src/lib/ast/Identifier.cpp +++ b/src/lib/ast/Identifier.cpp @@ -28,7 +28,7 @@ namespace filc::ast { Identifier::Identifier(antlr4::Token *token) : _name(token->getText()) { - setPosition(new filc::utils::Position(token)); + setPosition(new filc::utils::SimplePosition(token)); } Identifier::Identifier(std::string name) diff --git a/src/lib/grammar/FilParser.g4 b/src/lib/grammar/FilParser.g4 index 57133cb4..4e98050f 100644 --- a/src/lib/grammar/FilParser.g4 +++ b/src/lib/grammar/FilParser.g4 @@ -95,81 +95,81 @@ expression returns[filc::ast::AbstractExpression *tree] | el1=expression STAR er1=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::STAR); $tree = new filc::ast::BinaryCalcul($el1.tree, op, $er1.tree); - $tree->setPosition(new filc::utils::Position($el1.start)); + $tree->setPosition(new filc::utils::SimplePosition($el1.start)); } | el2=expression DIV er2=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::DIV); $tree = new filc::ast::BinaryCalcul($el2.tree, op, $er2.tree); - $tree->setPosition(new filc::utils::Position($el2.start)); + $tree->setPosition(new filc::utils::SimplePosition($el2.start)); } | el3=expression MOD er3=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::MOD); $tree = new filc::ast::BinaryCalcul($el3.tree, op, $er3.tree); - $tree->setPosition(new filc::utils::Position($el3.start)); + $tree->setPosition(new filc::utils::SimplePosition($el3.start)); } | el4=expression PLUS er4=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::PLUS); $tree = new filc::ast::BinaryCalcul($el4.tree, op, $er4.tree); - $tree->setPosition(new filc::utils::Position($el4.start)); + $tree->setPosition(new filc::utils::SimplePosition($el4.start)); } | el5=expression MINUS er5=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::MINUS); $tree = new filc::ast::BinaryCalcul($el5.tree, op, $er5.tree); - $tree->setPosition(new filc::utils::Position($el5.start)); + $tree->setPosition(new filc::utils::SimplePosition($el5.start)); } | el6=expression FLEFT er6=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::FLEFT); $tree = new filc::ast::BinaryCalcul($el6.tree, op, $er6.tree); - $tree->setPosition(new filc::utils::Position($el6.start)); + $tree->setPosition(new filc::utils::SimplePosition($el6.start)); } | el7=expression FRIGHT er7=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::FRIGHT); $tree = new filc::ast::BinaryCalcul($el7.tree, op, $er7.tree); - $tree->setPosition(new filc::utils::Position($el7.start)); + $tree->setPosition(new filc::utils::SimplePosition($el7.start)); } | el8=expression LESS er8=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::LESS); $tree = new filc::ast::BinaryCalcul($el8.tree, op, $er8.tree); - $tree->setPosition(new filc::utils::Position($el8.start)); + $tree->setPosition(new filc::utils::SimplePosition($el8.start)); } | el9=expression GREATER er9=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::GREATER); $tree = new filc::ast::BinaryCalcul($el9.tree, op, $er9.tree); - $tree->setPosition(new filc::utils::Position($el9.start)); + $tree->setPosition(new filc::utils::SimplePosition($el9.start)); } | el10=expression EQEQ er10=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::EQEQ); $tree = new filc::ast::BinaryCalcul($el10.tree, op, $er10.tree); - $tree->setPosition(new filc::utils::Position($el10.start)); + $tree->setPosition(new filc::utils::SimplePosition($el10.start)); } | el11=expression LEQ er11=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::LEQ); $tree = new filc::ast::BinaryCalcul($el11.tree, op, $er11.tree); - $tree->setPosition(new filc::utils::Position($el11.start)); + $tree->setPosition(new filc::utils::SimplePosition($el11.start)); } | el12=expression GEQ er12=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::GEQ); $tree = new filc::ast::BinaryCalcul($el12.tree, op, $er12.tree); - $tree->setPosition(new filc::utils::Position($el12.start)); + $tree->setPosition(new filc::utils::SimplePosition($el12.start)); } | el13=expression NEQ er13=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::NEQ); $tree = new filc::ast::BinaryCalcul($el13.tree, op, $er13.tree); - $tree->setPosition(new filc::utils::Position($el13.start)); + $tree->setPosition(new filc::utils::SimplePosition($el13.start)); } | el14=expression AND er14=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::AND); $tree = new filc::ast::BinaryCalcul($el14.tree, op, $er14.tree); - $tree->setPosition(new filc::utils::Position($el14.start)); + $tree->setPosition(new filc::utils::SimplePosition($el14.start)); } | el15=expression OR er15=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::OR); $tree = new filc::ast::BinaryCalcul($el15.tree, op, $er15.tree); - $tree->setPosition(new filc::utils::Position($el15.start)); + $tree->setPosition(new filc::utils::SimplePosition($el15.start)); } | el16=expression op16=assignation_operator er16=expression { $tree = new filc::ast::BinaryCalcul($el16.tree, $op16.tree, $er16.tree); - $tree->setPosition(new filc::utils::Position($el16.start)); + $tree->setPosition(new filc::utils::SimplePosition($el16.start)); } // ==== Binary calcul ==== @@ -187,7 +187,7 @@ expression returns[filc::ast::AbstractExpression *tree] } | i=IDENTIFIER { $tree = new filc::ast::Identifier($i); - $tree->setPosition(new filc::utils::Position($i)); + $tree->setPosition(new filc::utils::SimplePosition($i)); }; literal returns[filc::ast::AbstractExpression *tree] @@ -201,35 +201,35 @@ literal returns[filc::ast::AbstractExpression *tree] $tree = new filc::ast::CharacterLiteral( filc::ast::CharacterLiteral::stringToChar($c.text, $c) ); - $tree->setPosition(new filc::utils::Position($c)); + $tree->setPosition(new filc::utils::SimplePosition($c)); } | s=STRING { $tree = new filc::ast::StringLiteral($s.text); - $tree->setPosition(new filc::utils::Position($s)); + $tree->setPosition(new filc::utils::SimplePosition($s)); }; boolean returns[filc::ast::BooleanLiteral *tree] : t=TRUE { $tree = new filc::ast::BooleanLiteral(true); - $tree->setPosition(new filc::utils::Position($t)); + $tree->setPosition(new filc::utils::SimplePosition($t)); } | f=FALSE { $tree = new filc::ast::BooleanLiteral(false); - $tree->setPosition(new filc::utils::Position($f)); + $tree->setPosition(new filc::utils::SimplePosition($f)); }; number returns[filc::ast::AbstractExpression *tree] : i=INTEGER { $tree = new filc::ast::IntegerLiteral(stoi($i.text)); - $tree->setPosition(new filc::utils::Position($i)); + $tree->setPosition(new filc::utils::SimplePosition($i)); } | f=FLOAT { $tree = new filc::ast::FloatLiteral(stod($f.text), false); - $tree->setPosition(new filc::utils::Position($f)); + $tree->setPosition(new filc::utils::SimplePosition($f)); } | d=DOUBLE { $tree = new filc::ast::FloatLiteral(stod($d.text), true); - $tree->setPosition(new filc::utils::Position($d)); + $tree->setPosition(new filc::utils::SimplePosition($d)); }; variable_declaration returns[filc::ast::VariableDeclaration *tree] @@ -239,7 +239,7 @@ variable_declaration returns[filc::ast::VariableDeclaration *tree] } @after { $tree = new filc::ast::VariableDeclaration(is_constant, new filc::ast::Identifier($i), $t.tree); - $tree->setPosition(new filc::utils::Position($i)); + $tree->setPosition(new filc::utils::SimplePosition($i)); if (assign != nullptr) { $tree->setAssignation(assign); } @@ -271,7 +271,7 @@ type returns[std::shared_ptr tree] new filc::message::Error( filc::message::ERROR, "Array size must be positive", - new filc::utils::Position($it) + new filc::utils::SimplePosition($it) ) ); } @@ -286,11 +286,11 @@ type returns[std::shared_ptr tree] unary_calcul returns[filc::ast::UnaryCalcul *tree] : i=IDENTIFIER po=post_operator { $tree = new filc::ast::PostUnaryCalcul(new filc::ast::Identifier($i), $po.tree); - $tree->setPosition(new filc::utils::Position($i)); + $tree->setPosition(new filc::utils::SimplePosition($i)); } | pr=pre_operator i=IDENTIFIER { $tree = new filc::ast::PreUnaryCalcul(new filc::ast::Identifier($i), $pr.tree); - $tree->setPosition(new filc::utils::Position($pr.start)); + $tree->setPosition(new filc::utils::SimplePosition($pr.start)); }; post_operator returns[filc::ast::Operator *tree] @@ -373,7 +373,7 @@ classic_binary_operator returns[filc::ast::Operator *tree] function returns[filc::ast::Function *tree] : fd=function_declaration fb=function_body { $tree = new filc::ast::Function($fd.identifier, $fd.parameters, $fd.return_type, $fb.tree); - $tree->setPosition(new filc::utils::Position($fd.start)); + $tree->setPosition(new filc::utils::SimplePosition($fd.start)); }; function_declaration returns[filc::ast::Identifier *identifier, std::vector parameters, std::shared_ptr return_type] @@ -391,11 +391,11 @@ function_declaration returns[filc::ast::Identifier *identifier, std::vectorsetPosition(new filc::utils::Position($o)); + $tree->setPosition(new filc::utils::SimplePosition($o)); } | i=IDENTIFIER { $tree = new filc::ast::Identifier($i); - $tree->setPosition(new filc::utils::Position($i)); + $tree->setPosition(new filc::utils::SimplePosition($i)); }; function_operator @@ -472,7 +472,7 @@ lambda returns[filc::ast::Lambda *tree] } @after { $tree = new filc::ast::Lambda(parameters, $ft.tree, body); - $tree->setPosition(new filc::utils::Position($lp)); + $tree->setPosition(new filc::utils::SimplePosition($lp)); } : lp=LPAREN (fp=function_parameters { parameters = $fp.tree; @@ -514,12 +514,12 @@ condition returns[filc::ast::AbstractExpression *tree] if_c returns[filc::ast::If *tree] : i=IF ic=if_condition ib=if_body { $tree = new filc::ast::If($ic.tree, $ib.tree); - $tree->setPosition(new filc::utils::Position($i)); + $tree->setPosition(new filc::utils::SimplePosition($i)); } (ELSE (ic2=if_c { $tree->setElse($ic2.tree); } | ib2=if_body { auto *else_body = new filc::ast::If(new filc::ast::Identifier("true"), $ib2.tree); - $tree->setPosition(new filc::utils::Position($ib2.start)); + $tree->setPosition(new filc::utils::SimplePosition($ib2.start)); $tree->setElse(else_body); }))?; @@ -538,7 +538,7 @@ if_body returns[filc::ast::BlockBody *tree] switch_c returns[filc::ast::Switch *tree] : s=SWITCH ic=if_condition sb=switch_body { $tree = new filc::ast::Switch($ic.tree, $sb.tree); - $tree->setPosition(new filc::utils::Position($s)); + $tree->setPosition(new filc::utils::SimplePosition($s)); }; switch_body returns[std::vector tree] @@ -555,7 +555,7 @@ switch_case returns[filc::ast::SwitchCase *tree] } @after { $tree = new filc::ast::SwitchCase($sp.tree, body); - $tree->setPosition(new filc::utils::Position($sp.start)); + $tree->setPosition(new filc::utils::SimplePosition($sp.start)); } : sp=switch_pattern ARROW (pb=parenthesis_body { body = $pb.tree; @@ -568,7 +568,7 @@ switch_case returns[filc::ast::SwitchCase *tree] switch_pattern returns[filc::ast::AbstractExpression *tree] : d=DEFAULT { $tree = new filc::ast::Identifier("default"); - $tree->setPosition(new filc::utils::Position($d)); + $tree->setPosition(new filc::utils::SimplePosition($d)); } | l=literal { $tree = $l.tree; }; @@ -585,7 +585,7 @@ loop returns[filc::ast::AbstractExpression *tree] for_i returns[filc::ast::ForI *tree] : f=FOR fic=for_i_condition ib=if_body { $tree = new filc::ast::ForI($fic.declaration, $fic.limit, $fic.iteration, $ib.tree); - $tree->setPosition(new filc::utils::Position($f)); + $tree->setPosition(new filc::utils::SimplePosition($f)); }; for_i_condition returns[filc::ast::VariableDeclaration *declaration, filc::ast::AbstractExpression *limit, filc::ast::AbstractExpression *iteration] @@ -605,7 +605,7 @@ for_i_condition returns[filc::ast::VariableDeclaration *declaration, filc::ast:: for_iter returns[filc::ast::ForIter *tree] : f=FOR fic=for_iter_condition ib=if_body { $tree = new filc::ast::ForIter($fic.constant, $fic.identifier, $fic.array, $ib.tree); - $tree->setPosition(new filc::utils::Position($f)); + $tree->setPosition(new filc::utils::SimplePosition($f)); }; for_iter_condition returns[bool constant, filc::ast::Identifier *identifier, filc::ast::AbstractExpression *array] @@ -616,7 +616,7 @@ for_iter_condition returns[bool constant, filc::ast::Identifier *identifier, fil $constant = false; }) i=IDENTIFIER { $identifier = new filc::ast::Identifier($i); - $identifier->setPosition(new filc::utils::Position($i)); + $identifier->setPosition(new filc::utils::SimplePosition($i)); } COLON e=expression { $array = $e.tree; } RPAREN; @@ -624,7 +624,7 @@ for_iter_condition returns[bool constant, filc::ast::Identifier *identifier, fil while_l returns[filc::ast::While *tree] : w=WHILE ic=if_condition ib=if_body { $tree = new filc::ast::While($ic.tree, $ib.tree); - $tree->setPosition(new filc::utils::Position($w)); + $tree->setPosition(new filc::utils::SimplePosition($w)); }; function_call_params returns[std::vector tree] diff --git a/src/lib/message/Antlr4ErrorListener.cpp b/src/lib/message/Antlr4ErrorListener.cpp index 46d8ca83..86c5bb7e 100644 --- a/src/lib/message/Antlr4ErrorListener.cpp +++ b/src/lib/message/Antlr4ErrorListener.cpp @@ -35,6 +35,6 @@ namespace filc::message { size_t charPositionInLine, const std::string &msg, std::exception_ptr e) { - _collector->addError(new Error(LEVEL::ERROR, msg, new filc::utils::Position(offendingSymbol))); + _collector->addError(new Error(LEVEL::ERROR, msg, new filc::utils::SimplePosition(offendingSymbol))); } } diff --git a/src/lib/utils/Position.cpp b/src/lib/utils/Position.cpp index 5331d8b6..0fd37a00 100644 --- a/src/lib/utils/Position.cpp +++ b/src/lib/utils/Position.cpp @@ -28,26 +28,26 @@ #include namespace filc::utils { - Position::Position(std::string filename, unsigned int line, unsigned int column) + SimplePosition::SimplePosition(std::string filename, unsigned int line, unsigned int column) : _filename(std::move(filename)), _line(line), _column(column) {} - Position::Position(const antlr4::Token *token) + SimplePosition::SimplePosition(const antlr4::Token *token) : _filename(token->getTokenSource()->getSourceName()), _line(token->getLine()), _column(token->getCharPositionInLine()) {} - auto Position::getFilename() const -> const std::string & { + auto SimplePosition::getFilename() const -> const std::string & { return _filename; } - auto Position::getLine() const -> unsigned int { + auto SimplePosition::getLine() const -> unsigned int { return _line; } - auto Position::getColumn() const -> unsigned int { + auto SimplePosition::getColumn() const -> unsigned int { return _column; } - auto Position::getContent() const -> std::string { + auto SimplePosition::getContent() const -> std::string { std::ifstream file(_filename); if (!file.is_open() || !file.good()) { filc::message::MessageCollector::getCollector()->addError( @@ -68,7 +68,7 @@ namespace filc::utils { return line; } - auto Position::dump(const std::string &color) const -> std::string { + auto SimplePosition::dump(const std::string &color) const -> std::string { std::string nth = " " + std::to_string(_line) + " "; std::string res = std::string(nth.length() + 1, ' ') + _filename + "\n"; diff --git a/src/lib/utils/Position.h b/src/lib/utils/Position.h index 44892b99..53b8ca4c 100644 --- a/src/lib/utils/Position.h +++ b/src/lib/utils/Position.h @@ -38,11 +38,11 @@ namespace filc::utils { AbstractPosition() = default; }; - class Position final : public AbstractPosition { + class SimplePosition final : public AbstractPosition { public: - Position(std::string filename, unsigned int line, unsigned int column); + SimplePosition(std::string filename, unsigned int line, unsigned int column); - explicit Position(const antlr4::Token *token); + explicit SimplePosition(const antlr4::Token *token); [[nodiscard]] auto getFilename() const -> const std::string &; diff --git a/tests/unit/ast/AbstractExpressionTest.cpp b/tests/unit/ast/AbstractExpressionTest.cpp index 55bcc6e2..1160ba45 100644 --- a/tests/unit/ast/AbstractExpressionTest.cpp +++ b/tests/unit/ast/AbstractExpressionTest.cpp @@ -31,8 +31,8 @@ TEST(AbstractExpression, position) { ASSERT_EQ(nullptr, obj1.getPosition()); - obj1.setPosition(new filc::utils::Position("test.fil", 1, 2)); - auto *position = dynamic_cast(obj1.getPosition()); + obj1.setPosition(new filc::utils::SimplePosition("test.fil", 1, 2)); + auto *position = dynamic_cast(obj1.getPosition()); ASSERT_STREQ("test.fil", position->getFilename().c_str()); ASSERT_EQ(1, position->getLine()); ASSERT_EQ(2, position->getColumn()); diff --git a/tests/unit/grammar/ParserTest.cpp b/tests/unit/grammar/ParserTest.cpp index 87775d67..bed7ce54 100644 --- a/tests/unit/grammar/ParserTest.cpp +++ b/tests/unit/grammar/ParserTest.cpp @@ -58,7 +58,7 @@ TEST(Parser, position) { ASSERT_THAT(program->getExpressions(), SizeIs(1)); auto *expression = program->getExpressions()[0]; ASSERT_NE(nullptr, expression); - auto *position = dynamic_cast(expression->getPosition()); + auto *position = dynamic_cast(expression->getPosition()); ASSERT_STREQ(FIXTURES_PATH_GRAMMAR "/int1.fil", position->getFilename().c_str()); ASSERT_EQ(3, position->getLine()); ASSERT_EQ(0, position->getColumn()); diff --git a/tests/unit/utils/PositionTest.cpp b/tests/unit/utils/PositionTest.cpp index f24b1747..71149cc6 100644 --- a/tests/unit/utils/PositionTest.cpp +++ b/tests/unit/utils/PositionTest.cpp @@ -26,7 +26,7 @@ #include TEST(Position, constructor) { - filc::utils::Position pos("filename", 20, 10); + filc::utils::SimplePosition pos("filename", 20, 10); ASSERT_STREQ("filename", pos.getFilename().c_str()); ASSERT_EQ(20, pos.getLine()); @@ -34,7 +34,7 @@ TEST(Position, constructor) { } TEST(Position, getContent) { - filc::utils::Position pos("../../tests/unit/Fixtures/position.txt", 12, 10); + filc::utils::SimplePosition pos("../../tests/unit/Fixtures/position.txt", 12, 10); ASSERT_STREQ("12;abcd", pos.getContent().c_str()); } \ No newline at end of file From e787219d9515bb9a4779f070d4e51dce96bfa53e Mon Sep 17 00:00:00 2001 From: Kevin Traini Date: Thu, 30 Nov 2023 22:15:57 +0100 Subject: [PATCH 3/6] feat: Add DoublePosition Part of #67 DoublePosition is a position with a start and an end. It's needed when you need to show position of a long expression --- src/lib/ast/AbstractExpression.cpp | 3 +- src/lib/grammar/FilParser.g4 | 50 +++---- src/lib/utils/Position.cpp | 130 ++++++++++++++++++- src/lib/utils/Position.h | 29 ++++- tests/unit/Fixtures/{ => utils}/position.txt | 0 tests/unit/utils/PositionTest.cpp | 60 ++++++++- tests/unit/utils/ToolsTest.cpp | 2 +- 7 files changed, 240 insertions(+), 34 deletions(-) rename tests/unit/Fixtures/{ => utils}/position.txt (100%) diff --git a/src/lib/ast/AbstractExpression.cpp b/src/lib/ast/AbstractExpression.cpp index 1f8393f1..52824e05 100644 --- a/src/lib/ast/AbstractExpression.cpp +++ b/src/lib/ast/AbstractExpression.cpp @@ -67,9 +67,8 @@ namespace filc::ast { auto AbstractExpression::addNameToEnvironment( filc::environment::Environment *environment) const -> void { - auto *position = dynamic_cast(getPosition()); auto name = filc::utils::joinString(filc::utils::splitString(environment->getModule(), '.'), "_") - + "_" + std::to_string(position->getLine()); + + "_" + std::to_string(getPosition()->getLine()); environment->addName(name, getExpressionType()); } diff --git a/src/lib/grammar/FilParser.g4 b/src/lib/grammar/FilParser.g4 index 4e98050f..0da37c90 100644 --- a/src/lib/grammar/FilParser.g4 +++ b/src/lib/grammar/FilParser.g4 @@ -95,81 +95,81 @@ expression returns[filc::ast::AbstractExpression *tree] | el1=expression STAR er1=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::STAR); $tree = new filc::ast::BinaryCalcul($el1.tree, op, $er1.tree); - $tree->setPosition(new filc::utils::SimplePosition($el1.start)); + $tree->setPosition(new filc::utils::DoublePosition($el1.start, $er1.stop)); } | el2=expression DIV er2=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::DIV); $tree = new filc::ast::BinaryCalcul($el2.tree, op, $er2.tree); - $tree->setPosition(new filc::utils::SimplePosition($el2.start)); + $tree->setPosition(new filc::utils::DoublePosition($el2.start, $er2.stop)); } | el3=expression MOD er3=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::MOD); $tree = new filc::ast::BinaryCalcul($el3.tree, op, $er3.tree); - $tree->setPosition(new filc::utils::SimplePosition($el3.start)); + $tree->setPosition(new filc::utils::DoublePosition($el3.start, $er3.stop)); } | el4=expression PLUS er4=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::PLUS); $tree = new filc::ast::BinaryCalcul($el4.tree, op, $er4.tree); - $tree->setPosition(new filc::utils::SimplePosition($el4.start)); + $tree->setPosition(new filc::utils::DoublePosition($el4.start, $er4.stop)); } | el5=expression MINUS er5=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::MINUS); $tree = new filc::ast::BinaryCalcul($el5.tree, op, $er5.tree); - $tree->setPosition(new filc::utils::SimplePosition($el5.start)); + $tree->setPosition(new filc::utils::DoublePosition($el5.start, $er5.stop)); } | el6=expression FLEFT er6=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::FLEFT); $tree = new filc::ast::BinaryCalcul($el6.tree, op, $er6.tree); - $tree->setPosition(new filc::utils::SimplePosition($el6.start)); + $tree->setPosition(new filc::utils::DoublePosition($el6.start, $er6.stop)); } | el7=expression FRIGHT er7=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::FRIGHT); $tree = new filc::ast::BinaryCalcul($el7.tree, op, $er7.tree); - $tree->setPosition(new filc::utils::SimplePosition($el7.start)); + $tree->setPosition(new filc::utils::DoublePosition($el7.start, $er7.stop)); } | el8=expression LESS er8=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::LESS); $tree = new filc::ast::BinaryCalcul($el8.tree, op, $er8.tree); - $tree->setPosition(new filc::utils::SimplePosition($el8.start)); + $tree->setPosition(new filc::utils::DoublePosition($el8.start, $er8.stop)); } | el9=expression GREATER er9=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::GREATER); $tree = new filc::ast::BinaryCalcul($el9.tree, op, $er9.tree); - $tree->setPosition(new filc::utils::SimplePosition($el9.start)); + $tree->setPosition(new filc::utils::DoublePosition($el9.start, $er9.stop)); } | el10=expression EQEQ er10=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::EQEQ); $tree = new filc::ast::BinaryCalcul($el10.tree, op, $er10.tree); - $tree->setPosition(new filc::utils::SimplePosition($el10.start)); + $tree->setPosition(new filc::utils::DoublePosition($el10.start, $er10.stop)); } | el11=expression LEQ er11=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::LEQ); $tree = new filc::ast::BinaryCalcul($el11.tree, op, $er11.tree); - $tree->setPosition(new filc::utils::SimplePosition($el11.start)); + $tree->setPosition(new filc::utils::DoublePosition($el11.start, $er11.stop)); } | el12=expression GEQ er12=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::GEQ); $tree = new filc::ast::BinaryCalcul($el12.tree, op, $er12.tree); - $tree->setPosition(new filc::utils::SimplePosition($el12.start)); + $tree->setPosition(new filc::utils::DoublePosition($el12.start, $er12.stop)); } | el13=expression NEQ er13=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::NEQ); $tree = new filc::ast::BinaryCalcul($el13.tree, op, $er13.tree); - $tree->setPosition(new filc::utils::SimplePosition($el13.start)); + $tree->setPosition(new filc::utils::DoublePosition($el13.start, $er13.stop)); } | el14=expression AND er14=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::AND); $tree = new filc::ast::BinaryCalcul($el14.tree, op, $er14.tree); - $tree->setPosition(new filc::utils::SimplePosition($el14.start)); + $tree->setPosition(new filc::utils::DoublePosition($el14.start, $er14.stop)); } | el15=expression OR er15=expression { op = new filc::ast::ClassicOperator(filc::ast::ClassicOperator::OR); $tree = new filc::ast::BinaryCalcul($el15.tree, op, $er15.tree); - $tree->setPosition(new filc::utils::SimplePosition($el15.start)); + $tree->setPosition(new filc::utils::DoublePosition($el15.start, $er15.stop)); } | el16=expression op16=assignation_operator er16=expression { $tree = new filc::ast::BinaryCalcul($el16.tree, $op16.tree, $er16.tree); - $tree->setPosition(new filc::utils::SimplePosition($el16.start)); + $tree->setPosition(new filc::utils::DoublePosition($el16.start, $er16.stop)); } // ==== Binary calcul ==== @@ -239,7 +239,7 @@ variable_declaration returns[filc::ast::VariableDeclaration *tree] } @after { $tree = new filc::ast::VariableDeclaration(is_constant, new filc::ast::Identifier($i), $t.tree); - $tree->setPosition(new filc::utils::SimplePosition($i)); + $tree->setPosition(new filc::utils::DoublePosition($i, $a.stop)); if (assign != nullptr) { $tree->setAssignation(assign); } @@ -286,11 +286,11 @@ type returns[std::shared_ptr tree] unary_calcul returns[filc::ast::UnaryCalcul *tree] : i=IDENTIFIER po=post_operator { $tree = new filc::ast::PostUnaryCalcul(new filc::ast::Identifier($i), $po.tree); - $tree->setPosition(new filc::utils::SimplePosition($i)); + $tree->setPosition(new filc::utils::DoublePosition($i, $po.stop)); } | pr=pre_operator i=IDENTIFIER { $tree = new filc::ast::PreUnaryCalcul(new filc::ast::Identifier($i), $pr.tree); - $tree->setPosition(new filc::utils::SimplePosition($pr.start)); + $tree->setPosition(new filc::utils::DoublePosition($pr.start, $i)); }; post_operator returns[filc::ast::Operator *tree] @@ -373,7 +373,7 @@ classic_binary_operator returns[filc::ast::Operator *tree] function returns[filc::ast::Function *tree] : fd=function_declaration fb=function_body { $tree = new filc::ast::Function($fd.identifier, $fd.parameters, $fd.return_type, $fb.tree); - $tree->setPosition(new filc::utils::SimplePosition($fd.start)); + $tree->setPosition(new filc::utils::DoublePosition($fd.start, $fb.stop)); }; function_declaration returns[filc::ast::Identifier *identifier, std::vector parameters, std::shared_ptr return_type] @@ -519,7 +519,7 @@ if_c returns[filc::ast::If *tree] $tree->setElse($ic2.tree); } | ib2=if_body { auto *else_body = new filc::ast::If(new filc::ast::Identifier("true"), $ib2.tree); - $tree->setPosition(new filc::utils::SimplePosition($ib2.start)); + else_body->setPosition(new filc::utils::SimplePosition($ib2.start)); $tree->setElse(else_body); }))?; @@ -538,7 +538,7 @@ if_body returns[filc::ast::BlockBody *tree] switch_c returns[filc::ast::Switch *tree] : s=SWITCH ic=if_condition sb=switch_body { $tree = new filc::ast::Switch($ic.tree, $sb.tree); - $tree->setPosition(new filc::utils::SimplePosition($s)); + $tree->setPosition(new filc::utils::DoublePosition($s, $sb.stop)); }; switch_body returns[std::vector tree] @@ -585,7 +585,7 @@ loop returns[filc::ast::AbstractExpression *tree] for_i returns[filc::ast::ForI *tree] : f=FOR fic=for_i_condition ib=if_body { $tree = new filc::ast::ForI($fic.declaration, $fic.limit, $fic.iteration, $ib.tree); - $tree->setPosition(new filc::utils::SimplePosition($f)); + $tree->setPosition(new filc::utils::DoublePosition($f, $ib.stop)); }; for_i_condition returns[filc::ast::VariableDeclaration *declaration, filc::ast::AbstractExpression *limit, filc::ast::AbstractExpression *iteration] @@ -605,7 +605,7 @@ for_i_condition returns[filc::ast::VariableDeclaration *declaration, filc::ast:: for_iter returns[filc::ast::ForIter *tree] : f=FOR fic=for_iter_condition ib=if_body { $tree = new filc::ast::ForIter($fic.constant, $fic.identifier, $fic.array, $ib.tree); - $tree->setPosition(new filc::utils::SimplePosition($f)); + $tree->setPosition(new filc::utils::DoublePosition($f, $ib.stop)); }; for_iter_condition returns[bool constant, filc::ast::Identifier *identifier, filc::ast::AbstractExpression *array] @@ -624,7 +624,7 @@ for_iter_condition returns[bool constant, filc::ast::Identifier *identifier, fil while_l returns[filc::ast::While *tree] : w=WHILE ic=if_condition ib=if_body { $tree = new filc::ast::While($ic.tree, $ib.tree); - $tree->setPosition(new filc::utils::SimplePosition($w)); + $tree->setPosition(new filc::utils::DoublePosition($w, $ib.stop)); }; function_call_params returns[std::vector tree] diff --git a/src/lib/utils/Position.cpp b/src/lib/utils/Position.cpp index 0fd37a00..cb86a3d1 100644 --- a/src/lib/utils/Position.cpp +++ b/src/lib/utils/Position.cpp @@ -74,9 +74,137 @@ namespace filc::utils { res += nth + "|" + getContent() + "\n"; res += std::string(nth.length(), ' ') + "|"; - std::string spaces = _column > 0 ? std::string(_column - 1, ' ') : ""; + std::string spaces = _column > 0 ? std::string(_column, ' ') : ""; res += spaces + color + "^" + "\033[0m" + "\n"; return res; } + + DoublePosition::DoublePosition(std::string filename, unsigned int start_line, unsigned int start_column, + unsigned int end_line, unsigned int end_column) + : _filename(std::move(filename)), _start_position(std::make_pair(start_line, start_column)), + _end_position(std::make_pair(end_line, end_column)) {} + + DoublePosition::DoublePosition(const antlr4::Token *start_token, const antlr4::Token *end_token) { + _filename = start_token->getTokenSource()->getSourceName(); + if (end_token->getTokenSource()->getSourceName() != _filename) { + filc::message::MessageCollector::getCollector()->addError( + new filc::message::BasicError(filc::message::FATAL_ERROR, + "Tried to create a double position from two different sources: " + + _filename + " and " + end_token->getTokenSource()->getSourceName()) + ); + } + + _start_position = std::make_pair( + start_token->getLine(), + start_token->getCharPositionInLine() + ); + _end_position = std::make_pair( + end_token->getLine(), + end_token->getCharPositionInLine() + ); + } + + auto DoublePosition::getFilename() const -> const std::string & { + return _filename; + } + + auto DoublePosition::getStartPosition() const -> std::pair { + return _start_position; + } + + auto DoublePosition::getEndPosition() const -> std::pair { + return _end_position; + } + + auto DoublePosition::getLine() const -> unsigned int { + return getStartPosition().first; + } + + auto DoublePosition::getContent() const -> std::vector { + std::ifstream file(_filename); + if (!file.is_open() || !file.good()) { + filc::message::MessageCollector::getCollector()->addError( + new filc::message::BasicError(filc::message::ERROR, + "File " + _filename + " cannot be open or read") + ); + + return {}; + } + std::vector content; + + auto start_line = _start_position.first; + unsigned int idx = 0; + std::string line; + for (; idx < start_line; idx++) { + std::getline(file, line); + } + content.push_back(line); + + auto end_line = _end_position.first; + if (end_line > start_line) { + for (; idx < end_line; idx++) { + std::getline(file, line); + content.push_back(line); + } + } + + file.close(); + + return content; + } + + auto DoublePosition::dump(const std::string &color) const -> std::string { + auto start_line = _start_position.first; + auto start_column = _start_position.second; + auto end_line = _end_position.first; + auto end_column = _end_position.second; + auto content = getContent(); + + if (start_line == end_line && content.size() == 1) { // Single line + auto nth = " " + std::to_string(start_line) + " "; + auto res = std::string(nth.length() + 1, ' ') + _filename + "\n"; + + auto line = content[0]; + + res += nth + "|" + line + "\n"; + res += std::string(nth.length(), ' ') + "|"; + auto spaces = start_column > 0 ? std::string(start_column, ' ') : ""; + res += spaces + color + std::string(end_column - start_column, '^') + "\033[0m" + "\n"; + + return res; + } + if (content.size() > 1) { // Multi line + std::vector nths; + auto nth_end = " " + std::to_string(end_line) + " "; + for (unsigned int i = start_line; i <= end_line; i++) { + auto line = " " + std::to_string(i) + " "; + + nths.push_back(line + std::string(nth_end.length() - line.length(), ' ')); + } + auto nth_space = std::string(nth_end.length(), ' ') + "|"; + + auto res = std::string(nth_end.length() + 1, ' ') + _filename + "\n"; + + auto spaces = start_column > 0 ? std::string(start_column, ' ') : ""; + res += nth_space + spaces + color + "v" + "\033[0m" + "\n"; + + for (unsigned int i = 0; i < nths.size(); i++) { + res += nths[i] + "|" + content[i] + "\n"; + } + + spaces = end_column > 0 ? std::string(end_column, ' ') : ""; + res += nth_space + spaces + color + "^" + "\033[0m" + "\n"; + + return res; + } + + filc::message::MessageCollector::getCollector()->addError( + new filc::message::BasicError(filc::message::WARNING, + "Cannot get position content") + ); + + return ""; + + } } \ No newline at end of file diff --git a/src/lib/utils/Position.h b/src/lib/utils/Position.h index 53b8ca4c..14739b4c 100644 --- a/src/lib/utils/Position.h +++ b/src/lib/utils/Position.h @@ -34,6 +34,8 @@ namespace filc::utils { virtual ~AbstractPosition() = default; + [[nodiscard]] virtual auto getLine() const -> unsigned int = 0; + protected: AbstractPosition() = default; }; @@ -46,7 +48,7 @@ namespace filc::utils { [[nodiscard]] auto getFilename() const -> const std::string &; - [[nodiscard]] auto getLine() const -> unsigned int; + [[nodiscard]] auto getLine() const -> unsigned int override; [[nodiscard]] auto getColumn() const -> unsigned int; @@ -59,6 +61,31 @@ namespace filc::utils { unsigned int _line; unsigned int _column; }; + + class DoublePosition final : public AbstractPosition { + public: + DoublePosition(std::string filename, unsigned int start_line, unsigned int start_column, + unsigned int end_line, unsigned int end_column); + + DoublePosition(const antlr4::Token *start_token, const antlr4::Token *end_token); + + [[nodiscard]] auto getFilename() const -> const std::string &; + + [[nodiscard]] auto getStartPosition() const -> std::pair; + + [[nodiscard]] auto getEndPosition() const -> std::pair; + + [[nodiscard]] auto getLine() const -> unsigned int override; + + [[nodiscard]] auto getContent() const -> std::vector; + + [[nodiscard]] auto dump(const std::string &color) const -> std::string override; + + private: + std::string _filename; + std::pair _start_position; + std::pair _end_position; + }; } #endif //FILC_POSITION_H diff --git a/tests/unit/Fixtures/position.txt b/tests/unit/Fixtures/utils/position.txt similarity index 100% rename from tests/unit/Fixtures/position.txt rename to tests/unit/Fixtures/utils/position.txt diff --git a/tests/unit/utils/PositionTest.cpp b/tests/unit/utils/PositionTest.cpp index 71149cc6..68ddb0db 100644 --- a/tests/unit/utils/PositionTest.cpp +++ b/tests/unit/utils/PositionTest.cpp @@ -25,7 +25,9 @@ #include "test_tools.h" #include -TEST(Position, constructor) { +#define POSITION_FILE FIXTURES_PATH "/utils/position.txt" + +TEST(SimplePosition, constructor) { filc::utils::SimplePosition pos("filename", 20, 10); ASSERT_STREQ("filename", pos.getFilename().c_str()); @@ -33,8 +35,58 @@ TEST(Position, constructor) { ASSERT_EQ(10, pos.getColumn()); } -TEST(Position, getContent) { - filc::utils::SimplePosition pos("../../tests/unit/Fixtures/position.txt", 12, 10); +TEST(SimplePosition, getContent) { + filc::utils::SimplePosition pos(POSITION_FILE, 12, 10); ASSERT_STREQ("12;abcd", pos.getContent().c_str()); -} \ No newline at end of file +} + +TEST(SimplePosition, dump) { + filc::utils::SimplePosition pos(POSITION_FILE, 12, 10); + + const auto *expected = + " ../../tests/unit/Fixtures/utils/position.txt\n" + " 12 |12;abcd\n" + " | \033[31m^\033[0m\n"; + + ASSERT_STREQ(expected, pos.dump("\033[31m").c_str()); +} + +TEST(DoublePosition, constructor) { + filc::utils::DoublePosition pos("filename", 20, 10, 30, 40); + + ASSERT_STREQ("filename", pos.getFilename().c_str()); + ASSERT_EQ(20, pos.getStartPosition().first); + ASSERT_EQ(10, pos.getStartPosition().second); + ASSERT_EQ(30, pos.getEndPosition().first); + ASSERT_EQ(40, pos.getEndPosition().second); + ASSERT_EQ(20, pos.getLine()); +} + +TEST(DoublePosition, getContent) { + filc::utils::DoublePosition pos1(POSITION_FILE, 10, 0, 10, 10); + ASSERT_THAT(pos1.getContent(), ElementsAre("10;abcd")); + + filc::utils::DoublePosition pos2(POSITION_FILE, 5, 0, 8, 0); + ASSERT_THAT(pos2.getContent(), ElementsAre("05;abcd", "06;abcd", "07;abcd", "08;abcd")); +} + +TEST(DoublePosition, dump) { + filc::utils::DoublePosition pos1(POSITION_FILE, 15, 0, 15, 7); + const auto *expected1 = + " ../../tests/unit/Fixtures/utils/position.txt\n" + " 15 |15;abcd\n" + " |\033[31m^^^^^^^\033[0m\n"; + ASSERT_STREQ(expected1, pos1.dump("\033[31m").c_str()); + + filc::utils::DoublePosition pos2(POSITION_FILE, 3, 1, 6, 5); + const auto *expected2 = + " ../../tests/unit/Fixtures/utils/position.txt\n" + " | \033[31mv\033[0m\n" + " 3 |03;abcd\n" + " 4 |04;abcd\n" + " 5 |05;abcd\n" + " 6 |06;abcd\n" + " | \033[31m^\033[0m\n"; + ASSERT_STREQ(expected2, pos2.dump("\033[31m").c_str()); +} diff --git a/tests/unit/utils/ToolsTest.cpp b/tests/unit/utils/ToolsTest.cpp index c2df5fad..2be4965a 100644 --- a/tests/unit/utils/ToolsTest.cpp +++ b/tests/unit/utils/ToolsTest.cpp @@ -60,7 +60,7 @@ TEST(tools, strStartsWith) { } TEST(tools, fileExists) { - auto result = filc::utils::fileExists(FIXTURES_PATH "/position.txt"); + auto result = filc::utils::fileExists(FIXTURES_PATH "/utils/position.txt"); ASSERT_TRUE(result); result = filc::utils::fileExists("non-existing-file.a_file_extension"); From ee62db40642223ac5b80340cd68a769edeba23b6 Mon Sep 17 00:00:00 2001 From: Kevin Traini Date: Thu, 30 Nov 2023 22:28:54 +0100 Subject: [PATCH 4/6] fix: Issue from Codacy report --- src/lib/utils/Position.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/utils/Position.cpp b/src/lib/utils/Position.cpp index cb86a3d1..fc06e740 100644 --- a/src/lib/utils/Position.cpp +++ b/src/lib/utils/Position.cpp @@ -85,8 +85,8 @@ namespace filc::utils { : _filename(std::move(filename)), _start_position(std::make_pair(start_line, start_column)), _end_position(std::make_pair(end_line, end_column)) {} - DoublePosition::DoublePosition(const antlr4::Token *start_token, const antlr4::Token *end_token) { - _filename = start_token->getTokenSource()->getSourceName(); + DoublePosition::DoublePosition(const antlr4::Token *start_token, const antlr4::Token *end_token) + : _filename(start_token->getTokenSource()->getSourceName()) { if (end_token->getTokenSource()->getSourceName() != _filename) { filc::message::MessageCollector::getCollector()->addError( new filc::message::BasicError(filc::message::FATAL_ERROR, From 2a86bc3c2318dd140799f184dcd51e8a794f8c62 Mon Sep 17 00:00:00 2001 From: Kevin Traini Date: Sat, 2 Dec 2023 09:40:48 +0100 Subject: [PATCH 5/6] feat: Reformat dump of position Part of #67 New format is: --> :: 1 | | ^ With some color: - '-->', '1 |' and '|' are colored in bold blue --- src/lib/utils/Position.cpp | 34 ++++++++++++++++++------------- tests/unit/utils/PositionTest.cpp | 28 ++++++++++++------------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/lib/utils/Position.cpp b/src/lib/utils/Position.cpp index fc06e740..7b403fcc 100644 --- a/src/lib/utils/Position.cpp +++ b/src/lib/utils/Position.cpp @@ -27,6 +27,9 @@ #include #include +#define DETAILS_COLOR "\033[1;34m" +#define RESET_COLOR "\033[0m" + namespace filc::utils { SimplePosition::SimplePosition(std::string filename, unsigned int line, unsigned int column) : _filename(std::move(filename)), _line(line), _column(column) {} @@ -69,12 +72,13 @@ namespace filc::utils { } auto SimplePosition::dump(const std::string &color) const -> std::string { - std::string nth = " " + std::to_string(_line) + " "; - std::string res = std::string(nth.length() + 1, ' ') + _filename + "\n"; + auto nth = " " + std::to_string(_line) + " "; + auto res = std::string(nth.length() - 1, ' ') + DETAILS_COLOR + "--> " + RESET_COLOR + + _filename + ":" + std::to_string(_line) + ":" + std::to_string(_column) + "\n"; - res += nth + "|" + getContent() + "\n"; - res += std::string(nth.length(), ' ') + "|"; - std::string spaces = _column > 0 ? std::string(_column, ' ') : ""; + res += DETAILS_COLOR + nth + "| " + RESET_COLOR + getContent() + "\n"; + res += DETAILS_COLOR + std::string(nth.length(), ' ') + "| " + RESET_COLOR; + auto spaces = _column > 0 ? std::string(_column, ' ') : ""; res += spaces + color + "^" + "\033[0m" + "\n"; return res; @@ -163,14 +167,15 @@ namespace filc::utils { if (start_line == end_line && content.size() == 1) { // Single line auto nth = " " + std::to_string(start_line) + " "; - auto res = std::string(nth.length() + 1, ' ') + _filename + "\n"; + auto res = std::string(nth.length() - 1, ' ') + DETAILS_COLOR + "--> " + RESET_COLOR + + _filename + ":" + std::to_string(start_line) + ":" + std::to_string(start_column) + "\n"; auto line = content[0]; - res += nth + "|" + line + "\n"; - res += std::string(nth.length(), ' ') + "|"; + res += DETAILS_COLOR + nth + "| " + RESET_COLOR + line + "\n"; + res += DETAILS_COLOR + std::string(nth.length(), ' ') + "| " + RESET_COLOR; auto spaces = start_column > 0 ? std::string(start_column, ' ') : ""; - res += spaces + color + std::string(end_column - start_column, '^') + "\033[0m" + "\n"; + res += spaces + color + std::string(end_column - start_column + 1, '^') + "\033[0m" + "\n"; return res; } @@ -182,19 +187,20 @@ namespace filc::utils { nths.push_back(line + std::string(nth_end.length() - line.length(), ' ')); } - auto nth_space = std::string(nth_end.length(), ' ') + "|"; + auto nth_space = std::string(nth_end.length(), ' ') + "| "; - auto res = std::string(nth_end.length() + 1, ' ') + _filename + "\n"; + auto res = std::string(nth_end.length() - 1, ' ') + DETAILS_COLOR + "--> " + RESET_COLOR + + _filename + ":" + std::to_string(start_line) + ":" + std::to_string(start_column) + "\n"; auto spaces = start_column > 0 ? std::string(start_column, ' ') : ""; - res += nth_space + spaces + color + "v" + "\033[0m" + "\n"; + res += DETAILS_COLOR + nth_space + RESET_COLOR + spaces + color + "v" + "\033[0m" + "\n"; for (unsigned int i = 0; i < nths.size(); i++) { - res += nths[i] + "|" + content[i] + "\n"; + res += DETAILS_COLOR + nths[i] + "| " + RESET_COLOR + content[i] + "\n"; } spaces = end_column > 0 ? std::string(end_column, ' ') : ""; - res += nth_space + spaces + color + "^" + "\033[0m" + "\n"; + res += DETAILS_COLOR + nth_space + RESET_COLOR + spaces + color + "^" + "\033[0m" + "\n"; return res; } diff --git a/tests/unit/utils/PositionTest.cpp b/tests/unit/utils/PositionTest.cpp index 68ddb0db..17ce242f 100644 --- a/tests/unit/utils/PositionTest.cpp +++ b/tests/unit/utils/PositionTest.cpp @@ -45,9 +45,9 @@ TEST(SimplePosition, dump) { filc::utils::SimplePosition pos(POSITION_FILE, 12, 10); const auto *expected = - " ../../tests/unit/Fixtures/utils/position.txt\n" - " 12 |12;abcd\n" - " | \033[31m^\033[0m\n"; + " \033[1;34m--> \033[0m../../tests/unit/Fixtures/utils/position.txt:12:10\n" + "\033[1;34m 12 | \033[0m12;abcd\n" + "\033[1;34m | \033[0m \033[31m^\033[0m\n"; ASSERT_STREQ(expected, pos.dump("\033[31m").c_str()); } @@ -72,21 +72,21 @@ TEST(DoublePosition, getContent) { } TEST(DoublePosition, dump) { - filc::utils::DoublePosition pos1(POSITION_FILE, 15, 0, 15, 7); + filc::utils::DoublePosition pos1(POSITION_FILE, 15, 0, 15, 6); const auto *expected1 = - " ../../tests/unit/Fixtures/utils/position.txt\n" - " 15 |15;abcd\n" - " |\033[31m^^^^^^^\033[0m\n"; + " \033[1;34m--> \033[0m../../tests/unit/Fixtures/utils/position.txt:15:0\n" + "\033[1;34m 15 | \033[0m15;abcd\n" + "\033[1;34m | \033[0m\033[31m^^^^^^^\033[0m\n"; ASSERT_STREQ(expected1, pos1.dump("\033[31m").c_str()); filc::utils::DoublePosition pos2(POSITION_FILE, 3, 1, 6, 5); const auto *expected2 = - " ../../tests/unit/Fixtures/utils/position.txt\n" - " | \033[31mv\033[0m\n" - " 3 |03;abcd\n" - " 4 |04;abcd\n" - " 5 |05;abcd\n" - " 6 |06;abcd\n" - " | \033[31m^\033[0m\n"; + " \033[1;34m--> \033[0m../../tests/unit/Fixtures/utils/position.txt:3:1\n" + "\033[1;34m | \033[0m \033[31mv\033[0m\n" + "\033[1;34m 3 | \033[0m03;abcd\n" + "\033[1;34m 4 | \033[0m04;abcd\n" + "\033[1;34m 5 | \033[0m05;abcd\n" + "\033[1;34m 6 | \033[0m06;abcd\n" + "\033[1;34m | \033[0m \033[31m^\033[0m\n"; ASSERT_STREQ(expected2, pos2.dump("\033[31m").c_str()); } From 90018eb81e57abf07b83ea00529116e578083cbe Mon Sep 17 00:00:00 2001 From: Kevin Traini Date: Sat, 2 Dec 2023 10:30:37 +0100 Subject: [PATCH 6/6] feat: Reformat print of messages Part of #70 --- README.md | 8 ++-- src/lib/message/DevWarning.cpp | 6 ++- src/lib/message/DevWarning.h | 2 + src/lib/message/Error.cpp | 6 ++- src/lib/message/Warning.cpp | 3 +- tests/CMakeLists.txt | 3 ++ tests/unit/message/DevWarningTest.cpp | 45 ++++++++++++++++++++++ tests/unit/message/ErrorTest.cpp | 54 +++++++++++++++++++++++++++ tests/unit/message/MessageTest.cpp | 22 +++-------- tests/unit/message/WarningTest.cpp | 36 ++++++++++++++++++ tests/unit/test_tools.h | 8 ++++ 11 files changed, 169 insertions(+), 24 deletions(-) create mode 100644 tests/unit/message/DevWarningTest.cpp create mode 100644 tests/unit/message/ErrorTest.cpp create mode 100644 tests/unit/message/WarningTest.cpp diff --git a/README.md b/README.md index 1b0c1260..3e5c9949 100644 --- a/README.md +++ b/README.md @@ -86,10 +86,10 @@ your code. Dev warning are show like this : ``` -DEV WARNING - - | - | ^ +DEV WARNING[]: + --> + | + | ^ ``` | Dev code | Meaning | File | diff --git a/src/lib/message/DevWarning.cpp b/src/lib/message/DevWarning.cpp index 83700c79..c35dbdbb 100644 --- a/src/lib/message/DevWarning.cpp +++ b/src/lib/message/DevWarning.cpp @@ -28,12 +28,16 @@ namespace filc::message { DevWarning::DevWarning(unsigned int code, filc::utils::AbstractPosition *position, std::string content) : Message(ERROR, std::move(content)), _code(code), _position(position) {} + auto DevWarning::getCode() const -> unsigned int { + return _code; + } + auto DevWarning::print(std::ostream &out) -> std::ostream & { if (_printed) { return out; } - out << "\033[1;36mDEV WARNING:\033[0m " << "\033[1;46m " << _code << " \033[0m " << _content << std::endl; + out << "\033[1;36mDEV WARNING[" << _code << "]\033[0m\033[1m: " << _content << std::endl; out << _position->dump("\033[1;36m"); _printed = true; diff --git a/src/lib/message/DevWarning.h b/src/lib/message/DevWarning.h index e50c3cec..fa38253e 100644 --- a/src/lib/message/DevWarning.h +++ b/src/lib/message/DevWarning.h @@ -32,6 +32,8 @@ namespace filc::message { public: DevWarning(unsigned int code, filc::utils::AbstractPosition *position, std::string content); + [[nodiscard]] auto getCode() const -> unsigned int; + auto print(std::ostream &out) -> std::ostream & override; private: diff --git a/src/lib/message/Error.cpp b/src/lib/message/Error.cpp index 7fce5f4c..55212d69 100644 --- a/src/lib/message/Error.cpp +++ b/src/lib/message/Error.cpp @@ -30,7 +30,7 @@ namespace filc::message { return out; } - out << "\033[1;31mERROR:\033[0m " << _content; + out << "\033[1;31mERROR\033[0m\033[1m: " << _content << "\033[0m"; _printed = true; return out; @@ -44,9 +44,11 @@ namespace filc::message { return out; } - out << "\033[1;31mERROR:\033[0m " << _content << '\n'; + out << "\033[1;31mERROR\033[0m\033[1m: " << _content << "\033[0m\n"; out << _position->dump("\033[1;31m"); + _printed = true; + return out; } } \ No newline at end of file diff --git a/src/lib/message/Warning.cpp b/src/lib/message/Warning.cpp index 611055a7..46fe57a0 100644 --- a/src/lib/message/Warning.cpp +++ b/src/lib/message/Warning.cpp @@ -29,7 +29,8 @@ namespace filc::message { return out; } - out << "\033[1;33mWARNING:\033[0m " << _content; + out << "\033[1;33mWARNING\033[0m\033[1m: " << _content << "\033[0m"; + _printed = true; return out; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 750c0160..65e3031d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -16,6 +16,9 @@ add_executable(tests # === Message === unit/message/MessageTest.cpp unit/message/MessageCollectorTest.cpp + unit/message/WarningTest.cpp + unit/message/ErrorTest.cpp + unit/message/DevWarningTest.cpp # === Grammar === unit/grammar/ParserTest.cpp # === AST === diff --git a/tests/unit/message/DevWarningTest.cpp b/tests/unit/message/DevWarningTest.cpp new file mode 100644 index 00000000..8316ab19 --- /dev/null +++ b/tests/unit/message/DevWarningTest.cpp @@ -0,0 +1,45 @@ +/** + * MIT License + * + * Copyright (c) 2023-Present Kevin Traini + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DevWarning.h" +#include "test_tools.h" + +TEST(DevWarning, constructor) { + auto dev_warning = filc::message::DevWarning(5, new filc::utils::SimplePosition( + FIXTURES_PATH "/utils/position.txt", 12, 3 + ), "My dev warning"); + ASSERT_EQ(filc::message::ERROR, dev_warning.getLevel()); + ASSERT_EQ(5, dev_warning.getCode()); +} + +TEST(DevWarning, print) { + auto dev_warning = filc::message::DevWarning(5, new filc::utils::SimplePosition( + FIXTURES_PATH "/utils/position.txt", 12, 3 + ), "My dev warning"); + auto expected = + "\033[1;36mDEV WARNING[5]\033[0m\033[1m: My dev warning\n" + " \033[1;34m--> \033[0m../../tests/unit/Fixtures/utils/position.txt:12:3\n" + "\033[1;34m 12 | \033[0m12;abcd\n" + "\033[1;34m | \033[0m \033[1;36m^\033[0m\n"; + ASSERT_MESSAGE_CONTENT(expected, dev_warning); +} \ No newline at end of file diff --git a/tests/unit/message/ErrorTest.cpp b/tests/unit/message/ErrorTest.cpp new file mode 100644 index 00000000..e7c3e8f0 --- /dev/null +++ b/tests/unit/message/ErrorTest.cpp @@ -0,0 +1,54 @@ +/** + * MIT License + * + * Copyright (c) 2023-Present Kevin Traini + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Error.h" +#include "test_tools.h" + +TEST(BasicError, constructor) { + auto basic_error = filc::message::BasicError(filc::message::ERROR, "My error"); + ASSERT_EQ(filc::message::ERROR, basic_error.getLevel()); +} + +TEST(BasicError, print) { + auto basic_error = filc::message::BasicError(filc::message::ERROR, "My error"); + ASSERT_MESSAGE_CONTENT("\033[1;31mERROR\033[0m\033[1m: My error\033[0m", basic_error); + ASSERT_MESSAGE_CONTENT("", basic_error); +} + +TEST(Error, constructor) { + auto error = filc::message::Error(filc::message::ERROR, "My error", + new filc::utils::SimplePosition(FIXTURES_PATH "/utils/position.txt", 5, 2)); + ASSERT_EQ(filc::message::ERROR, error.getLevel()); +} + +TEST(Error, print) { + auto error = filc::message::Error(filc::message::ERROR, "My error", + new filc::utils::SimplePosition(FIXTURES_PATH "/utils/position.txt", 5, 2)); + auto expected = + "\033[1;31mERROR\033[0m\033[1m: My error\033[0m\n" + " \033[1;34m--> \033[0m../../tests/unit/Fixtures/utils/position.txt:5:2\n" + "\033[1;34m 5 | \033[0m05;abcd\n" + "\033[1;34m | \033[0m \033[1;31m^\033[0m\n"; + ASSERT_MESSAGE_CONTENT(expected, error); + ASSERT_MESSAGE_CONTENT("", error); +} diff --git a/tests/unit/message/MessageTest.cpp b/tests/unit/message/MessageTest.cpp index 0ff27350..105ef337 100644 --- a/tests/unit/message/MessageTest.cpp +++ b/tests/unit/message/MessageTest.cpp @@ -23,32 +23,22 @@ */ #include "Message.h" #include "test_tools.h" -#include - -auto getMessageContent(filc::message::Message &message) -> std::string { - std::stringstream stream; - stream << message; - - std::string result(std::istreambuf_iterator(stream), {}); - - return result; -} TEST(Message, constructor) { - std::string expected = "My message"; + auto expected = "My message"; auto message = filc::message::Message(filc::message::WARNING, expected); ASSERT_EQ(filc::message::WARNING, message.getLevel()); - ASSERT_STREQ(expected.c_str(), getMessageContent(message).c_str()); + ASSERT_MESSAGE_CONTENT(expected, message); expected = "My message 2"; message = filc::message::Message((filc::message::LEVEL) 9, expected); ASSERT_EQ(5, message.getLevel()); - ASSERT_STREQ(expected.c_str(), getMessageContent(message).c_str()); + ASSERT_MESSAGE_CONTENT(expected, message); } TEST(Message, print) { - std::string expected = "My message"; + auto expected = "My message"; auto message = filc::message::Message(filc::message::WARNING, expected); - ASSERT_STREQ(expected.c_str(), getMessageContent(message).c_str()); - ASSERT_STREQ("", getMessageContent(message).c_str()); + ASSERT_MESSAGE_CONTENT(expected, message); + ASSERT_MESSAGE_CONTENT("", message); } \ No newline at end of file diff --git a/tests/unit/message/WarningTest.cpp b/tests/unit/message/WarningTest.cpp new file mode 100644 index 00000000..455c6d43 --- /dev/null +++ b/tests/unit/message/WarningTest.cpp @@ -0,0 +1,36 @@ +/** + * MIT License + * + * Copyright (c) 2023-Present Kevin Traini + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Warning.h" +#include "test_tools.h" + +TEST(BasicWarning, constructor) { + auto basic_warning = filc::message::BasicWarning(filc::message::WARNING, "My warning"); + ASSERT_EQ(filc::message::WARNING, basic_warning.getLevel()); +} + +TEST(BasicWarning, print) { + auto basic_warning = filc::message::BasicWarning(filc::message::WARNING, "My warning"); + ASSERT_MESSAGE_CONTENT("\033[1;33mWARNING\033[0m\033[1m: My warning\033[0m", basic_warning); + ASSERT_MESSAGE_CONTENT("", basic_warning); +} \ No newline at end of file diff --git a/tests/unit/test_tools.h b/tests/unit/test_tools.h index db490b64..a6b02b09 100644 --- a/tests/unit/test_tools.h +++ b/tests/unit/test_tools.h @@ -24,6 +24,7 @@ #include #include #include "MessageCollector.h" +#include using namespace ::testing; @@ -48,3 +49,10 @@ using namespace ::testing; ASSERT_IDENTIFIER(name, var_##variable->getIdentifier()); \ ASSERT_TYPE(type, var_##variable->getType()); \ ASSERT_LITERAL(value, literal, var_##variable->getAssignation()) + +#define ASSERT_MESSAGE_CONTENT(expected, message) { \ + std::stringstream stream; \ + message.print(stream); \ + std::string result(std::istreambuf_iterator(stream), {}); \ + ASSERT_STREQ(expected, result.c_str()); \ + }