Skip to content

Commit

Permalink
Merge pull request #1179 from MarijnS95/enum-flag-links
Browse files Browse the repository at this point in the history
codegen/doc: Generate links for enum/flag functions/methods
  • Loading branch information
sdroege committed Jun 2, 2021
2 parents 4889e2e + f66953e commit 72e79f7
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 25 deletions.
3 changes: 1 addition & 2 deletions src/analysis/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,11 @@ impl Info {
}

// returns whether the method can be linked in the docs
pub fn should_be_doc_linked<F: Fn(&Self) -> bool>(&self, env: &Env, search: F) -> bool {
pub fn should_be_doc_linked(&self, env: &Env) -> bool {
!self.status.ignored()
&& (self.status.manual() || self.visibility.code_visible())
&& !self.is_special()
&& !self.is_async_finish(env)
&& search(self)
}

pub fn doc_link(
Expand Down
62 changes: 49 additions & 13 deletions src/analysis/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,23 @@ pub struct Analysis {
pub flags_imports: Imports,
}

fn find_function<'a>(
env: &Env,
mut functions: impl Iterator<Item = &'a functions::Info>,
search_fn: impl Fn(&functions::Info) -> bool + Copy,
) -> Option<&'a functions::Info> {
functions.find(|fn_info| fn_info.should_be_doc_linked(env) && search_fn(fn_info))
}

impl Analysis {
pub fn find_global_function<F: Fn(&functions::Info) -> bool + Copy>(
&self,
env: &Env,
search: F,
) -> Option<&functions::Info> {
self.global_functions.as_ref().and_then(move |info| {
info.functions
.iter()
.find(move |fn_info| fn_info.should_be_doc_linked(env, search))
})
self.global_functions
.as_ref()
.and_then(move |info| find_function(env, info.functions.iter(), search))
}

pub fn find_record_by_function<
Expand All @@ -83,10 +89,7 @@ impl Analysis {
.values()
.filter(|r| search_record(r))
.find_map(|record_info| {
record_info
.functions
.iter()
.find(|fn_info| fn_info.should_be_doc_linked(env, search_fn))
find_function(env, record_info.functions.iter(), search_fn)
.map(|fn_info| (record_info, fn_info))
})
}
Expand All @@ -104,10 +107,43 @@ impl Analysis {
.values()
.filter(|o| search_obj(o))
.find_map(|obj_info| {
obj_info
.functions
.iter()
.find(|fn_info| fn_info.should_be_doc_linked(env, search_fn))
find_function(env, obj_info.functions.iter(), search_fn)
.map(|fn_info| (obj_info, fn_info))
})
}

pub fn find_enum_by_function<
F: Fn(&functions::Info) -> bool + Copy,
G: Fn(&enums::Info) -> bool + Copy,
>(
&self,
env: &Env,
search_enum: G,
search_fn: F,
) -> Option<(&enums::Info, &functions::Info)> {
self.enumerations
.iter()
.filter(|o| search_enum(o))
.find_map(|obj_info| {
find_function(env, obj_info.functions.iter(), search_fn)
.map(|fn_info| (obj_info, fn_info))
})
}

pub fn find_flag_by_function<
F: Fn(&functions::Info) -> bool + Copy,
G: Fn(&flags::Info) -> bool + Copy,
>(
&self,
env: &Env,
search_flag: G,
search_fn: F,
) -> Option<(&flags::Info, &functions::Info)> {
self.flags
.iter()
.filter(|o| search_flag(o))
.find_map(|obj_info| {
find_function(env, obj_info.functions.iter(), search_fn)
.map(|fn_info| (obj_info, fn_info))
})
}
Expand Down
40 changes: 30 additions & 10 deletions src/codegen/doc/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,8 @@ fn find_method_or_function_by_ctype(
|f| f.glib_name == name,
|o| c_type.map_or(true, |t| o.c_type == t),
|r| c_type.map_or(true, |t| r.type_(&env.library).c_type == t),
|r| c_type.map_or(true, |t| r.type_(&env.library).c_type == t),
|r| c_type.map_or(true, |t| r.type_(&env.library).c_type == t),
c_type.map_or(false, |t| t.ends_with("Class")),
)
}
Expand All @@ -366,17 +368,15 @@ fn find_method_or_function_by_ctype(
/// This function is generic so it can be de-duplicated between a
/// - [`find_method_or_function_by_ctype()`] where the object/records are looked by their C name
/// - [`gi_docgen::find_method_or_function_by_name()`] where the object/records are looked by their name
pub(crate) fn find_method_or_function<
F: Fn(&crate::analysis::functions::Info) -> bool + Copy,
G: Fn(&crate::analysis::object::Info) -> bool + Copy,
H: Fn(&crate::analysis::record::Info) -> bool + Copy,
>(
pub(crate) fn find_method_or_function(
name: &str,
env: &Env,
in_type: Option<(&TypeId, Option<LocationInObject>)>,
search_fn: F,
search_obj: G,
search_record: H,
search_fn: impl Fn(&crate::analysis::functions::Info) -> bool + Copy,
search_obj: impl Fn(&crate::analysis::object::Info) -> bool + Copy,
search_record: impl Fn(&crate::analysis::record::Info) -> bool + Copy,
search_enum: impl Fn(&crate::analysis::enums::Info) -> bool + Copy,
search_flag: impl Fn(&crate::analysis::flags::Info) -> bool + Copy,
is_class_method: bool,
) -> Option<String> {
if is_class_method {
Expand All @@ -401,12 +401,32 @@ pub(crate) fn find_method_or_function<
env.analysis
.find_record_by_function(env, search_record, search_fn)
{
Some(gen_record_fn_doc_link(
Some(gen_type_fn_doc_link(
record_info.type_id,
fn_info,
env,
in_type,
))
} else if let Some((enum_info, fn_info)) =
env.analysis
.find_enum_by_function(env, search_enum, search_fn)
{
Some(gen_type_fn_doc_link(
enum_info.type_id,
fn_info,
env,
in_type,
))
} else if let Some((flag_info, fn_info)) =
env.analysis
.find_flag_by_function(env, search_flag, search_fn)
{
Some(gen_type_fn_doc_link(
flag_info.type_id,
fn_info,
env,
in_type,
))
// or as a global function
} else if let Some(fn_info) = env.analysis.find_global_function(env, search_fn) {
Some(fn_info.doc_link(None, None, false))
Expand All @@ -415,7 +435,7 @@ pub(crate) fn find_method_or_function<
}
}

pub(crate) fn gen_record_fn_doc_link(
pub(crate) fn gen_type_fn_doc_link(
type_id: TypeId,
fn_info: &Info,
env: &Env,
Expand Down
2 changes: 2 additions & 0 deletions src/codegen/doc/gi_docgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ fn find_method_or_function_by_name(
|f| f.name == mangle_keywords(name),
|o| type_.map_or(true, |t| o.name == t),
|r| type_.map_or(true, |t| r.name == t),
|e| type_.map_or(true, |t| e.name == t),
|f| type_.map_or(true, |t| f.name == t),
is_class_method,
)
}
Expand Down

0 comments on commit 72e79f7

Please sign in to comment.