GDevelop Core
Core library for developing platforms and tools compatible with GDevelop.
ExpressionVariableOwnerFinder.h
1 /*
2  * GDevelop Core
3  * Copyright 2008-present Florian Rival ([email protected]). All rights
4  * reserved. This project is released under the MIT License.
5  */
6 #ifndef GDCORE_EXPRESSIONVARIABLEOWNERFINDER_H
7 #define GDCORE_EXPRESSIONVARIABLEOWNERFINDER_H
8 
9 #include <memory>
10 #include <vector>
11 #include "GDCore/Events/Parsers/ExpressionParser2Node.h"
12 #include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
13 #include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
14 #include "GDCore/Extensions/Metadata/MetadataProvider.h"
15 #include "GDCore/Extensions/Metadata/ObjectMetadata.h"
16 #include "GDCore/Extensions/Metadata/ParameterMetadata.h"
17 #include "GDCore/Project/Layout.h" // For GetTypeOfObject and GetTypeOfBehavior
18 #include "GDCore/Project/ObjectsContainersList.h"
20 
21 namespace gd {
22 class Expression;
23 class ObjectsContainer;
24 class Platform;
25 class ParameterMetadata;
26 class ExpressionMetadata;
27 } // namespace gd
28 
29 namespace gd {
30 
42  public:
43 
48  static const gd::String GetObjectName(const gd::Platform &platform,
49  const gd::ObjectsContainersList &objectsContainersList,
50  const gd::String& rootObjectName,
51  gd::ExpressionNode& node) {
53  platform, objectsContainersList, rootObjectName);
54  node.Visit(typeFinder);
55  return typeFinder.GetObjectName();
56  }
57 
58  virtual ~ExpressionVariableOwnerFinder(){};
59 
60  protected:
61  ExpressionVariableOwnerFinder(const gd::Platform &platform_,
62  const gd::ObjectsContainersList &objectsContainersList_,
63  const gd::String& rootObjectName_)
64  : platform(platform_),
65  objectsContainersList(objectsContainersList_),
66  rootObjectName(rootObjectName_),
67  objectName(""),
68  variableNode(nullptr) {};
69 
76  return objectName;
77  };
78 
79  void OnVisitSubExpressionNode(SubExpressionNode& node) override {}
80  void OnVisitOperatorNode(OperatorNode& node) override {}
81  void OnVisitUnaryOperatorNode(UnaryOperatorNode& node) override {}
82  void OnVisitNumberNode(NumberNode& node) override {}
83  void OnVisitTextNode(TextNode& node) override {}
84  void OnVisitVariableNode(VariableNode& node) override {
85  if (variableNode != nullptr) {
86  // This is not possible
87  return;
88  }
89  if (node.parent == nullptr) {
90  objectName = rootObjectName;
91  return;
92  }
93  variableNode = &node;
94  node.parent->Visit(*this);
95  }
96  void OnVisitVariableAccessorNode(VariableAccessorNode& node) override {}
97  void OnVisitIdentifierNode(IdentifierNode& node) override {
98  if (variableNode != nullptr) {
99  // This is not possible
100  return;
101  }
102  if (node.parent == nullptr) {
103  objectName = rootObjectName;
104  return;
105  }
106  // This node is not necessarily a variable node.
107  // It will be checked when visiting the FunctionCallNode.
108  variableNode = &node;
109  node.parent->Visit(*this);
110  }
111  void OnVisitEmptyNode(EmptyNode& node) override {}
112  void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override {}
113  void OnVisitVariableBracketAccessorNode(
114  VariableBracketAccessorNode& node) override {}
115  void OnVisitFunctionCallNode(FunctionCallNode& functionCall) override {
116  if (variableNode == nullptr) {
117  return;
118  }
119  int parameterIndex = -1;
120  for (int i = 0; i < functionCall.parameters.size(); i++) {
121  if (functionCall.parameters.at(i).get() == variableNode) {
122  parameterIndex = i;
123  break;
124  }
125  }
126  if (parameterIndex < 0) {
127  return;
128  }
129  const gd::ParameterMetadata* parameterMetadata =
130  MetadataProvider::GetFunctionCallParameterMetadata(
131  platform,
132  objectsContainersList,
133  functionCall,
134  parameterIndex);
135  if (parameterMetadata == nullptr
136  || parameterMetadata->GetType() != "objectvar") {
137  return;
138  }
139 
140  // The object on which the function is called is returned if no previous
141  // parameters are objects.
142  objectName = functionCall.objectName;
143  for (int previousIndex = parameterIndex - 1; previousIndex >= 0; previousIndex--) {
144  const gd::ParameterMetadata* previousParameterMetadata =
145  MetadataProvider::GetFunctionCallParameterMetadata(
146  platform,
147  objectsContainersList,
148  functionCall,
149  previousIndex);
150  if (previousParameterMetadata != nullptr
151  && gd::ParameterMetadata::IsObject(previousParameterMetadata->GetType())) {
152  auto previousParameterNode = functionCall.parameters[previousIndex].get();
153  IdentifierNode* objectNode = dynamic_cast<IdentifierNode*>(previousParameterNode);
154  objectName = objectNode->identifierName;
155  return;
156  }
157  }
158  }
159 
160  private:
161  gd::String objectName;
162  gd::ExpressionNode *variableNode;
163 
164  const gd::Platform &platform;
165  const gd::ObjectsContainersList &objectsContainersList;
166  const gd::String &rootObjectName;
167 };
168 
169 } // namespace gd
170 
171 #endif // GDCORE_EXPRESSIONVARIABLEOWNERFINDER_H
The interface for any worker class ("visitor" pattern) that want to interact with the nodes of a pars...
Definition: ExpressionParser2NodeWorker.h:36
Find the object name that should be used as a context of the expression or sub-expression that a give...
Definition: ExpressionVariableOwnerFinder.h:41
const gd::String & GetObjectName()
Get all the errors.
Definition: ExpressionVariableOwnerFinder.h:75
static const gd::String GetObjectName(const gd::Platform &platform, const gd::ObjectsContainersList &objectsContainersList, const gd::String &rootObjectName, gd::ExpressionNode &node)
Helper function to find the object name that should be used as a context of the expression or sub-exp...
Definition: ExpressionVariableOwnerFinder.h:48
A list of objects containers, useful for accessing objects in a scoped way, along with methods to acc...
Definition: ObjectsContainersList.h:29
Describe a parameter of an instruction (action, condition) or of an expression: type,...
Definition: ParameterMetadata.h:27
static bool IsObject(const gd::String &parameterType)
Return true if the type of the parameter is representing one object (or more, i.e: an object group).
Definition: ParameterMetadata.h:192
const gd::String & GetType() const
Return the type of the parameter.
Definition: ParameterMetadata.h:61
Base class for implementing a platform.
Definition: Platform.h:42
String represents an UTF8 encoded string.
Definition: String.h:33
Definition: CommonTools.h:24
The base node, from which all nodes in the tree of an expression inherits from.
Definition: ExpressionParser2Node.h:100
Definition: ExpressionParser2Node.h:115