From 23145033a8acc9f40f95b6398f36ec8019ac4443 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Thu, 18 Nov 2021 17:24:33 +0100 Subject: [PATCH 1/4] config: add a use_gi_docgen option This would be used for setting whether the bindings docs would use the gi-docgen parser or the default one --- book/src/config_api.md | 2 ++ src/config/config.rs | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/book/src/config_api.md b/book/src/config_api.md index ad6c1c03a..0116e2b55 100644 --- a/book/src/config_api.md +++ b/book/src/config_api.md @@ -12,6 +12,8 @@ target_path = "." # Path where objects generated (defaults to /src/auto) # auto_path = "src/auto" work_mode = "normal" +# Whether the library uses https://gitlab.gnome.org/GNOME/gi-docgen for its documentation +use_gi_docgen = false generate_safety_asserts = true deprecate_by_min_version = true # With this option enabled, versions for gir and gir-files saved only to one file to minimize noise, diff --git a/src/config/config.rs b/src/config/config.rs index abd632aa6..349400892 100644 --- a/src/config/config.rs +++ b/src/config/config.rs @@ -107,6 +107,7 @@ pub struct Config { pub external_libraries: Vec, pub objects: gobjects::GObjects, pub min_cfg_version: Version, + pub use_gi_docgen: bool, pub make_backup: bool, pub generate_safety_asserts: bool, pub deprecate_by_min_version: bool, @@ -300,6 +301,11 @@ impl Config { None => Default::default(), }; + let use_gi_docgen = match toml.lookup("options.use_gi_docgen") { + Some(v) => v.as_result_bool("options.use_gi_docgen")?, + None => false, + }; + let generate_safety_asserts = match toml.lookup("options.generate_safety_asserts") { Some(v) => v.as_result_bool("options.generate_safety_asserts")?, None => false, @@ -354,6 +360,7 @@ impl Config { objects, min_cfg_version, make_backup, + use_gi_docgen, generate_safety_asserts, deprecate_by_min_version, show_statistics, From 86247a649b67714bcfb80f92754feee278986801 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Thu, 18 Nov 2021 17:26:22 +0100 Subject: [PATCH 2/4] codgen: use a different parser for docs depending on use_gi_docgen --- src/codegen/doc/format.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/codegen/doc/format.rs b/src/codegen/doc/format.rs index d8208be31..1a23601a8 100644 --- a/src/codegen/doc/format.rs +++ b/src/codegen/doc/format.rs @@ -135,9 +135,12 @@ fn replace_symbols( env: &Env, in_type: Option<(&TypeId, Option)>, ) -> String { - // We run gi_docgen first because it's super picky about the types it replaces - let out = gi_docgen::replace_c_types(input, env, in_type); - let out = replace_c_types(&out, env, in_type); + let out = if env.config.use_gi_docgen { + // We run gi_docgen first because it's super picky about the types it replaces + gi_docgen::replace_c_types(input, env, in_type) + } else { + replace_c_types(input, env, in_type) + }; // this has to be done after gi_docgen replaced the various types it knows as it uses `@` in it's linking format PARAM_SYMBOL .replace_all(&out, |caps: &Captures<'_>| format!("`{}`", &caps[2])) From e65154bf3f4796fe9460c74187697f065c1e6d77 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Thu, 18 Nov 2021 17:51:29 +0100 Subject: [PATCH 3/4] codgen: borrow some parts from gtk-doc parser to gi-docgen Only the minimum that's known to not regress the general functionnality --- src/codegen/doc/format.rs | 48 +++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/src/codegen/doc/format.rs b/src/codegen/doc/format.rs index 1a23601a8..ea74ee012 100644 --- a/src/codegen/doc/format.rs +++ b/src/codegen/doc/format.rs @@ -135,21 +135,31 @@ fn replace_symbols( env: &Env, in_type: Option<(&TypeId, Option)>, ) -> String { - let out = if env.config.use_gi_docgen { - // We run gi_docgen first because it's super picky about the types it replaces - gi_docgen::replace_c_types(input, env, in_type) + if env.config.use_gi_docgen { + let out = gi_docgen::replace_c_types(input, env, in_type); + let out = GI_DOCGEN_SYMBOL.replace_all(&out, |caps: &Captures<'_>| match &caps[2] { + "TRUE" => "[`true`]".to_string(), + "FALSE" => "[`false`]".to_string(), + "NULL" => "[`None`]".to_string(), + symbol_name => match &caps[1] { + // Opt-in only for the %SYMBOLS, @/# causes breakages + "%" => find_constant_or_variant_wrapper(symbol_name, env, in_type), + s => panic!("Unknown symbol prefix `{}`", s), + }, + }); + let out = GDK_GTK.replace_all(&out, |caps: &Captures<'_>| { + find_type(&caps[2], env).unwrap_or_else(|| format!("`{}`", &caps[2])) + }); + + out.to_string() } else { replace_c_types(input, env, in_type) - }; - // this has to be done after gi_docgen replaced the various types it knows as it uses `@` in it's linking format - PARAM_SYMBOL - .replace_all(&out, |caps: &Captures<'_>| format!("`{}`", &caps[2])) - .to_string() + } } static SYMBOL: Lazy = Lazy::new(|| Regex::new(r"([@#%])(\w+\b)([:.]+[\w-]+\b)?").unwrap()); -static PARAM_SYMBOL: Lazy = - Lazy::new(|| Regex::new(r"([@])(\w+\b)([:.]+[\w-]+\b)?").unwrap()); +static GI_DOCGEN_SYMBOL: Lazy = + Lazy::new(|| Regex::new(r"([%])(\w+\b)([:.]+[\w-]+\b)?").unwrap()); static FUNCTION: Lazy = Lazy::new(|| Regex::new(r"([@#%])?(\w+\b[:.]+)?(\b[a-z0-9_]+)\(\)").unwrap()); // **note** @@ -180,10 +190,7 @@ fn replace_c_types( "FALSE" => "[`false`]".to_string(), "NULL" => "[`None`]".to_string(), symbol_name => match &caps[1] { - "%" => find_constant_or_variant(symbol_name, env, in_type).unwrap_or_else(|| { - info!("Constant or variant `%{}` not found", symbol_name); - format!("`{}`", symbol_name) - }), + "%" => find_constant_or_variant_wrapper(symbol_name, env, in_type), "#" => { if let Some(member_path) = caps.get(3).map(|m| m.as_str()) { let method_name = member_path.trim_start_matches('.'); @@ -238,6 +245,19 @@ fn replace_c_types( SPACES.replace_all(&out, " ").into_owned() } +/// Wrapper around [`find_constant_or_variant`] that fallbacks to returning +/// the `symbol_name` +fn find_constant_or_variant_wrapper( + symbol_name: &str, + env: &Env, + in_type: Option<(&TypeId, Option)>, +) -> String { + find_constant_or_variant(symbol_name, env, in_type).unwrap_or_else(|| { + info!("Constant or variant `%{}` not found", symbol_name); + format!("`{}`", symbol_name) + }) +} + fn find_member( type_: &str, method_name: &str, From e3b56b2ccbc6b4e84bc5707f24b93128f932684b Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Thu, 18 Nov 2021 19:06:25 +0100 Subject: [PATCH 4/4] codgen: detect cairo/graphene/Adwaita/Handy/GtkSourceview types This should probably be rewritten someday to make use of some other config options --- src/codegen/doc/format.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/codegen/doc/format.rs b/src/codegen/doc/format.rs index ea74ee012..e3b6b6810 100644 --- a/src/codegen/doc/format.rs +++ b/src/codegen/doc/format.rs @@ -165,8 +165,10 @@ static FUNCTION: Lazy = // **note** // The optional . at the end is to make the regex more relaxed for some weird broken cases on gtk3's docs // it doesn't hurt other docs so please don't drop it -static GDK_GTK: Lazy = - Lazy::new(|| Regex::new(r"`([^\(:])?((G[dts]k|Pango)\w+\b)(\.)?`").unwrap()); +static GDK_GTK: Lazy = Lazy::new(|| { + Regex::new(r"`([^\(:])?((G[dts]k|Pango|cairo_|graphene_|Adw|Hdy|GtkSource)\w+\b)(\.)?`") + .unwrap() +}); static TAGS: Lazy = Lazy::new(|| Regex::new(r"<[\w/-]+>").unwrap()); static SPACES: Lazy = Lazy::new(|| Regex::new(r"[ ]{2,}").unwrap());