Use ExpressionParser2 for EventsVariablesFinder

This commit is contained in:
Florian Rival
2018-12-09 15:58:15 +00:00
parent dfe4a75fbd
commit b14238c692
2 changed files with 98 additions and 96 deletions

View File

@@ -7,7 +7,9 @@
#include "EventsVariablesFinder.h" #include "EventsVariablesFinder.h"
#include "GDCore/Events/Event.h" #include "GDCore/Events/Event.h"
#include "GDCore/Events/Instruction.h" #include "GDCore/Events/Instruction.h"
#include "GDCore/Events/Parsers/ExpressionParser.h" #include "GDCore/Events/Parsers/ExpressionParser2.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodePrinter.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h" #include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h" #include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h" #include "GDCore/Extensions/Metadata/MetadataProvider.h"
@@ -20,86 +22,67 @@ using namespace std;
namespace gd { namespace gd {
// TODO: Replace and remove (ExpressionParameterSearcher) /**
class CallbacksForSearchingVariable : public gd::ParserCallbacks { * \brief Go through the nodes and change the given object name to a new one.
*
* \see gd::ExpressionParser2
*/
class GD_CORE_API ExpressionParameterSearcher
: public ExpressionParser2NodeWorker {
public: public:
CallbacksForSearchingVariable(std::set<gd::String>& results_, ExpressionParameterSearcher(std::set<gd::String>& results_,
const gd::String& parameterType_, const gd::String& parameterType_,
const gd::String& objectName_ = "") const gd::String& objectName_ = "")
: results(results_), : results(results_),
parameterType(parameterType_), parameterType(parameterType_),
objectName(objectName_){}; objectName(objectName_){};
virtual ~CallbacksForSearchingVariable(){}; virtual ~ExpressionParameterSearcher(){};
virtual void OnConstantToken(gd::String text) {} protected:
void OnVisitSubExpressionNode(SubExpressionNode& node) override {
virtual void OnStaticFunction(gd::String functionName, node.expression->Visit(*this);
const std::vector<gd::Expression>& parameters,
const gd::ExpressionMetadata& expressionInfo) {
SearchInParameters(parameters, expressionInfo);
} }
virtual void OnObjectFunction(gd::String functionName, void OnVisitOperatorNode(OperatorNode& node) override {
const std::vector<gd::Expression>& parameters, node.leftHandSide->Visit(*this);
const gd::ExpressionMetadata& expressionInfo) { node.rightHandSide->Visit(*this);
SearchInParameters(parameters, expressionInfo);
} }
virtual void OnObjectBehaviorFunction( void OnVisitNumberNode(NumberNode& node) override {}
gd::String functionName, void OnVisitTextNode(TextNode& node) override {}
const std::vector<gd::Expression>& parameters, void OnVisitVariableNode(VariableNode& node) override {
const gd::ExpressionMetadata& expressionInfo) { if (node.child) node.child->Visit(*this);
SearchInParameters(parameters, expressionInfo);
} }
void OnVisitVariableAccessorNode(VariableAccessorNode& node) override {
virtual bool OnSubMathExpression(const gd::Platform& platform, if (node.child) node.child->Visit(*this);
const gd::ObjectsContainer& project,
const gd::ObjectsContainer& layout,
gd::Expression& expression) {
CallbacksForSearchingVariable callbacks(results, parameterType, objectName);
gd::ExpressionParser parser(expression.GetPlainString());
parser.ParseMathExpression(platform, project, layout, callbacks);
return true;
} }
void OnVisitVariableBracketAccessorNode(
virtual bool OnSubTextExpression(const gd::Platform& platform, VariableBracketAccessorNode& node) override {
const gd::ObjectsContainer& project, node.expression->Visit(*this);
const gd::ObjectsContainer& layout, if (node.child) node.child->Visit(*this);
gd::Expression& expression) {
CallbacksForSearchingVariable callbacks(results, parameterType, objectName);
gd::ExpressionParser parser(expression.GetPlainString());
parser.ParseStringExpression(platform, project, layout, callbacks);
return true;
} }
void OnVisitIdentifierNode(IdentifierNode& node) override {}
void SearchInParameters(const std::vector<gd::Expression>& parameters, void OnVisitFunctionNode(FunctionNode& node) override {
const gd::ExpressionMetadata& expressionInfo) { bool considerFunction = objectName.empty() || node.objectName == objectName;
gd::String lastObjectParameter = ""; for (size_t i = 0; i < node.parameters.size() &&
for (std::size_t i = 0; i < parameters.size(); ++i) { i < node.expressionMetadata.parameters.size();
if (i >= expressionInfo.parameters.size()) break; ++i) {
auto& parameterMetadata = node.expressionMetadata.parameters[i];
// The parameter has the searched type... if (considerFunction && parameterMetadata.GetType() == parameterType) {
if (expressionInfo.parameters[i].type == parameterType) { // Store the value of the parameter
//...remember the value of the parameter. results.insert(
if (objectName.empty() || objectName == lastObjectParameter) gd::ExpressionParser2NodePrinter::PrintNode(*node.parameters[i]));
results.insert(parameters[i].GetPlainString()); } else {
node.parameters[i]->Visit(*this);
} }
// Remember the value of the last "object" parameter.
else if (gd::ParameterMetadata::IsObject(
expressionInfo.parameters[i].type))
lastObjectParameter = parameters[i].GetPlainString();
} }
} }
void OnVisitEmptyNode(EmptyNode& node) override {}
private: private:
std::set<gd::String>& results; ///< Reference to the std::set where arguments std::set<gd::String>& results; ///< Reference to the std::set where argument
///< values must be stored. ///< values must be stored.
gd::String parameterType; ///< The name of the parameter to be searched for gd::String parameterType; ///< The type of the parameters to be searched for.
gd::String gd::String objectName; ///< If not empty, parameters will be taken into
objectName; ///< If not empty, parameters will be taken into account only ///< account only if related to this object.
///< if the last object parameter is filled with this value.
}; };
std::set<gd::String> EventsVariablesFinder::FindAllGlobalVariables( std::set<gd::String> EventsVariablesFinder::FindAllGlobalVariables(
@@ -175,22 +158,26 @@ std::set<gd::String> EventsVariablesFinder::FindArgumentsInInstructions(
results.insert(instructions[aId].GetParameter(pNb).GetPlainString()); results.insert(instructions[aId].GetParameter(pNb).GetPlainString());
} }
// Search in expressions // Search in expressions
else if (ParameterMetadata::IsExpression("number", instrInfos.parameters[pNb].type)) { else if (ParameterMetadata::IsExpression(
CallbacksForSearchingVariable callbacks( "number", instrInfos.parameters[pNb].type)) {
results, parameterType, objectName); gd::ExpressionParser2 parser(platform, project, layout);
auto node = parser.ParseExpression(
"number", instructions[aId].GetParameter(pNb).GetPlainString());
gd::ExpressionParser parser( ExpressionParameterSearcher searcher(
instructions[aId].GetParameter(pNb).GetPlainString()); results, parameterType, objectName);
parser.ParseMathExpression(platform, project, layout, callbacks); node->Visit(searcher);
} }
// Search in gd::String expressions // Search in gd::String expressions
else if (ParameterMetadata::IsExpression("string", instrInfos.parameters[pNb].type)) { else if (ParameterMetadata::IsExpression(
CallbacksForSearchingVariable callbacks( "string", instrInfos.parameters[pNb].type)) {
results, parameterType, objectName); gd::ExpressionParser2 parser(platform, project, layout);
auto node = parser.ParseExpression(
"number", instructions[aId].GetParameter(pNb).GetPlainString());
gd::ExpressionParser parser( ExpressionParameterSearcher searcher(
instructions[aId].GetParameter(pNb).GetPlainString()); results, parameterType, objectName);
parser.ParseStringExpression(platform, project, layout, callbacks); node->Visit(searcher);
} }
// Remember the value of the last "object" parameter. // Remember the value of the last "object" parameter.
else if (gd::ParameterMetadata::IsObject( else if (gd::ParameterMetadata::IsObject(

View File

@@ -15,7 +15,7 @@ class Platform;
class Object; class Object;
class Project; class Project;
class Layout; class Layout;
} } // namespace gd
namespace gd { namespace gd {
@@ -23,7 +23,7 @@ namespace gd {
* \brief Perform a search over a project or a layout, searching for layout, * \brief Perform a search over a project or a layout, searching for layout,
* global or object variables. * global or object variables.
* *
* \todo Refactor this class using ArbitraryEventsWorker! * \todo Refactor this class using ArbitraryEventsWorker
* *
* \ingroup IDE * \ingroup IDE
*/ */
@@ -31,16 +31,21 @@ class EventsVariablesFinder {
public: public:
/** /**
* Construct a list containing the name of all global variables used in the * Construct a list containing the name of all global variables used in the
* project. \param project The project to be scanned \return A std::set * project.
* containing the names of all global variables used *
* \param project The project to be scanned
* \return A std::set containing the names of all global variables used
*/ */
static std::set<gd::String> FindAllGlobalVariables( static std::set<gd::String> FindAllGlobalVariables(
const gd::Platform& platform, const gd::Project& project); const gd::Platform& platform, const gd::Project& project);
/** /**
* Construct a list containing the name of all layout variables used in the * Construct a list containing the name of all layout variables used in the
* layout. \param project The project \param layout The layout to be scanned * layout.
* \return A std::set containing the names of all layout variables used *
* \param project The project
* \param layout The layout to be scanned
* \return A std::set containing the names of all layout variables used.
*/ */
static std::set<gd::String> FindAllLayoutVariables( static std::set<gd::String> FindAllLayoutVariables(
const gd::Platform& platform, const gd::Platform& platform,
@@ -49,9 +54,12 @@ class EventsVariablesFinder {
/** /**
* Construct a list containing the name of all object variables used in the * Construct a list containing the name of all object variables used in the
* layout. \param project The project \param layout The layout to use. \param * layout.
* object The object to be scanned \return A std::set containing the names of *
* all object variables used * \param project The project
* \param layout The layout to use.
* \param object The object to be scanned
* \return A std::set containing the names of all object variables used.
*/ */
static std::set<gd::String> FindAllObjectVariables( static std::set<gd::String> FindAllObjectVariables(
const gd::Platform& platform, const gd::Platform& platform,
@@ -62,12 +70,15 @@ class EventsVariablesFinder {
private: private:
/** /**
* Construct a list of the value of the arguments for parameters of type @ * Construct a list of the value of the arguments for parameters of type @
* parameterType \param project The project used \param project The layout * parameterType
* used \param instructions The instructions to be analyzed \param *
* instructionsAreConditions True if the instructions are conditions. \param * \param project The project used
* parameterType The parameters type to be analyzed \param objectName If not * \param project The layout used
* empty, parameters will be taken into account only if the last object * \param instructions The instructions to be analyzed
* parameter is filled with this value. * \param instructionsAreConditions True if the instructions are conditions.
* \param parameterType The parameters type to be analyzed
* \param objectName If not empty, parameters will be taken into account only
* if the last object parameter is filled with this value.
* *
* \return A std::set filled with the values used for all parameters of the * \return A std::set filled with the values used for all parameters of the
* specified type * specified type
@@ -83,10 +94,14 @@ class EventsVariablesFinder {
/** /**
* Construct a list of the value of the arguments for parameters of type @ * Construct a list of the value of the arguments for parameters of type @
* parameterType \param project The project used \param project The layout * parameterType
* used \param events The events to be analyzed \param parameterType The *
* parameters type to be analyzed \param objectName If not empty, parameters * \param project The project used
* will be taken into account only if the last object parameter is filled with * \param project The layout used
* \param events The events to be analyzed
* \param parameterType The parameters type to be analyzed
* \param objectName If not empty, parameters will be taken into account
* only if the last object parameter is filled with
* this value. * this value.
* *
* \return A std::set filled with the values used for all parameters of the * \return A std::set filled with the values used for all parameters of the