difftreelog
feat(fmt) basic comment formatting in objects
in: master
21 files changed
.cargo/configdiffbeforeafterbothno changes
.cargo/config.tomldiffbeforeafterbothno changes
cmds/jrsonnet-fmt/Cargo.tomldiffbeforeafterboth6[dependencies]6[dependencies]7dprint-core = "0.58.2"7dprint-core = "0.58.2"8jrsonnet-rowan-parser = { path = "../../crates/jrsonnet-rowan-parser" }8jrsonnet-rowan-parser = { path = "../../crates/jrsonnet-rowan-parser" }9insta = "1.15"10indoc = "1.0"911cmds/jrsonnet-fmt/src/children.rsdiffbeforeafterbothno changes
cmds/jrsonnet-fmt/src/comments.rsdiffbeforeafterbothno changes
cmds/jrsonnet-fmt/src/main.rsdiffbeforeafterboth1use std::any::type_name;1use std::any::type_name;223use children::children_between;3use dprint_core::formatting::{PrintItems, PrintOptions, Signal};4use dprint_core::formatting::{PrintItems, PrintOptions};4use jrsonnet_rowan_parser::{5use jrsonnet_rowan_parser::{5 nodes::{6 nodes::{6 ArgsDesc, Assertion, BinaryOperator, Bind, CompSpec, Destruct, DestructArrayPart,7 ArgsDesc, Assertion, BinaryOperator, Bind, CompSpec, Destruct, DestructArrayPart,7 DestructRest, Expr, Field, FieldName, ForSpec, IfSpec, ImportKind, LhsExpr, Literal,8 DestructRest, Expr, Field, FieldName, ForSpec, IfSpec, ImportKind, LhsExpr, Literal,8 Member, Name, Number, ObjBody, ObjLocal, ParamsDesc, SliceDesc, SourceFile, Text,9 Member, Name, Number, ObjBody, ObjLocal, ParamsDesc, SliceDesc, SourceFile, Text,9 UnaryOperator,10 UnaryOperator,10 },11 },11 AstToken, SyntaxToken,12 AstNode, AstToken, SyntaxToken,12};13};1415use crate::{16 children::should_start_with_newline,17 comments::{format_comments, CommentLocation},18};1920mod children;21mod comments;22#[cfg(test)]23mod tests;132414pub trait Printable {25pub trait Printable {15 fn print(&self) -> PrintItems;26 fn print(&self) -> PrintItems;18macro_rules! pi {29macro_rules! pi {19 (@i; $($t:tt)*) => {{30 (@i; $($t:tt)*) => {{20 #[allow(unused_mut)]31 #[allow(unused_mut)]21 let mut o = PrintItems::new();32 let mut o = dprint_core::formatting::PrintItems::new();22 pi!(@s; o: $($t)*);33 pi!(@s; o: $($t)*);23 o34 o24 }};35 }};27 pi!(@s; $o: $($t)*);38 pi!(@s; $o: $($t)*);28 }};39 }};29 (@s; $o:ident: nl $($t:tt)*) => {{40 (@s; $o:ident: nl $($t:tt)*) => {{30 $o.push_signal(Signal::NewLine);41 $o.push_signal(dprint_core::formatting::Signal::NewLine);31 pi!(@s; $o: $($t)*);42 pi!(@s; $o: $($t)*);32 }};43 }};44 (@s; $o:ident: tab $($t:tt)*) => {{45 $o.push_signal(dprint_core::formatting::Signal::Tab);46 pi!(@s; $o: $($t)*);47 }};33 (@s; $o:ident: >i $($t:tt)*) => {{48 (@s; $o:ident: >i $($t:tt)*) => {{34 $o.push_signal(Signal::StartIndent);49 $o.push_signal(dprint_core::formatting::Signal::StartIndent);35 pi!(@s; $o: $($t)*);50 pi!(@s; $o: $($t)*);36 }};51 }};37 (@s; $o:ident: <i $($t:tt)*) => {{52 (@s; $o:ident: <i $($t:tt)*) => {{38 $o.push_signal(Signal::FinishIndent);53 $o.push_signal(dprint_core::formatting::Signal::FinishIndent);39 pi!(@s; $o: $($t)*);54 pi!(@s; $o: $($t)*);40 }};55 }};41 (@s; $o:ident: {$expr:expr} $($t:tt)*) => {{56 (@s; $o:ident: {$expr:expr} $($t:tt)*) => {{42 $o.extend($expr.print());57 $o.extend($expr.print());43 pi!(@s; $o: $($t)*);58 pi!(@s; $o: $($t)*);44 }};59 }};60 (@s; $o:ident: items($expr:expr) $($t:tt)*) => {{61 $o.extend($expr);62 pi!(@s; $o: $($t)*);63 }};45 (@s; $o:ident: if ($e:expr)($($then:tt)*) $($t:tt)*) => {{64 (@s; $o:ident: if ($e:expr)($($then:tt)*) $($t:tt)*) => {{46 if $e {65 if $e {47 pi!(@s; $o: $($then)*);66 pi!(@s; $o: $($then)*);66 pi!(@s; $o: $($t)*)85 pi!(@s; $o: $($t)*)67 };86 };68}87}88pub(crate) use p;89pub(crate) use pi;699070impl<P> Printable for Option<P>91impl<P> Printable for Option<P>71where92where266 match self {287 match self {267 ObjBody::ObjBodyComp(_) => todo!(),288 ObjBody::ObjBodyComp(_) => todo!(),268 ObjBody::ObjBodyMemberList(l) => {289 ObjBody::ObjBodyMemberList(l) => {269 let mut pi = p!(new:);290 let mut pi = p!(new: str("{") >i nl);291 let (children, end_comments) = children_between::<Member>(292 l.syntax().clone(),293 l.l_brace_token().map(Into::into).as_ref(),294 l.r_brace_token().map(Into::into).as_ref(),295 );270 for mem in l.members() {296 for mem in children.into_iter() {297 if mem.needs_newline_above() {298 p!(pi: nl);299 }300 p!(pi: items(format_comments(&mem.before_trivia, CommentLocation::AboveItem)));271 match mem {301 match mem.value {272 Member::MemberBindStmt(b) => {302 Member::MemberBindStmt(b) => {273 p!(pi: {b.obj_local()})303 p!(pi: {b.obj_local()})274 }304 }279 p!(pi: {f.field()})309 p!(pi: {f.field()})280 }310 }281 }311 }282 p!(pi: str(",") nl)312 p!(pi: str(","));313 p!(pi: items(format_comments(&mem.inline_trivia, CommentLocation::ItemInline)));314 p!(pi: nl)283 }315 }316317 // TODO: implement same thing as needs_newline_above, but for end comments318 if should_start_with_newline(&end_comments) {319 p!(pi: nl);320 }321 p!(pi: items(format_comments(&end_comments, CommentLocation::EndOfItems)));322 p!(pi: <i str("}"));284 pi323 pi285 }324 }286 }325 }382 pi421 pi383 }422 }384 Expr::ExprObject(o) => {423 Expr::ExprObject(o) => {385 p!(new: str("{") >i nl {o.obj_body()} <i str("}"))424 p!(new: {o.obj_body()})386 }425 }387 Expr::ExprArrayComp(arr) => {426 Expr::ExprArrayComp(arr) => {388 let mut pi = p!(new: str("[") {arr.expr()});427 let mut pi = p!(new: str("[") {arr.expr()});431470432fn main() {471fn main() {433 let (parsed, _errors) = jrsonnet_rowan_parser::parse(472 let (parsed, _errors) = jrsonnet_rowan_parser::parse(434 r#"473 r#"435474436475437 # Edit me!476 # Edit me!438 local b = import "b.libsonnet"; # comment477 local b = import "b.libsonnet"; # comment439 local a = import "a.libsonnet";478 local a = import "a.libsonnet";440479441 local f(x,y)=x+y;480 local f(x,y)=x+y;442481443 local {a: [b, ..., c], d, ...e} = null;482 local {a: [b, ..., c], d, ...e} = null;444483445 local ass = assert false : false; false;484 local ass = assert false : false; false;446485447 local fn = function(a, b, c = 3) 4;486 local fn = function(a, b, c = 3) 4;448487449 local comp = [a for b in c if d == e];488 local comp = [a for b in c if d == e];450 local ocomp = {[k]: 1 for k in v};489 local ocomp = {[k]: 1 for k in v};451490452 local ? = skip;491 local ? = skip;453492454 local intr = $intrinsic(test);493 local intr = $intrinsic(test);455 local intrId = $intrinsicId;494 local intrId = $intrinsicId;456 local intrThisFile = $intrinsicThisFile;495 local intrThisFile = $intrinsicThisFile;457496458 local ie = a[expr];497 local ie = a[expr];459498460 local unary = !a;499 local unary = !a;461500462 local Template = {z: "foo"};501 local Template = {z: "foo"};463502464 {503 {465 local504 local466505467 h = 3,506 h = 3,468 assert self.a == 1507 assert self.a == 1469508470 : "error",509 : "error",471 "f": ((((((3)))))) ,510 "f": ((((((3)))))) ,472 "g g":511 "g g":473 f(4,2),512 f(4,2),474 arr: [[513 arr: [[475 1, 2,514 1, 2,476 ],515 ],477 3,516 3,478 {517 {479 b: {518 b: {480 c: {519 c: {481 k: [16]520 k: [16]482 }521 }483 }522 }484 }523 }485 ],524 ],486 m: a[1::],525 m: a[1::],487 m: b[::],526 m: b[::],527528 comments: {529 _: '',530 // Plain comment531 a: '',532533 # Plain comment with empty line before534 b: '',535 /*Single-line multiline comment536537 */538 c: '',539540 /**Single-line multiline doc comment541542 */543 c: '',544545 /**multiline doc comment546 s547 */548 c: '',549550 /*551552 Multi-line553554 comment555 */556 d: '',557558 e: '', // Inline comment559560 k: '',561562 // Text after everything563 },564 comments2: {565 k: '',566 // Text after everything, but no newline above567 },488 k: if a == b then568 k: if a == b then489569490570491 2571 2492572493 else Template {}573 else Template {}494 } + Template574 } + Template495575496576497"#,577"#,498 );578 );499579500 // dbg!(errors);580 // dbg!(errors);cmds/jrsonnet-fmt/src/snapshots/jrsonnet_fmt__tests__complex_comments_snapshot.snapdiffbeforeafterbothno changes
cmds/jrsonnet-fmt/src/tests.rsdiffbeforeafterbothno changes
cmds/jrsonnet-lsp/Cargo.tomldiffbeforeafterbothno changes
cmds/jrsonnet-lsp/src/main.rsdiffbeforeafterbothno changes
crates/jrsonnet-rowan-parser/Cargo.tomldiffbeforeafterboth4edition = "2021"4edition = "2021"556[dependencies]6[dependencies]7anyhow = "1.0.51"7anyhow = "1.0"8backtrace = "0.3.63"8backtrace = "0.3.63"9drop_bomb = "0.1.5"9drop_bomb = "0.1.5"10indoc = "1.0.3"10indoc = "1.0"11logos = "0.12.0"11logos = "0.12"12miette = { version = "4.2.1", features = ["fancy"] }12miette = { version = "4.2", features = ["fancy"] }13rowan = "0.15.0"13rowan = "0.15"14text-size = "1.1.0"14text-size = "1.1"15thiserror = "1.0.30"15thiserror = "1.0"161617[dev-dependencies]17[dev-dependencies]18backtrace = "0.3.63"18backtrace = "0.3.63"19indoc = "1.0.3"19indoc = "1.0"20insta = "1.10.0"20insta = "1.15"21anyhow = "1.0.57"21anyhow = "1.0"22jrsonnet-stdlib = { path = "../jrsonnet-stdlib" }22jrsonnet-stdlib = { path = "../jrsonnet-stdlib" }2323crates/jrsonnet-rowan-parser/jsonnet.ungramdiffbeforeafterboth56 (Expr (',' Expr)* ','?)?56 (Expr (',' Expr)* ','?)?57 ']'57 ']'58ExprObject =58ExprObject =59 '{'60 ObjBody59 ObjBody61 '}'62ExprArrayComp =60ExprArrayComp =63 '['61 '['64 Expr62 Expr168 (name:Name '=')? Expr166 (name:Name '=')? Expr169167170ObjBodyComp =168ObjBodyComp =169 '{'171 pre:ObjLocalPostComma*170 pre:ObjLocalPostComma*172 '['171 '['173 key:LhsExpr172 key:LhsExpr177 value:Expr176 value:Expr178 post:ObjLocalPreComma*177 post:ObjLocalPreComma*179 CompSpec*178 CompSpec*179 '}'180ObjBodyMemberList =180ObjBodyMemberList =181 '{'181 (Member (',' Member)* ','?)?182 (Member (',' Member)* ','?)?183 '}'182ObjBody =184ObjBody =183 ObjBodyComp185 ObjBodyComp184| ObjBodyMemberList186| ObjBodyMemberListcrates/jrsonnet-rowan-parser/src/event.rsdiffbeforeafterboth24 Token {24 Token {25 kind: SyntaxKind,25 kind: SyntaxKind,26 },26 },27 /// Push token, but do not eat anything,28 VirtualToken {29 kind: SyntaxKind,30 },27 /// Position of finished node31 /// Position of finished node28 Finish {32 Finish {29 /// Same as forward_parent of Start, but for wrapping33 /// Same as forward_parent of Start, but for wrapping105 self.token(kind);109 self.token(kind);106 eat_start_whitespace = true;110 eat_start_whitespace = true;107 }111 }112 Event::VirtualToken { kind } => {113 if eat_start_whitespace {114 self.skip_whitespace();115 }116 self.virtual_token(kind);117 eat_start_whitespace = false;118 }108 Event::Finish { wrapper } => {119 Event::Finish { wrapper } => {109 self.builder.finish_node();120 self.builder.finish_node();110 depth -= 1;121 depth -= 1;124 }135 }125 eat_start_whitespace = true;136 eat_start_whitespace = true;126 }137 }127 Event::Pending => panic!("placeholder should not end in events"),138 Event::Pending => panic!("pending event should not appear in finished events"),128 Event::Noop => {}139 Event::Noop => {}129 Event::Error(e) => {140 Event::Error(e) => {130 self.errors.push(e);141 self.errors.push(e);137 errors: self.errors,148 errors: self.errors,138 }149 }139 }150 }151 fn virtual_token(&mut self, kind: SyntaxKind) {152 self.builder.token(JsonnetLanguage::kind_to_raw(kind), "")153 }140 fn token(&mut self, kind: SyntaxKind) {154 fn token(&mut self, kind: SyntaxKind) {141 let lexeme = self.lexemes[self.offset];155 let lexeme = self.lexemes[self.offset];142 self.builder156 self.buildercrates/jrsonnet-rowan-parser/src/generated/nodes.rsdiffbeforeafterboth291 pub(crate) syntax: SyntaxNode,291 pub(crate) syntax: SyntaxNode,292}292}293impl ExprObject {293impl ExprObject {294 pub fn l_brace_token(&self) -> Option<SyntaxToken> {295 support::token(&self.syntax, T!['{'])296 }297 pub fn obj_body(&self) -> Option<ObjBody> {294 pub fn obj_body(&self) -> Option<ObjBody> {298 support::child(&self.syntax)295 support::child(&self.syntax)299 }296 }300 pub fn r_brace_token(&self) -> Option<SyntaxToken> {301 support::token(&self.syntax, T!['}'])302 }303}297}304298305#[derive(Debug, Clone, PartialEq, Eq, Hash)]299#[derive(Debug, Clone, PartialEq, Eq, Hash)]538 pub(crate) syntax: SyntaxNode,532 pub(crate) syntax: SyntaxNode,539}533}540impl ObjBodyComp {534impl ObjBodyComp {535 pub fn l_brace_token(&self) -> Option<SyntaxToken> {536 support::token(&self.syntax, T!['{'])537 }541 pub fn pre(&self) -> AstChildren<ObjLocalPostComma> {538 pub fn pre(&self) -> AstChildren<ObjLocalPostComma> {542 support::children(&self.syntax)539 support::children(&self.syntax)543 }540 }565 pub fn comp_specs(&self) -> AstChildren<CompSpec> {562 pub fn comp_specs(&self) -> AstChildren<CompSpec> {566 support::children(&self.syntax)563 support::children(&self.syntax)567 }564 }565 pub fn r_brace_token(&self) -> Option<SyntaxToken> {566 support::token(&self.syntax, T!['}'])567 }568}568}569569570#[derive(Debug, Clone, PartialEq, Eq, Hash)]570#[derive(Debug, Clone, PartialEq, Eq, Hash)]598 pub(crate) syntax: SyntaxNode,598 pub(crate) syntax: SyntaxNode,599}599}600impl ObjBodyMemberList {600impl ObjBodyMemberList {601 pub fn l_brace_token(&self) -> Option<SyntaxToken> {602 support::token(&self.syntax, T!['{'])603 }601 pub fn members(&self) -> AstChildren<Member> {604 pub fn members(&self) -> AstChildren<Member> {602 support::children(&self.syntax)605 support::children(&self.syntax)603 }606 }607 pub fn r_brace_token(&self) -> Option<SyntaxToken> {608 support::token(&self.syntax, T!['}'])609 }604}610}605611606#[derive(Debug, Clone, PartialEq, Eq, Hash)]612#[derive(Debug, Clone, PartialEq, Eq, Hash)]crates/jrsonnet-rowan-parser/src/lib.rsdiffbeforeafterboth1#![deny(unused_must_use)]1#![deny(unused_must_use)]23use event::Sink;4use generated::nodes::{SourceFile, Trivia};5use lex::lex;6use parser::{Parser, SyntaxError};7pub use rowan;283mod ast;9mod ast;4mod event;10mod event;13mod token_set;19mod token_set;142015pub use ast::{AstChildren, AstNode, AstToken};21pub use ast::{AstChildren, AstNode, AstToken};16use event::Sink;17use generated::nodes::SourceFile;18pub use generated::{nodes, syntax_kinds::SyntaxKind};22pub use generated::{nodes, syntax_kinds::SyntaxKind};19pub use language::{23pub use language::*;20 JsonnetLanguage, PreorderWithTokens, SyntaxElement, SyntaxElementChildren, SyntaxNode,21 SyntaxNodeChildren, SyntaxToken,22};23use lex::lex;24pub use token_set::SyntaxKindSet;24use parser::{Parser, SyntaxError};2525pub fn parse(input: &str) -> (SourceFile, Vec<SyntaxError>) {26pub fn parse(input: &str) -> (SourceFile, Vec<SyntaxError>) {26 let lexemes = lex(input);27 let lexemes = lex(input);28 let kinds = lexemes29 .iter()30 .map(|l| l.kind)31 .filter(|k| !Trivia::can_cast(*k))32 .collect();27 let parser = Parser::new(&lexemes);33 let parser = Parser::new(kinds);28 let events = parser.parse();34 let events = parser.parse();29 let sink = Sink::new(events, &lexemes);35 let sink = Sink::new(events, &lexemes);3036crates/jrsonnet-rowan-parser/src/marker.rsdiffbeforeafterboth114 }114 }115}115}116117pub trait AsRange {118 fn as_range(&self, p: &Parser) -> TextRange;119 fn end_token(&self) -> usize;120}121122impl AsRange for FinishedRanger {123 fn as_range(&self, p: &Parser) -> TextRange {124 TextRange::new(125 p.start_of_token(self.start_token),126 p.end_of_token(self.end_token),127 )128 }129130 fn end_token(&self) -> usize {131 self.end_token132 }133}134116crates/jrsonnet-rowan-parser/src/parser.rsdiffbeforeafterboth6use crate::{6use crate::{7 event::Event,7 event::Event,8 lex::Lexeme,8 lex::Lexeme,9 marker::{AsRange, CompletedMarker, Marker, Ranger},9 marker::{CompletedMarker, Marker, Ranger},10 nodes::{BinaryOperatorKind, Literal, Number, Text, Trivia, UnaryOperatorKind},10 nodes::{BinaryOperatorKind, Literal, Number, Text, Trivia, UnaryOperatorKind},11 token_set::SyntaxKindSet,11 token_set::SyntaxKindSet,12 AstToken, SyntaxKind,12 AstToken, SyntaxKind,33 }33 }34}34}353536pub struct Parser<'i> {36pub struct Parser {37 // TODO: remove all trivia before feeding to parser?37 // TODO: remove all trivia before feeding to parser?38 lexemes: &'i [Lexeme<'i>],38 kinds: Vec<SyntaxKind>,39 pub offset: usize,39 pub offset: usize,40 pub events: Vec<Event>,40 pub events: Vec<Event>,41 pub entered: u32,41 pub entered: u32,103 }103 }104}104}105105106impl<'i> Parser<'i> {106impl Parser {107 pub fn new(lexemes: &'i [Lexeme<'i>]) -> Self {107 pub fn new(kinds: Vec<SyntaxKind>) -> Self {108 Self {108 Self {109 lexemes,109 kinds,110 offset: 0,110 offset: 0,111 events: vec![],111 events: vec![],112 entered: 0,112 entered: 0,134 .set(ExpectedSyntaxTrackingState::Unnamed);134 .set(ExpectedSyntaxTrackingState::Unnamed);135 }135 }136 pub fn start(&mut self) -> Marker {136 pub fn start(&mut self) -> Marker {137 self.skip_trivia();138 let start_event_idx = self.events.len();137 let start_event_idx = self.events.len();139 self.events.push(Event::Pending);138 self.events.push(Event::Pending);140 self.entered += 1;139 self.entered += 1;141 Marker::new(start_event_idx)140 Marker::new(start_event_idx)142 }141 }143 pub fn start_ranger(&mut self) -> Ranger {142 pub fn start_ranger(&mut self) -> Ranger {144 self.skip_trivia();145 let pos = self.offset;143 let pos = self.offset;146 Ranger { pos }144 Ranger { pos }147 }145 }179 self.error_with_no_skip();177 self.error_with_no_skip();180 }178 }181 }179 }182 fn current_token(&self) -> Lexeme<'i> {183 self.lexemes[self.offset]184 }185 fn previous_token(&mut self) -> Option<Lexeme<'i>> {186 if self.offset == 0 {187 return None;188 }189 let mut previous_token_idx = self.offset - 1;190 while self191 .lexemes192 .get(previous_token_idx)193 .map_or(false, |l| Trivia::can_cast(l.kind))194 && previous_token_idx != 0195 {196 previous_token_idx -= 1;197 }198199 Some(self.lexemes[previous_token_idx])200 }201 pub fn start_of_token(&self, mut idx: usize) -> TextSize {202 while Trivia::can_cast(self.lexemes[idx].kind) {203 idx += 1;204 }205 self.lexemes[idx].range.start()206 }207 pub fn end_of_token(&self, mut idx: usize) -> TextSize {208 while Trivia::can_cast(self.lexemes[idx].kind) {209 idx -= 1;210 }211 self.lexemes[idx].range.end()212 }213 pub(crate) fn custom_error(&mut self, marker: impl AsRange, error: impl AsRef<str>) {214 self.last_error_token = marker.end_token();215 self.events.push(Event::Error(SyntaxError::Custom {216 error: error.as_ref().to_string(),217 range: marker.as_range(self),218 }));219 }220 pub(crate) fn error_with_recovery_set(180 pub(crate) fn error_with_recovery_set(221 &mut self,181 &mut self,222 recovery_set: SyntaxKindSet,182 recovery_set: SyntaxKindSet,238 self.expected_syntax_tracking_state198 self.expected_syntax_tracking_state239 .set(ExpectedSyntaxTrackingState::Unnamed);199 .set(ExpectedSyntaxTrackingState::Unnamed);240200241 self.skip_trivia();242 if self.at_end() || self.at_ts(recovery_set) {201 if self.at_end() || self.at_ts(recovery_set) {243 let range = self202 // let range = self244 .previous_token()203 // .previous_token()245 .map(|t| t.range)204 // .map(|t| t.range)246 .unwrap_or_else(|| TextRange::at(TextSize::from(0), TextSize::from(0)));205 // .unwrap_or_else(|| TextRange::at(TextSize::from(0), TextSize::from(0)));247206248 self.events.push(Event::Error(SyntaxError::Missing {207 // self.events.push(Event::Error(SyntaxError::Missing {249 expected: expected_syntax,208 // expected: expected_syntax,250 offset: range.end(),209 // offset: range.end(),251 }));210 // }));252 return None;211 return None;253 }212 }254213255 let current_token = self.current_token();214 let current_token = self.current();256215257 self.events.push(Event::Error(SyntaxError::Unexpected {216 // self.events.push(Event::Error(SyntaxError::Unexpected {258 expected: expected_syntax,217 // expected: expected_syntax,259 found: current_token.kind,218 // found: current_token.kind,260 range: current_token.range,219 // range: current_token.range,261 }));220 // }));262 self.clear_expected_syntaxes();221 self.clear_expected_syntaxes();263 self.last_error_token = self.offset;222 self.last_error_token = self.offset;264223267 Some(m.complete(self, SyntaxKind::ERROR))226 Some(m.complete(self, SyntaxKind::ERROR))268 }227 }269 fn bump_assert(&mut self, kind: SyntaxKind) {228 fn bump_assert(&mut self, kind: SyntaxKind) {270 self.skip_trivia();271 assert!(self.at(kind), "expected {:?}", kind);229 assert!(self.at(kind), "expected {:?}", kind);272 self.bump_remap(self.current());230 self.bump_remap(self.current());273 }231 }274 fn bump(&mut self) {232 fn bump(&mut self) {275 self.skip_trivia();276 self.bump_remap(self.current());233 self.bump_remap(self.current());277 }234 }278 fn bump_remap(&mut self, kind: SyntaxKind) {235 fn bump_remap(&mut self, kind: SyntaxKind) {279 self.skip_trivia();280 assert_ne!(self.offset, self.lexemes.len(), "already at end");236 assert_ne!(self.offset, self.kinds.len(), "already at end");281 self.events.push(Event::Token { kind });237 self.events.push(Event::Token { kind });282 self.offset += 1;238 self.offset += 1;283 self.clear_expected_syntaxes();239 self.clear_expected_syntaxes();302 {258 {303 let next = 20;259 let next = 20;304 write!(out, "\n\nNext {next} tokens:").unwrap();260 write!(out, "\n\nNext {next} tokens:").unwrap();305 for (i, tok) in self.lexemes.iter().skip(self.offset).take(next).enumerate() {261 for (i, tok) in self.kinds.iter().skip(self.offset).take(next).enumerate() {306 write!(out, "\n{i}. {tok:?}").unwrap();262 write!(out, "\n{i}. {tok:?}").unwrap();307 }263 }308 }264 }314 self.step();270 self.step();315 let mut offset = self.offset;271 let mut offset = self.offset;316 for _ in 0..i {272 for _ in 0..i {317 while self318 .lexemes319 .get(offset)320 .map(|l| Trivia::can_cast(l.kind))321 .unwrap_or(false)322 {323 offset += 1;273 offset += 1;324 }325 offset += 1;326 }274 }327 while self328 .lexemes329 .get(offset)330 .map(|l| Trivia::can_cast(l.kind))331 .unwrap_or(false)332 {333 offset += 1;334 }335 self.lexemes.get(offset).map(|l| l.kind).unwrap_or(EOF)275 self.kinds.get(offset).copied().unwrap_or(EOF)336 }276 }337 fn current(&self) -> SyntaxKind {277 fn current(&self) -> SyntaxKind {338 self.nth(0)278 self.nth(0)339 }279 }340 fn skip_trivia(&mut self) {341 while Trivia::can_cast(self.peek_raw()) {342 self.offset += 1;343 }344 }345 fn peek_raw(&mut self) -> SyntaxKind {346 self.lexemes347 .get(self.offset)348 .map(|l| l.kind)349 .unwrap_or(SyntaxKind::EOF)350 }351 #[must_use]280 #[must_use]352 pub(crate) fn expected_syntax_name(&mut self, name: &'static str) -> ExpectedSyntaxGuard {281 pub(crate) fn expected_syntax_name(&mut self, name: &'static str) -> ExpectedSyntaxGuard {353 self.expected_syntax_tracking_state282 self.expected_syntax_tracking_state507 None436 None508 };437 };509 let params = if p.at(T!['(']) {438 let params = if p.at(T!['(']) {510 if let Some(plus) = plus {439 // if let Some(plus) = plus {511 p.custom_error(plus, "can't extend with method");440 // p.custom_error(plus, "can't extend with method");512 }441 // }513 params_desc(p);442 params_desc(p);514 if p.at(T![+]) {443 // if p.at(T![+]) {515 let r = p.start_ranger();444 // let r = p.start_ranger();516 p.bump();445 // p.bump();517 p.custom_error(r.finish(p), "can't extend with method");446 // p.custom_error(r.finish(p), "can't extend with method");518 }447 // }519 true448 true520 } else {449 } else {521 false450 false669598670 if elems > 1 && !compspecs.is_empty() {599 if elems > 1 && !compspecs.is_empty() {671 for spec in compspecs {600 for spec in compspecs {672 p.custom_error(601 // p.custom_error(673 spec,602 // spec,674 "compspec may only be used if there is only one array element",603 // "compspec may only be used if there is only one array element",675 )604 // )676 }605 }677606678 m.complete(p, EXPR_ARRAY)607 m.complete(p, EXPR_ARRAY)797 } else if p.at(T![...]) {726 } else if p.at(T![...]) {798 let m_err = p.start_ranger();727 let m_err = p.start_ranger();799 destruct_rest(p);728 destruct_rest(p);800 if had_rest {729 // if had_rest {801 p.custom_error(m_err.finish(p), "only one rest can be present in array");730 // p.custom_error(m_err.finish(p), "only one rest can be present in array");802 }731 // }803 had_rest = true;732 had_rest = true;804 } else {733 } else {805 destruct(p);734 destruct(p);822 } else if p.at(T![...]) {751 } else if p.at(T![...]) {823 let m_err = p.start_ranger();752 let m_err = p.start_ranger();824 destruct_rest(p);753 destruct_rest(p);825 if had_rest {754 // if had_rest {826 p.custom_error(m_err.finish(p), "only one rest can be present in object");755 // p.custom_error(m_err.finish(p), "only one rest can be present in object");827 }756 // }828 had_rest = true;757 had_rest = true;829 } else {758 } else {830 if had_rest {759 if had_rest {crates/jrsonnet-rowan-parser/src/token_set.rsdiffbeforeafterboth34#[macro_export]34#[macro_export]35macro_rules! TS {35macro_rules! TS {36 ($($tt:tt)*) => {36 ($($tt:tt)*) => {37 SyntaxKindSet::new(&[37 $crate::SyntaxKindSet::new(&[38 $(38 $(39 T![$tt]39 $crate::T![$tt]40 ),*40 ),*41 ])41 ])42 };42 };jrsonnet-lsp/Cargo.tomldiffbeforeafterbothno changes
jrsonnet-lsp/src/main.rsdiffbeforeafterbothno changes
xtask/src/sourcegen/ast.rsdiffbeforeafterboth151 if let Some(old) = types.insert(field.ty(), field.method_name(kinds)) {151 if let Some(old) = types.insert(field.ty(), field.method_name(kinds)) {152 panic!("{name}.{} has same type as {name}.{}, resolve conflict by wrapping one field: {}", old, field.method_name(kinds), field.ty());152 panic!("{name}.{} has same type as {name}.{}, resolve conflict by wrapping one field: {}", old, field.method_name(kinds), field.ty());153 }153 }154 // TODO: check for assignable field types, i.e you can have155 // ```156 // SomeEnum =157 // SomeItem158 // | SomeOtherItem159 // ```160 // And check above will fail to detect conflict in161 // ```162 // SomeStruct =163 // SomeEnum164 // SomeItem165 // ```166 // Despite generating getters, which will both return SomeEnum154 }167 }155 res.nodes.push(AstNodeSrc {168 res.nodes.push(AstNodeSrc {156 doc: Vec::new(),169 doc: Vec::new(),