Skip to content

try to add doc comments to functions #1207

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

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions godot-codegen/src/generator/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ fn make_builtin_method_definition(
is_virtual_required: false,
is_varcall_fallible: false,
},
None,
safety_doc,
&TokenStream::new(),
)
Expand Down
3 changes: 3 additions & 0 deletions godot-codegen/src/generator/classes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,8 @@ fn make_class_method_definition(
let rust_method_name = method.name();
let godot_method_name = method.godot_name();

let doc = docs::make_method_doc(class, method.name());

let receiver = functions_common::make_receiver(method.qualifier(), quote! { self.object_ptr });

let table_index = ctx.get_table_index(&MethodTableKey::from_class(class, method));
Expand Down Expand Up @@ -634,6 +636,7 @@ fn make_class_method_definition(
is_virtual_required: false,
is_varcall_fallible: true,
},
Some(quote! {#[doc = #doc] }),
None,
cfg_attributes,
)
Expand Down
55 changes: 54 additions & 1 deletion godot-codegen/src/generator/docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//! Single module for documentation, rather than having it in each symbol-specific file, so it's easier to keep docs consistent.

use crate::generator::signals;
use crate::models::domain::{ModName, TyName};
use crate::models::domain::{Class, ClassLike as _, ModName, TyName};
use crate::special_cases;
use proc_macro2::Ident;

Expand Down Expand Up @@ -158,3 +158,56 @@ pub fn make_module_doc(class_name: &TyName) -> String {
See also [Godot docs for `{godot_ty}` enums]({online_link}).\n\n"
)
}

pub fn make_method_doc(class: &Class, method_name: &str) -> String {
let class_name = class.name();
let TyName { rust_ty, godot_ty } = class_name;

let class_name_lower = godot_ty.to_ascii_lowercase();
let method_name_slug = method_name.to_ascii_lowercase().replace('_', "-");

let getter_for = class
.properties
.iter()
.find(|prop| prop.getter == Some(method_name.to_string()));
let setter_for = class
.properties
.iter()
.find(|prop| prop.setter == Some(method_name.to_string()));

let property_for = getter_for.or(setter_for);

match property_for {
None => {
let online_link = format!(
"https://docs.godotengine.org/en/stable/classes/class_{class_name_lower}.html#class-{class_name_lower}-method-{method_name_slug}"
);

format!(
"Method `{method_name}` of class [`{rust_ty}`][crate::classes::{rust_ty}].\
\n\n\
See also [Godot docs for `{godot_ty}.{method_name}`]({online_link}).\n\n"
)
}
Some(prop) => {
let prop_name = &prop.name;
let prop_name_slug = prop_name.to_ascii_lowercase().replace('_', "-");

let getter_setter = if getter_for.is_some() {
"Getter"
} else {
"Setter"
};

let online_link = format!(
"https://docs.godotengine.org/en/stable/classes/class_{class_name_lower}.html#class-{class_name_lower}-property-{prop_name_slug}"
);

format!(
"{getter_setter} function for Property `{prop_name}` of class [`{rust_ty}`][crate::classes::{rust_ty}].\
\n\n\
See also [Godot docs for `{godot_ty}.{prop_name}`]({online_link}).\n\n"
)
}
}
}
12 changes: 12 additions & 0 deletions godot-codegen/src/generator/functions_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ pub struct FnParamTokens {
pub fn make_function_definition(
sig: &dyn Function,
code: &FnCode,
doc: Option<TokenStream>,
safety_doc: Option<TokenStream>,
cfg_attributes: &TokenStream,
) -> FnDefinition {
Expand All @@ -115,6 +116,12 @@ pub fn make_function_definition(
make_vis(sig.is_private())
};

let maybe_doc = if let Some(doc) = doc {
doc
} else {
TokenStream::new()
};

// Functions are marked unsafe as soon as raw pointers are involved, irrespectively of whether they appear in parameter or return type
// position. In cases of virtual functions called by Godot, a returned pointer must be valid and of the expected type. It might be possible
// to only use `unsafe` for pointers in parameters (for outbound calls), and in return values (for virtual calls). Or technically more
Expand Down Expand Up @@ -196,6 +203,7 @@ pub fn make_function_definition(

quote! {
#maybe_safety_doc
#maybe_doc
#maybe_unsafe fn #primary_fn_name (
#receiver_param
#( #params, )*
Expand All @@ -211,6 +219,7 @@ pub fn make_function_definition(
if !code.is_varcall_fallible {
quote! {
#maybe_safety_doc
#maybe_doc
#vis #maybe_unsafe fn #primary_fn_name (
#receiver_param
#( #params, )*
Expand Down Expand Up @@ -243,6 +252,7 @@ pub fn make_function_definition(
/// This is a _varcall_ method, meaning parameters and return values are passed as `Variant`.
/// It can detect call failures and will panic in such a case.
#maybe_safety_doc
#maybe_doc
#vis #maybe_unsafe fn #primary_fn_name (
#receiver_param
#( #params, )*
Expand All @@ -256,6 +266,7 @@ pub fn make_function_definition(
/// This is a _varcall_ method, meaning parameters and return values are passed as `Variant`.
/// It can detect call failures and will return `Err` in such a case.
#maybe_safety_doc
#maybe_doc
#vis #maybe_unsafe fn #try_fn_name(
#receiver_param
#( #params, )*
Expand All @@ -278,6 +289,7 @@ pub fn make_function_definition(

quote! {
#maybe_safety_doc
#maybe_doc
#vis #maybe_unsafe fn #primary_fn_name #fn_lifetime (
#receiver_param
#( #params, )*
Expand Down
1 change: 1 addition & 0 deletions godot-codegen/src/generator/utility_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ pub(crate) fn make_utility_function_definition(function: &UtilityFunction) -> To
is_varcall_fallible: false,
},
None,
None,
&TokenStream::new(),
);

Expand Down
1 change: 1 addition & 0 deletions godot-codegen/src/generator/virtual_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ fn make_virtual_method(
is_varcall_fallible: true,
},
None,
None,
&TokenStream::new(),
);

Expand Down
9 changes: 9 additions & 0 deletions godot-codegen/src/models/domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ pub struct Class {
pub enums: Vec<Enum>,
pub methods: Vec<ClassMethod>,
pub signals: Vec<ClassSignal>,
pub properties: Vec<ClassProperty>,
}

impl ClassLike for Class {
Expand Down Expand Up @@ -453,6 +454,14 @@ pub struct ClassSignal {

// ----------------------------------------------------------------------------------------------------------------------------------------------

pub struct ClassProperty {
pub name: String,
pub getter: Option<String>,
pub setter: Option<String>,
}

// ----------------------------------------------------------------------------------------------------------------------------------------------

#[derive(Copy, Clone, Debug)]
pub enum FnDirection {
/// Godot -> Rust.
Expand Down
25 changes: 20 additions & 5 deletions godot-codegen/src/models/domain_mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
use crate::context::Context;
use crate::models::domain::{
BuildConfiguration, BuiltinClass, BuiltinMethod, BuiltinSize, BuiltinVariant, Class,
ClassCommons, ClassConstant, ClassConstantValue, ClassMethod, ClassSignal, Constructor, Enum,
Enumerator, EnumeratorValue, ExtensionApi, FnDirection, FnParam, FnQualifier, FnReturn,
FunctionCommon, GodotApiVersion, ModName, NativeStructure, Operator, RustTy, Singleton, TyName,
UtilityFunction,
ClassCommons, ClassConstant, ClassConstantValue, ClassMethod, ClassProperty, ClassSignal,
Constructor, Enum, Enumerator, EnumeratorValue, ExtensionApi, FnDirection, FnParam,
FnQualifier, FnReturn, FunctionCommon, GodotApiVersion, ModName, NativeStructure, Operator,
RustTy, Singleton, TyName, UtilityFunction,
};
use crate::models::json::{
JsonBuiltinClass, JsonBuiltinMethod, JsonBuiltinSizes, JsonClass, JsonClassConstant,
JsonClassMethod, JsonConstructor, JsonEnum, JsonEnumConstant, JsonExtensionApi, JsonHeader,
JsonMethodReturn, JsonNativeStructure, JsonOperator, JsonSignal, JsonSingleton,
JsonMethodReturn, JsonNativeStructure, JsonOperator, JsonProperty, JsonSignal, JsonSingleton,
JsonUtilityFunction,
};
use crate::util::{get_api_level, ident, option_as_slice};
Expand Down Expand Up @@ -128,6 +128,11 @@ impl Class {
})
.collect();

let properties = option_as_slice(&json.properties)
.iter()
.map(|p| ClassProperty::from_json(p, ctx))
.collect::<Vec<_>>();

let base_class = json
.inherits
.as_ref()
Expand All @@ -148,6 +153,7 @@ impl Class {
enums,
methods,
signals,
properties,
})
}
}
Expand Down Expand Up @@ -589,6 +595,15 @@ impl ClassSignal {
})
}
}
impl ClassProperty {
pub fn from_json(json_property: &JsonProperty, _ctx: &mut Context) -> Self {
Self {
name: json_property.name.clone(),
getter: json_property.getter.clone(),
setter: json_property.setter.clone(),
}
}
}

impl UtilityFunction {
pub fn from_json(function: &JsonUtilityFunction, ctx: &mut Context) -> Option<Self> {
Expand Down
14 changes: 7 additions & 7 deletions godot-codegen/src/models/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ pub struct JsonClass {
pub constants: Option<Vec<JsonClassConstant>>,
pub enums: Option<Vec<JsonEnum>>,
pub methods: Option<Vec<JsonClassMethod>>,
// pub properties: Option<Vec<Property>>,
pub properties: Option<Vec<JsonProperty>>,
pub signals: Option<Vec<JsonSignal>>,
}

Expand Down Expand Up @@ -173,12 +173,12 @@ pub struct JsonMember {
#[derive(DeJson)]
#[allow(dead_code)]
pub struct JsonProperty {
#[nserde(rename = "type")]
type_: String,
name: String,
setter: String,
getter: String,
index: i32, // can be -1
// #[nserde(rename = "type")]
// type_: String,
pub name: String,
pub setter: Option<String>,
pub getter: Option<String>,
// index: Option<i32>,
}

#[derive(DeJson)]
Expand Down
Loading