summaryrefslogtreecommitdiff
path: root/modules/gdscript
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript')
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp12
-rw-r--r--modules/gdscript/gdscript_analyzer.h2
-rw-r--r--modules/gdscript/gdscript_parser.cpp7
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_local_variable.gd3
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_local_variable.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_member_variable.gd5
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_member_variable.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_parameter.gd5
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_parameter.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/assignments_with_untyped.gd5
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/assignments_with_untyped.out1
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/class_name_after_annotation.out2
12 files changed, 32 insertions, 16 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 95f53d3d39..03b0dd73e1 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -1544,10 +1544,8 @@ void GDScriptAnalyzer::resolve_assignable(GDScriptParser::AssignableNode *p_assi
GDScriptParser::DataType initializer_type = p_assignable->initializer->get_datatype();
if (p_assignable->infer_datatype) {
- if (!initializer_type.is_set() || initializer_type.has_no_type()) {
+ if (!initializer_type.is_set() || initializer_type.has_no_type() || !initializer_type.is_hard_type()) {
push_error(vformat(R"(Cannot infer the type of "%s" %s because the value doesn't have a set type.)", p_assignable->identifier->name, p_kind), p_assignable->initializer);
- } else if (initializer_type.is_variant() && !initializer_type.is_hard_type()) {
- push_error(vformat(R"(Cannot infer the type of "%s" %s because the value is Variant. Use explicit "Variant" type if this is intended.)", p_assignable->identifier->name, p_kind), p_assignable->initializer);
} else if (initializer_type.kind == GDScriptParser::DataType::BUILTIN && initializer_type.builtin_type == Variant::NIL && !is_constant) {
push_error(vformat(R"(Cannot infer the type of "%s" %s because the value is "null".)", p_assignable->identifier->name, p_kind), p_assignable->initializer);
}
@@ -2014,7 +2012,7 @@ void GDScriptAnalyzer::reduce_expression(GDScriptParser::ExpressionNode *p_expre
reduce_subscript(static_cast<GDScriptParser::SubscriptNode *>(p_expression));
break;
case GDScriptParser::Node::TERNARY_OPERATOR:
- reduce_ternary_op(static_cast<GDScriptParser::TernaryOpNode *>(p_expression));
+ reduce_ternary_op(static_cast<GDScriptParser::TernaryOpNode *>(p_expression), p_is_root);
break;
case GDScriptParser::Node::UNARY_OPERATOR:
reduce_unary_op(static_cast<GDScriptParser::UnaryOpNode *>(p_expression));
@@ -3736,10 +3734,10 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri
p_subscript->set_datatype(result_type);
}
-void GDScriptAnalyzer::reduce_ternary_op(GDScriptParser::TernaryOpNode *p_ternary_op) {
+void GDScriptAnalyzer::reduce_ternary_op(GDScriptParser::TernaryOpNode *p_ternary_op, bool p_is_root) {
reduce_expression(p_ternary_op->condition);
- reduce_expression(p_ternary_op->true_expr);
- reduce_expression(p_ternary_op->false_expr);
+ reduce_expression(p_ternary_op->true_expr, p_is_root);
+ reduce_expression(p_ternary_op->false_expr, p_is_root);
GDScriptParser::DataType result;
diff --git a/modules/gdscript/gdscript_analyzer.h b/modules/gdscript/gdscript_analyzer.h
index b22d47982f..5397be33f0 100644
--- a/modules/gdscript/gdscript_analyzer.h
+++ b/modules/gdscript/gdscript_analyzer.h
@@ -99,7 +99,7 @@ class GDScriptAnalyzer {
void reduce_preload(GDScriptParser::PreloadNode *p_preload);
void reduce_self(GDScriptParser::SelfNode *p_self);
void reduce_subscript(GDScriptParser::SubscriptNode *p_subscript);
- void reduce_ternary_op(GDScriptParser::TernaryOpNode *p_ternary_op);
+ void reduce_ternary_op(GDScriptParser::TernaryOpNode *p_ternary_op, bool p_is_root = false);
void reduce_unary_op(GDScriptParser::UnaryOpNode *p_unary_op);
void const_fold_array(GDScriptParser::ArrayNode *p_array, bool p_is_const);
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 6dc63c502c..eb966229c1 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -1434,7 +1434,11 @@ GDScriptParser::AnnotationNode *GDScriptParser::parse_annotation(uint32_t p_vali
annotation->info = &valid_annotations[annotation->name];
if (!annotation->applies_to(p_valid_targets)) {
- push_error(vformat(R"(Annotation "%s" is not allowed in this level.)", annotation->name));
+ if (annotation->applies_to(AnnotationInfo::SCRIPT)) {
+ push_error(vformat(R"(Annotation "%s" must be at the top of the script, before "extends" and "class_name".)", annotation->name));
+ } else {
+ push_error(vformat(R"(Annotation "%s" is not allowed in this level.)", annotation->name));
+ }
valid = false;
}
@@ -1697,6 +1701,7 @@ GDScriptParser::Node *GDScriptParser::parse_statement() {
case Node::CALL:
case Node::ASSIGNMENT:
case Node::AWAIT:
+ case Node::TERNARY_OPERATOR:
// Fine.
break;
case Node::LAMBDA:
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_local_variable.gd b/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_local_variable.gd
new file mode 100644
index 0000000000..6014ee831c
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_local_variable.gd
@@ -0,0 +1,3 @@
+func test():
+ var untyped = 1
+ var inferred := untyped
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_local_variable.out b/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_local_variable.out
new file mode 100644
index 0000000000..b6dc6d0b01
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_local_variable.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Cannot infer the type of "inferred" variable because the value doesn't have a set type.
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_member_variable.gd b/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_member_variable.gd
new file mode 100644
index 0000000000..040aa2e82a
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_member_variable.gd
@@ -0,0 +1,5 @@
+var untyped = 1
+var inferred := untyped
+
+func test():
+ pass
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_member_variable.out b/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_member_variable.out
new file mode 100644
index 0000000000..b6dc6d0b01
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_member_variable.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Cannot infer the type of "inferred" variable because the value doesn't have a set type.
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_parameter.gd b/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_parameter.gd
new file mode 100644
index 0000000000..80c676488e
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_parameter.gd
@@ -0,0 +1,5 @@
+func check(untyped = 1, inferred := untyped):
+ pass
+
+func test():
+ check()
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_parameter.out b/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_parameter.out
new file mode 100644
index 0000000000..8c9f0c13ae
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/inferring_with_weak_type_parameter.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Cannot infer the type of "inferred" parameter because the value doesn't have a set type.
diff --git a/modules/gdscript/tests/scripts/analyzer/features/assignments_with_untyped.gd b/modules/gdscript/tests/scripts/analyzer/features/assignments_with_untyped.gd
index 2d2c2bef19..595563541f 100644
--- a/modules/gdscript/tests/scripts/analyzer/features/assignments_with_untyped.gd
+++ b/modules/gdscript/tests/scripts/analyzer/features/assignments_with_untyped.gd
@@ -1,9 +1,4 @@
func test():
- var one_0 = 0
- one_0 = 1
- var one_1 := one_0
- print(one_1)
-
var two: Variant = 0
two += 2
print(two)
diff --git a/modules/gdscript/tests/scripts/analyzer/features/assignments_with_untyped.out b/modules/gdscript/tests/scripts/analyzer/features/assignments_with_untyped.out
index 7536c38490..0ddfa4b75f 100644
--- a/modules/gdscript/tests/scripts/analyzer/features/assignments_with_untyped.out
+++ b/modules/gdscript/tests/scripts/analyzer/features/assignments_with_untyped.out
@@ -1,5 +1,4 @@
GDTEST_OK
-1
2
3
4
diff --git a/modules/gdscript/tests/scripts/parser/errors/class_name_after_annotation.out b/modules/gdscript/tests/scripts/parser/errors/class_name_after_annotation.out
index a598ff8424..5fcf1cbcad 100644
--- a/modules/gdscript/tests/scripts/parser/errors/class_name_after_annotation.out
+++ b/modules/gdscript/tests/scripts/parser/errors/class_name_after_annotation.out
@@ -1,2 +1,2 @@
GDTEST_PARSER_ERROR
-Annotation "@icon" is not allowed in this level.
+Annotation "@icon" must be at the top of the script, before "extends" and "class_name".