From 546be18e3a91e4844b0dacc76c9f055397b6d89e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 13 Jun 2021 12:33:08 +0300 Subject: [PATCH] internal: check that coverage marks are always paired --- crates/hir_def/src/body/tests/block.rs | 10 +++--- crates/ide_completion/src/render.rs | 1 + xtask/src/tidy.rs | 49 +++++++++++++++++++++++++- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/crates/hir_def/src/body/tests/block.rs b/crates/hir_def/src/body/tests/block.rs index bc3d0f13875..15c10d053f2 100644 --- a/crates/hir_def/src/body/tests/block.rs +++ b/crates/hir_def/src/body/tests/block.rs @@ -163,14 +163,14 @@ fn legacy_macro_items() { // correctly. check_at( r#" -macro_rules! hit { +macro_rules! mark { () => { struct Hit {} } } fn f() { - hit!(); + mark!(); $0 } "#, @@ -193,20 +193,20 @@ fn macro_resolve() { fn f() { fn nested() { - cov_mark::hit!(Hit); + cov_mark::mark!(Hit); $0 } } //- /core.rs crate:core pub mod cov_mark { #[macro_export] - macro_rules! _hit { + macro_rules! _mark { ($name:ident) => { struct $name {} } } - pub use crate::_hit as hit; + pub use crate::_mark as mark; } "#, expect![[r#" diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs index a5508163124..d8ca18c733e 100644 --- a/crates/ide_completion/src/render.rs +++ b/crates/ide_completion/src/render.rs @@ -1007,6 +1007,7 @@ fn go(…) [] #[test] fn too_many_arguments() { + cov_mark::check!(too_many_arguments); check_relevance( r#" struct Foo; diff --git a/xtask/src/tidy.rs b/xtask/src/tidy.rs index 9447d463d0f..e6fa5868de5 100644 --- a/xtask/src/tidy.rs +++ b/xtask/src/tidy.rs @@ -1,4 +1,7 @@ -use std::path::{Path, PathBuf}; +use std::{ + collections::HashSet, + path::{Path, PathBuf}, +}; use xshell::{cmd, pushd, pushenv, read_file}; @@ -81,6 +84,7 @@ fn check_lsp_extensions_docs() { #[test] fn rust_files_are_tidy() { let mut tidy_docs = TidyDocs::default(); + let mut tidy_marks = TidyMarks::default(); for path in rust_files() { let text = read_file(&path).unwrap(); check_todo(&path, &text); @@ -88,8 +92,10 @@ fn rust_files_are_tidy() { check_trailing_ws(&path, &text); deny_clippy(&path, &text); tidy_docs.visit(&path, &text); + tidy_marks.visit(&path, &text); } tidy_docs.finish(); + tidy_marks.finish(); } #[test] @@ -408,6 +414,39 @@ fn is_exclude_dir(p: &Path, dirs_to_exclude: &[&str]) -> bool { .any(|it| dirs_to_exclude.contains(&it)) } +#[derive(Default)] +struct TidyMarks { + hits: HashSet, + checks: HashSet, +} + +impl TidyMarks { + fn visit(&mut self, _path: &Path, text: &str) { + for line in text.lines() { + if let Some(mark) = find_mark(line, "hit") { + self.hits.insert(mark.to_string()); + } + if let Some(mark) = find_mark(line, "check") { + self.checks.insert(mark.to_string()); + } + if let Some(mark) = find_mark(line, "check_count") { + self.checks.insert(mark.to_string()); + } + } + } + + fn finish(self) { + assert!(!self.hits.is_empty()); + + let diff: Vec<_> = + self.hits.symmetric_difference(&self.checks).map(|it| it.as_str()).collect(); + + if !diff.is_empty() { + panic!("unpaired marks: {:?}", diff) + } + } +} + #[allow(deprecated)] fn stable_hash(text: &str) -> u64 { use std::hash::{Hash, Hasher, SipHasher}; @@ -417,3 +456,11 @@ fn stable_hash(text: &str) -> u64 { text.hash(&mut hasher); hasher.finish() } + +fn find_mark<'a>(text: &'a str, mark: &'static str) -> Option<&'a str> { + let idx = text.find(mark)?; + let text = text[idx + mark.len()..].strip_prefix("!(")?; + let idx = text.find(|c: char| !(c.is_alphanumeric() || c == '_'))?; + let text = &text[..idx]; + Some(text) +}