summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgnacio Etcheverry <ignalfonsore@gmail.com>2019-03-27 20:01:16 +0100
committerIgnacio Etcheverry <ignalfonsore@gmail.com>2019-03-29 23:40:31 +0100
commitc8aa85189a8736bb9723770b9409e6f9c00fc249 (patch)
treeaec78e008cd5e1e3e08968434ede66b2993ee517
parente45393482463ddb606bab4f2a78f4a5024cdce7a (diff)
EditorHelp, makerst: Improve enum ref resolving and constant ref support
Enum reference resolving will now search in the @GlobalScope if no class is specified and the enum cannot be resolved in the current class. Added support for constant references in EditorHelp, e.g.: [constant KEY_ENTER] or [constant Control.FOCUS_CLICK]. It supports enum constants (the enum name must not be included).
-rw-r--r--doc/classes/BaseButton.xml2
-rw-r--r--doc/classes/Input.xml14
-rw-r--r--doc/classes/InputEventJoypadButton.xml2
-rw-r--r--doc/classes/InputEventJoypadMotion.xml2
-rw-r--r--doc/classes/InputEventKey.xml2
-rw-r--r--doc/classes/InputEventMouse.xml2
-rw-r--r--doc/classes/InputEventMouseButton.xml2
-rw-r--r--doc/classes/LineEdit.xml4
-rwxr-xr-xdoc/tools/makerst.py28
-rw-r--r--editor/editor_help.cpp49
-rw-r--r--modules/mono/editor/bindings_generator.cpp95
-rw-r--r--modules/mono/editor/bindings_generator.h11
12 files changed, 179 insertions, 34 deletions
diff --git a/doc/classes/BaseButton.xml b/doc/classes/BaseButton.xml
index ff3e22ba26..39329e037a 100644
--- a/doc/classes/BaseButton.xml
+++ b/doc/classes/BaseButton.xml
@@ -48,7 +48,7 @@
</member>
<member name="button_mask" type="int" setter="set_button_mask" getter="get_button_mask">
Binary mask to choose which mouse buttons this button will respond to.
- To allow both left-click and right-click, set this to 3, because it's BUTTON_MASK_LEFT | BUTTON_MASK_RIGHT.
+ To allow both left-click and right-click, use [code]BUTTON_MASK_LEFT | BUTTON_MASK_RIGHT[/code].
</member>
<member name="disabled" type="bool" setter="set_disabled" getter="is_disabled">
If [code]true[/code], the button is in disabled state and can't be clicked or toggled.
diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml
index 29c60f902e..0be5b81a8e 100644
--- a/doc/classes/Input.xml
+++ b/doc/classes/Input.xml
@@ -90,7 +90,7 @@
<argument index="1" name="axis" type="int">
</argument>
<description>
- Returns the current value of the joypad axis at given index (see [code]JOY_*[/code] constants in [@GlobalScope])
+ Returns the current value of the joypad axis at given index (see [enum JoystickList]).
</description>
</method>
<method name="get_joy_axis_index_from_string">
@@ -108,7 +108,7 @@
<argument index="0" name="axis_index" type="int">
</argument>
<description>
- Receives a [code]JOY_AXIS_*[/code] Enum and returns its equivalent name as a string.
+ Receives a [enum JoystickList] axis and returns its equivalent name as a string.
</description>
</method>
<method name="get_joy_button_index_from_string">
@@ -126,7 +126,7 @@
<argument index="0" name="button_index" type="int">
</argument>
<description>
- Receives a [code]JOY_BUTTON_*[/code] Enum and returns its equivalent name as a string.
+ Receives a joy button from [enum JoystickList] and returns its equivalent name as a string.
</description>
</method>
<method name="get_joy_guid" qualifiers="const">
@@ -229,7 +229,7 @@
<argument index="1" name="button" type="int">
</argument>
<description>
- Returns [code]true[/code] if you are pressing the joypad button. (see [code]JOY_*[/code] constants in [@GlobalScope])
+ Returns [code]true[/code] if you are pressing the joypad button (see [enum JoystickList]).
</description>
</method>
<method name="is_joy_known">
@@ -238,7 +238,7 @@
<argument index="0" name="device" type="int">
</argument>
<description>
- Returns [code]true[/code] if the system knows the specified device. This means that it sets all button and axis indices exactly as defined in the [code]JOY_*[/code] constants (see [@GlobalScope]). Unknown joypads are not expected to match these constants, but you can still retrieve events from them.
+ Returns [code]true[/code] if the system knows the specified device. This means that it sets all button and axis indices exactly as defined in [enum JoystickList]. Unknown joypads are not expected to match these constants, but you can still retrieve events from them.
</description>
</method>
<method name="is_key_pressed" qualifiers="const">
@@ -247,7 +247,7 @@
<argument index="0" name="scancode" type="int">
</argument>
<description>
- Returns [code]true[/code] if you are pressing the key. You can pass [code]KEY_*[/code], which are pre-defined constants listed in [@GlobalScope].
+ Returns [code]true[/code] if you are pressing the key. You can pass a [enum KeyList] constant.
</description>
</method>
<method name="is_mouse_button_pressed" qualifiers="const">
@@ -256,7 +256,7 @@
<argument index="0" name="button" type="int">
</argument>
<description>
- Returns [code]true[/code] if you are pressing the mouse button. You can pass [code]BUTTON_*[/code], which are pre-defined constants listed in [@GlobalScope].
+ Returns [code]true[/code] if you are pressing the mouse button specified with [enum ButtonList].
</description>
</method>
<method name="joy_connection_changed">
diff --git a/doc/classes/InputEventJoypadButton.xml b/doc/classes/InputEventJoypadButton.xml
index 1875ea508a..0ccaa8e142 100644
--- a/doc/classes/InputEventJoypadButton.xml
+++ b/doc/classes/InputEventJoypadButton.xml
@@ -15,7 +15,7 @@
</methods>
<members>
<member name="button_index" type="int" setter="set_button_index" getter="get_button_index">
- Button identifier. One of the [code]JOY_BUTTON_*[/code] constants from [@GlobalScope].
+ Button identifier. One of the [enum JoystickList] button constants.
</member>
<member name="pressed" type="bool" setter="set_pressed" getter="is_pressed">
If [code]true[/code], the button's state is pressed. If [code]false[/code], the button's state is released.
diff --git a/doc/classes/InputEventJoypadMotion.xml b/doc/classes/InputEventJoypadMotion.xml
index 0c73f53158..132215884b 100644
--- a/doc/classes/InputEventJoypadMotion.xml
+++ b/doc/classes/InputEventJoypadMotion.xml
@@ -15,7 +15,7 @@
</methods>
<members>
<member name="axis" type="int" setter="set_axis" getter="get_axis">
- Axis identifier. Use one of the [code]JOY_AXIS_*[/code] constants in [@GlobalScope].
+ Axis identifier. Use one of the [enum JoystickList] axis constants.
</member>
<member name="axis_value" type="float" setter="set_axis_value" getter="get_axis_value">
Current position of the joystick on the given axis. The value ranges from [code]-1.0[/code] to [code]1.0[/code]. A value of [code]0[/code] means the axis is in its resting position.
diff --git a/doc/classes/InputEventKey.xml b/doc/classes/InputEventKey.xml
index 4d8a2f6242..236846aca2 100644
--- a/doc/classes/InputEventKey.xml
+++ b/doc/classes/InputEventKey.xml
@@ -28,7 +28,7 @@
If [code]true[/code], the key's state is pressed. If [code]false[/code], the key's state is released.
</member>
<member name="scancode" type="int" setter="set_scancode" getter="get_scancode">
- Key scancode, one of the [code]KEY_*[/code] constants in [@GlobalScope].
+ Key scancode, one of the [enum KeyList] constants.
</member>
<member name="unicode" type="int" setter="set_unicode" getter="get_unicode">
Key unicode identifier when relevant.
diff --git a/doc/classes/InputEventMouse.xml b/doc/classes/InputEventMouse.xml
index 27e8d17407..585b0a673d 100644
--- a/doc/classes/InputEventMouse.xml
+++ b/doc/classes/InputEventMouse.xml
@@ -15,7 +15,7 @@
</methods>
<members>
<member name="button_mask" type="int" setter="set_button_mask" getter="get_button_mask">
- Mouse button mask identifier, one of or a bitwise combination of the BUTTON_MASK_* constants in [@GlobalScope].
+ Mouse button mask identifier, one of or a bitwise combination of the [enum ButtonList] button masks.
</member>
<member name="global_position" type="Vector2" setter="set_global_position" getter="get_global_position">
Mouse position relative to the current [Viewport] when used in [method Control._gui_input], otherwise is at 0,0.
diff --git a/doc/classes/InputEventMouseButton.xml b/doc/classes/InputEventMouseButton.xml
index 8603a4f673..fde1fcb70a 100644
--- a/doc/classes/InputEventMouseButton.xml
+++ b/doc/classes/InputEventMouseButton.xml
@@ -15,7 +15,7 @@
</methods>
<members>
<member name="button_index" type="int" setter="set_button_index" getter="get_button_index">
- Mouse button identifier, one of the BUTTON_* or BUTTON_WHEEL_* constants in [@GlobalScope].
+ Mouse button identifier, one of the [enum ButtonList] button or button wheel constants.
</member>
<member name="doubleclick" type="bool" setter="set_doubleclick" getter="is_doubleclick">
If [code]true[/code], the mouse button's state is a double-click.
diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml
index 1e1ffd71b5..fd3fda19a5 100644
--- a/doc/classes/LineEdit.xml
+++ b/doc/classes/LineEdit.xml
@@ -101,7 +101,7 @@
If [code]true[/code], the [code]LineEdit[/code] width will increase to stay longer than the [member text]. It will [b]not[/b] compress if the [member text] is shortened.
</member>
<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" enum="Control.FocusMode">
- Defines how the [code]LineEdit[/code] can grab focus (Keyboard and mouse, only keyboard, or none). See [code]enum FocusMode[/code] in [Control] for details.
+ Defines how the [code]LineEdit[/code] can grab focus (Keyboard and mouse, only keyboard, or none). See [enum Control.FocusMode] in [Control] for details.
</member>
<member name="max_length" type="int" setter="set_max_length" getter="get_max_length">
Maximum amount of characters that can be entered inside the [code]LineEdit[/code]. If [code]0[/code], there is no limit.
@@ -134,7 +134,7 @@
<argument index="0" name="new_text" type="String">
</argument>
<description>
- Emitted when the user presses [code]KEY_ENTER[/code] on the [code]LineEdit[/code].
+ Emitted when the user presses [constant KEY_ENTER] on the [code]LineEdit[/code].
</description>
</signal>
</signals>
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index 40dde48432..6d9cd7140a 100755
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -757,14 +757,25 @@ def rstize_text(text, state): # type: (str, State) -> str
elif cmd.startswith("constant"):
found = False
- if method_param in class_def.constants:
- found = True
- else:
- for enum in class_def.enums.values():
- if method_param in enum.values:
- found = True
- break
+ # Search in the current class
+ search_class_defs = [class_def]
+
+ if param.find('.') == -1:
+ # Also search in @GlobalScope as a last resort if no class was specified
+ search_class_defs.append(state.classes["@GlobalScope"])
+
+ for search_class_def in search_class_defs:
+ if method_param in search_class_def.constants:
+ class_param = search_class_def.name
+ found = True
+
+ else:
+ for enum in search_class_def.enums.values():
+ if method_param in enum.values:
+ class_param = search_class_def.name
+ found = True
+ break
if not found:
print_error("Unresolved constant '{}', file: {}".format(param, state.current_class), state)
@@ -917,6 +928,9 @@ def make_enum(t, state): # type: (str, State) -> str
if c in state.classes and e not in state.classes[c].enums:
c = "@GlobalScope"
+ if not c in state.classes and c.startswith("_"):
+ c = c[1:] # Remove the underscore prefix
+
if c in state.classes and e in state.classes[c].enums:
return ":ref:`{0}<enum_{1}_{0}>`".format(e, c)
print_error("Unresolved enum '{}', file: {}".format(t, state.current_class), state)
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index e0acc5cd70..a781a56eed 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -96,8 +96,8 @@ void EditorHelp::_class_desc_select(const String &p_select) {
emit_signal("go_to_help", "class_name:" + p_select.substr(1, p_select.length()));
return;
} else if (p_select.begins_with("@")) {
- String tag = p_select.substr(1, 6);
- String link = p_select.substr(7, p_select.length());
+ String tag = p_select.substr(1, 8).rstrip(" ");
+ String link = p_select.substr(9, p_select.length());
String topic;
Map<String, int> *table = NULL;
@@ -108,24 +108,50 @@ void EditorHelp::_class_desc_select(const String &p_select) {
} else if (tag == "member") {
topic = "class_property";
table = &this->property_line;
- } else if (tag == "enum ") {
+ } else if (tag == "enum") {
topic = "class_enum";
table = &this->enum_line;
} else if (tag == "signal") {
topic = "class_signal";
table = &this->signal_line;
+ } else if (tag == "constant") {
+ topic = "class_constant";
+ table = &this->constant_line;
} else {
return;
}
if (link.find(".") != -1) {
-
emit_signal("go_to_help", topic + ":" + link.get_slice(".", 0) + ":" + link.get_slice(".", 1));
} else {
-
- if (!table->has(link))
- return;
- class_desc->scroll_to_line((*table)[link]);
+ if (table->has(link)) {
+ // Found in the current page
+ class_desc->scroll_to_line((*table)[link]);
+ } else {
+ if (topic == "class_enum") {
+ // Try to find the enum in @GlobalScope
+ const DocData::ClassDoc &cd = doc->class_list["@GlobalScope"];
+
+ for (int i = 0; i < cd.constants.size(); i++) {
+ if (cd.constants[i].enumeration == link) {
+ // Found in @GlobalScope
+ emit_signal("go_to_help", topic + ":@GlobalScope:" + link);
+ break;
+ }
+ }
+ } else if (topic == "class_constant") {
+ // Try to find the constant in @GlobalScope
+ const DocData::ClassDoc &cd = doc->class_list["@GlobalScope"];
+
+ for (int i = 0; i < cd.constants.size(); i++) {
+ if (cd.constants[i].name == link) {
+ // Found in @GlobalScope
+ emit_signal("go_to_help", topic + ":@GlobalScope:" + link);
+ break;
+ }
+ }
+ }
+ }
}
} else if (p_select.begins_with("http")) {
OS::get_singleton()->shell_open(p_select);
@@ -733,6 +759,9 @@ void EditorHelp::_update_doc() {
if (cd.name == "@GlobalScope")
enumValuesContainer[enum_list[i].name] = enumStartingLine;
+ // Add the enum constant line to the constant_line map so we can locate it as a constant
+ constant_line[enum_list[i].name] = class_desc->get_line_count() - 2;
+
class_desc->push_font(doc_code_font);
class_desc->push_color(headline_color);
_add_text(enum_list[i].name);
@@ -1160,10 +1189,10 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
p_rt->add_text("[");
pos = brk_pos + 1;
- } else if (tag.begins_with("method ") || tag.begins_with("member ") || tag.begins_with("signal ") || tag.begins_with("enum ")) {
+ } else if (tag.begins_with("method ") || tag.begins_with("member ") || tag.begins_with("signal ") || tag.begins_with("enum ") || tag.begins_with("constant ")) {
String link_target = tag.substr(tag.find(" ") + 1, tag.length());
- String link_tag = tag.substr(0, tag.find(" ")).rpad(6);
+ String link_tag = tag.substr(0, tag.find(" ")).rpad(8);
p_rt->push_color(link_color);
p_rt->push_meta("@" + link_tag + link_target);
p_rt->add_text(link_target + (tag.begins_with("method ") ? "()" : ""));
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index a6b5c1535b..3549d34236 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -277,7 +277,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
} else if (code_tag) {
xml_output.append("[");
pos = brk_pos + 1;
- } else if (tag.begins_with("method ") || tag.begins_with("member ") || tag.begins_with("signal ") || tag.begins_with("enum ")) {
+ } else if (tag.begins_with("method ") || tag.begins_with("member ") || tag.begins_with("signal ") || tag.begins_with("enum ") || tag.begins_with("constant ")) {
String link_target = tag.substr(tag.find(" ") + 1, tag.length());
String link_tag = tag.substr(0, tag.find(" "));
@@ -386,6 +386,97 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
xml_output.append(link_target);
xml_output.append("</c>");
}
+ } else if (link_tag == "const") {
+ if (!target_itype || !target_itype->is_object_type) {
+ if (OS::get_singleton()->is_stdout_verbose()) {
+ if (target_itype) {
+ OS::get_singleton()->print("Cannot resolve constant reference for non-Godot.Object type in documentation: %s\n", link_target.utf8().get_data());
+ } else {
+ OS::get_singleton()->print("Cannot resolve type from constant reference in documentation: %s\n", link_target.utf8().get_data());
+ }
+ }
+
+ // TODO Map what we can
+ xml_output.append("<c>");
+ xml_output.append(link_target);
+ xml_output.append("</c>");
+ } else if (!target_itype && target_cname == name_cache.type_at_GlobalScope) {
+ String target_name = (String)target_cname;
+
+ // Try to find as a global constant
+ const ConstantInterface *target_iconst = find_constant_by_name(target_name, global_constants);
+
+ if (target_iconst) {
+ // Found global constant
+ xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "." BINDINGS_GLOBAL_SCOPE_CLASS ".");
+ xml_output.append(target_iconst->proxy_name);
+ xml_output.append("\"/>");
+ } else {
+ // Try to find as global enum constant
+ const EnumInterface *target_ienum = NULL;
+
+ for (const List<EnumInterface>::Element *E = global_enums.front(); E; E = E->next()) {
+ target_ienum = &E->get();
+ target_iconst = find_constant_by_name(target_name, target_ienum->constants);
+ if (target_iconst)
+ break;
+ }
+
+ if (target_iconst) {
+ xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
+ xml_output.append(target_ienum->cname);
+ xml_output.append(".");
+ xml_output.append(target_iconst->proxy_name);
+ xml_output.append("\"/>");
+ } else {
+ ERR_PRINTS("Cannot resolve global constant reference in documentation: " + link_target);
+
+ xml_output.append("<c>");
+ xml_output.append(link_target);
+ xml_output.append("</c>");
+ }
+ }
+ } else {
+ String target_name = (String)target_cname;
+
+ // Try to find the constant in the current class
+ const ConstantInterface *target_iconst = find_constant_by_name(target_name, target_itype->constants);
+
+ if (target_iconst) {
+ // Found constant in current class
+ xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
+ xml_output.append(target_itype->proxy_name);
+ xml_output.append(".");
+ xml_output.append(target_iconst->proxy_name);
+ xml_output.append("\"/>");
+ } else {
+ // Try to find as enum constant in the current class
+ const EnumInterface *target_ienum = NULL;
+
+ for (const List<EnumInterface>::Element *E = target_itype->enums.front(); E; E = E->next()) {
+ target_ienum = &E->get();
+ target_iconst = find_constant_by_name(target_name, target_ienum->constants);
+ if (target_iconst)
+ break;
+ }
+
+ if (target_iconst) {
+ xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".");
+ xml_output.append(target_itype->proxy_name);
+ xml_output.append(".");
+ xml_output.append(target_ienum->cname);
+ xml_output.append(".");
+ xml_output.append(target_iconst->proxy_name);
+ xml_output.append("\"/>");
+ } else {
+ ERR_PRINTS("Cannot resolve constant reference in documentation: " + link_target);
+
+ xml_output.append("<c>");
+ xml_output.append(link_target);
+ xml_output.append("</c>");
+ }
+ }
+ }
}
pos = brk_end + 1;
@@ -414,7 +505,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
} else if (tag == "Nil") {
xml_output.append("<see langword=\"null\"/>");
} else if (tag.begins_with("@")) {
- // @Global Scope, @GDScript, etc
+ // @GlobalScope, @GDScript, etc
xml_output.append("<c>");
xml_output.append(tag);
xml_output.append("</c>");
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index 7eaebeabbd..42071f9c0d 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -497,6 +497,7 @@ class BindingsGenerator {
StringName type_Object;
StringName type_Reference;
StringName type_String;
+ StringName type_at_GlobalScope;
StringName enum_Error;
NameCache() {
@@ -509,6 +510,7 @@ class BindingsGenerator {
type_Object = StaticCString::create("Object");
type_Reference = StaticCString::create("Reference");
type_String = StaticCString::create("String");
+ type_at_GlobalScope = StaticCString::create("@GlobalScope");
enum_Error = StaticCString::create("Error");
}
@@ -527,6 +529,15 @@ class BindingsGenerator {
return NULL;
}
+ const ConstantInterface *find_constant_by_name(const String &p_name, const List<ConstantInterface> &p_constants) const {
+ for (const List<ConstantInterface>::Element *E = p_constants.front(); E; E = E->next()) {
+ if (E->get().name == p_name)
+ return &E->get();
+ }
+
+ return NULL;
+ }
+
inline String get_unique_sig(const TypeInterface &p_type) {
if (p_type.is_reference)
return "Ref";