summaryrefslogtreecommitdiffstats
path: root/modules/gdscript/editor
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/editor')
-rw-r--r--modules/gdscript/editor/gdscript_docgen.cpp126
-rw-r--r--modules/gdscript/editor/gdscript_docgen.h10
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp22
-rw-r--r--modules/gdscript/editor/script_templates/CharacterBody2D/basic_movement.gd2
-rw-r--r--modules/gdscript/editor/script_templates/CharacterBody3D/basic_movement.gd2
-rw-r--r--modules/gdscript/editor/script_templates/EditorPlugin/plugin.gd3
-rw-r--r--modules/gdscript/editor/script_templates/EditorScenePostImport/basic_import_script.gd3
-rw-r--r--modules/gdscript/editor/script_templates/EditorScenePostImport/no_comments.gd3
-rw-r--r--modules/gdscript/editor/script_templates/EditorScript/basic_editor_script.gd3
-rw-r--r--modules/gdscript/editor/script_templates/RichTextEffect/default.gd7
-rw-r--r--modules/gdscript/editor/script_templates/VisualShaderNodeCustom/basic.gd9
11 files changed, 158 insertions, 32 deletions
diff --git a/modules/gdscript/editor/gdscript_docgen.cpp b/modules/gdscript/editor/gdscript_docgen.cpp
index 0b440274c0..cffd661261 100644
--- a/modules/gdscript/editor/gdscript_docgen.cpp
+++ b/modules/gdscript/editor/gdscript_docgen.cpp
@@ -32,14 +32,11 @@
#include "../gdscript.h"
-using GDP = GDScriptParser;
-using GDType = GDP::DataType;
-
-static String _get_script_path(const String &p_path) {
+String GDScriptDocGen::_get_script_path(const String &p_path) {
return p_path.trim_prefix("res://").quote();
}
-static String _get_class_name(const GDP::ClassNode &p_class) {
+String GDScriptDocGen::_get_class_name(const GDP::ClassNode &p_class) {
const GDP::ClassNode *curr_class = &p_class;
if (!curr_class->identifier) { // All inner classes have an identifier, so this is the outer class.
return _get_script_path(curr_class->fqcn);
@@ -56,7 +53,7 @@ static String _get_class_name(const GDP::ClassNode &p_class) {
return full_name;
}
-static void _doctype_from_gdtype(const GDType &p_gdtype, String &r_type, String &r_enum, bool p_is_return = false) {
+void GDScriptDocGen::_doctype_from_gdtype(const GDType &p_gdtype, String &r_type, String &r_enum, bool p_is_return) {
if (!p_gdtype.is_hard_type()) {
r_type = "Variant";
return;
@@ -82,9 +79,18 @@ static void _doctype_from_gdtype(const GDType &p_gdtype, String &r_type, String
r_type = Variant::get_type_name(p_gdtype.builtin_type);
return;
case GDType::NATIVE:
+ if (p_gdtype.is_meta_type) {
+ //r_type = GDScriptNativeClass::get_class_static();
+ r_type = "Object"; // "GDScriptNativeClass" refers to a blank page.
+ return;
+ }
r_type = p_gdtype.native_type;
return;
case GDType::SCRIPT:
+ if (p_gdtype.is_meta_type) {
+ r_type = p_gdtype.script_type.is_valid() ? p_gdtype.script_type->get_class() : Script::get_class_static();
+ return;
+ }
if (p_gdtype.script_type.is_valid()) {
if (p_gdtype.script_type->get_global_name() != StringName()) {
r_type = p_gdtype.script_type->get_global_name();
@@ -102,9 +108,17 @@ static void _doctype_from_gdtype(const GDType &p_gdtype, String &r_type, String
r_type = "Object";
return;
case GDType::CLASS:
+ if (p_gdtype.is_meta_type) {
+ r_type = GDScript::get_class_static();
+ return;
+ }
r_type = _get_class_name(*p_gdtype.class_type);
return;
case GDType::ENUM:
+ if (p_gdtype.is_meta_type) {
+ r_type = "Dictionary";
+ return;
+ }
r_type = "int";
r_enum = String(p_gdtype.native_type).replace("::", ".");
if (r_enum.begins_with("res://")) {
@@ -123,6 +137,90 @@ static void _doctype_from_gdtype(const GDType &p_gdtype, String &r_type, String
}
}
+String GDScriptDocGen::_docvalue_from_variant(const Variant &p_variant, int p_recursion_level) {
+ constexpr int MAX_RECURSION_LEVEL = 2;
+
+ switch (p_variant.get_type()) {
+ case Variant::STRING:
+ return String(p_variant).c_escape().quote();
+ case Variant::OBJECT:
+ return "<Object>";
+ case Variant::DICTIONARY: {
+ const Dictionary dict = p_variant;
+
+ if (dict.is_empty()) {
+ return "{}";
+ }
+
+ if (p_recursion_level > MAX_RECURSION_LEVEL) {
+ return "{...}";
+ }
+
+ List<Variant> keys;
+ dict.get_key_list(&keys);
+ keys.sort();
+
+ String data;
+ for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
+ if (E->prev()) {
+ data += ", ";
+ }
+ data += _docvalue_from_variant(E->get(), p_recursion_level + 1) + ": " + _docvalue_from_variant(dict[E->get()], p_recursion_level + 1);
+ }
+
+ return "{" + data + "}";
+ } break;
+ case Variant::ARRAY: {
+ const Array array = p_variant;
+ String result;
+
+ if (array.get_typed_builtin() != Variant::NIL) {
+ result += "Array[";
+
+ Ref<Script> script = array.get_typed_script();
+ if (script.is_valid()) {
+ if (script->get_global_name() != StringName()) {
+ result += script->get_global_name();
+ } else if (!script->get_path().get_file().is_empty()) {
+ result += script->get_path().get_file();
+ } else {
+ result += array.get_typed_class_name();
+ }
+ } else if (array.get_typed_class_name() != StringName()) {
+ result += array.get_typed_class_name();
+ } else {
+ result += Variant::get_type_name((Variant::Type)array.get_typed_builtin());
+ }
+
+ result += "](";
+ }
+
+ if (array.is_empty()) {
+ result += "[]";
+ } else if (p_recursion_level > MAX_RECURSION_LEVEL) {
+ result += "[...]";
+ } else {
+ result += "[";
+ for (int i = 0; i < array.size(); i++) {
+ if (i > 0) {
+ result += ", ";
+ }
+ result += _docvalue_from_variant(array[i], p_recursion_level + 1);
+ }
+ result += "]";
+ }
+
+ if (array.get_typed_builtin() != Variant::NIL) {
+ result += ")";
+ }
+
+ return result;
+ } break;
+ default:
+ return p_variant.get_construct_string();
+ }
+}
+
void GDScriptDocGen::generate_docs(GDScript *p_script, const GDP::ClassNode *p_class) {
p_script->_clear_doc();
@@ -183,7 +281,10 @@ void GDScriptDocGen::generate_docs(GDScript *p_script, const GDP::ClassNode *p_c
p_script->member_lines[const_name] = m_const->start_line;
DocData::ConstantDoc const_doc;
- DocData::constant_doc_from_variant(const_doc, const_name, m_const->initializer->reduced_value, m_const->doc_data.description);
+ const_doc.name = const_name;
+ const_doc.value = _docvalue_from_variant(m_const->initializer->reduced_value);
+ const_doc.is_value_valid = true;
+ const_doc.description = m_const->doc_data.description;
const_doc.is_deprecated = m_const->doc_data.is_deprecated;
const_doc.is_experimental = m_const->doc_data.is_experimental;
doc.constants.push_back(const_doc);
@@ -217,7 +318,7 @@ void GDScriptDocGen::generate_docs(GDScript *p_script, const GDP::ClassNode *p_c
_doctype_from_gdtype(p->get_datatype(), arg_doc.type, arg_doc.enumeration);
if (p->initializer != nullptr) {
if (p->initializer->is_constant) {
- arg_doc.default_value = p->initializer->reduced_value.get_construct_string().replace("\n", "\\n");
+ arg_doc.default_value = _docvalue_from_variant(p->initializer->reduced_value);
} else {
arg_doc.default_value = "<unknown>";
}
@@ -286,7 +387,7 @@ void GDScriptDocGen::generate_docs(GDScript *p_script, const GDP::ClassNode *p_c
if (m_var->initializer) {
if (m_var->initializer->is_constant) {
- prop_doc.default_value = m_var->initializer->reduced_value.get_construct_string().replace("\n", "\\n");
+ prop_doc.default_value = _docvalue_from_variant(m_var->initializer->reduced_value);
} else {
prop_doc.default_value = "<unknown>";
}
@@ -312,7 +413,7 @@ void GDScriptDocGen::generate_docs(GDScript *p_script, const GDP::ClassNode *p_c
for (const GDP::EnumNode::Value &val : m_enum->values) {
DocData::ConstantDoc const_doc;
const_doc.name = val.identifier->name;
- const_doc.value = String(Variant(val.value));
+ const_doc.value = _docvalue_from_variant(val.value);
const_doc.is_value_valid = true;
const_doc.enumeration = name;
const_doc.description = val.doc_data.description;
@@ -331,8 +432,11 @@ void GDScriptDocGen::generate_docs(GDScript *p_script, const GDP::ClassNode *p_c
p_script->member_lines[name] = m_enum_val.identifier->start_line;
DocData::ConstantDoc const_doc;
- DocData::constant_doc_from_variant(const_doc, name, m_enum_val.value, m_enum_val.doc_data.description);
+ const_doc.name = name;
+ const_doc.value = _docvalue_from_variant(m_enum_val.value);
+ const_doc.is_value_valid = true;
const_doc.enumeration = "@unnamed_enums";
+ const_doc.description = m_enum_val.doc_data.description;
const_doc.is_deprecated = m_enum_val.doc_data.is_deprecated;
const_doc.is_experimental = m_enum_val.doc_data.is_experimental;
doc.constants.push_back(const_doc);
diff --git a/modules/gdscript/editor/gdscript_docgen.h b/modules/gdscript/editor/gdscript_docgen.h
index 3357fb680c..a326c02c5f 100644
--- a/modules/gdscript/editor/gdscript_docgen.h
+++ b/modules/gdscript/editor/gdscript_docgen.h
@@ -36,8 +36,16 @@
#include "core/doc_data.h"
class GDScriptDocGen {
+ using GDP = GDScriptParser;
+ using GDType = GDP::DataType;
+
+ static String _get_script_path(const String &p_path);
+ static String _get_class_name(const GDP::ClassNode &p_class);
+ static void _doctype_from_gdtype(const GDType &p_gdtype, String &r_type, String &r_enum, bool p_is_return = false);
+ static String _docvalue_from_variant(const Variant &p_variant, int p_recursion_level = 1);
+
public:
- static void generate_docs(GDScript *p_script, const GDScriptParser::ClassNode *p_class);
+ static void generate_docs(GDScript *p_script, const GDP::ClassNode *p_class);
};
#endif // GDSCRIPT_DOCGEN_H
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index e621e987f6..45ac142eaa 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -444,7 +444,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
if (str[k] == '(') {
in_function_name = true;
- } else if (prev_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::VAR)) {
+ } else if (prev_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::VAR) || prev_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FOR)) {
in_variable_declaration = true;
}
@@ -494,7 +494,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
in_function_arg_dicts = 0;
}
- if (expect_type && (prev_is_char || str[j] == '=') && str[j] != '[') {
+ if (expect_type && (prev_is_char || str[j] == '=') && str[j] != '[' && str[j] != '.') {
expect_type = false;
}
@@ -576,16 +576,11 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
} else if (in_keyword) {
next_type = KEYWORD;
color = keyword_color;
- } else if (in_member_variable) {
- next_type = MEMBER;
- color = member_color;
} else if (in_signal_declaration) {
next_type = SIGNAL;
-
color = member_color;
} else if (in_function_name) {
next_type = FUNCTION;
-
if (!in_lambda && prev_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) {
color = function_definition_color;
} else {
@@ -600,6 +595,9 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
} else if (expect_type) {
next_type = TYPE;
color = type_color;
+ } else if (in_member_variable) {
+ next_type = MEMBER;
+ color = member_color;
} else {
next_type = IDENTIFIER;
}
@@ -697,6 +695,12 @@ void GDScriptSyntaxHighlighter::_update_cache() {
for (const String &E : core_types) {
class_names[StringName(E)] = basetype_color;
}
+ class_names[SNAME("Variant")] = basetype_color;
+ class_names[SNAME("void")] = basetype_color;
+ // `get_core_type_words()` doesn't return primitive types.
+ class_names[SNAME("bool")] = basetype_color;
+ class_names[SNAME("int")] = basetype_color;
+ class_names[SNAME("float")] = basetype_color;
/* Reserved words. */
const Color keyword_color = EDITOR_GET("text_editor/theme/highlighting/keyword_color");
@@ -711,6 +715,10 @@ void GDScriptSyntaxHighlighter::_update_cache() {
}
}
+ // Highlight `set` and `get` as "keywords" with the function color to avoid conflicts with method calls.
+ reserved_keywords[SNAME("set")] = function_color;
+ reserved_keywords[SNAME("get")] = function_color;
+
/* Global functions. */
List<StringName> global_function_list;
GDScriptUtilityFunctions::get_function_list(&global_function_list);
diff --git a/modules/gdscript/editor/script_templates/CharacterBody2D/basic_movement.gd b/modules/gdscript/editor/script_templates/CharacterBody2D/basic_movement.gd
index b8fc8c75dc..28ab080dd2 100644
--- a/modules/gdscript/editor/script_templates/CharacterBody2D/basic_movement.gd
+++ b/modules/gdscript/editor/script_templates/CharacterBody2D/basic_movement.gd
@@ -15,7 +15,7 @@ func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity.y += gravity * delta
- # Handle Jump.
+ # Handle jump.
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = JUMP_VELOCITY
diff --git a/modules/gdscript/editor/script_templates/CharacterBody3D/basic_movement.gd b/modules/gdscript/editor/script_templates/CharacterBody3D/basic_movement.gd
index 53bc606c9a..9b0e4be4ed 100644
--- a/modules/gdscript/editor/script_templates/CharacterBody3D/basic_movement.gd
+++ b/modules/gdscript/editor/script_templates/CharacterBody3D/basic_movement.gd
@@ -15,7 +15,7 @@ func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity.y -= gravity * delta
- # Handle Jump.
+ # Handle jump.
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = JUMP_VELOCITY
diff --git a/modules/gdscript/editor/script_templates/EditorPlugin/plugin.gd b/modules/gdscript/editor/script_templates/EditorPlugin/plugin.gd
index b27b3e5655..547943b910 100644
--- a/modules/gdscript/editor/script_templates/EditorPlugin/plugin.gd
+++ b/modules/gdscript/editor/script_templates/EditorPlugin/plugin.gd
@@ -1,6 +1,7 @@
# meta-description: Basic plugin template
+
@tool
-extends EditorPlugin
+extends _BASE_
func _enter_tree() -> void:
diff --git a/modules/gdscript/editor/script_templates/EditorScenePostImport/basic_import_script.gd b/modules/gdscript/editor/script_templates/EditorScenePostImport/basic_import_script.gd
index 556afe994b..6772ea4a26 100644
--- a/modules/gdscript/editor/script_templates/EditorScenePostImport/basic_import_script.gd
+++ b/modules/gdscript/editor/script_templates/EditorScenePostImport/basic_import_script.gd
@@ -1,6 +1,7 @@
# meta-description: Basic import script template
+
@tool
-extends EditorScenePostImport
+extends _BASE_
# Called by the editor when a scene has this script set as the import script in the import tab.
diff --git a/modules/gdscript/editor/script_templates/EditorScenePostImport/no_comments.gd b/modules/gdscript/editor/script_templates/EditorScenePostImport/no_comments.gd
index 875afb4fc0..e8f907f43b 100644
--- a/modules/gdscript/editor/script_templates/EditorScenePostImport/no_comments.gd
+++ b/modules/gdscript/editor/script_templates/EditorScenePostImport/no_comments.gd
@@ -1,6 +1,7 @@
# meta-description: Basic import script template (no comments)
+
@tool
-extends EditorScenePostImport
+extends _BASE_
func _post_import(scene: Node) -> Object:
diff --git a/modules/gdscript/editor/script_templates/EditorScript/basic_editor_script.gd b/modules/gdscript/editor/script_templates/EditorScript/basic_editor_script.gd
index fdb8550d43..fee7353f0d 100644
--- a/modules/gdscript/editor/script_templates/EditorScript/basic_editor_script.gd
+++ b/modules/gdscript/editor/script_templates/EditorScript/basic_editor_script.gd
@@ -1,6 +1,7 @@
# meta-description: Basic editor script template
+
@tool
-extends EditorScript
+extends _BASE_
# Called when the script is executed (using File -> Run in Script Editor).
diff --git a/modules/gdscript/editor/script_templates/RichTextEffect/default.gd b/modules/gdscript/editor/script_templates/RichTextEffect/default.gd
index c79eeb91ec..c7a999ef24 100644
--- a/modules/gdscript/editor/script_templates/RichTextEffect/default.gd
+++ b/modules/gdscript/editor/script_templates/RichTextEffect/default.gd
@@ -1,15 +1,16 @@
# meta-description: Base template for rich text effects
@tool
-class_name _CLASS_
+# Having a class name is handy for picking the effect in the Inspector.
+class_name RichText_CLASS_
extends _BASE_
# To use this effect:
# - Enable BBCode on a RichTextLabel.
# - Register this effect on the label.
-# - Use [_CLASS_ param=2.0]hello[/_CLASS_] in text.
-var bbcode := "_CLASS_"
+# - Use [_CLASS_SNAKE_CASE_ param=2.0]hello[/_CLASS_SNAKE_CASE_] in text.
+var bbcode := "_CLASS_SNAKE_CASE_"
func _process_custom_fx(char_fx: CharFXTransform) -> bool:
diff --git a/modules/gdscript/editor/script_templates/VisualShaderNodeCustom/basic.gd b/modules/gdscript/editor/script_templates/VisualShaderNodeCustom/basic.gd
index 283a95d3b4..458e22dae4 100644
--- a/modules/gdscript/editor/script_templates/VisualShaderNodeCustom/basic.gd
+++ b/modules/gdscript/editor/script_templates/VisualShaderNodeCustom/basic.gd
@@ -1,6 +1,7 @@
# meta-description: Visual shader's node plugin template
@tool
+# Having a class name is required for a custom node.
class_name VisualShaderNode_CLASS_
extends _BASE_
@@ -17,7 +18,7 @@ func _get_description() -> String:
return ""
-func _get_return_icon_type() -> int:
+func _get_return_icon_type() -> PortType:
return PORT_TYPE_SCALAR
@@ -29,7 +30,7 @@ func _get_input_port_name(port: int) -> String:
return ""
-func _get_input_port_type(port: int) -> int:
+func _get_input_port_type(port: int) -> PortType:
return PORT_TYPE_SCALAR
@@ -41,10 +42,10 @@ func _get_output_port_name(port: int) -> String:
return "result"
-func _get_output_port_type(port: int) -> int:
+func _get_output_port_type(port: int) -> PortType:
return PORT_TYPE_SCALAR
func _get_code(input_vars: Array[String], output_vars: Array[String],
- mode: int, type: int) -> String:
+ mode: Shader.Mode, type: VisualShader.Type) -> String:
return output_vars[0] + " = 0.0;"