Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

feat: 🎸 allow comments in json file #4382

Closed
Closed
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/rome_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ rome_json_syntax = { path = "../rome_json_syntax" }
rome_migrate = { path = "../rome_migrate" }
rome_rowan = { path = "../rome_rowan" }
indexmap = { workspace = true }
globset = "0.4.10"

[target.'cfg(unix)'.dependencies]
libc = "0.2.127"
Expand Down
3 changes: 2 additions & 1 deletion crates/rome_cli/src/execute/migrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::{CliDiagnostic, CliSession};
use rome_console::{markup, ConsoleExt};
use rome_diagnostics::PrintDiagnostic;
use rome_fs::OpenOptions;
use rome_json_parser::JsonParserConfig;
use rome_json_syntax::JsonRoot;
use rome_migrate::{migrate_configuration, ControlFlow};
use rome_rowan::AstNode;
Expand All @@ -26,7 +27,7 @@ pub(crate) fn run(
fs.open_with_options(configuration_path.as_path(), open_options)?;
let mut configuration_content = String::new();
configuration_file.read_to_string(&mut configuration_content)?;
let parsed = rome_json_parser::parse_json(&configuration_content);
let parsed = rome_json_parser::parse_json(&configuration_content, JsonParserConfig::default());
let mut errors = 0;
let mut tree = parsed.tree();
let mut actions = Vec::new();
Expand Down
1 change: 1 addition & 0 deletions crates/rome_cli/src/execute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ pub(crate) fn execute_mode(
cli_options: &CliOptions,
paths: Vec<OsString>,
) -> Result<(), CliDiagnostic> {
dbg!(&paths);
mode.max_diagnostics = if let Some(max_diagnostics) = cli_options.max_diagnostics {
if max_diagnostics > MAXIMUM_DISPLAYABLE_DIAGNOSTICS {
return Err(CliDiagnostic::overflown_argument(
Expand Down
3 changes: 3 additions & 0 deletions crates/rome_cli/src/execute/process_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ pub(crate) type FileResult = Result<FileStatus, Message>;
pub(crate) fn process_file(ctx: &TraversalOptions, path: &Path) -> FileResult {
tracing::trace_span!("process_file", path = ?path).in_scope(move || {
let rome_path = RomePath::new(path);
dbg!(&rome_path);

let supported_format = ctx.can_format(&rome_path).with_file_path_and_code(
path.display().to_string(),
Expand Down Expand Up @@ -204,6 +205,7 @@ pub(crate) fn process_file(ctx: &TraversalOptions, path: &Path) -> FileResult {

// In formatting mode, abort immediately if the file has errors
errors = result.errors;
dbg!(&errors);
match ctx.execution.traversal_mode() {
TraversalMode::Format { ignore_errors, .. } if errors > 0 => {
return Err(if *ignore_errors {
Expand Down Expand Up @@ -284,6 +286,7 @@ pub(crate) fn process_file(ctx: &TraversalOptions, path: &Path) -> FileResult {
TraversalMode::Migrate { write: dry_run, .. } => *dry_run,
};

dbg!(&"process file");
let printed = file_guard
.format_file()
.with_file_path_and_code(path.display().to_string(), category!("format"))?;
Expand Down
1 change: 0 additions & 1 deletion crates/rome_cli/src/execute/traverse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ pub(crate) fn traverse(
inputs: Vec<OsString>,
) -> Result<(), CliDiagnostic> {
init_thread_pool();

if inputs.is_empty() && execution.as_stdin_file().is_none() {
return Err(CliDiagnostic::missing_argument(
"<INPUT>",
Expand Down
40 changes: 40 additions & 0 deletions crates/rome_cli/tests/commands/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1608,3 +1608,43 @@ file2.js
result,
));
}

#[test]
fn ignore_comments_error_when_allow_comments() {
let mut fs = MemoryFileSystem::default();
let mut console = BufferConsole::default();

let config_json = r#"

{
"json": {
"allowComments": ["*.json"]
}
}

"#;
let rome_config = "rome.json";
let code = r#"
/*test*/ [1, 2, 3]
"#;
let file_path = Path::new("tsconfig.json");
fs.insert(file_path.into(), code.as_bytes());
fs.insert(rome_config.into(), config_json);

println!("something--------------------xxxxxxxxxxxxxxxxxx");
let result = run_cli(
DynRef::Borrowed(&mut fs),
&mut console,
Args::from(&[("format"), file_path.as_os_str().to_str().unwrap()]),
);

// assert!(result.is_ok(), "run_cli returned {result:?}");

assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"ignore_comments_error_when_allow_comments",
fs,
console,
result,
));
}
9 changes: 6 additions & 3 deletions crates/rome_cli/tests/commands/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use bpaf::Args;
use rome_console::BufferConsole;
use rome_fs::{FileSystemExt, MemoryFileSystem};
use rome_json_formatter::context::JsonFormatOptions;
use rome_json_parser::parse_json;
use rome_json_parser::{parse_json, JsonParserConfig};
use rome_service::DynRef;
use std::path::Path;

Expand Down Expand Up @@ -52,7 +52,7 @@ fn creates_config_file() {
let mut content = String::new();
file.read_to_string(&mut content)
.expect("failed to read file from memory FS");
let parsed = parse_json(CONFIG_INIT_DEFAULT);
let parsed = parse_json(CONFIG_INIT_DEFAULT, JsonParserConfig::default());
let formatted =
rome_json_formatter::format_node(JsonFormatOptions::default(), &parsed.syntax())
.expect("valid format document")
Expand Down Expand Up @@ -95,7 +95,10 @@ fn creates_config_file_when_rome_installed_via_package_manager() {
let mut content = String::new();
file.read_to_string(&mut content)
.expect("failed to read file from memory FS");
let parsed = parse_json(CONFIG_INIT_DEFAULT_WHEN_INSTALLED);
let parsed = parse_json(
CONFIG_INIT_DEFAULT_WHEN_INSTALLED,
JsonParserConfig::default(),
);
let formatted =
rome_json_formatter::format_node(JsonFormatOptions::default(), &parsed.syntax())
.expect("valid format document")
Expand Down
4 changes: 2 additions & 2 deletions crates/rome_cli/tests/snap_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rome_formatter::IndentStyle;
use rome_fs::{FileSystemExt, MemoryFileSystem};
use rome_json_formatter::context::JsonFormatOptions;
use rome_json_formatter::format_node;
use rome_json_parser::parse_json;
use rome_json_parser::{parse_json, JsonParserConfig};
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::env::{current_exe, temp_dir};
Expand Down Expand Up @@ -49,7 +49,7 @@ impl CliSnapshot {
let mut content = String::new();

if let Some(configuration) = &self.configuration {
let parsed = parse_json(&redact_snapshot(configuration));
let parsed = parse_json(&redact_snapshot(configuration), JsonParserConfig::default());
let formatted = format_node(
JsonFormatOptions::default().with_indent_style(IndentStyle::Space(2)),
&parsed.syntax(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
source: crates/rome_cli/tests/snap_test.rs
expression: content
---
## `rome.json`

```json
{
"json": {
"allowComments": ["*.json"]
}
}
```

## `tsconfig.json`

```json

/*test*/ [1, 2, 3]

```

# Emitted Messages

```block
tsconfig.json format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

i Formatter would have printed the following content:

1 │ -
2 │ - /*test*/·[1,·2,·3]
3 │ - →
1 │ + [1,·2,·3]
2 │ +


```

```block
Compared 1 file(s) in <TIME>
```


2 changes: 1 addition & 1 deletion crates/rome_deserialize/src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ where
{
let mut output = Output::default();
let mut diagnostics = vec![];
let parse = parse_json(source);
let parse = parse_json(source, rome_json_parser::JsonParserConfig::default());
Output::deserialize_from_ast(parse.tree(), &mut output, &mut diagnostics);
let mut errors = parse
.into_diagnostics()
Expand Down
5 changes: 3 additions & 2 deletions crates/rome_json_formatter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,9 +290,10 @@ pub fn format_sub_tree(options: JsonFormatOptions, root: &JsonSyntaxNode) -> For

#[cfg(test)]
mod tests {

use crate::context::JsonFormatOptions;
use crate::format_node;
use rome_json_parser::parse_json;
use rome_json_parser::{parse_json, JsonParserConfig};

#[test]
fn smoke_test() {
Expand All @@ -305,7 +306,7 @@ mod tests {
"e": false
}
"#;
let parse = parse_json(src);
let parse = parse_json(src, JsonParserConfig::default());
let options = JsonFormatOptions::default();
let formatted = format_node(options, &parse.syntax()).unwrap();
assert_eq!(
Expand Down
4 changes: 2 additions & 2 deletions crates/rome_json_formatter/tests/language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use rome_formatter::{FormatContext, FormatResult, Formatted, IndentStyle, LineWi
use rome_formatter_test::TestFormatLanguage;
use rome_json_formatter::context::{JsonFormatContext, JsonFormatOptions};
use rome_json_formatter::{format_node, format_range, JsonFormatLanguage};
use rome_json_parser::parse_json;
use rome_json_parser::{parse_json, JsonParserConfig};
use rome_json_syntax::JsonLanguage;
use rome_parser::AnyParse;
use rome_rowan::{SyntaxNode, TextRange};
Expand All @@ -18,7 +18,7 @@ impl TestFormatLanguage for JsonTestFormatLanguage {
type FormatLanguage = JsonFormatLanguage;

fn parse(&self, text: &str) -> AnyParse {
parse_json(text).into()
parse_json(text, JsonParserConfig::default()).into()
}

fn deserialize_format_options(
Expand Down
4 changes: 2 additions & 2 deletions crates/rome_json_formatter/tests/quick_test.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use rome_formatter_test::check_reformat::CheckReformat;
use rome_json_formatter::context::JsonFormatOptions;
use rome_json_formatter::format_node;
use rome_json_parser::parse_json;
use rome_json_parser::{parse_json, JsonParserConfig};

mod language {
include!("language.rs");
Expand All @@ -27,7 +27,7 @@ fn quick_test() {
]
}
"#;
let parse = parse_json(src);
let parse = parse_json(src, JsonParserConfig::default());
let options = JsonFormatOptions::default();
let result = format_node(options.clone(), &parse.syntax())
.unwrap()
Expand Down
29 changes: 21 additions & 8 deletions crates/rome_json_parser/src/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use rome_parser::diagnostic::ParseDiagnostic;
use std::iter::FusedIterator;
use std::ops::Add;

use crate::JsonParserConfig;

pub struct Token {
kind: JsonSyntaxKind,
range: TextRange,
Expand All @@ -34,6 +36,7 @@ pub(crate) struct Lexer<'src> {
position: usize,

diagnostics: Vec<ParseDiagnostic>,
config: JsonParserConfig,
}

impl<'src> Lexer<'src> {
Expand All @@ -43,6 +46,7 @@ impl<'src> Lexer<'src> {
source: string,
position: 0,
diagnostics: vec![],
config: JsonParserConfig::default(),
}
}

Expand Down Expand Up @@ -695,10 +699,12 @@ impl<'src> Lexer<'src> {
b'*' if self.peek_byte() == Some(b'/') => {
self.advance(2);

self.diagnostics.push(ParseDiagnostic::new(
"JSON standard does not allow comments.",
start..self.text_position(),
));
if !self.config.allow_comments {
self.diagnostics.push(ParseDiagnostic::new(
"JSON standard does not allow comments.",
start..self.text_position(),
));
}

if has_newline {
return MULTILINE_COMMENT;
Expand Down Expand Up @@ -739,16 +745,23 @@ impl<'src> Lexer<'src> {
}
}

self.diagnostics.push(ParseDiagnostic::new(
"JSON standard does not allow comments.",
start..self.text_position(),
));
if !self.config.allow_comments {
self.diagnostics.push(ParseDiagnostic::new(
"JSON standard does not allow comments.",
start..self.text_position(),
));
}

COMMENT
}
_ => self.eat_unexpected_character(),
}
}

pub(crate) fn with_config(mut self, config: JsonParserConfig) -> Self {
self.config = config;
self
}
}

impl Iterator for Lexer<'_> {
Expand Down
16 changes: 11 additions & 5 deletions crates/rome_json_parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use crate::parser::JsonParser;
use crate::syntax::parse_root;
pub use parser::JsonParserConfig;
use rome_json_factory::JsonSyntaxFactory;
use rome_json_syntax::{JsonLanguage, JsonRoot, JsonSyntaxNode};
pub use rome_parser::prelude::*;
Expand All @@ -18,15 +19,19 @@ mod token_source;
pub(crate) type JsonLosslessTreeSink<'source> =
LosslessTreeSink<'source, JsonLanguage, JsonSyntaxFactory>;

pub fn parse_json(source: &str) -> JsonParse {
pub fn parse_json(source: &str, config: JsonParserConfig) -> JsonParse {
let mut cache = NodeCache::default();
parse_json_with_cache(source, &mut cache)
parse_json_with_cache(source, &mut cache, config)
}

/// Parses the provided string as JSON program using the provided node cache.
pub fn parse_json_with_cache(source: &str, cache: &mut NodeCache) -> JsonParse {
pub fn parse_json_with_cache(
source: &str,
cache: &mut NodeCache,
config: JsonParserConfig,
) -> JsonParse {
tracing::debug_span!("parse").in_scope(move || {
let mut parser = JsonParser::new(source);
let mut parser = JsonParser::new(source, config);

parse_root(&mut parser);

Expand Down Expand Up @@ -61,7 +66,8 @@ impl JsonParse {
///
/// # fn main() -> Result<(), SyntaxError> {
/// use rome_json_syntax::JsonSyntaxKind;
/// let parse = parse_json(r#"["a", 1]"#);
/// use rome_json_parser::JsonParserConfig;
/// let parse = parse_json(r#"["a", 1]"#, JsonParserConfig::default());
///
/// // Get the root value
/// let root_value = parse.tree().value()?;
Expand Down
Loading