summaryrefslogtreecommitdiffstats
path: root/modules/gdscript/gdscript_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/gdscript_parser.cpp')
-rw-r--r--modules/gdscript/gdscript_parser.cpp54
1 files changed, 15 insertions, 39 deletions
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index f5d3306376..99b78a8326 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -41,6 +41,7 @@
#include "core/os/os.h"
#include "core/string/string_builder.h"
#include "gdscript_warning.h"
+#include "servers/text_server.h"
#endif // DEBUG_ENABLED
#ifdef TOOLS_ENABLED
@@ -186,24 +187,6 @@ void GDScriptParser::push_error(const String &p_message, const Node *p_origin) {
}
#ifdef DEBUG_ENABLED
-void GDScriptParser::push_warning(const Node *p_source, GDScriptWarning::Code p_code, const String &p_symbol1, const String &p_symbol2, const String &p_symbol3, const String &p_symbol4) {
- ERR_FAIL_COND(p_source == nullptr);
- Vector<String> symbols;
- if (!p_symbol1.is_empty()) {
- symbols.push_back(p_symbol1);
- }
- if (!p_symbol2.is_empty()) {
- symbols.push_back(p_symbol2);
- }
- if (!p_symbol3.is_empty()) {
- symbols.push_back(p_symbol3);
- }
- if (!p_symbol4.is_empty()) {
- symbols.push_back(p_symbol4);
- }
- push_warning(p_source, p_code, symbols);
-}
-
void GDScriptParser::push_warning(const Node *p_source, GDScriptWarning::Code p_code, const Vector<String> &p_symbols) {
ERR_FAIL_COND(p_source == nullptr);
if (is_ignoring_warnings) {
@@ -1451,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;
}
@@ -1806,11 +1793,10 @@ GDScriptParser::BreakNode *GDScriptParser::parse_break() {
GDScriptParser::ContinueNode *GDScriptParser::parse_continue() {
if (!can_continue) {
- push_error(R"(Cannot use "continue" outside of a loop or pattern matching block.)");
+ push_error(R"(Cannot use "continue" outside of a loop.)");
}
current_suite->has_continue = true;
ContinueNode *cont = alloc_node<ContinueNode>();
- cont->is_for_match = is_continue_match;
complete_extents(cont);
end_statement(R"("continue")");
return cont;
@@ -1836,12 +1822,10 @@ GDScriptParser::ForNode *GDScriptParser::parse_for() {
// Save break/continue state.
bool could_break = can_break;
bool could_continue = can_continue;
- bool was_continue_match = is_continue_match;
// Allow break/continue.
can_break = true;
can_continue = true;
- is_continue_match = false;
SuiteNode *suite = alloc_node<SuiteNode>();
if (n_for->variable) {
@@ -1859,7 +1843,6 @@ GDScriptParser::ForNode *GDScriptParser::parse_for() {
// Reset break/continue state.
can_break = could_break;
can_continue = could_continue;
- is_continue_match = was_continue_match;
return n_for;
}
@@ -1996,13 +1979,6 @@ GDScriptParser::MatchBranchNode *GDScriptParser::parse_match_branch() {
return nullptr;
}
- // Save continue state.
- bool could_continue = can_continue;
- bool was_continue_match = is_continue_match;
- // Allow continue for match.
- can_continue = true;
- is_continue_match = true;
-
SuiteNode *suite = alloc_node<SuiteNode>();
if (branch->patterns.size() > 0) {
for (const KeyValue<StringName, IdentifierNode *> &E : branch->patterns[0]->binds) {
@@ -2015,10 +1991,6 @@ GDScriptParser::MatchBranchNode *GDScriptParser::parse_match_branch() {
branch->block = parse_suite("match pattern block", suite);
complete_extents(branch);
- // Restore continue state.
- can_continue = could_continue;
- is_continue_match = was_continue_match;
-
return branch;
}
@@ -2177,12 +2149,10 @@ GDScriptParser::WhileNode *GDScriptParser::parse_while() {
// Save break/continue state.
bool could_break = can_break;
bool could_continue = can_continue;
- bool was_continue_match = is_continue_match;
// Allow break/continue.
can_break = true;
can_continue = true;
- is_continue_match = false;
n_while->loop = parse_suite(R"("while" block)");
n_while->loop->is_loop = true;
@@ -2191,7 +2161,6 @@ GDScriptParser::WhileNode *GDScriptParser::parse_while() {
// Reset break/continue state.
can_break = could_break;
can_continue = could_continue;
- is_continue_match = was_continue_match;
return n_while;
}
@@ -2251,7 +2220,14 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_expression(bool p_can_assi
}
GDScriptParser::IdentifierNode *GDScriptParser::parse_identifier() {
- return static_cast<IdentifierNode *>(parse_identifier(nullptr, false));
+ IdentifierNode *identifier = static_cast<IdentifierNode *>(parse_identifier(nullptr, false));
+#ifdef DEBUG_ENABLED
+ // Check for spoofing here (if available in TextServer) since this isn't called inside expressions. This is only relevant for declarations.
+ if (identifier && TS->has_feature(TextServer::FEATURE_UNICODE_SECURITY) && TS->spoof_check(identifier->name.operator String())) {
+ push_warning(identifier, GDScriptWarning::CONFUSABLE_IDENTIFIER, identifier->name.operator String());
+ }
+#endif
+ return identifier;
}
GDScriptParser::ExpressionNode *GDScriptParser::parse_identifier(ExpressionNode *p_previous_operand, bool p_can_assign) {