This repository has been archived by the owner on Aug 31, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 664
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(rome_json_analyze): noDuplicateKeys (#4592)
* feat(rome_json_analyze): noDuplicateKeys * codegen and dependencies * rebase * chore: clippy and codegen * code suggestions * code suggestions * clippy * codegen * change rule name
- Loading branch information
Showing
32 changed files
with
1,120 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
[package] | ||
name = "rome_json_analyze" | ||
version = "0.0.0" | ||
edition.workspace = true | ||
authors.workspace = true | ||
repository.workspace = true | ||
license.workspace = true | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
rome_analyze = { workspace = true } | ||
rome_json_syntax = { workspace = true } | ||
rome_rowan = { workspace = true } | ||
rome_console = { workspace = true } | ||
rome_diagnostics = { workspace = true } | ||
lazy_static = { workspace = true } | ||
|
||
[dev-dependencies] | ||
rome_deserialize = { workspace = true } | ||
rome_json_parser = { workspace = true } | ||
rome_json_factory = { workspace = true } | ||
tests_macros = { workspace = true } | ||
rome_text_edit = { workspace = true } | ||
insta = { workspace = true, features = ["glob"] } | ||
countme = { workspace = true, features = ["enable"] } | ||
similar = "2.1.0" | ||
json_comments = "0.2.1" | ||
rome_service = { workspace = true } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
//! Generated file, do not edit by hand, see `xtask/codegen` | ||
|
||
pub(crate) mod nursery; | ||
::rome_analyze::declare_category! { pub (crate) Analyzers { kind : Lint , groups : [self :: nursery :: Nursery ,] } } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
//! Generated file, do not edit by hand, see `xtask/codegen` | ||
|
||
use rome_analyze::declare_group; | ||
pub(crate) mod no_duplicate_json_keys; | ||
declare_group! { pub (crate) Nursery { name : "nursery" , rules : [self :: no_duplicate_json_keys :: NoDuplicateJsonKeys ,] } } |
109 changes: 109 additions & 0 deletions
109
crates/rome_json_analyze/src/analyzers/nursery/no_duplicate_json_keys.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
use rome_analyze::{context::RuleContext, declare_rule, Ast, Rule, RuleDiagnostic}; | ||
use rome_console::markup; | ||
use rome_json_syntax::{JsonMemberName, JsonObjectValue, TextRange}; | ||
use rome_rowan::{AstNode, AstSeparatedList}; | ||
use std::collections::HashMap; | ||
|
||
declare_rule! { | ||
/// Disallow two keys with the same name inside a JSON object. | ||
/// | ||
/// ## Examples | ||
/// | ||
/// ### Invalid | ||
/// | ||
/// ```json,expect_diagnostic | ||
/// { | ||
/// "title": "New title", | ||
/// "title": "Second title" | ||
/// } | ||
/// ``` | ||
/// | ||
/// ### Valid | ||
/// | ||
/// ```json | ||
/// { | ||
/// "title": "New title", | ||
/// "secondTitle": "Second title" | ||
/// } | ||
/// ``` | ||
pub(crate) NoDuplicateJsonKeys { | ||
version: "next", | ||
name: "noDuplicateJsonKeys", | ||
recommended: true, | ||
} | ||
} | ||
|
||
pub(crate) struct DuplicatedKeys { | ||
/// The fist key, which should be the correct one | ||
original_key: JsonMemberName, | ||
/// The ranges where the duplicated keys are found | ||
duplicated_keys: Vec<TextRange>, | ||
} | ||
|
||
impl Rule for NoDuplicateJsonKeys { | ||
type Query = Ast<JsonObjectValue>; | ||
type State = DuplicatedKeys; | ||
type Signals = Option<Self::State>; | ||
type Options = (); | ||
|
||
fn run(ctx: &RuleContext<Self>) -> Self::Signals { | ||
let query = ctx.query(); | ||
let mut names = HashMap::<String, Vec<TextRange>>::new(); | ||
let mut original_key = None; | ||
for (index, member) in query.json_member_list().iter().flatten().enumerate() { | ||
let name = member.name().ok()?; | ||
if index == 0 { | ||
original_key = Some(name.clone()); | ||
} | ||
let text = name.inner_string_text().ok()?; | ||
if let Some(ranges) = names.get_mut(text.text()) { | ||
ranges.push(name.range()); | ||
} else { | ||
names.insert(text.text().to_string(), vec![]); | ||
} | ||
} | ||
|
||
let duplicated_keys: Vec<_> = names | ||
.into_values() | ||
.filter(|ranges| !ranges.is_empty()) | ||
.flatten() | ||
.collect(); | ||
|
||
if !duplicated_keys.is_empty() { | ||
let Some(original_key) = original_key else { return None}; | ||
|
||
return Some(DuplicatedKeys { | ||
original_key, | ||
duplicated_keys, | ||
}); | ||
} | ||
None | ||
} | ||
|
||
fn diagnostic(_ctx: &RuleContext<Self>, state: &Self::State) -> Option<RuleDiagnostic> { | ||
let DuplicatedKeys { | ||
duplicated_keys, | ||
original_key, | ||
} = state; | ||
let mut diagnostic = RuleDiagnostic::new( | ||
rule_category!(), | ||
original_key.range(), | ||
markup! { | ||
"The key "<Emphasis>{{original_key.inner_string_text().ok()?.text()}}</Emphasis>" was already declared." | ||
}, | ||
); | ||
for range in duplicated_keys { | ||
diagnostic = diagnostic.detail( | ||
range, | ||
markup! { | ||
"This where a duplicated key was declared again." | ||
}, | ||
); | ||
} | ||
Some(diagnostic.note( | ||
markup! { | ||
"If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored." | ||
}, | ||
)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
use rome_diagnostics::Diagnostic; | ||
|
||
#[derive(Clone, Debug, PartialEq, Eq, Diagnostic)] | ||
#[diagnostic(category = "suppressions/parse")] | ||
pub struct SuppressionDiagnostic {} |
Oops, something went wrong.