Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add built-in GDScript keywords to the class reference #97196

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions core/doc_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,7 @@ class DocData {
Vector<ConstantDoc> constants;
HashMap<String, EnumDoc> enums;
Vector<PropertyDoc> properties;
Vector<MethodDoc> builtins;
Vector<MethodDoc> annotations;
Vector<ThemeItemDoc> theme_properties;
bool is_deprecated = false;
Expand Down Expand Up @@ -810,6 +811,14 @@ class DocData {
doc.properties.push_back(PropertyDoc::from_dict(properties[i]));
}

Array builtins;
if (p_dict.has("builtins")) {
builtins = p_dict["builtins"];
}
for (int i = 0; i < builtins.size(); i++) {
doc.builtins.push_back(MethodDoc::from_dict(builtins[i]));
}

Array annotations;
if (p_dict.has("annotations")) {
annotations = p_dict["annotations"];
Expand Down Expand Up @@ -939,6 +948,14 @@ class DocData {
dict["properties"] = properties;
}

if (!p_doc.builtins.is_empty()) {
Array builtins;
for (int i = 0; i < p_doc.builtins.size(); i++) {
builtins.push_back(MethodDoc::to_dict(p_doc.builtins[i]));
}
dict["builtins"] = builtins;
}

if (!p_doc.annotations.is_empty()) {
Array annotations;
for (int i = 0; i < p_doc.annotations.size(); i++) {
Expand Down
2 changes: 2 additions & 0 deletions core/object/script_language.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ class ScriptLanguage : public Object {
LOOKUP_RESULT_CLASS_ENUM,
LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE,
LOOKUP_RESULT_CLASS_ANNOTATION,
LOOKUP_RESULT_CLASS_BUILTIN,
LOOKUP_RESULT_MAX
};

Expand Down Expand Up @@ -397,6 +398,7 @@ class ScriptLanguage : public Object {
/* LOADER FUNCTIONS */

virtual void get_recognized_extensions(List<String> *p_extensions) const = 0;
virtual void get_public_keywords(List<MethodInfo> *p_keywords) const = 0;
virtual void get_public_functions(List<MethodInfo> *p_functions) const = 0;
virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const = 0;
virtual void get_public_annotations(List<MethodInfo> *p_annotations) const = 0;
Expand Down
2 changes: 2 additions & 0 deletions core/object/script_language_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ void ScriptLanguageExtension::_bind_methods() {
GDVIRTUAL_BIND(_reload_tool_script, "script", "soft_reload");

GDVIRTUAL_BIND(_get_recognized_extensions);
GDVIRTUAL_BIND(_get_public_keywords);
GDVIRTUAL_BIND(_get_public_functions);
GDVIRTUAL_BIND(_get_public_constants);
GDVIRTUAL_BIND(_get_public_annotations);
Expand All @@ -171,6 +172,7 @@ void ScriptLanguageExtension::_bind_methods() {
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_ENUM);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_ANNOTATION);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_BUILTIN);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_MAX);

BIND_ENUM_CONSTANT(LOCATION_LOCAL);
Expand Down
10 changes: 10 additions & 0 deletions core/object/script_language_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,16 @@ class ScriptLanguageExtension : public ScriptLanguage {
}
}

GDVIRTUAL0RC(TypedArray<Dictionary>, _get_public_keywords)
virtual void get_public_keywords(List<MethodInfo> *p_keywords) const override {
TypedArray<Dictionary> ret;
GDVIRTUAL_REQUIRED_CALL(_get_public_keywords, ret);
for (const Variant &var : ret) {
MethodInfo mi = MethodInfo::from_dict(var);
p_keywords->push_back(mi);
}
}

GDVIRTUAL0RC(TypedArray<Dictionary>, _get_public_functions)
virtual void get_public_functions(List<MethodInfo> *p_functions) const override {
TypedArray<Dictionary> ret;
Expand Down
28 changes: 28 additions & 0 deletions doc/class.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,34 @@
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="builtins" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="builtin" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="param" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:sequence />
</xs:sequence>
<xs:attribute type="xs:byte" name="index" />
<xs:attribute type="xs:string" name="name" />
<xs:attribute type="xs:string" name="type" />
<xs:attribute type="xs:string" name="enum" use="optional" />
<xs:attribute type="xs:boolean" name="is_bitfield" use="optional" />
<xs:attribute type="xs:string" name="default" use="optional" />
</xs:complexType>
</xs:element>
<xs:element type="xs:string" name="description" />
</xs:sequence>
<xs:attribute type="xs:string" name="name" use="optional" />
<xs:attribute type="xs:string" name="keywords" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="annotations" minOccurs="0">
<xs:complexType>
<xs:sequence>
Expand Down
2 changes: 2 additions & 0 deletions doc/classes/ScriptEditor.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
class_signal:BaseButton:pressed
# Shows help for the CanvasItem property visible.
class_property:CanvasItem:visible
# Shows help for the GDScript built-in keyword.
class_builtin:@GDScript:for
# Shows help for the GDScript annotation export.
# Annotations should be prefixed with the `@` symbol in the descriptor, as shown here.
class_annotation:@GDScript:@export
Expand Down
9 changes: 8 additions & 1 deletion doc/classes/ScriptLanguageExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,11 @@
<description>
</description>
</method>
<method name="_get_public_keywords" qualifiers="virtual const">
<return type="Dictionary[]" />
<description>
</description>
</method>
<method name="_get_recognized_extensions" qualifiers="virtual const">
<return type="PackedStringArray" />
<description>
Expand Down Expand Up @@ -391,7 +396,9 @@
</constant>
<constant name="LOOKUP_RESULT_CLASS_ANNOTATION" value="8" enum="LookupResultType">
</constant>
<constant name="LOOKUP_RESULT_MAX" value="9" enum="LookupResultType">
<constant name="LOOKUP_RESULT_CLASS_BUILTIN" value="9" enum="LookupResultType">
</constant>
<constant name="LOOKUP_RESULT_MAX" value="10" enum="LookupResultType">
</constant>
<constant name="LOCATION_LOCAL" value="0" enum="CodeCompletionLocation">
The option is local to the location of the code completion query - e.g. a local variable. Subsequent value of location represent options from the outer class, the exact value represent how far they are (in terms of inner classes).
Expand Down
42 changes: 42 additions & 0 deletions doc/tools/make_rst.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"Signals",
"Enumerations",
"Constants",
"Built-ins",
"Annotations",
"Property Descriptions",
"Constructor Descriptions",
Expand Down Expand Up @@ -603,6 +604,7 @@ def __init__(self, name: str) -> None:
self.methods: OrderedDict[str, List[MethodDef]] = OrderedDict()
self.operators: OrderedDict[str, List[MethodDef]] = OrderedDict()
self.signals: OrderedDict[str, SignalDef] = OrderedDict()
self.builtins: OrderedDict[str, List[AnnotationDef]] = OrderedDict()
self.annotations: OrderedDict[str, List[AnnotationDef]] = OrderedDict()
self.theme_items: OrderedDict[str, ThemeItemDef] = OrderedDict()
self.inherits: Optional[str] = None
Expand Down Expand Up @@ -1219,6 +1221,46 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir:

f.write("\n\n")

# Built-in keyword descriptions
if len(class_def.builtins) > 0:
f.write(make_separator(True))
f.write(make_heading("Built-in keywords", "-"))

index = 0

for method_list in class_def.builtins.values(): # type: ignore
for i, m in enumerate(method_list):
if index != 0:
f.write(make_separator())

# Create builtin signature and anchor point.

self_link = ""
if i == 0:
builtin_anchor = f"class_{class_name}_builtin_{m.name}"
f.write(f".. _{builtin_anchor}:\n\n")
self_link = f" :ref:`🔗<{builtin_anchor}>`"

f.write(".. rst-class:: classref-builtin\n\n")

_, signature = make_method_signature(class_def, m, "", state)
f.write(f"{signature}{self_link}\n\n")

# Add builtin description, or a call to action if it's missing.

if m.description is not None and m.description.strip() != "":
f.write(f"{format_text_block(m.description.strip(), m, state)}\n\n")
else:
f.write(".. container:: contribute\n\n\t")
f.write(
translate(
"There is currently no description for this built-in keyword. Please help us by :ref:`contributing one <doc_updating_the_class_reference>`!"
)
+ "\n\n"
)

index += 1

# Annotation descriptions
if len(class_def.annotations) > 0:
f.write(make_separator(True))
Expand Down
45 changes: 43 additions & 2 deletions editor/doc_tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,8 @@ void DocTools::merge_from(const DocTools &p_data) {

merge_constants(c.constants, cf.constants);

merge_methods(c.builtins, cf.builtins);

merge_methods(c.annotations, cf.annotations);

merge_properties(c.properties, cf.properties);
Expand Down Expand Up @@ -1009,7 +1011,7 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
// Add scripting language built-ins.
{
// We only add a doc entry for languages which actually define any built-in
// methods, constants, or annotations.
// keywords (builtins), methods, constants, or annotations.
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
ScriptLanguage *lang = ScriptServer::get_language(i);
String cname = "@" + lang->get_name();
Expand Down Expand Up @@ -1063,6 +1065,39 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
c.constants.push_back(cd);
}

// Get keywords.
List<MethodInfo> binfo;
lang->get_public_keywords(&binfo);

for (const MethodInfo &bi : binfo) {
DocData::MethodDoc btd;
btd.name = bi.name;

if (bi.flags & METHOD_FLAG_VARARG) {
if (!btd.qualifiers.is_empty()) {
btd.qualifiers += " ";
}
btd.qualifiers += "vararg";
}

DocData::return_doc_from_retinfo(btd, bi.return_val);

int j = 0;
for (List<PropertyInfo>::ConstIterator itr = bi.arguments.begin(); itr != bi.arguments.end(); ++itr, ++j) {
DocData::ArgumentDoc ad;
DocData::argument_doc_from_arginfo(ad, *itr);

int darg_idx = j - (bi.arguments.size() - bi.default_arguments.size());
if (darg_idx >= 0) {
ad.default_value = DocData::get_default_value_string(bi.default_arguments[darg_idx]);
}

btd.arguments.push_back(ad);
}

c.builtins.push_back(btd);
}

// Get annotations.
List<MethodInfo> ainfo;
lang->get_public_annotations(&ainfo);
Expand Down Expand Up @@ -1097,11 +1132,12 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
}

// Skip adding the lang if it doesn't expose anything (e.g. C#).
if (c.methods.is_empty() && c.constants.is_empty() && c.annotations.is_empty()) {
if (c.methods.is_empty() && c.constants.is_empty() && c.builtins.is_empty() && c.annotations.is_empty()) {
continue;
}

c.methods.sort_custom<MethodCompare>();
c.builtins.sort_custom<MethodCompare>();
c.annotations.sort_custom<MethodCompare>();

class_list[cname] = c;
Expand Down Expand Up @@ -1350,6 +1386,9 @@ Error DocTools::_load(Ref<XMLParser> parser) {
} else if (name2 == "signals") {
Error err2 = _parse_methods(parser, c.signals);
ERR_FAIL_COND_V(err2, err2);
} else if (name2 == "builtins") {
Error err2 = _parse_methods(parser, c.builtins);
ERR_FAIL_COND_V(err2, err2);
} else if (name2 == "annotations") {
Error err2 = _parse_methods(parser, c.annotations);
ERR_FAIL_COND_V(err2, err2);
Expand Down Expand Up @@ -1741,6 +1780,8 @@ Error DocTools::save_classes(const String &p_default_path, const HashMap<String,
_write_string(f, 1, "</constants>");
}

_write_method_doc(f, "builtin", c.builtins);

_write_method_doc(f, "annotation", c.annotations);

if (!c.theme_properties.is_empty()) {
Expand Down
Loading
Loading