1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-22 15:06:45 +00:00

GDScript: fix type-check of indexed values

This commit is contained in:
George Marques
2019-01-16 16:02:56 -02:00
parent 31433ae8e4
commit 20e6ff263a
2 changed files with 14 additions and 24 deletions

View File

@@ -5932,7 +5932,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
int idx = current_function->arguments.find(id->name); int idx = current_function->arguments.find(id->name);
node_type = current_function->argument_types[idx]; node_type = current_function->argument_types[idx];
} else { } else {
node_type = _reduce_identifier_type(NULL, id->name, id->line); node_type = _reduce_identifier_type(NULL, id->name, id->line, false);
} }
} break; } break;
case Node::TYPE_CAST: { case Node::TYPE_CAST: {
@@ -6182,7 +6182,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
result.is_constant = false; result.is_constant = false;
node_type = result; node_type = result;
} else { } else {
node_type = _reduce_identifier_type(&base_type, member_id->name, op->line); node_type = _reduce_identifier_type(&base_type, member_id->name, op->line, true);
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
if (!node_type.has_type) { if (!node_type.has_type) {
_add_warning(GDScriptWarning::UNSAFE_PROPERTY_ACCESS, op->line, member_id->name.operator String(), base_type.to_string()); _add_warning(GDScriptWarning::UNSAFE_PROPERTY_ACCESS, op->line, member_id->name.operator String(), base_type.to_string());
@@ -6898,9 +6898,9 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
if (!base_type.is_meta_type) { if (!base_type.is_meta_type) {
for (int i = 0; i < base->variables.size(); i++) { for (int i = 0; i < base->variables.size(); i++) {
ClassNode::Member m = base->variables[i]; if (base->variables[i].identifier == p_member) {
if (m.identifier == p_member) { r_member_type = base->variables[i].data_type;
r_member_type = m.data_type; base->variables.write[i].usages += 1;
return true; return true;
} }
} }
@@ -7095,43 +7095,33 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
return false; return false;
} }
GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType *p_base_type, const StringName &p_identifier, int p_line) { GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType *p_base_type, const StringName &p_identifier, int p_line, bool p_is_indexing) {
if (p_base_type && !p_base_type->has_type) { if (p_base_type && !p_base_type->has_type) {
return DataType(); return DataType();
} }
DataType base_type; DataType base_type;
DataType member_type;
// Check classes in current file
ClassNode *base = NULL;
if (!p_base_type) { if (!p_base_type) {
base = current_class;
base_type.has_type = true; base_type.has_type = true;
base_type.is_constant = true; base_type.is_constant = true;
base_type.kind = DataType::CLASS; base_type.kind = DataType::CLASS;
base_type.class_type = base; base_type.class_type = current_class;
} else { } else {
base_type = DataType(*p_base_type); base_type = DataType(*p_base_type);
if (base_type.kind == DataType::CLASS) {
base = base_type.class_type;
}
}
DataType member_type;
for (int i = 0; i < current_class->variables.size(); i++) {
if (current_class->variables[i].identifier == p_identifier) {
member_type = current_class->variables[i].data_type;
current_class->variables.write[i].usages += 1;
return member_type;
}
} }
if (_get_member_type(base_type, p_identifier, member_type)) { if (_get_member_type(base_type, p_identifier, member_type)) {
return member_type; return member_type;
} }
if (p_is_indexing) {
// Don't look for globals since this is an indexed identifier
return DataType();
}
if (!p_base_type) { if (!p_base_type) {
// Possibly this is a global, check before failing // Possibly this is a global, check before failing

View File

@@ -607,7 +607,7 @@ private:
DataType _reduce_node_type(Node *p_node); DataType _reduce_node_type(Node *p_node);
DataType _reduce_function_call_type(const OperatorNode *p_call); DataType _reduce_function_call_type(const OperatorNode *p_call);
DataType _reduce_identifier_type(const DataType *p_base_type, const StringName &p_identifier, int p_line); DataType _reduce_identifier_type(const DataType *p_base_type, const StringName &p_identifier, int p_line, bool p_is_indexing);
void _check_class_level_types(ClassNode *p_class); void _check_class_level_types(ClassNode *p_class);
void _check_class_blocks_types(ClassNode *p_class); void _check_class_blocks_types(ClassNode *p_class);
void _check_function_types(FunctionNode *p_function); void _check_function_types(FunctionNode *p_function);