| 260 | } |
| 261 | |
| 262 | GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &codegen, Error &r_error, const GDScriptParser::ExpressionNode *p_expression, bool p_root, bool p_initializer) { |
| 263 | if (p_expression->is_constant && !(p_expression->get_datatype().is_meta_type && p_expression->get_datatype().kind == GDScriptParser::DataType::CLASS)) { |
| 264 | return codegen.add_constant(p_expression->reduced_value); |
| 265 | } |
| 266 | |
| 267 | GDScriptCodeGenerator *gen = codegen.generator; |
| 268 | |
| 269 | switch (p_expression->type) { |
| 270 | case GDScriptParser::Node::IDENTIFIER: { |
| 271 | // Look for identifiers in current scope. |
| 272 | const GDScriptParser::IdentifierNode *in = static_cast<const GDScriptParser::IdentifierNode *>(p_expression); |
| 273 | |
| 274 | StringName identifier = in->name; |
| 275 | |
| 276 | switch (in->source) { |
| 277 | // LOCALS. |
| 278 | case GDScriptParser::IdentifierNode::FUNCTION_PARAMETER: |
| 279 | case GDScriptParser::IdentifierNode::LOCAL_VARIABLE: |
| 280 | case GDScriptParser::IdentifierNode::LOCAL_CONSTANT: |
| 281 | case GDScriptParser::IdentifierNode::LOCAL_ITERATOR: |
| 282 | case GDScriptParser::IdentifierNode::LOCAL_BIND: { |
| 283 | // Try function parameters. |
| 284 | if (codegen.parameters.has(identifier)) { |
| 285 | return codegen.parameters[identifier]; |
| 286 | } |
| 287 | |
| 288 | // Try local variables and constants. |
| 289 | if (!p_initializer && codegen.locals.has(identifier)) { |
| 290 | return codegen.locals[identifier]; |
| 291 | } |
| 292 | } break; |
| 293 | |
| 294 | // MEMBERS. |
| 295 | case GDScriptParser::IdentifierNode::MEMBER_VARIABLE: |
| 296 | case GDScriptParser::IdentifierNode::MEMBER_FUNCTION: |
| 297 | case GDScriptParser::IdentifierNode::MEMBER_SIGNAL: |
| 298 | case GDScriptParser::IdentifierNode::INHERITED_VARIABLE: { |
| 299 | // Try class members. |
| 300 | if (_is_class_member_property(codegen, identifier)) { |
| 301 | // Get property. |
| 302 | GDScriptCodeGenerator::Address temp = codegen.add_temporary(_gdtype_from_datatype(p_expression->get_datatype(), codegen.script)); |
| 303 | gen->write_get_member(temp, identifier); |
| 304 | return temp; |
| 305 | } |
| 306 | |
| 307 | // Try members. |
| 308 | if (!codegen.function_node || !codegen.function_node->is_static) { |
| 309 | // Try member variables. |
| 310 | if (codegen.script->member_indices.has(identifier)) { |
| 311 | if (codegen.script->member_indices[identifier].getter != StringName() && codegen.script->member_indices[identifier].getter != codegen.function_name) { |
| 312 | // Perform getter. |
| 313 | GDScriptCodeGenerator::Address temp = codegen.add_temporary(codegen.script->member_indices[identifier].data_type); |
| 314 | Vector<GDScriptCodeGenerator::Address> args; // No argument needed. |
| 315 | gen->write_call_self(temp, codegen.script->member_indices[identifier].getter, args); |
| 316 | return temp; |
| 317 | } else { |
| 318 | // No getter or inside getter: direct member access. |
| 319 | int idx = codegen.script->member_indices[identifier].index; |
nothing calls this directly
no test coverage detected