Skip to content
This repository was archived by the owner on Aug 31, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
216773f
feat: 🎸 allow comments in json file
IWANABETHATGUY Apr 17, 2023
62527a6
chore: 🤖 fmt
IWANABETHATGUY Apr 17, 2023
091b957
chore: 🤖 update schema
IWANABETHATGUY Apr 17, 2023
a50910e
chore: 🤖 lint
IWANABETHATGUY Apr 17, 2023
77939fa
chore: 🤖 update codegen
IWANABETHATGUY Apr 22, 2023
9e5d51f
chore: 🤖 pass all tests
IWANABETHATGUY May 3, 2023
8a2531e
chore: 🤖 basic finish parse with comments
IWANABETHATGUY May 3, 2023
43c655d
chore: 🤖 format
IWANABETHATGUY May 4, 2023
b816d45
chore: 🤖 lint
IWANABETHATGUY May 4, 2023
584e045
fix: 🐛 compile erorr
IWANABETHATGUY May 4, 2023
7fc1bec
chore: 🤖 add matcher
IWANABETHATGUY May 5, 2023
a55484f
chore: 🤖 add extra test
IWANABETHATGUY May 5, 2023
872b164
chore: 🤖 update snap
IWANABETHATGUY May 5, 2023
4e2ef9b
chore: 🤖 update snap
IWANABETHATGUY May 5, 2023
94d581b
chore: 🤖 basic finish
IWANABETHATGUY May 5, 2023
955fca0
fix Cargo.toml
ematipico Jul 20, 2023
228ed45
chore: rebase
ematipico Jul 20, 2023
d172dac
chore: rebase
ematipico Jul 20, 2023
a8b520d
just ready
ematipico Jul 20, 2023
3f0240d
feat(rome_formatter): add support to format comments
ematipico Jul 20, 2023
f299ba5
Merge remote-tracking branch 'origin/main' into feat/formatter-json-c…
ematipico Jul 20, 2023
d3e0f32
chore: add proper comments
ematipico Jul 21, 2023
91a535c
update changelog
ematipico Jul 21, 2023
ad2eaec
refactor
ematipico Jul 21, 2023
7b6f93a
update playground
ematipico Jul 21, 2023
71a71f8
regression
ematipico Jul 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore: 🤖 basic finish parse with comments
  • Loading branch information
IWANABETHATGUY authored and ematipico committed Jul 20, 2023
commit 8a2531e46dddde2e37220c2feca5d9399ead5d54
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
31 changes: 27 additions & 4 deletions crates/rome_json_parser/src/parser.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::token_source::JsonTokenSource;
use rome_json_syntax::JsonSyntaxKind;
use rome_parser::diagnostic::merge_diagnostics;
use rome_parser::diagnostic::{expected_token, merge_diagnostics};
use rome_parser::event::Event;
use rome_parser::prelude::*;
use rome_parser::token_source::Trivia;
Expand All @@ -12,16 +12,16 @@ pub(crate) struct JsonParser<'source> {
config: JsonParserConfig,
}

#[derive(Default)]
#[derive(Default, Debug, Clone, Copy)]
pub struct JsonParserConfig {
allow_comments: bool,
pub allow_comments: bool,
}

impl<'source> JsonParser<'source> {
pub fn new(source: &'source str, config: JsonParserConfig) -> Self {
Self {
context: ParserContext::default(),
source: JsonTokenSource::from_str(source),
source: JsonTokenSource::from_str(source, config),
config,
}
}
Expand Down Expand Up @@ -61,4 +61,27 @@ impl<'source> Parser for JsonParser<'source> {
fn source_mut(&mut self) -> &mut Self::Source {
&mut self.source
}

/// Try to eat a specific token kind, if the kind is not there then adds an error to the events stack.
fn expect(&mut self, kind: Self::Kind) -> bool {
if self.eat(kind) {
true
} else {
if self.config.allow_comments {
println!("something");
while matches!(
kind,
JsonSyntaxKind::COMMENT | JsonSyntaxKind::MULTILINE_COMMENT
) {
self.bump_any();
}
}
if self.eat(kind) {
return true;
}

self.error(expected_token(kind));
false
}
}
}
19 changes: 17 additions & 2 deletions crates/rome_json_parser/src/token_source.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::lexer::Lexer;
use crate::JsonParserConfig;
use rome_json_syntax::JsonSyntaxKind::{EOF, TOMBSTONE};
use rome_json_syntax::{JsonSyntaxKind, TextRange};
use rome_parser::diagnostic::ParseDiagnostic;
Expand All @@ -12,18 +13,20 @@ pub(crate) struct JsonTokenSource<'source> {
current: JsonSyntaxKind,
current_range: TextRange,
preceding_line_break: bool,
config: JsonParserConfig,
}

impl<'source> JsonTokenSource<'source> {
pub fn from_str(source: &'source str) -> Self {
let lexer = Lexer::from_str(source);
pub fn from_str(source: &'source str, config: JsonParserConfig) -> Self {
let lexer = Lexer::from_str(source).with_config(config);

let mut source = Self {
lexer,
trivia: Vec::new(),
current: TOMBSTONE,
current_range: TextRange::default(),
preceding_line_break: false,
config,
};

source.next_non_trivia_token(true);
Expand All @@ -39,6 +42,18 @@ impl<'source> JsonTokenSource<'source> {

match trivia_kind {
Err(_) => {
if self.config.allow_comments && token.kind().is_comments() {
dbg!(token.kind());
let trivia_kind = match token.kind() {
JsonSyntaxKind::COMMENT => TriviaPieceKind::SingleLineComment,
JsonSyntaxKind::MULTILINE_COMMENT => TriviaPieceKind::MultiLineComment,
_ => unreachable!(),
};
self.trivia
.push(Trivia::new(trivia_kind, token.range(), trailing));
continue;
}

self.current = token.kind();
self.current_range = token.range();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/*leading*/ [1,true] // trivial
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
source: crates/rome_json_parser/tests/spec_test.rs
expression: snapshot
---

## Input

```json
/*leading*/ [1,true] // trivial

```


## AST

```
JsonRoot {
value: JsonArrayValue {
l_brack_token: [email protected] "[" [Comments("/*leading*/"), Whitespace(" ")] [],
elements: JsonArrayElementList [
JsonNumberValue {
value_token: [email protected] "1" [] [],
},
[email protected] "," [] [],
JsonBooleanValue {
value_token: [email protected] "true" [] [],
},
],
r_brack_token: [email protected] "]" [] [Whitespace(" "), Comments("// trivial")],
},
eof_token: [email protected] "" [Newline("\n")] [],
}
```

## CST

```
0: [email protected]
0: [email protected]
0: [email protected] "[" [Comments("/*leading*/"), Whitespace(" ")] []
1: [email protected]
0: [email protected]
0: [email protected] "1" [] []
1: [email protected] "," [] []
2: [email protected]
0: [email protected] "true" [] []
2: [email protected] "]" [] [Whitespace(" "), Comments("// trivial")]
1: [email protected] "" [Newline("\n")] []

```


12 changes: 8 additions & 4 deletions crates/rome_json_parser/tests/spec_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ pub enum ExpectedOutcome {
Undefined,
}

pub fn run(test_case: &str, _snapshot_name: &str, test_directory: &str, outcome: &str) {
let outcome = match outcome {
pub fn run(test_case: &str, _snapshot_name: &str, test_directory: &str, outcome_str: &str) {
let outcome = match outcome_str {
"ok" => ExpectedOutcome::Pass,
"error" => ExpectedOutcome::Fail,
"undefined" => ExpectedOutcome::Undefined,
_ => panic!("Invalid expected outcome {outcome}"),
"allow_comments" => ExpectedOutcome::Pass,
_ => panic!("Invalid expected outcome {outcome_str}"),
};

let test_case_path = Path::new(test_case);
Expand All @@ -35,7 +36,10 @@ pub fn run(test_case: &str, _snapshot_name: &str, test_directory: &str, outcome:
let content = fs::read_to_string(test_case_path)
.expect("Expected test path to be a readable file in UTF8 encoding");

let parsed = parse_json(&content, JsonParserConfig::default());
let parse_conifg = JsonParserConfig {
allow_comments: outcome_str == "allow_comments",
};
let parsed = parse_json(&content, parse_conifg);
let formatted_ast = format!("{:#?}", parsed.tree());

let mut snapshot = String::new();
Expand Down
5 changes: 5 additions & 0 deletions crates/rome_json_parser/tests/spec_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,8 @@ mod undefined {
//! parsers are free to accept or reject content
tests_macros::gen_tests! {"tests/json_test_suite/undefined/*.json", crate::spec_test::run, "undefined"}
}

mod allow_comments {
//! Tests should pass even with comments in json
tests_macros::gen_tests! {"tests/json_test_suite/allow_comments/*.json", crate::spec_test::run, "allow_comments"}
}
7 changes: 7 additions & 0 deletions crates/rome_json_syntax/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ impl JsonSyntaxKind {
matches!(self, JsonSyntaxKind::NEWLINE | JsonSyntaxKind::WHITESPACE)
}

pub fn is_comments(self) -> bool {
matches!(
self,
JsonSyntaxKind::COMMENT | JsonSyntaxKind::MULTILINE_COMMENT
)
}

#[inline]
pub const fn is_keyword(self) -> bool {
matches!(self, T![null] | T![true] | T![false])
Expand Down
4 changes: 0 additions & 4 deletions crates/rome_service/src/configuration/json.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
use std::str::FromStr;

use bpaf::Bpaf;
use indexmap::IndexSet;
use serde::{Deserialize, Serialize};
use serde_json::from_str;

use super::StringSet;
#[derive(Default, Debug, Deserialize, Serialize, Eq, PartialEq, Clone, Bpaf)]
Expand Down