summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuri Sizov <11782833+YuriSizov@users.noreply.github.com>2023-04-17 17:14:58 +0200
committerGitHub <noreply@github.com>2023-04-17 17:14:58 +0200
commit6596a6c1b5523b8e7b8110b14f6765da48ff62ef (patch)
treeff34e941c3e58c55183c74d737643a379e3f2c9e
parentd220680bd09181bd8e11006153d800eb9173578b (diff)
parent5038a336bed6ccb5901c1437494e34312cfdc4ad (diff)
downloadredot-engine-6596a6c1b5523b8e7b8110b14f6765da48ff62ef.tar.gz
Merge pull request #72979 from dalexeev/gds-annotation-parsing
GDScript: Fix and improve annotation parsing
-rw-r--r--modules/gdscript/gdscript_parser.cpp39
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/annotation_extra_comma.gd4
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/annotation_extra_comma.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/annotations.gd48
-rw-r--r--modules/gdscript/tests/scripts/parser/features/annotations.out13
5 files changed, 89 insertions, 17 deletions
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index b7d85ea6c2..8a49398f1a 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -1439,27 +1439,32 @@ GDScriptParser::AnnotationNode *GDScriptParser::parse_annotation(uint32_t p_vali
valid = false;
}
- if (match(GDScriptTokenizer::Token::PARENTHESIS_OPEN)) {
+ if (check(GDScriptTokenizer::Token::PARENTHESIS_OPEN)) {
+ push_multiline(true);
+ advance();
// Arguments.
push_completion_call(annotation);
make_completion_context(COMPLETION_ANNOTATION_ARGUMENTS, annotation, 0, true);
- if (!check(GDScriptTokenizer::Token::PARENTHESIS_CLOSE) && !is_at_end()) {
- push_multiline(true);
- int argument_index = 0;
- do {
- make_completion_context(COMPLETION_ANNOTATION_ARGUMENTS, annotation, argument_index, true);
- set_last_completion_call_arg(argument_index++);
- ExpressionNode *argument = parse_expression(false);
- if (argument == nullptr) {
- valid = false;
- continue;
- }
- annotation->arguments.push_back(argument);
- } while (match(GDScriptTokenizer::Token::COMMA));
- pop_multiline();
+ int argument_index = 0;
+ do {
+ if (check(GDScriptTokenizer::Token::PARENTHESIS_CLOSE)) {
+ // Allow for trailing comma.
+ break;
+ }
- consume(GDScriptTokenizer::Token::PARENTHESIS_CLOSE, R"*(Expected ")" after annotation arguments.)*");
- }
+ make_completion_context(COMPLETION_ANNOTATION_ARGUMENTS, annotation, argument_index, true);
+ set_last_completion_call_arg(argument_index++);
+ ExpressionNode *argument = parse_expression(false);
+ if (argument == nullptr) {
+ push_error("Expected expression as the annotation argument.");
+ valid = false;
+ continue;
+ }
+ annotation->arguments.push_back(argument);
+ } while (match(GDScriptTokenizer::Token::COMMA) && !is_at_end());
+
+ pop_multiline();
+ consume(GDScriptTokenizer::Token::PARENTHESIS_CLOSE, R"*(Expected ")" after annotation arguments.)*");
pop_completion_call();
}
complete_extents(annotation);
diff --git a/modules/gdscript/tests/scripts/parser/errors/annotation_extra_comma.gd b/modules/gdscript/tests/scripts/parser/errors/annotation_extra_comma.gd
new file mode 100644
index 0000000000..271a831732
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/errors/annotation_extra_comma.gd
@@ -0,0 +1,4 @@
+@export_enum("A",, "B", "C") var a
+
+func test():
+ pass
diff --git a/modules/gdscript/tests/scripts/parser/errors/annotation_extra_comma.out b/modules/gdscript/tests/scripts/parser/errors/annotation_extra_comma.out
new file mode 100644
index 0000000000..70eee5b39f
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/errors/annotation_extra_comma.out
@@ -0,0 +1,2 @@
+GDTEST_PARSER_ERROR
+Expected expression as the annotation argument.
diff --git a/modules/gdscript/tests/scripts/parser/features/annotations.gd b/modules/gdscript/tests/scripts/parser/features/annotations.gd
new file mode 100644
index 0000000000..13c89a0a09
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/annotations.gd
@@ -0,0 +1,48 @@
+extends Node
+
+@export_enum("A", "B", "C") var a0
+@export_enum("A", "B", "C",) var a1
+
+@export_enum(
+ "A",
+ "B",
+ "C"
+) var a2
+
+@export_enum(
+ "A",
+ "B",
+ "C",
+) var a3
+
+@export
+var a4: int
+
+@export()
+var a5: int
+
+@export() var a6: int
+@warning_ignore("onready_with_export") @onready @export var a7: int
+@warning_ignore("onready_with_export") @onready() @export() var a8: int
+
+@warning_ignore("onready_with_export")
+@onready
+@export
+var a9: int
+
+@warning_ignore("onready_with_export")
+@onready()
+@export()
+var a10: int
+
+@warning_ignore("onready_with_export")
+@onready()
+@export()
+
+var a11: int
+
+
+func test():
+ for property in get_property_list():
+ if property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE:
+ print(property)
diff --git a/modules/gdscript/tests/scripts/parser/features/annotations.out b/modules/gdscript/tests/scripts/parser/features/annotations.out
new file mode 100644
index 0000000000..3af0436c53
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/annotations.out
@@ -0,0 +1,13 @@
+GDTEST_OK
+{ "name": "a0", "class_name": &"", "type": 2, "hint": 2, "hint_string": "A,B,C", "usage": 4102 }
+{ "name": "a1", "class_name": &"", "type": 2, "hint": 2, "hint_string": "A,B,C", "usage": 4102 }
+{ "name": "a2", "class_name": &"", "type": 2, "hint": 2, "hint_string": "A,B,C", "usage": 4102 }
+{ "name": "a3", "class_name": &"", "type": 2, "hint": 2, "hint_string": "A,B,C", "usage": 4102 }
+{ "name": "a4", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
+{ "name": "a5", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
+{ "name": "a6", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
+{ "name": "a7", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
+{ "name": "a8", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
+{ "name": "a9", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
+{ "name": "a10", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
+{ "name": "a11", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }