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).
This commit is contained in:
parent
e453934824
commit
c8aa85189a
12 changed files with 178 additions and 33 deletions
|
@ -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.
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)) {
|
||||
// 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"];
|
||||
|
||||
if (!table->has(link))
|
||||
return;
|
||||
class_desc->scroll_to_line((*table)[link]);
|
||||
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 ") ? "()" : ""));
|
||||
|
|
|
@ -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>");
|
||||
|
|
|
@ -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";
|
||||
|
|
Loading…
Reference in a new issue