diff options
author | Ignacio Etcheverry <ignalfonsore@gmail.com> | 2019-03-27 20:01:16 +0100 |
---|---|---|
committer | Ignacio Etcheverry <ignalfonsore@gmail.com> | 2019-03-29 23:40:31 +0100 |
commit | c8aa85189a8736bb9723770b9409e6f9c00fc249 (patch) | |
tree | aec78e008cd5e1e3e08968434ede66b2993ee517 | |
parent | e45393482463ddb606bab4f2a78f4a5024cdce7a (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.xml | 2 | ||||
-rw-r--r-- | doc/classes/Input.xml | 14 | ||||
-rw-r--r-- | doc/classes/InputEventJoypadButton.xml | 2 | ||||
-rw-r--r-- | doc/classes/InputEventJoypadMotion.xml | 2 | ||||
-rw-r--r-- | doc/classes/InputEventKey.xml | 2 | ||||
-rw-r--r-- | doc/classes/InputEventMouse.xml | 2 | ||||
-rw-r--r-- | doc/classes/InputEventMouseButton.xml | 2 | ||||
-rw-r--r-- | doc/classes/LineEdit.xml | 4 | ||||
-rwxr-xr-x | doc/tools/makerst.py | 28 | ||||
-rw-r--r-- | editor/editor_help.cpp | 49 | ||||
-rw-r--r-- | modules/mono/editor/bindings_generator.cpp | 95 | ||||
-rw-r--r-- | modules/mono/editor/bindings_generator.h | 11 |
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"; |