GDScript: Replace abstract keyword with @abstract annotation
Co-authored-by: Danil Alexeev <dalexeev12@yandex.ru>
This commit is contained in:
@ -1540,12 +1540,12 @@ void GDScriptAnalyzer::resolve_class_body(GDScriptParser::ClassNode *p_class, co
|
||||
if (member.function->is_abstract) {
|
||||
if (base_class == p_class) {
|
||||
const String class_name = p_class->identifier == nullptr ? p_class->fqcn.get_file() : String(p_class->identifier->name);
|
||||
push_error(vformat(R"*(Class "%s" is not abstract but contains abstract methods. Mark the class as abstract or remove "abstract" from all methods in this class.)*", class_name), p_class);
|
||||
push_error(vformat(R"*(Class "%s" is not abstract but contains abstract methods. Mark the class as "@abstract" or remove "@abstract" from all methods in this class.)*", class_name), p_class);
|
||||
break;
|
||||
} else if (!implemented_funcs.has(member.function->identifier->name)) {
|
||||
const String class_name = p_class->identifier == nullptr ? p_class->fqcn.get_file() : String(p_class->identifier->name);
|
||||
const String base_class_name = base_class->identifier == nullptr ? base_class->fqcn.get_file() : String(base_class->identifier->name);
|
||||
push_error(vformat(R"*(Class "%s" must implement "%s.%s()" and other inherited abstract methods or be marked as abstract.)*", class_name, base_class_name, member.function->identifier->name), p_class);
|
||||
push_error(vformat(R"*(Class "%s" must implement "%s.%s()" and other inherited abstract methods or be marked as "@abstract".)*", class_name, base_class_name, member.function->identifier->name), p_class);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -1987,6 +1987,20 @@ void GDScriptAnalyzer::resolve_function_body(GDScriptParser::FunctionNode *p_fun
|
||||
}
|
||||
p_function->resolved_body = true;
|
||||
|
||||
if (p_function->is_abstract) {
|
||||
// Abstract functions don't have a body.
|
||||
if (!p_function->body->statements.is_empty()) {
|
||||
push_error(R"(Abstract function cannot have a body.)", p_function->body);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
// Non-abstract functions must have a body.
|
||||
if (p_function->body->statements.is_empty()) {
|
||||
push_error(R"(A function must either have a ":" followed by a body, or be marked as "@abstract".)", p_function);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
GDScriptParser::FunctionNode *previous_function = parser->current_function;
|
||||
parser->current_function = p_function;
|
||||
|
||||
@ -1999,7 +2013,7 @@ void GDScriptAnalyzer::resolve_function_body(GDScriptParser::FunctionNode *p_fun
|
||||
// Use the suite inferred type if return isn't explicitly set.
|
||||
p_function->set_datatype(p_function->body->get_datatype());
|
||||
} else if (p_function->get_datatype().is_hard_type() && (p_function->get_datatype().kind != GDScriptParser::DataType::BUILTIN || p_function->get_datatype().builtin_type != Variant::NIL)) {
|
||||
if (!p_function->is_abstract && !p_function->body->has_return && (p_is_lambda || p_function->identifier->name != GDScriptLanguage::get_singleton()->strings._init)) {
|
||||
if (!p_function->body->has_return && (p_is_lambda || p_function->identifier->name != GDScriptLanguage::get_singleton()->strings._init)) {
|
||||
push_error(R"(Not all code paths return a value.)", p_function);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user