mirror of
https://github.com/godotengine/godot.git
synced 2025-01-23 19:12:24 -05:00
Prefer identifiers annotated type if assigned type is incompatible to it
This commit is contained in:
parent
107f2961cc
commit
0203b3c310
3 changed files with 39 additions and 22 deletions
|
@ -5315,8 +5315,21 @@ GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add safe/unsafe return variable (for variant cases)
|
|
||||||
bool GDScriptAnalyzer::is_type_compatible(const GDScriptParser::DataType &p_target, const GDScriptParser::DataType &p_source, bool p_allow_implicit_conversion, const GDScriptParser::Node *p_source_node) {
|
bool GDScriptAnalyzer::is_type_compatible(const GDScriptParser::DataType &p_target, const GDScriptParser::DataType &p_source, bool p_allow_implicit_conversion, const GDScriptParser::Node *p_source_node) {
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (p_source_node) {
|
||||||
|
if (p_target.kind == GDScriptParser::DataType::ENUM) {
|
||||||
|
if (p_source.kind == GDScriptParser::DataType::BUILTIN && p_source.builtin_type == Variant::INT) {
|
||||||
|
parser->push_warning(p_source_node, GDScriptWarning::INT_AS_ENUM_WITHOUT_CAST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return check_type_compatibility(p_target, p_source, p_allow_implicit_conversion, p_source_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add safe/unsafe return variable (for variant cases)
|
||||||
|
bool GDScriptAnalyzer::check_type_compatibility(const GDScriptParser::DataType &p_target, const GDScriptParser::DataType &p_source, bool p_allow_implicit_conversion, const GDScriptParser::Node *p_source_node) {
|
||||||
// These return "true" so it doesn't affect users negatively.
|
// These return "true" so it doesn't affect users negatively.
|
||||||
ERR_FAIL_COND_V_MSG(!p_target.is_set(), true, "Parser bug (please report): Trying to check compatibility of unset target type");
|
ERR_FAIL_COND_V_MSG(!p_target.is_set(), true, "Parser bug (please report): Trying to check compatibility of unset target type");
|
||||||
ERR_FAIL_COND_V_MSG(!p_source.is_set(), true, "Parser bug (please report): Trying to check compatibility of unset value type");
|
ERR_FAIL_COND_V_MSG(!p_source.is_set(), true, "Parser bug (please report): Trying to check compatibility of unset value type");
|
||||||
|
@ -5351,11 +5364,6 @@ bool GDScriptAnalyzer::is_type_compatible(const GDScriptParser::DataType &p_targ
|
||||||
|
|
||||||
if (p_target.kind == GDScriptParser::DataType::ENUM) {
|
if (p_target.kind == GDScriptParser::DataType::ENUM) {
|
||||||
if (p_source.kind == GDScriptParser::DataType::BUILTIN && p_source.builtin_type == Variant::INT) {
|
if (p_source.kind == GDScriptParser::DataType::BUILTIN && p_source.builtin_type == Variant::INT) {
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
if (p_source_node) {
|
|
||||||
parser->push_warning(p_source_node, GDScriptWarning::INT_AS_ENUM_WITHOUT_CAST);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (p_source.kind == GDScriptParser::DataType::ENUM) {
|
if (p_source.kind == GDScriptParser::DataType::ENUM) {
|
||||||
|
|
|
@ -147,6 +147,7 @@ public:
|
||||||
|
|
||||||
Variant make_variable_default_value(GDScriptParser::VariableNode *p_variable);
|
Variant make_variable_default_value(GDScriptParser::VariableNode *p_variable);
|
||||||
const HashMap<String, Ref<GDScriptParserRef>> &get_depended_parsers();
|
const HashMap<String, Ref<GDScriptParserRef>> &get_depended_parsers();
|
||||||
|
static bool check_type_compatibility(const GDScriptParser::DataType &p_target, const GDScriptParser::DataType &p_source, bool p_allow_implicit_conversion = false, const GDScriptParser::Node *p_source_node = nullptr);
|
||||||
|
|
||||||
GDScriptAnalyzer(GDScriptParser *p_parser);
|
GDScriptAnalyzer(GDScriptParser *p_parser);
|
||||||
};
|
};
|
||||||
|
|
|
@ -2009,6 +2009,21 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (p_context.current_class) {
|
||||||
|
GDScriptCompletionIdentifier base_identifier;
|
||||||
|
|
||||||
|
GDScriptCompletionIdentifier base;
|
||||||
|
base.value = p_context.base;
|
||||||
|
base.type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
|
||||||
|
base.type.kind = GDScriptParser::DataType::CLASS;
|
||||||
|
base.type.class_type = p_context.current_class;
|
||||||
|
base.type.is_meta_type = p_context.current_function && p_context.current_function->is_static;
|
||||||
|
|
||||||
|
if (_guess_identifier_type_from_base(p_context, base, p_identifier->name, base_identifier)) {
|
||||||
|
id_type = base_identifier.type;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (suite) {
|
while (suite) {
|
||||||
|
@ -2062,8 +2077,15 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
|
||||||
if (last_assigned_expression && last_assign_line < p_context.current_line) {
|
if (last_assigned_expression && last_assign_line < p_context.current_line) {
|
||||||
GDScriptParser::CompletionContext c = p_context;
|
GDScriptParser::CompletionContext c = p_context;
|
||||||
c.current_line = last_assign_line;
|
c.current_line = last_assign_line;
|
||||||
r_type.assigned_expression = last_assigned_expression;
|
GDScriptCompletionIdentifier assigned_type;
|
||||||
if (_guess_expression_type(c, last_assigned_expression, r_type)) {
|
if (_guess_expression_type(c, last_assigned_expression, assigned_type)) {
|
||||||
|
if (id_type.is_set() && assigned_type.type.is_set() && !GDScriptAnalyzer::check_type_compatibility(id_type, assigned_type.type)) {
|
||||||
|
// The assigned type is incompatible. The annotated type takes priority.
|
||||||
|
r_type.assigned_expression = last_assigned_expression;
|
||||||
|
r_type.type = id_type;
|
||||||
|
} else {
|
||||||
|
r_type = assigned_type;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2121,20 +2143,6 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check current class (including inheritance).
|
|
||||||
if (p_context.current_class) {
|
|
||||||
GDScriptCompletionIdentifier base;
|
|
||||||
base.value = p_context.base;
|
|
||||||
base.type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
|
|
||||||
base.type.kind = GDScriptParser::DataType::CLASS;
|
|
||||||
base.type.class_type = p_context.current_class;
|
|
||||||
base.type.is_meta_type = p_context.current_function && p_context.current_function->is_static;
|
|
||||||
|
|
||||||
if (_guess_identifier_type_from_base(p_context, base, p_identifier->name, r_type)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check global scripts.
|
// Check global scripts.
|
||||||
if (ScriptServer::is_global_class(p_identifier->name)) {
|
if (ScriptServer::is_global_class(p_identifier->name)) {
|
||||||
String script = ScriptServer::get_global_class_path(p_identifier->name);
|
String script = ScriptServer::get_global_class_path(p_identifier->name);
|
||||||
|
|
Loading…
Add table
Reference in a new issue