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/ProjectScopedContainers.h"
18 #include "GDCore/Project/Variable.h"
23 class ObjectsContainer;
25 class ParameterMetadata;
26 class ExpressionMetadata;
57 projectScopedContainers);
58 node.Visit(typeFinder);
59 return typeFinder.variableAndItsParent;
68 : platform(platform_),
69 projectScopedContainers(projectScopedContainers_),
70 variableNode(
nullptr),
71 thisIsALegacyPrescopedVariable(
false),
72 bailOutBecauseEmptyVariableName(
false),
73 legacyPrescopedVariablesContainer(
nullptr),
74 variableAndItsParent{} {};
79 void OnVisitNumberNode(
NumberNode& node)
override {}
80 void OnVisitTextNode(
TextNode& node)
override {}
82 if (variableNode !=
nullptr) {
90 if (node.parent) node.parent->Visit(*
this);
92 if (thisIsALegacyPrescopedVariable) {
95 childVariableNames.insert(childVariableNames.begin(), node.name);
96 if (legacyPrescopedVariablesContainer)
97 variableAndItsParent = WalkUntilLastParent(
98 *legacyPrescopedVariablesContainer, childVariableNames);
103 projectScopedContainers.MatchIdentifierWithName<
void>(
107 const auto* variablesContainer =
108 projectScopedContainers.GetObjectsContainersList()
110 if (variablesContainer)
111 variableAndItsParent =
112 WalkUntilLastParent(*variablesContainer, childVariableNames);
116 if (projectScopedContainers.GetVariablesContainersList().
Has(
118 variableAndItsParent = WalkUntilLastParent(
119 projectScopedContainers.GetVariablesContainersList().
Get(
138 if (node.name.
empty() && node.child) {
143 bailOutBecauseEmptyVariableName =
true;
145 childVariableNames.insert(childVariableNames.begin(), node.name);
146 if (node.parent) node.parent->Visit(*
this);
149 if (variableNode !=
nullptr) {
155 variableNode = &node;
159 if (node.parent) node.parent->Visit(*
this);
161 if (thisIsALegacyPrescopedVariable) {
165 childVariableNames.insert(childVariableNames.begin(),
167 childVariableNames.insert(childVariableNames.begin(),
170 if (legacyPrescopedVariablesContainer)
171 variableAndItsParent = WalkUntilLastParent(
172 *legacyPrescopedVariablesContainer, childVariableNames);
178 projectScopedContainers.MatchIdentifierWithName<
void>(
183 childVariableNames.
insert(childVariableNames.begin(),
186 const auto* variablesContainer =
187 projectScopedContainers.GetObjectsContainersList()
189 if (variablesContainer)
190 variableAndItsParent =
191 WalkUntilLastParent(*variablesContainer, childVariableNames);
196 childVariableNames.insert(childVariableNames.begin(),
199 if (projectScopedContainers.GetVariablesContainersList().
Has(
201 variableAndItsParent = WalkUntilLastParent(
202 projectScopedContainers.GetVariablesContainersList().
Get(
220 void OnVisitEmptyNode(
EmptyNode& node)
override {}
222 void OnVisitVariableBracketAccessorNode(
226 childVariableNames.insert(childVariableNames.begin(),
"");
227 if (node.parent) node.parent->Visit(*
this);
230 if (variableNode ==
nullptr) {
233 int parameterIndex = -1;
234 for (
int i = 0; i < functionCall.parameters.size(); i++) {
235 if (functionCall.parameters.at(i).get() == variableNode) {
240 if (parameterIndex < 0) {
244 const auto& objectsContainersList =
245 projectScopedContainers.GetObjectsContainersList();
248 MetadataProvider::GetFunctionCallParameterMetadata(
249 platform, objectsContainersList, functionCall, parameterIndex);
250 if (parameterMetadata ==
nullptr)
return;
254 if (parameterMetadata->
GetType() ==
"objectvar") {
259 gd::String objectName = functionCall.objectName;
260 for (
int previousIndex = parameterIndex - 1; previousIndex >= 0;
263 MetadataProvider::GetFunctionCallParameterMetadata(
264 platform, objectsContainersList, functionCall, previousIndex);
265 if (previousParameterMetadata !=
nullptr &&
267 previousParameterMetadata->
GetType())) {
268 auto previousParameterNode =
269 functionCall.parameters[previousIndex].get();
277 legacyPrescopedVariablesContainer =
278 projectScopedContainers.GetObjectsContainersList()
280 thisIsALegacyPrescopedVariable =
true;
281 }
else if (parameterMetadata->
GetType() ==
"scenevar") {
282 legacyPrescopedVariablesContainer =
283 projectScopedContainers.GetVariablesContainersList()
285 thisIsALegacyPrescopedVariable =
true;
286 }
else if (parameterMetadata->
GetType() ==
"globalvar") {
287 legacyPrescopedVariablesContainer =
288 projectScopedContainers.GetVariablesContainersList()
290 thisIsALegacyPrescopedVariable =
true;
293 thisIsALegacyPrescopedVariable =
false;
294 legacyPrescopedVariablesContainer =
nullptr;
301 const std::vector<gd::String>& childVariableNames,
302 size_t startIndex = 0) {
303 if (bailOutBecauseEmptyVariableName)
310 for (
size_t index = startIndex; index + 1 < childVariableNames.size();
312 const gd::String& childName = childVariableNames[index];
314 if (childName.
empty()) {
321 if (currentVariable->
GetType() == gd::Variable::Array) {
322 currentVariable = ¤tVariable->
GetAtIndex(0);
328 if (!currentVariable->
HasChild(childName)) {
333 currentVariable = ¤tVariable->
GetChild(childName);
339 return {.parentVariable = currentVariable};
344 const std::vector<gd::String>& childVariableNames) {
345 if (bailOutBecauseEmptyVariableName)
348 if (childVariableNames.empty())
354 ? &variablesContainer.
Get(firstChildName)
356 if (childVariableNames.size() == 1 || !variable)
358 .parentVariablesContainer = &variablesContainer};
360 return WalkUntilLastParent(*variable, childVariableNames, 1);
364 std::vector<gd::String> childVariableNames;
365 bool thisIsALegacyPrescopedVariable;
366 bool bailOutBecauseEmptyVariableName;
The interface for any worker class ("visitor" pattern) that want to interact with the nodes of a pars...
Definition: ExpressionParser2NodeWorker.h:36
Find the last parent (i.e: the variables container) of a node representing a variable.
Definition: ExpressionVariableParentFinder.h:50
const gd::VariablesContainer * GetObjectOrGroupVariablesContainer(const gd::String &objectOrGroupName) const
Return the container of the variables for the specified object or group of objects.
Definition: ObjectsContainersList.cpp:158
Holds references to variables, objects, properties and other containers.
Definition: ProjectScopedContainers.h:30
String represents an UTF8 encoded string.
Definition: String.h:31
String::iterator begin()
Get a beginning iterator.
Definition: String.cpp:66
bool empty() const
Returns true if the string is empty.
Definition: String.h:155
String & insert(size_type pos, const String &str)
Inserts characters right before the character at pos.
Definition: String.cpp:231
Defines a variable which can be used by an object, a layout or a project.
Definition: Variable.h:29
size_t GetChildrenCount() const
Get the count of children that the variable has.
Definition: Variable.h:187
const std::map< gd::String, std::shared_ptr< Variable > > & GetAllChildren() const
Get the map containing all the children.
Definition: Variable.h:244
bool HasChild(const gd::String &name) const
Return true if the variable is a structure and has the specified child.
Definition: Variable.cpp:130
Variable & GetChild(const gd::String &name)
Return the child with the specified name.
Definition: Variable.cpp:140
Type GetType() const
Get the type of the variable.
Definition: Variable.h:60
Variable & GetAtIndex(const size_t index)
Return the element with the specified index.
Definition: Variable.cpp:180
Class defining a container for gd::Variable.
Definition: VariablesContainer.h:30
bool Has(const gd::String &name) const
Return true if the specified variable is in the container.
Definition: VariablesContainer.cpp:40
Variable & Get(const gd::String &name)
Return a reference to the variable called name.
Definition: VariablesContainer.cpp:46
const VariablesContainer * GetTopMostVariablesContainer() const
Avoid using apart when a scope must be forced.
Definition: VariablesContainersList.h:54
const Variable & Get(const gd::String &name) const
Return a reference to the variable called name.
Definition: VariablesContainersList.cpp:37
const VariablesContainer * GetBottomMostVariablesContainer() const
Avoid using apart when a scope must be forced.
Definition: VariablesContainersList.h:63
bool Has(const gd::String &name) const
Return true if the specified variable is in one of the containers.
Definition: VariablesContainersList.cpp:28
Definition: CommonTools.h:24
An empty node, used when parsing failed/a syntax error was encountered and any other node could not m...
Definition: ExpressionParser2Node.h:416
The base node, from which all nodes in the tree of an expression inherits from.
Definition: ExpressionParser2Node.h:93
A function call node (either free function, object function or object behavior function)....
Definition: ExpressionParser2Node.h:364
An identifier node, usually representing an object or a variable with an optional function name or ch...
Definition: ExpressionParser2Node.h:197
gd::String childIdentifierName
The object function or variable child name.
Definition: ExpressionParser2Node.h:215
gd::String identifierName
The object or variable name.
Definition: ExpressionParser2Node.h:212
A number node. For example: "123". Its type is always "number".
Definition: ExpressionParser2Node.h:154
The name of a function to call on an object or the behavior For example: "MyObject....
Definition: ExpressionParser2Node.h:314
An operator node. For example: "lhs + rhs".
Definition: ExpressionParser2Node.h:122
Definition: ExpressionParser2Node.h:108
A text node. For example: "Hello World". Its type is always "string".
Definition: ExpressionParser2Node.h:170
A unary operator node. For example: "-2".
Definition: ExpressionParser2Node.h:138
A direct accessor to a child variable. Example: MyChild in MyVariable.MyChild.
Definition: ExpressionParser2Node.h:275
Contains a variables container or a variable. Useful to refer to the parent of a variable (which can ...
Definition: ExpressionVariableParentFinder.h:36
A bracket accessor to a child variable. Example: ["MyChild"] (in MyVariable["MyChild"]).
Definition: ExpressionParser2Node.h:293
A variable, or object variable, with bracket accessor or at least 2 "dot" accessors.
Definition: ExpressionParser2Node.h:254