74 个版本 (稳定)

3.1.2 2024 年 5 月 15 日
3.1.0 2024 年 4 月 30 日
3.0.0 2024 年 3 月 15 日
2.6.1 2024 年 1 月 23 日
0.1.0-pre.32021 年 3 月 29 日

#334 in Rust 模式

Download history 357/week @ 2024-05-03 566/week @ 2024-05-10 489/week @ 2024-05-17 122/week @ 2024-05-24 96/week @ 2024-05-31 99/week @ 2024-06-07 66/week @ 2024-06-14 100/week @ 2024-06-21 44/week @ 2024-06-28 121/week @ 2024-07-05 194/week @ 2024-07-12 243/week @ 2024-07-19 493/week @ 2024-07-26 117/week @ 2024-08-02 115/week @ 2024-08-09 364/week @ 2024-08-16

1,188 个月下载量

MIT/Apache

78KB
1.5K SLoC

dylint_linting

docs.rs 文档

该软件包提供了创建 Dylint 库的宏和创建可配置库的实用工具。

内容

dylint_library!

dylint_library! 宏展开为以下内容

#[allow(unused_extern_crates)]
extern crate rustc_driver;

#[no_mangle]
pub extern "C" fn dylint_version() -> *mut std::os::raw::c_char {
    std::ffi::CString::new($crate::DYLINT_VERSION)
        .unwrap()
        .into_raw()
}

如果您的库使用 dylint_library! 宏和 dylint-link 工具,那么您只需实现 register_lints 函数即可。请参阅此存储库中的 示例

declare_late_lint! 等。

如果您的库仅包含一个 lint,使用 declare_late_lint! 等可以使您的代码更简洁。这些宏中的每个都需要与 declare_lint! 相同的参数,并包装以下内容:

  • dylint_library! 的调用
  • register_lints 函数的实现
  • declare_lint! 的调用
  • declare_lint_pass! 的调用

例如,以下代码

dylint_linting::dylint_library!();

extern crate rustc_lint;
extern crate rustc_session;

#[no_mangle]
pub fn register_lints(sess: &rustc_session::Session, lint_store: &mut rustc_lint::LintStore) {
    dylint_linting::init_config(sess);
    lint_store.register_lints(&[NAME]);
    lint_store.register_late_pass(|_| Box::new(Name));
}

rustc_session::declare_lint!(vis NAME, Level, "description");

rustc_session::declare_lint_pass!(Name => [NAME]);

declare_late_lint!) 扩展为以下内容

declare_early_lint!declare_pre_expansion_lint! 的定义方式类似。

impl_late_lint! 等。

  • impl_late_lint! 等. 与 declare_late_lint! 等. 类似,除了
  • 每个调用 impl_lint_pass! 而不是 declare_lint_pass!;

这意味着 impl_late_lint! 的附加参数是这里的内容

    lint_store.register_late_pass(|_| Box::new(...));
                                               ^^^

constituent 功能

启用包级别的 constituent 功能会改变上述宏的工作方式。具体来说,它会 排除

  • dylint_library! 的调用
  • register_lints 声明之前使用 #[no_mangle] 的用法

这些更改有助于将使用上述宏之一声明的 lint 包含到更大的库中。也就是说

  • 在关闭功能的情况下,lint 可以作为库独立构建。
  • 在开启功能的情况下,lint 可以作为更大库的一部分构建,与其他 lint 一起。

本存储库中的 通用补充 lint 使用了这项技术。也就是说,每个通用 lint 都可以独立构建为一个库,或者作为 general 的一部分。类似的说法也适用于补充 lint 和 supplementaryconstituent 功能是这个工作背后的机制。

可配置库

可以通过在目标工作空间的根目录中包含一个 dylint.toml 文件来配置库。此 crate 为读取和解析 dylint.toml 文件提供了以下功能

仅包含一个 lint 的可配置库通常具有以下形式的 lib.rs 文件

dylint_linting::impl_late_lint! {
    ...,
    LintName::new()
}

// Lint configuration
#[derive(Default, serde::Deserialize)]
struct Config {
    boolean: bool,
    strings: Vec<String>,
}

// Keep a copy of the configuration in the `LintPass` structure.
struct LintName {
    config: Config,
}

// Read the configuration from the `dylint.toml` file, or use the default configuration if
// none is present.
impl LintName {
    pub fn new() -> Self {
        Self {
            config: dylint_linting::config_or_default(env!("CARGO_PKG_NAME")),
        }
    }
}

有关此形式 lib.rs 文件的具体示例,请参阅本存储库中的 non_local_effect_before_error_return 库。

包含多个 lint 的库必须实现 register_lints 函数,而不依赖于上述宏。如果库是可配置的,那么它的 register_lints 函数应包含对 dylint_linting::init_config 的调用,如下例所示

#[no_mangle]
pub fn register_lints(sess: &rustc_session::Session, lint_store: &mut rustc_lint::LintStore) {
    // `init_config` or `try_init_config` must be called before `config_or_default`, `config`,
    // or `config_toml` is called.
    dylint_linting::init_config(sess);

    lint_store.register_lints(&[FIRST_LINT_NAME, SECOND_LINT_NAME]);

    lint_store.register_late_pass(|_| Box::new(LintPassName::new()));
}

有关 config_or_default 等. 的其他文档可以在 docs.rs 上找到。

依赖项

~1.3–2.2MB
~45K SLoC