summaryrefslogtreecommitdiff
path: root/modules/gdscript
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript')
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml12
-rw-r--r--modules/gdscript/gdscript.cpp22
-rw-r--r--modules/gdscript/gdscript_parser.cpp109
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp9
-rw-r--r--modules/gdscript/gdscript_tokenizer.h1
-rw-r--r--modules/gdscript/gdscript_utility_functions.cpp19
-rw-r--r--modules/gdscript/gdscript_vm.cpp14
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.cpp2
-rw-r--r--modules/gdscript/language_server/gdscript_workspace.cpp2
-rw-r--r--modules/gdscript/language_server/lsp.hpp86
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.out2
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/stringify.gd2
12 files changed, 199 insertions, 81 deletions
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index 631ee4d895..5b476cda01 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -98,6 +98,7 @@
[codeblock]
[{function:bar, line:12, source:res://script.gd}, {function:foo, line:9, source:res://script.gd}, {function:_ready, line:6, source:res://script.gd}]
[/codeblock]
+ [b]Note:[/b] Not supported for calling from threads. Instead, this will return an empty array.
</description>
</method>
<method name="inst2dict">
@@ -160,17 +161,24 @@
<method name="print_debug" qualifiers="vararg">
<return type="void" />
<description>
- Like [method @GlobalScope.print], but prints only when used in debug mode.
+ Like [method @GlobalScope.print], but includes the current stack frame when running with the debugger turned on.
+ Output in the console would look something like this:
+ [codeblock]
+ Test print
+ At: res://test.gd:15:_process()
+ [/codeblock]
+ [b]Note:[/b] Not supported for calling from threads. Instead of the stack frame, this will print the thread ID.
</description>
</method>
<method name="print_stack">
<return type="void" />
<description>
- Prints a stack track at code location, only works when running with debugger turned on.
+ Prints a stack trace at the current code location. Only works when running with debugger turned on.
Output in the console would look something like this:
[codeblock]
Frame 0 - res://test.gd:16 in function '_process'
[/codeblock]
+ [b]Note:[/b] Not supported for calling from threads. Instead of the stack trace, this will print the thread ID.
</description>
</method>
<method name="range" qualifiers="vararg">
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 42865242d3..e4d3ed118c 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -979,7 +979,7 @@ bool GDScript::_set(const StringName &p_name, const Variant &p_value) {
}
void GDScript::_get_property_list(List<PropertyInfo> *p_properties) const {
- p_properties->push_back(PropertyInfo(Variant::STRING, "script/source", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ p_properties->push_back(PropertyInfo(Variant::STRING, "script/source", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
}
void GDScript::_bind_methods() {
@@ -1257,6 +1257,8 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) {
call(member->setter, &val, 1, err);
if (err.error == Callable::CallError::CALL_OK) {
return true; //function exists, call was successful
+ } else {
+ return false;
}
} else {
if (member->data_type.has_type) {
@@ -2040,15 +2042,15 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
bool GDScriptLanguage::is_control_flow_keyword(String p_keyword) const {
return p_keyword == "break" ||
- p_keyword == "continue" ||
- p_keyword == "elif" ||
- p_keyword == "else" ||
- p_keyword == "if" ||
- p_keyword == "for" ||
- p_keyword == "match" ||
- p_keyword == "pass" ||
- p_keyword == "return" ||
- p_keyword == "while";
+ p_keyword == "continue" ||
+ p_keyword == "elif" ||
+ p_keyword == "else" ||
+ p_keyword == "if" ||
+ p_keyword == "for" ||
+ p_keyword == "match" ||
+ p_keyword == "pass" ||
+ p_keyword == "return" ||
+ p_keyword == "while";
}
bool GDScriptLanguage::handles_global_class_type(const String &p_type) const {
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 7ddb9b93b4..bde6783322 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -740,10 +740,24 @@ void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)()
#endif // TOOLS_ENABLED
if (member->identifier != nullptr) {
- // Enums may be unnamed.
- // TODO: Consider names in outer scope too, for constants and classes (and static functions?)
- if (current_class->members_indices.has(member->identifier->name)) {
- push_error(vformat(R"(%s "%s" has the same name as a previously declared %s.)", p_member_kind.capitalize(), member->identifier->name, current_class->get_member(member->identifier->name).get_type_name()), member->identifier);
+ if (!((String)member->identifier->name).is_empty()) { // Enums may be unnamed.
+ List<MethodInfo> gdscript_funcs;
+ GDScriptLanguage::get_singleton()->get_public_functions(&gdscript_funcs);
+ for (MethodInfo &info : gdscript_funcs) {
+ if (info.name == member->identifier->name) {
+ push_error(vformat(R"(%s "%s" has the same name as a built-in function.)", p_member_kind.capitalize(), member->identifier->name), member->identifier);
+ return;
+ }
+ }
+ if (current_class->members_indices.has(member->identifier->name)) {
+ push_error(vformat(R"(%s "%s" has the same name as a previously declared %s.)", p_member_kind.capitalize(), member->identifier->name, current_class->get_member(member->identifier->name).get_type_name()), member->identifier);
+ } else if (Variant::has_utility_function(member->identifier->name)) {
+ push_error(vformat(R"(%s "%s" has the same name as a built-in function.)", p_member_kind.capitalize(), member->identifier->name), member->identifier);
+ } else if (ClassDB::class_exists(member->identifier->name)) {
+ push_error(vformat(R"(%s "%s" has the same name as a global class.)", p_member_kind.capitalize(), member->identifier->name), member->identifier);
+ } else {
+ current_class->add_member(member);
+ }
} else {
current_class->add_member(member);
}
@@ -811,9 +825,27 @@ GDScriptParser::VariableNode *GDScriptParser::parse_variable(bool p_allow_proper
return nullptr;
}
+ GDScriptParser::IdentifierNode *identifier = parse_identifier();
+
+ List<MethodInfo> gdscript_funcs;
+ GDScriptLanguage::get_singleton()->get_public_functions(&gdscript_funcs);
+ for (MethodInfo &info : gdscript_funcs) {
+ if (info.name == identifier->name) {
+ push_error(vformat(R"(Local var "%s" has the same name as a built-in function.)", identifier->name), identifier);
+ return nullptr;
+ }
+ }
+ if (Variant::has_utility_function(identifier->name)) {
+ push_error(vformat(R"(Local var "%s" has the same name as a built-in function.)", identifier->name), identifier);
+ return nullptr;
+ } else if (ClassDB::class_exists(identifier->name)) {
+ push_error(vformat(R"(Local var "%s" has the same name as a global class.)", identifier->name), identifier);
+ return nullptr;
+ }
+
VariableNode *variable = alloc_node<VariableNode>();
- variable->identifier = parse_identifier();
- variable->export_info.name = variable->identifier->name;
+ variable->identifier = identifier;
+ variable->export_info.name = identifier->name;
if (match(GDScriptTokenizer::Token::COLON)) {
if (check(GDScriptTokenizer::Token::NEWLINE)) {
@@ -1066,8 +1098,26 @@ GDScriptParser::ParameterNode *GDScriptParser::parse_parameter() {
return nullptr;
}
+ GDScriptParser::IdentifierNode *identifier = parse_identifier();
+
+ List<MethodInfo> gdscript_funcs;
+ GDScriptLanguage::get_singleton()->get_public_functions(&gdscript_funcs);
+ for (MethodInfo &info : gdscript_funcs) {
+ if (info.name == identifier->name) {
+ push_error(vformat(R"(Parameter "%s" has the same name as a built-in function.)", identifier->name), identifier);
+ return nullptr;
+ }
+ }
+ if (Variant::has_utility_function(identifier->name)) {
+ push_error(vformat(R"(Parameter "%s" has the same name as a built-in function.)", identifier->name), identifier);
+ return nullptr;
+ } else if (ClassDB::class_exists(identifier->name)) {
+ push_error(vformat(R"(Parameter "%s" has the same name as a global class.)", identifier->name), identifier);
+ return nullptr;
+ }
+
ParameterNode *parameter = alloc_node<ParameterNode>();
- parameter->identifier = parse_identifier();
+ parameter->identifier = identifier;
if (match(GDScriptTokenizer::Token::COLON)) {
if (check((GDScriptTokenizer::Token::EQUAL))) {
@@ -1145,13 +1195,31 @@ GDScriptParser::EnumNode *GDScriptParser::parse_enum() {
HashMap<StringName, int> elements;
+ List<MethodInfo> gdscript_funcs;
+ GDScriptLanguage::get_singleton()->get_public_functions(&gdscript_funcs);
+
do {
if (check(GDScriptTokenizer::Token::BRACE_CLOSE)) {
break; // Allow trailing comma.
}
if (consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected identifier for enum key.)")) {
EnumNode::Value item;
- item.identifier = parse_identifier();
+ GDScriptParser::IdentifierNode *identifier = parse_identifier();
+
+ for (MethodInfo &info : gdscript_funcs) {
+ if (info.name == identifier->name) {
+ push_error(vformat(R"(Enum member "%s" has the same name as a built-in function.)", identifier->name), identifier);
+ return nullptr;
+ }
+ }
+ if (Variant::has_utility_function(identifier->name)) {
+ push_error(vformat(R"(Enum member "%s" has the same name as a built-in function.)", identifier->name), identifier);
+ return nullptr;
+ } else if (ClassDB::class_exists(identifier->name)) {
+ push_error(vformat(R"(Enum member "%s" has the same name as a global class.)", identifier->name), identifier);
+ return nullptr;
+ }
+ item.identifier = identifier;
item.parent_enum = enum_node;
item.line = previous.start_line;
item.leftmost_column = previous.leftmost_column;
@@ -2774,6 +2842,23 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_get_node(ExpressionNode *p
get_node->chain.push_back(identifier);
} while (match(GDScriptTokenizer::Token::SLASH));
return get_node;
+ } else if (match(GDScriptTokenizer::Token::SLASH)) {
+ GetNodeNode *get_node = alloc_node<GetNodeNode>();
+ IdentifierNode *identifier_root = alloc_node<IdentifierNode>();
+ get_node->chain.push_back(identifier_root);
+ int chain_position = 0;
+ do {
+ make_completion_context(COMPLETION_GET_NODE, get_node, chain_position++);
+ if (!current.is_node_name()) {
+ push_error(R"(Expect node path after "/".)");
+ return nullptr;
+ }
+ advance();
+ IdentifierNode *identifier = alloc_node<IdentifierNode>();
+ identifier->name = previous.get_identifier();
+ get_node->chain.push_back(identifier);
+ } while (match(GDScriptTokenizer::Token::SLASH));
+ return get_node;
} else {
push_error(R"(Expect node path as string or identifier after "$".)");
return nullptr;
@@ -3068,9 +3153,9 @@ void GDScriptParser::get_class_doc_comment(int p_line, String &p_brief, String &
} else {
/* Syntax:
- @tutorial ( The Title Here ) : https://the.url/
- ^ open ^ close ^ colon ^ url
- */
+ * @tutorial ( The Title Here ) : https://the.url/
+ * ^ open ^ close ^ colon ^ url
+ */
int open_bracket_pos = begin_scan, close_bracket_pos = 0;
while (open_bracket_pos < striped_line.length() && (striped_line[open_bracket_pos] == ' ' || striped_line[open_bracket_pos] == '\t')) {
open_bracket_pos++;
@@ -4533,7 +4618,7 @@ void GDScriptParser::TreePrinter::print_tree(const GDScriptParser &p_parser) {
}
print_class(p_parser.get_tree());
- print_line(printed);
+ print_line(String(printed));
}
#endif // DEBUG_ENABLED
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index d4a098811a..cd247d1d26 100644
--- a/modules/gdscript/gdscript_tokenizer.cpp
+++ b/modules/gdscript/gdscript_tokenizer.cpp
@@ -1064,7 +1064,8 @@ void GDScriptTokenizer::check_indent() {
// First time indenting, choose character now.
indent_char = current_indent_char;
} else if (current_indent_char != indent_char) {
- Token error = make_error(vformat("Used \"%s\" for indentation instead \"%s\" as used before in the file.", String(&current_indent_char, 1).c_escape(), String(&indent_char, 1).c_escape()));
+ Token error = make_error(vformat("Used %s character for indentation instead of %s as used before in the file.",
+ _get_indent_char_name(current_indent_char), _get_indent_char_name(indent_char)));
error.start_line = line;
error.start_column = 1;
error.leftmost_column = 1;
@@ -1114,6 +1115,12 @@ void GDScriptTokenizer::check_indent() {
}
}
+String GDScriptTokenizer::_get_indent_char_name(char32_t ch) {
+ ERR_FAIL_COND_V(ch != ' ' && ch != '\t', String(&ch, 1).c_escape());
+
+ return ch == ' ' ? "space" : "tab";
+}
+
void GDScriptTokenizer::_skip_whitespace() {
if (pending_indents != 0) {
// Still have some indent/dedent tokens to give.
diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h
index 84b82c07f0..b4ee11fd9a 100644
--- a/modules/gdscript/gdscript_tokenizer.h
+++ b/modules/gdscript/gdscript_tokenizer.h
@@ -233,6 +233,7 @@ private:
bool has_error() const { return !error_stack.is_empty(); }
Token pop_error();
char32_t _advance();
+ String _get_indent_char_name(char32_t ch);
void _skip_whitespace();
void check_indent();
diff --git a/modules/gdscript/gdscript_utility_functions.cpp b/modules/gdscript/gdscript_utility_functions.cpp
index f1b0079536..e997d3a51e 100644
--- a/modules/gdscript/gdscript_utility_functions.cpp
+++ b/modules/gdscript/gdscript_utility_functions.cpp
@@ -437,9 +437,13 @@ struct GDScriptUtilityFunctionsDefinitions {
str += p_args[i]->operator String();
}
- ScriptLanguage *script = GDScriptLanguage::get_singleton();
- if (script->debug_get_stack_level_count() > 0) {
- str += "\n At: " + script->debug_get_stack_level_source(0) + ":" + itos(script->debug_get_stack_level_line(0)) + ":" + script->debug_get_stack_level_function(0) + "()";
+ if (Thread::get_caller_id() == Thread::get_main_id()) {
+ ScriptLanguage *script = GDScriptLanguage::get_singleton();
+ if (script->debug_get_stack_level_count() > 0) {
+ str += "\n At: " + script->debug_get_stack_level_source(0) + ":" + itos(script->debug_get_stack_level_line(0)) + ":" + script->debug_get_stack_level_function(0) + "()";
+ }
+ } else {
+ str += "\n At: Cannot retrieve debug info outside the main thread. Thread ID: " + itos(Thread::get_caller_id());
}
print_line(str);
@@ -448,15 +452,24 @@ struct GDScriptUtilityFunctionsDefinitions {
static inline void print_stack(Variant *r_ret, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
VALIDATE_ARG_COUNT(0);
+ if (Thread::get_caller_id() != Thread::get_main_id()) {
+ print_line("Cannot retrieve debug info outside the main thread. Thread ID: " + itos(Thread::get_caller_id()));
+ return;
+ }
ScriptLanguage *script = GDScriptLanguage::get_singleton();
for (int i = 0; i < script->debug_get_stack_level_count(); i++) {
print_line("Frame " + itos(i) + " - " + script->debug_get_stack_level_source(i) + ":" + itos(script->debug_get_stack_level_line(i)) + " in function '" + script->debug_get_stack_level_function(i) + "'");
};
+ *r_ret = Variant();
}
static inline void get_stack(Variant *r_ret, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
VALIDATE_ARG_COUNT(0);
+ if (Thread::get_caller_id() != Thread::get_main_id()) {
+ *r_ret = Array();
+ return;
+ }
ScriptLanguage *script = GDScriptLanguage::get_singleton();
Array ret;
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp
index 40f03979c6..6dd8c3e0dd 100644
--- a/modules/gdscript/gdscript_vm.cpp
+++ b/modules/gdscript/gdscript_vm.cpp
@@ -1110,7 +1110,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
} else {
#ifdef DEBUG_ENABLED
err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) +
- "' to a variable of type '" + Variant::get_type_name(var_type) + "'.";
+ "' to a variable of type '" + Variant::get_type_name(var_type) + "'.";
OPCODE_BREAK;
}
} else {
@@ -1132,7 +1132,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
if (src->get_type() != Variant::ARRAY) {
#ifdef DEBUG_ENABLED
err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) +
- "' to a variable of type '" + +"'.";
+ "' to a variable of type '" + +"'.";
#endif
OPCODE_BREAK;
}
@@ -1158,14 +1158,14 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
GD_ERR_BREAK(!nc);
if (src->get_type() != Variant::OBJECT && src->get_type() != Variant::NIL) {
err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) +
- "' to a variable of type '" + nc->get_name() + "'.";
+ "' to a variable of type '" + nc->get_name() + "'.";
OPCODE_BREAK;
}
Object *src_obj = src->operator Object *();
if (src_obj && !ClassDB::is_parent_class(src_obj->get_class_name(), nc->get_name())) {
err_text = "Trying to assign value of type '" + src_obj->get_class_name() +
- "' to a variable of type '" + nc->get_name() + "'.";
+ "' to a variable of type '" + nc->get_name() + "'.";
OPCODE_BREAK;
}
#endif // DEBUG_ENABLED
@@ -1195,7 +1195,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
ScriptInstance *scr_inst = src->operator Object *()->get_script_instance();
if (!scr_inst) {
err_text = "Trying to assign value of type '" + src->operator Object *()->get_class_name() +
- "' to a variable of type '" + base_type->get_path().get_file() + "'.";
+ "' to a variable of type '" + base_type->get_path().get_file() + "'.";
OPCODE_BREAK;
}
@@ -1212,7 +1212,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
if (!valid) {
err_text = "Trying to assign value of type '" + src->operator Object *()->get_script_instance()->get_script()->get_path().get_file() +
- "' to a variable of type '" + base_type->get_path().get_file() + "'.";
+ "' to a variable of type '" + base_type->get_path().get_file() + "'.";
OPCODE_BREAK;
}
}
@@ -3309,7 +3309,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
int err_line = line;
if (err_text == "") {
- err_text = "Internal Script Error! - opcode #" + itos(last_opcode) + " (report please).";
+ err_text = "Internal script error! Opcode: " + itos(last_opcode) + " (please report).";
}
if (!GDScriptLanguage::get_singleton()->debug_break(err_text, false)) {
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp
index f4c0c4d9bb..80f4721e2d 100644
--- a/modules/gdscript/language_server/gdscript_extend_parser.cpp
+++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp
@@ -269,7 +269,7 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
if (j > 0) {
symbol.detail += ", ";
}
- symbol.detail += m.signal->parameters[i]->identifier->name;
+ symbol.detail += m.signal->parameters[j]->identifier->name;
}
symbol.detail += ")";
diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp
index 371e3de419..932bfb2caa 100644
--- a/modules/gdscript/language_server/gdscript_workspace.cpp
+++ b/modules/gdscript/language_server/gdscript_workspace.cpp
@@ -338,7 +338,9 @@ Error GDScriptWorkspace::initialize() {
}
Vector<DocData::MethodDoc> methods_signals;
+ methods_signals.append_array(class_data.constructors);
methods_signals.append_array(class_data.methods);
+ methods_signals.append_array(class_data.operators);
const int signal_start_idx = methods_signals.size();
methods_signals.append_array(class_data.signals);
diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp
index 3710a84a28..b12d1f5f3b 100644
--- a/modules/gdscript/language_server/lsp.hpp
+++ b/modules/gdscript/language_server/lsp.hpp
@@ -358,21 +358,21 @@ struct Command {
namespace TextDocumentSyncKind {
/**
- * Documents should not be synced at all.
- */
+ * Documents should not be synced at all.
+ */
static const int None = 0;
/**
- * Documents are synced by always sending the full content
- * of the document.
- */
+ * Documents are synced by always sending the full content
+ * of the document.
+ */
static const int Full = 1;
/**
- * Documents are synced by sending the full content on open.
- * After that only incremental updates to the document are
- * send.
- */
+ * Documents are synced by sending the full content on open.
+ * After that only incremental updates to the document are
+ * send.
+ */
static const int Incremental = 2;
}; // namespace TextDocumentSyncKind
@@ -667,20 +667,20 @@ struct TextDocumentContentChangeEvent {
// Use namespace instead of enumeration to follow the LSP specifications
namespace DiagnosticSeverity {
/**
- * Reports an error.
- */
+ * Reports an error.
+ */
static const int Error = 1;
/**
- * Reports a warning.
- */
+ * Reports a warning.
+ */
static const int Warning = 2;
/**
- * Reports an information.
- */
+ * Reports an information.
+ */
static const int Information = 3;
/**
- * Reports a hint.
- */
+ * Reports a hint.
+ */
static const int Hint = 4;
}; // namespace DiagnosticSeverity
@@ -871,18 +871,18 @@ static const int TypeParameter = 25;
*/
namespace InsertTextFormat {
/**
- * The primary text to be inserted is treated as a plain string.
- */
+ * The primary text to be inserted is treated as a plain string.
+ */
static const int PlainText = 1;
/**
- * The primary text to be inserted is treated as a snippet.
- *
- * A snippet can define tab stops and placeholders with `$1`, `$2`
- * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
- * the end of the snippet. Placeholders with equal identifiers are linked,
- * that is typing in one will update others too.
- */
+ * The primary text to be inserted is treated as a snippet.
+ *
+ * A snippet can define tab stops and placeholders with `$1`, `$2`
+ * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
+ * the end of the snippet. Placeholders with equal identifiers are linked,
+ * that is typing in one will update others too.
+ */
static const int Snippet = 2;
}; // namespace InsertTextFormat
@@ -1359,16 +1359,16 @@ struct NativeSymbolInspectParams {
*/
namespace FoldingRangeKind {
/**
- * Folding range for a comment
- */
+ * Folding range for a comment
+ */
static const String Comment = "comment";
/**
- * Folding range for a imports or includes
- */
+ * Folding range for a imports or includes
+ */
static const String Imports = "imports";
/**
- * Folding range for a region (e.g. `#region`)
- */
+ * Folding range for a region (e.g. `#region`)
+ */
static const String Region = "region";
} // namespace FoldingRangeKind
@@ -1419,20 +1419,20 @@ struct FoldingRange {
*/
namespace CompletionTriggerKind {
/**
- * Completion was triggered by typing an identifier (24x7 code
- * complete), manual invocation (e.g Ctrl+Space) or via API.
- */
+ * Completion was triggered by typing an identifier (24x7 code
+ * complete), manual invocation (e.g Ctrl+Space) or via API.
+ */
static const int Invoked = 1;
/**
- * Completion was triggered by a trigger character specified by
- * the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
- */
+ * Completion was triggered by a trigger character specified by
+ * the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
+ */
static const int TriggerCharacter = 2;
/**
- * Completion was re-triggered as the current completion list is incomplete.
- */
+ * Completion was re-triggered as the current completion list is incomplete.
+ */
static const int TriggerForIncompleteCompletions = 3;
} // namespace CompletionTriggerKind
@@ -1441,8 +1441,8 @@ static const int TriggerForIncompleteCompletions = 3;
*/
struct CompletionContext {
/**
- * How the completion was triggered.
- */
+ * How the completion was triggered.
+ */
int triggerKind = CompletionTriggerKind::TriggerCharacter;
/**
@@ -1906,7 +1906,7 @@ struct GodotNativeClassInfo {
struct GodotCapabilities {
/**
* Native class list
- */
+ */
List<GodotNativeClassInfo> native_classes;
Dictionary to_json() {
diff --git a/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.out b/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.out
index 6390de9788..31bed2dbc7 100644
--- a/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.out
+++ b/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.out
@@ -1,2 +1,2 @@
GDTEST_PARSER_ERROR
-Used "\t" for indentation instead " " as used before in the file.
+Used tab character for indentation instead of space as used before in the file.
diff --git a/modules/gdscript/tests/scripts/runtime/features/stringify.gd b/modules/gdscript/tests/scripts/runtime/features/stringify.gd
index de269b92b3..fead2df854 100644
--- a/modules/gdscript/tests/scripts/runtime/features/stringify.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/stringify.gd
@@ -17,7 +17,7 @@ func test():
print(Plane(1, 2, 3, 4))
print(Quaternion(1, 2, 3, 4))
print(AABB(Vector3.ZERO, Vector3.ONE))
- print(Basis(Vector3(0, 0, 0)))
+ print(Basis.from_euler(Vector3(0, 0, 0)))
print(Transform3D.IDENTITY)
print(Color(1, 2, 3, 4))