difftreelog
style fix clippy warnings
in: master
19 files changed
bindings/jsonnet/src/import.rsdiffbeforeafterboth--- a/bindings/jsonnet/src/import.rs
+++ b/bindings/jsonnet/src/import.rs
@@ -64,7 +64,7 @@
self.ctx,
base.as_ptr(),
rel.as_ptr(),
- &mut (found_here as *const _),
+ &mut found_here.cast_const(),
&mut buf,
&mut buf_len,
)
@@ -121,7 +121,7 @@
cb,
ctx,
out: RefCell::new(HashMap::new()),
- })
+ });
}
/// # Safety
bindings/jsonnet/src/lib.rsdiffbeforeafterboth--- a/bindings/jsonnet/src/lib.rs
+++ b/bindings/jsonnet/src/lib.rs
@@ -86,7 +86,6 @@
let state = State::default();
state.settings_mut().import_resolver = tb!(FileImportResolver::default());
state.settings_mut().context_initializer = tb!(jrsonnet_stdlib::ContextInitializer::new(
- state.clone(),
PathResolver::new_cwd_fallback(),
));
Box::into_raw(Box::new(VM {
@@ -107,7 +106,7 @@
/// Set the maximum stack depth.
#[no_mangle]
pub extern "C" fn jsonnet_max_stack(_vm: &VM, v: c_uint) {
- set_stack_depth_limit(v as usize)
+ set_stack_depth_limit(v as usize);
}
/// Set the number of objects required before a garbage collection cycle is allowed.
@@ -175,7 +174,7 @@
#[no_mangle]
pub extern "C" fn jsonnet_max_trace(vm: &mut VM, v: c_uint) {
if let Some(format) = vm.trace_format.as_any_mut().downcast_mut::<CompactFormat>() {
- format.max_trace = v as usize
+ format.max_trace = v as usize;
} else {
panic!("max_trace is not supported by current tracing format")
}
@@ -183,7 +182,7 @@
/// Evaluate a file containing Jsonnet code, return a JSON string.
///
-/// The returned string should be cleaned up with jsonnet_realloc.
+/// The returned string should be cleaned up with `jsonnet_realloc`.
///
/// # Safety
///
@@ -216,7 +215,7 @@
/// Evaluate a string containing Jsonnet code, return a JSON string.
///
-/// The returned string should be cleaned up with jsonnet_realloc.
+/// The returned string should be cleaned up with `jsonnet_realloc`.
///
/// # Safety
///
@@ -359,7 +358,7 @@
out.push(0);
let v = out.as_ptr();
std::mem::forget(out);
- v as *const c_char
+ v.cast::<c_char>()
}
/// # Safety
bindings/jsonnet/src/val_extract.rsdiffbeforeafterboth--- a/bindings/jsonnet/src/val_extract.rs
+++ b/bindings/jsonnet/src/val_extract.rs
@@ -26,7 +26,7 @@
pub extern "C" fn jsonnet_json_extract_number(_vm: &VM, v: &Val, out: &mut c_double) -> c_int {
match v {
Val::Num(n) => {
- *out = *n;
+ *out = n.get();
1
}
_ => 0,
bindings/jsonnet/src/val_make.rsdiffbeforeafterboth--- a/bindings/jsonnet/src/val_make.rs
+++ b/bindings/jsonnet/src/val_make.rs
@@ -5,7 +5,10 @@
os::raw::{c_char, c_double, c_int},
};
-use jrsonnet_evaluator::{val::ArrValue, ObjValue, Val};
+use jrsonnet_evaluator::{
+ val::{ArrValue, NumValue},
+ ObjValue, Val,
+};
use crate::VM;
@@ -24,7 +27,9 @@
/// Convert the given double to a `JsonnetJsonValue`.
#[no_mangle]
pub extern "C" fn jsonnet_json_make_number(_vm: &VM, v: c_double) -> *mut Val {
- Box::into_raw(Box::new(Val::Num(v)))
+ Box::into_raw(Box::new(Val::Num(
+ NumValue::new(v).expect("jsonnet numbers are finite"),
+ )))
}
/// Convert the given `bool` (`1` or `0`) to a `JsonnetJsonValue`.
bindings/jsonnet/src/val_modify.rsdiffbeforeafterboth--- a/bindings/jsonnet/src/val_modify.rs
+++ b/bindings/jsonnet/src/val_modify.rs
@@ -12,7 +12,7 @@
///
/// # Safety
///
-/// `arr` should be a pointer to array value allocated by make_array, or returned by other library call
+/// `arr` should be a pointer to array value allocated by `make_array`, or returned by other library call
/// `val` should be a pointer to value allocated using this library
#[no_mangle]
pub unsafe extern "C" fn jsonnet_json_array_append(_vm: &VM, arr: &mut Val, val: &Val) {
bindings/jsonnet/src/vars_tlas.rsdiffbeforeafterboth--- a/bindings/jsonnet/src/vars_tlas.rs
+++ b/bindings/jsonnet/src/vars_tlas.rs
@@ -27,7 +27,7 @@
.add_ext_str(
name.to_str().expect("name is not utf-8").into(),
value.to_str().expect("value is not utf-8").into(),
- )
+ );
}
/// Binds a Jsonnet external variable to the given code.
@@ -51,7 +51,7 @@
name.to_str().expect("name is not utf-8"),
code.to_str().expect("code is not utf-8"),
)
- .expect("can't parse ext code")
+ .expect("can't parse ext code");
}
/// Binds a top-level string argument for a top-level parameter.
cmds/jrsonnet-fmt/src/children.rsdiffbeforeafterboth--- a/cmds/jrsonnet-fmt/src/children.rs
+++ b/cmds/jrsonnet-fmt/src/children.rs
@@ -28,7 +28,7 @@
TS![, ;].contains(item.kind()),
"silently eaten token: {:?}",
item.kind()
- )
+ );
}
}
out
@@ -48,13 +48,13 @@
if let Some(trivia) = item.as_token().cloned().and_then(Trivia::cast) {
out.push(Ok(trivia));
} else if CustomError::can_cast(item.kind()) {
- out.push(Err(item.to_string()))
+ out.push(Err(item.to_string()));
} else {
assert!(
TS![, ;].contains(item.kind()),
"silently eaten token: {:?}",
item.kind()
- )
+ );
}
}
out
@@ -115,11 +115,7 @@
TriviaKind::Whitespace => {
nl_count += t.text().bytes().filter(|b| *b == b'\n').count();
}
- TriviaKind::SingleLineHashComment => {
- nl_count += 1;
- break;
- }
- TriviaKind::SingleLineSlashComment => {
+ TriviaKind::SingleLineHashComment | TriviaKind::SingleLineSlashComment => {
nl_count += 1;
break;
}
@@ -163,7 +159,7 @@
inline_trivia: Vec::new(),
});
if let Some(last_child) = last_child {
- out.push(last_child)
+ out.push(last_child);
}
had_some = true;
started_next = false;
@@ -188,7 +184,7 @@
}
had_some = true;
} else if CustomError::can_cast(item.kind()) {
- next.push(Err(item.to_string()))
+ next.push(Err(item.to_string()));
} else if loose {
if had_some {
break;
@@ -199,7 +195,7 @@
TS![, ;].contains(item.kind()),
"silently eaten token: {:?}",
item.kind()
- )
+ );
}
}
cmds/jrsonnet-fmt/src/comments.rsdiffbeforeafterboth--- a/cmds/jrsonnet-fmt/src/comments.rs
+++ b/cmds/jrsonnet-fmt/src/comments.rs
@@ -1,3 +1,5 @@
+use std::string::String;
+
use dprint_core::formatting::PrintItems;
use jrsonnet_rowan_parser::{nodes::TriviaKind, AstToken};
@@ -12,6 +14,7 @@
EndOfItems,
}
+#[allow(clippy::too_many_lines, clippy::cognitive_complexity)]
pub fn format_comments(comments: &ChildTrivia, loc: CommentLocation, out: &mut PrintItems) {
for c in comments {
let Ok(c) = c else {
@@ -62,14 +65,14 @@
}
})
.collect::<Vec<_>>();
- while lines.last().map(|l| l.is_empty()).unwrap_or(false) {
+ while lines.last().is_some_and(String::is_empty) {
lines.pop();
}
if lines.len() == 1 && !doc {
if matches!(loc, CommentLocation::ItemInline) {
p!(out, str(" "));
}
- p!(out, str("/* ") string(lines[0].trim().to_string()) str(" */") nl)
+ p!(out, str("/* ") string(lines[0].trim().to_string()) str(" */") nl);
} else if !lines.is_empty() {
fn common_ws_prefix<'a>(a: &'a str, b: &str) -> &'a str {
let offset = a
@@ -95,7 +98,7 @@
}
for line in lines
.iter_mut()
- .skip(if immediate_start { 1 } else { 0 })
+ .skip(usize::from(immediate_start))
.filter(|l| !l.is_empty())
{
*line = line
@@ -127,13 +130,13 @@
}
line = new_line.to_string();
}
- p!(out, string(line.to_string()) nl)
+ p!(out, string(line.to_string()) nl);
}
}
if doc {
p!(out, str(" "));
}
- p!(out, str("*/") nl)
+ p!(out, str("*/") nl);
}
}
// TODO: Keep common padding for multiple continous lines of single-line comments
@@ -154,20 +157,20 @@
// ```
TriviaKind::SingleLineHashComment => {
if matches!(loc, CommentLocation::ItemInline) {
- p!(out, str(" "))
+ p!(out, str(" "));
}
p!(out, str("# ") string(c.text().strip_prefix('#').expect("hash comment starts with #").trim().to_string()));
if !matches!(loc, CommentLocation::ItemInline) {
- p!(out, nl)
+ p!(out, nl);
}
}
TriviaKind::SingleLineSlashComment => {
if matches!(loc, CommentLocation::ItemInline) {
- p!(out, str(" "))
+ p!(out, str(" "));
}
p!(out, str("// ") string(c.text().strip_prefix("//").expect("comment starts with //").trim().to_string()));
if !matches!(loc, CommentLocation::ItemInline) {
- p!(out, nl)
+ p!(out, nl);
}
}
// Garbage in - garbage out
cmds/jrsonnet-fmt/src/main.rsdiffbeforeafterboth1use std::{2 any::type_name,3 fs,4 io::{self, Write},5 path::PathBuf,6 process,7 rc::Rc,8};910use children::{children_between, trivia_before};11use clap::Parser;12use dprint_core::formatting::{13 condition_helpers::is_multiple_lines, condition_resolvers::true_resolver,14 ConditionResolverContext, LineNumber, PrintItems, PrintOptions,15};16use hi_doc::Formatting;17use jrsonnet_rowan_parser::{18 nodes::{19 Arg, ArgsDesc, Assertion, BinaryOperator, Bind, CompSpec, Destruct, DestructArrayPart,20 DestructRest, Expr, ExprBase, FieldName, ForSpec, IfSpec, ImportKind, Literal, Member,21 Name, Number, ObjBody, ObjLocal, ParamsDesc, SliceDesc, SourceFile, Stmt, Suffix, Text,22 UnaryOperator, Visibility,23 },24 AstNode, AstToken as _, SyntaxToken,25};2627use crate::{28 children::trivia_after,29 comments::{format_comments, CommentLocation},30};3132mod children;33mod comments;34#[cfg(test)]35mod tests;3637pub trait Printable {38 fn print(&self, out: &mut PrintItems);39}4041macro_rules! pi {42 (@i; $($t:tt)*) => {{43 #[allow(unused_mut)]44 let mut o = dprint_core::formatting::PrintItems::new();45 pi!(@s; o: $($t)*);46 o47 }};48 (@s; $o:ident: str($e:expr $(,)?) $($t:tt)*) => {{49 $o.push_str($e);50 pi!(@s; $o: $($t)*);51 }};52 (@s; $o:ident: string($e:expr $(,)?) $($t:tt)*) => {{53 $o.push_string($e);54 pi!(@s; $o: $($t)*);55 }};56 (@s; $o:ident: nl $($t:tt)*) => {{57 $o.push_signal(dprint_core::formatting::Signal::NewLine);58 pi!(@s; $o: $($t)*);59 }};60 (@s; $o:ident: tab $($t:tt)*) => {{61 $o.push_signal(dprint_core::formatting::Signal::Tab);62 pi!(@s; $o: $($t)*);63 }};64 (@s; $o:ident: >i $($t:tt)*) => {{65 $o.push_signal(dprint_core::formatting::Signal::StartIndent);66 pi!(@s; $o: $($t)*);67 }};68 (@s; $o:ident: <i $($t:tt)*) => {{69 $o.push_signal(dprint_core::formatting::Signal::FinishIndent);70 pi!(@s; $o: $($t)*);71 }};72 (@s; $o:ident: info($v:expr) $($t:tt)*) => {{73 $o.push_info($v);74 pi!(@s; $o: $($t)*);75 }};76 (@s; $o:ident: if($s:literal, $cond:expr, $($i:tt)*) $($t:tt)*) => {{77 $o.push_condition(dprint_core::formatting::conditions::if_true(78 $s,79 $cond.clone(),80 {81 let mut o = PrintItems::new();82 p!(o, $($i)*);83 o84 },85 ));86 pi!(@s; $o: $($t)*);87 }};88 (@s; $o:ident: if_else($s:literal, $cond:expr, $($i:tt)*)($($e:tt)+) $($t:tt)*) => {{89 $o.push_condition(dprint_core::formatting::conditions::if_true_or(90 $s,91 $cond.clone(),92 {93 let mut o = PrintItems::new();94 p!(o, $($i)*);95 o96 },97 {98 let mut o = PrintItems::new();99 p!(o, $($e)*);100 o101 },102 ));103 pi!(@s; $o: $($t)*);104 }};105 (@s; $o:ident: if_not($s:literal, $cond:expr, $($e:tt)*) $($t:tt)*) => {{106 $o.push_condition(dprint_core::formatting::conditions::if_true_or(107 $s,108 $cond.clone(),109 {110 let o = PrintItems::new();111 o112 },113 {114 let mut o = PrintItems::new();115 p!(o, $($e)*);116 o117 },118 ));119 pi!(@s; $o: $($t)*);120 }};121 (@s; $o:ident: {$expr:expr} $($t:tt)*) => {{122 $expr.print($o);123 pi!(@s; $o: $($t)*);124 }};125 (@s; $o:ident: items($expr:expr) $($t:tt)*) => {{126 $o.extend($expr);127 pi!(@s; $o: $($t)*);128 }};129 (@s; $o:ident: if ($e:expr)($($then:tt)*) $($t:tt)*) => {{130 if $e {131 pi!(@s; $o: $($then)*);132 }133 pi!(@s; $o: $($t)*);134 }};135 (@s; $o:ident: ifelse ($e:expr)($($then:tt)*)($($else:tt)*) $($t:tt)*) => {{136 if $e {137 pi!(@s; $o: $($then)*);138 } else {139 pi!(@s; $o: $($else)*);140 }141 pi!(@s; $o: $($t)*);142 }};143 (@s; $i:ident:) => {}144}145macro_rules! p {146 ($o:ident, $($t:tt)*) => {147 pi!(@s; $o: $($t)*)148 };149}150pub(crate) use p;151pub(crate) use pi;152153impl<P> Printable for Option<P>154where155 P: Printable,156{157 fn print(&self, out: &mut PrintItems) {158 if let Some(v) = self {159 v.print(out);160 } else {161 p!(162 out,163 string(format!(164 "/*missing {}*/",165 type_name::<P>().replace("jrsonnet_rowan_parser::generated::nodes::", "")166 ),)167 );168 }169 }170}171172impl Printable for SyntaxToken {173 fn print(&self, out: &mut PrintItems) {174 p!(out, string(self.to_string()));175 }176}177178impl Printable for Text {179 fn print(&self, out: &mut PrintItems) {180 p!(out, string(format!("{}", self)));181 }182}183impl Printable for Number {184 fn print(&self, out: &mut PrintItems) {185 p!(out, string(format!("{}", self)));186 }187}188189impl Printable for Name {190 fn print(&self, out: &mut PrintItems) {191 p!(out, { self.ident_lit() });192 }193}194195impl Printable for DestructRest {196 fn print(&self, out: &mut PrintItems) {197 p!(out, str("..."));198 if let Some(name) = self.into() {199 p!(out, { name });200 }201 }202}203204impl Printable for Destruct {205 fn print(&self, out: &mut PrintItems) {206 match self {207 Self::DestructFull(f) => {208 p!(out, { f.name() });209 }210 Self::DestructSkip(_) => p!(out, str("?")),211 Self::DestructArray(a) => {212 p!(out, str("[") >i nl);213 for el in a.destruct_array_parts() {214 match el {215 DestructArrayPart::DestructArrayElement(e) => {216 p!(out, {e.destruct()} str(",") nl);217 }218 DestructArrayPart::DestructRest(d) => {219 p!(out, {d} str(",") nl);220 }221 }222 }223 p!(out, <i str("]"));224 }225 Self::DestructObject(o) => {226 p!(out, str("{") >i nl);227 for item in o.destruct_object_fields() {228 p!(out, { item.field() });229 if let Some(des) = item.destruct() {230 p!(out, str(": ") {des});231 }232 if let Some(def) = item.expr() {233 p!(out, str(" = ") {def});234 }235 p!(out, str(",") nl);236 }237 if let Some(rest) = o.destruct_rest() {238 p!(out, {rest} nl);239 }240 p!(out, <i str("}"));241 }242 }243 }244}245246impl Printable for FieldName {247 fn print(&self, out: &mut PrintItems) {248 match self {249 Self::FieldNameFixed(f) => {250 if let Some(id) = f.id() {251 p!(out, { id });252 } else if let Some(str) = f.text() {253 p!(out, { str });254 } else {255 p!(out, str("/*missing FieldName*/"));256 }257 }258 Self::FieldNameDynamic(d) => {259 p!(out, str("[") {d.expr()} str("]"));260 }261 }262 }263}264265impl Printable for Visibility {266 fn print(&self, out: &mut PrintItems) {267 p!(out, string(self.to_string()));268 }269}270271impl Printable for ObjLocal {272 fn print(&self, out: &mut PrintItems) {273 p!(out, str("local ") {self.bind()});274 }275}276277impl Printable for Assertion {278 fn print(&self, out: &mut PrintItems) {279 p!(out, str("assert ") {self.condition()});280 if self.colon_token().is_some() || self.message().is_some() {281 p!(out, str(": ") {self.message()});282 }283 }284}285286impl Printable for ParamsDesc {287 fn print(&self, out: &mut PrintItems) {288 p!(out, str("(") >i nl);289 for param in self.params() {290 p!(out, { param.destruct() });291 if param.assign_token().is_some() || param.expr().is_some() {292 p!(out, str(" = ") {param.expr()});293 }294 p!(out, str(",") nl);295 }296 p!(out, <i str(")"));297 }298}299impl Printable for ArgsDesc {300 fn print(&self, out: &mut PrintItems) {301 let start = LineNumber::new("start");302 let end = LineNumber::new("end");303 let multi_line = Rc::new(move |condition_context: &mut ConditionResolverContext| {304 is_multiple_lines(condition_context, start, end).map(|v| !v)305 });306 p!(out, str("(") info(start) if("start args", multi_line, >i nl));307 let (children, end_comments) = children_between::<Arg>(308 self.syntax().clone(),309 self.l_paren_token().map(Into::into).as_ref(),310 self.r_paren_token().map(Into::into).as_ref(),311 None,312 );313 let mut args = children.into_iter().peekable();314 while let Some(ele) = args.next() {315 if ele.should_start_with_newline {316 p!(out, nl);317 }318 format_comments(&ele.before_trivia, CommentLocation::AboveItem, out);319 let arg = ele.value;320 if arg.name().is_some() || arg.assign_token().is_some() {321 p!(out, {arg.name()} str(" = "));322 }323 let comma_between = if args.peek().is_some() {324 true_resolver()325 } else {326 multi_line.clone()327 };328 p!(out, {arg.expr()} if("arg comma", comma_between, str(",") if_not("between args", multi_line, str(" "))));329 format_comments(&ele.inline_trivia, CommentLocation::ItemInline, out);330 p!(out, if("between args", multi_line, nl));331 }332 if end_comments.should_start_with_newline {333 p!(out, nl);334 }335 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);336 p!(out, if("end args", multi_line, <i info(end)) str(")"));337 }338}339impl Printable for SliceDesc {340 fn print(&self, out: &mut PrintItems) {341 p!(out, str("["));342 if self.from().is_some() {343 p!(out, { self.from() });344 }345 p!(out, str(":"));346 if self.end().is_some() {347 p!(out, { self.end().map(|e| e.expr()) });348 }349 // Keep only one : in case if we don't need step350 if self.step().is_some() {351 p!(out, str(":") {self.step().map(|e|e.expr())});352 }353 p!(out, str("]"));354 }355}356357impl Printable for Member {358 fn print(&self, out: &mut PrintItems) {359 match self {360 Self::MemberBindStmt(b) => {361 p!(out, { b.obj_local() });362 }363 Self::MemberAssertStmt(ass) => {364 p!(out, { ass.assertion() });365 }366 Self::MemberFieldNormal(n) => {367 p!(out, {n.field_name()} if(n.plus_token().is_some())({n.plus_token()}) {n.visibility()} str(" ") {n.expr()});368 }369 Self::MemberFieldMethod(m) => {370 p!(out, {m.field_name()} {m.params_desc()} {m.visibility()} str(" ") {m.expr()});371 }372 }373 }374}375376impl Printable for ObjBody {377 fn print(&self, out: &mut PrintItems) {378 match self {379 Self::ObjBodyComp(l) => {380 let (children, mut end_comments) = children_between::<Member>(381 l.syntax().clone(),382 l.l_brace_token().map(Into::into).as_ref(),383 Some(384 &(l.comp_specs()385 .next()386 .expect("at least one spec is defined")387 .syntax()388 .clone())389 .into(),390 ),391 None,392 );393 let trailing_for_comp = end_comments.extract_trailing();394 p!(out, str("{") >i nl);395 for mem in children {396 if mem.should_start_with_newline {397 p!(out, nl);398 }399 format_comments(&mem.before_trivia, CommentLocation::AboveItem, out);400 p!(out, {mem.value} str(","));401 format_comments(&mem.inline_trivia, CommentLocation::ItemInline, out);402 p!(out, nl);403 }404405 if end_comments.should_start_with_newline {406 p!(out, nl);407 }408 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);409410 let (compspecs, end_comments) = children_between::<CompSpec>(411 l.syntax().clone(),412 l.member_comps()413 .last()414 .map(|m| m.syntax().clone())415 .map(Into::into)416 .or_else(|| l.l_brace_token().map(Into::into))417 .as_ref(),418 l.r_brace_token().map(Into::into).as_ref(),419 Some(trailing_for_comp),420 );421 for mem in compspecs {422 if mem.should_start_with_newline {423 p!(out, nl);424 }425 format_comments(&mem.before_trivia, CommentLocation::AboveItem, out);426 p!(out, { mem.value });427 format_comments(&mem.inline_trivia, CommentLocation::ItemInline, out);428 }429 if end_comments.should_start_with_newline {430 p!(out, nl);431 }432 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);433434 p!(out, nl <i str("}"));435 }436 Self::ObjBodyMemberList(l) => {437 let (children, end_comments) = children_between::<Member>(438 l.syntax().clone(),439 l.l_brace_token().map(Into::into).as_ref(),440 l.r_brace_token().map(Into::into).as_ref(),441 None,442 );443 if children.is_empty() && end_comments.is_empty() {444 p!(out, str("{ }"));445 return;446 }447 p!(out, str("{") >i nl);448 for (i, mem) in children.into_iter().enumerate() {449 if mem.should_start_with_newline && i != 0 {450 p!(out, nl);451 }452 format_comments(&mem.before_trivia, CommentLocation::AboveItem, out);453 p!(out, {mem.value} str(","));454 format_comments(&mem.inline_trivia, CommentLocation::ItemInline, out);455 p!(out, nl);456 }457458 if end_comments.should_start_with_newline {459 p!(out, nl);460 }461 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);462 p!(out, <i str("}"));463 }464 }465 }466}467impl Printable for UnaryOperator {468 fn print(&self, out: &mut PrintItems) {469 p!(out, string(self.text().to_string()));470 }471}472impl Printable for BinaryOperator {473 fn print(&self, out: &mut PrintItems) {474 p!(out, string(self.text().to_string()));475 }476}477impl Printable for Bind {478 fn print(&self, out: &mut PrintItems) {479 match self {480 Self::BindDestruct(d) => {481 p!(out, {d.into()} str(" = ") {d.value()});482 }483 Self::BindFunction(f) => {484 p!(out, {f.name()} {f.params()} str(" = ") {f.value()});485 }486 }487 }488}489impl Printable for Literal {490 fn print(&self, out: &mut PrintItems) {491 p!(out, string(self.syntax().to_string()));492 }493}494impl Printable for ImportKind {495 fn print(&self, out: &mut PrintItems) {496 p!(out, string(self.syntax().to_string()));497 }498}499impl Printable for ForSpec {500 fn print(&self, out: &mut PrintItems) {501 p!(out, str("for ") {self.bind()} str(" in ") {self.expr()});502 }503}504impl Printable for IfSpec {505 fn print(&self, out: &mut PrintItems) {506 p!(out, str("if ") {self.expr()});507 }508}509impl Printable for CompSpec {510 fn print(&self, out: &mut PrintItems) {511 match self {512 Self::ForSpec(f) => f.print(out),513 Self::IfSpec(i) => i.print(out),514 }515 }516}517impl Printable for Expr {518 fn print(&self, out: &mut PrintItems) {519 let (stmts, _ending) = children_between::<Stmt>(520 self.syntax().clone(),521 None,522 self.expr_base()523 .as_ref()524 .map(ExprBase::syntax)525 .cloned()526 .map(Into::into)527 .as_ref(),528 None,529 );530 for stmt in stmts {531 p!(out, { stmt.value });532 }533 p!(out, { self.expr_base() });534 let (suffixes, _ending) = children_between::<Suffix>(535 self.syntax().clone(),536 self.expr_base()537 .as_ref()538 .map(ExprBase::syntax)539 .cloned()540 .map(Into::into)541 .as_ref(),542 None,543 None,544 );545 for suffix in suffixes {546 p!(out, { suffix.value });547 }548 }549}550impl Printable for Suffix {551 fn print(&self, out: &mut PrintItems) {552 match self {553 Self::SuffixIndex(i) => {554 if i.question_mark_token().is_some() {555 p!(out, str("?"));556 }557 p!(out, str(".") {i.index()});558 }559 Self::SuffixIndexExpr(e) => {560 if e.question_mark_token().is_some() {561 p!(out, str(".?"));562 }563 p!(out, str("[") {e.index()} str("]"));564 }565 Self::SuffixSlice(d) => {566 p!(out, { d.slice_desc() });567 }568 Self::SuffixApply(a) => {569 p!(out, { a.args_desc() });570 }571 }572 }573}574impl Printable for Stmt {575 fn print(&self, out: &mut PrintItems) {576 match self {577 Self::StmtLocal(l) => {578 let (binds, end_comments) = children_between::<Bind>(579 l.syntax().clone(),580 l.local_kw_token().map(Into::into).as_ref(),581 l.semi_token().map(Into::into).as_ref(),582 None,583 );584 if binds.len() == 1 {585 let bind = &binds[0];586 format_comments(&bind.before_trivia, CommentLocation::AboveItem, out);587 p!(out, str("local ") {bind.value});588 // TODO: keep end_comments, child.inline_trivia somehow, force multiple locals formatting in case of presence?589 } else {590 p!(out,str("local") >i nl);591 for bind in binds {592 if bind.should_start_with_newline {593 p!(out, nl);594 }595 format_comments(&bind.before_trivia, CommentLocation::AboveItem, out);596 p!(out, {bind.value} str(","));597 format_comments(&bind.inline_trivia, CommentLocation::ItemInline, out);598 p!(out, nl);599 }600 if end_comments.should_start_with_newline {601 p!(out, nl);602 }603 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);604 p!(out,<i);605 }606 p!(out,str(";") nl);607 }608 Self::StmtAssert(a) => {609 p!(out, {a.assertion()} str(";") nl);610 }611 }612 }613}614impl Printable for ExprBase {615 fn print(&self, out: &mut PrintItems) {616 match self {617 Self::ExprBinary(b) => {618 p!(out, {b.lhs_work()} str(" ") {b.binary_operator()} str(" ") {b.rhs_work()});619 }620 Self::ExprUnary(u) => p!(out, {u.unary_operator()} {u.rhs()}),621 // Self::ExprSlice(s) => {622 // p!(new: {s.expr()} {s.slice_desc()})623 // }624 // Self::ExprIndex(i) => {625 // p!(new: {i.expr()} str(".") {i.index()})626 // }627 // Self::ExprIndexExpr(i) => p!(new: {i.base()} str("[") {i.index()} str("]")),628 // Self::ExprApply(a) => {629 // let mut pi = p!(new: {a.expr()} {a.args_desc()});630 // if a.tailstrict_kw_token().is_some() {631 // p!(out,str(" tailstrict"));632 // }633 // pi634 // }635 Self::ExprObjExtend(ex) => {636 p!(out, {ex.lhs_work()} str(" ") {ex.rhs_work()});637 }638 Self::ExprParened(p) => {639 p!(out, str("(") {p.expr()} str(")"));640 }641 Self::ExprString(s) => p!(out, { s.text() }),642 Self::ExprNumber(n) => p!(out, { n.number() }),643 Self::ExprArray(a) => {644 p!(out, str("[") >i nl);645 for el in a.exprs() {646 p!(out, {el} str(",") nl);647 }648 p!(out, <i str("]"));649 }650 Self::ExprObject(obj) => {651 p!(out, { obj.obj_body() });652 }653 Self::ExprArrayComp(arr) => {654 p!(out, str("[") {arr.expr()});655 for spec in arr.comp_specs() {656 p!(out, str(" ") {spec});657 }658 p!(out, str("]"));659 }660 Self::ExprImport(v) => {661 p!(out, {v.import_kind()} str(" ") {v.text()});662 }663 Self::ExprVar(n) => p!(out, { n.name() }),664 // Self::ExprLocal(l) => {665 // }666 Self::ExprIfThenElse(ite) => {667 p!(out, str("if ") {ite.cond()} str(" then ") {ite.then().map(|t| t.expr())});668 if ite.else_kw_token().is_some() || ite.else_().is_some() {669 p!(out, str(" else ") {ite.else_().map(|t| t.expr())});670 }671 }672 Self::ExprFunction(f) => p!(out, str("function") {f.params_desc()} nl {f.expr()}),673 // Self::ExprAssert(a) => p!(new: {a.assertion()} str("; ") {a.expr()}),674 Self::ExprError(e) => p!(out, str("error ") {e.expr()}),675 Self::ExprLiteral(l) => {676 p!(out, { l.literal() });677 }678 }679 }680}681682impl Printable for SourceFile {683 fn print(&self, out: &mut PrintItems) {684 let before = trivia_before(685 self.syntax().clone(),686 self.expr()687 .map(|e| e.syntax().clone())688 .map(Into::into)689 .as_ref(),690 );691 let after = trivia_after(692 self.syntax().clone(),693 self.expr()694 .map(|e| e.syntax().clone())695 .map(Into::into)696 .as_ref(),697 );698 format_comments(&before, CommentLocation::AboveItem, out);699 p!(out, {self.expr()} nl);700 format_comments(&after, CommentLocation::EndOfItems, out);701 }702}703704struct FormatOptions {705 // 0 for hard tabs706 indent: u8,707}708fn format(input: &str, opts: &FormatOptions) -> Option<String> {709 let (parsed, errors) = jrsonnet_rowan_parser::parse(input);710 if !errors.is_empty() {711 let mut builder = hi_doc::SnippetBuilder::new(input);712 for error in errors {713 builder714 .error(hi_doc::Text::single(715 format!("{:?}", error.error).chars(),716 Formatting::default(),717 ))718 .range(719 error.range.start().into()720 ..=(usize::from(error.range.end()) - 1).max(error.range.start().into()),721 )722 .build();723 }724 let snippet = builder.build();725 let ansi = hi_doc::source_to_ansi(&snippet);726 eprintln!("{ansi}");727 // It is possible to recover from this failure, but the output may be broken, as formatter is free to skip728 // ERROR rowan nodes.729 // Recovery needs to be enabled for LSP, though.730 //731 // TODO: Verify how formatter interacts in cases of missing positional values, i.e `if cond then /*missing Expr*/ else residual`.732 return None;733 }734 Some(dprint_core::formatting::format(735 || {736 let mut out = PrintItems::new();737 parsed.print(&mut out);738 out739 },740 PrintOptions {741 indent_width: if opts.indent == 0 {742 // Reasonable max length for both 2 and 4 space sized tabs.743 3744 } else {745 opts.indent746 },747 max_width: 100,748 use_tabs: opts.indent == 0,749 new_line_text: "\n",750 },751 ))752}753754#[derive(Parser)]755#[allow(clippy::struct_excessive_bools)]756struct Opts {757 /// Treat input as code, reformat it instead of reading file.758 #[clap(long, short = 'e')]759 exec: bool,760 /// Path to be reformatted if `--exec` if unset, otherwise code itself.761 input: String,762 /// Replace code with formatted in-place, instead of printing it to stdout.763 /// Only applicable if `--exec` is unset.764 #[clap(long, short = 'i')]765 in_place: bool,766767 /// Exit with error if formatted does not match input768 #[arg(long)]769 test: bool,770 /// Number of spaces to indent with771 ///772 /// 0 for guess from input (default), and use hard tabs if unable to guess.773 #[arg(long, default_value = "0")]774 indent: u8,775 /// Force hard tab for indentation776 #[arg(long)]777 hard_tabs: bool,778779 /// Debug option: how many times to call reformatting in case of unstable dprint output resolution.780 ///781 /// 0 for not retrying to reformat.782 #[arg(long, default_value = "0")]783 conv_limit: usize,784}785786#[derive(thiserror::Error, Debug)]787enum Error {788 #[error("--in-place is incompatible with --exec")]789 InPlaceExec,790 #[error("io: {0}")]791 Io(#[from] io::Error),792 #[error("persist: {0}")]793 Persist(#[from] tempfile::PersistError),794 #[error("parsing failed, refusing to reformat corrupted input")]795 Parse,796}797798fn main_result() -> Result<(), Error> {799 eprintln!("jrsonnet-fmt is a prototype of a jsonnet code formatter, do not expect it to produce meaningful results right now.");800 eprintln!("It is not expected for its output to match other implementations, it will be completly separate implementation with maybe different name.");801 let mut opts = Opts::parse();802 let input = if opts.exec {803 if opts.in_place {804 return Err(Error::InPlaceExec);805 }806 opts.input.clone()807 } else {808 fs::read_to_string(&opts.input)?809 };810811 if opts.indent == 0 {812 // Sane default.813 // TODO: Implement actual guessing.814 opts.hard_tabs = true;815 }816817 let mut iteration = 0;818 let mut formatted = input.clone();819 let mut convergence_tmp;820 // https://github.com/dprint/dprint/pull/423821 loop {822 let Some(reformatted) = format(823 &formatted,824 &FormatOptions {825 indent: if opts.indent == 0 || opts.hard_tabs {826 0827 } else {828 opts.indent829 },830 },831 ) else {832 return Err(Error::Parse);833 };834 convergence_tmp = reformatted.trim().to_owned();835 if formatted == convergence_tmp {836 break;837 }838 formatted = convergence_tmp;839 if opts.conv_limit == 0 {840 break;841 }842 iteration += 1;843 assert!(iteration <= opts.conv_limit, "formatting not converged");844 }845 formatted.push('\n');846 if opts.test && formatted != input {847 process::exit(1);848 }849 if opts.in_place {850 let path = PathBuf::from(opts.input);851 let mut temp = tempfile::NamedTempFile::new_in(path.parent().expect(852 "not failed during read, this path is not a directory, and there is a parent",853 ))?;854 temp.write_all(formatted.as_bytes())?;855 temp.flush()?;856 temp.persist(&path)?;857 } else {858 print!("{formatted}");859 }860 Ok(())861}862863fn main() {864 if let Err(e) = main_result() {865 eprintln!("{e}");866 process::exit(1);867 }868}crates/jrsonnet-rowan-parser/src/lex.rsdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/lex.rs
+++ b/crates/jrsonnet-rowan-parser/src/lex.rs
@@ -37,9 +37,10 @@
// In kinds, string blocks is parsed at least as `|||`
lexer.bump(3);
let res = lex_str_block(&mut lexer);
- debug_assert!(lexer.next().is_none(), "str_block is lexed");
+ let next = lexer.next();
+ assert!(next.is_none(), "str_block is lexed");
match res {
- Ok(_) => {}
+ Ok(()) => {}
Err(e) => {
kind = Ok(match e {
StringBlockError::UnexpectedEnd => ERROR_STRING_BLOCK_UNEXPECTED_END,
@@ -48,7 +49,7 @@
ERROR_STRING_BLOCK_MISSING_TERMINATION
}
StringBlockError::MissingIndent => ERROR_STRING_BLOCK_MISSING_INDENT,
- })
+ });
}
}
}
crates/jrsonnet-rowan-parser/src/marker.rsdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/marker.rs
+++ b/crates/jrsonnet-rowan-parser/src/marker.rs
@@ -146,7 +146,7 @@
p: &mut Parser,
kind: SyntaxKind,
error: Option<SyntaxError>,
- ) -> CompletedMarker {
+ ) -> Self {
let new_m = p.start();
match &mut p.events[self.start_event_idx] {
Event::Start { forward_parent, .. } => {
@@ -173,10 +173,10 @@
}
completed
}
- pub fn wrap(self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker {
+ pub fn wrap(self, p: &mut Parser, kind: SyntaxKind) -> Self {
self.wrap_raw(p, kind, None)
}
- pub fn wrap_error(self, p: &mut Parser, msg: impl AsRef<str>) -> CompletedMarker {
+ pub fn wrap_error(self, p: &mut Parser, msg: impl AsRef<str>) -> Self {
self.wrap_raw(
p,
SyntaxKind::ERROR_CUSTOM,
crates/jrsonnet-rowan-parser/src/parser.rsdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/parser.rs
+++ b/crates/jrsonnet-rowan-parser/src/parser.rs
@@ -72,9 +72,9 @@
.rev()
.take_while(|h| h.0 > self.entered)
.count();
- self.hints.truncate(self.hints.len() - amount)
+ self.hints.truncate(self.hints.len() - amount);
}
- fn clear_expected_syntaxes(&mut self) {
+ fn clear_expected_syntaxes(&self) {
self.expected_syntax_tracking_state
.set(ExpectedSyntax::Unnamed(TS![]));
}
@@ -104,7 +104,7 @@
}
pub(crate) fn expect(&mut self, kind: SyntaxKind) {
- self.expect_with_recovery_set(kind, TS![])
+ self.expect_with_recovery_set(kind, TS![]);
}
pub(crate) fn expect_with_recovery_set(
@@ -153,7 +153,7 @@
m
}
fn bump_assert(&mut self, kind: SyntaxKind) {
- assert!(self.at(kind), "expected {:?}", kind);
+ assert!(self.at(kind), "expected {kind:?}");
self.bump_remap(self.current());
}
fn bump(&mut self) {
@@ -168,11 +168,11 @@
fn step(&self) {
use std::fmt::Write;
let steps = self.steps.get();
- if steps >= 15000000 {
+ if steps >= 15_000_000 {
let mut out = "seems like parsing is stuck".to_owned();
{
let last = 20;
- write!(out, "\n\nLast {} events:", last).unwrap();
+ write!(out, "\n\nLast {last} events:").unwrap();
for (i, event) in self
.events
.iter()
@@ -205,38 +205,38 @@
self.nth(0)
}
#[must_use]
- pub(crate) fn expected_syntax_name(&mut self, name: &'static str) -> ExpectedSyntaxGuard {
+ pub(crate) fn expected_syntax_name(&self, name: &'static str) -> ExpectedSyntaxGuard {
self.expected_syntax_tracking_state
.set(ExpectedSyntax::Named(name));
ExpectedSyntaxGuard::new(Rc::clone(&self.expected_syntax_tracking_state))
}
- pub fn at(&mut self, kind: SyntaxKind) -> bool {
+ pub fn at(&self, kind: SyntaxKind) -> bool {
self.nth_at(0, kind)
}
- pub fn nth_at(&mut self, n: usize, kind: SyntaxKind) -> bool {
+ pub fn nth_at(&self, n: usize, kind: SyntaxKind) -> bool {
if n == 0 {
if let ExpectedSyntax::Unnamed(kinds) = self.expected_syntax_tracking_state.get() {
let kinds = kinds.with(kind);
self.expected_syntax_tracking_state
- .set(ExpectedSyntax::Unnamed(kinds))
+ .set(ExpectedSyntax::Unnamed(kinds));
}
}
self.nth(n) == kind
}
- pub fn at_ts(&mut self, set: SyntaxKindSet) -> bool {
+ pub fn at_ts(&self, set: SyntaxKindSet) -> bool {
if let ExpectedSyntax::Unnamed(kinds) = self.expected_syntax_tracking_state.get() {
let kinds = kinds.union(set);
self.expected_syntax_tracking_state
- .set(ExpectedSyntax::Unnamed(kinds))
+ .set(ExpectedSyntax::Unnamed(kinds));
}
set.contains(self.current())
}
- pub fn at_end(&mut self) -> bool {
+ pub fn at_end(&self) -> bool {
self.at(EOF)
}
}
-pub(crate) struct ExpectedSyntaxGuard {
+pub struct ExpectedSyntaxGuard {
expected_syntax_tracking_state: Rc<Cell<ExpectedSyntax>>,
}
@@ -263,8 +263,8 @@
impl fmt::Display for ExpectedSyntax {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
- ExpectedSyntax::Named(name) => write!(f, "{name}"),
- ExpectedSyntax::Unnamed(set) => write!(f, "{set}"),
+ Self::Named(name) => write!(f, "{name}"),
+ Self::Unnamed(set) => write!(f, "{set}"),
}
}
}
@@ -298,8 +298,7 @@
}
}
match expr_binding_power(p, 0) {
- Ok(m) => m,
- Err(m) => m,
+ Ok(m) | Err(m) => m,
};
m.complete(p, EXPR)
}
@@ -399,7 +398,7 @@
}
fn visibility(p: &mut Parser) {
if p.at_ts(TS![: :: :::]) {
- p.bump()
+ p.bump();
} else {
p.error_with_recovery_set(TS![=]);
}
@@ -556,7 +555,7 @@
expr(p);
let arg = m.complete(p, ARG);
if started_named.get() {
- unnamed_after_named.push(arg)
+ unnamed_after_named.push(arg);
}
}
if comma(p) {
@@ -566,7 +565,7 @@
}
p.expect(T![')']);
if p.at(T![tailstrict]) {
- p.bump()
+ p.bump();
}
for errored in unnamed_after_named {
@@ -719,7 +718,7 @@
let m = p.start();
p.bump_assert(T![...]);
if p.at(IDENT) {
- p.bump()
+ p.bump();
}
m.complete(p, DESTRUCT_REST);
}
crates/jrsonnet-rowan-parser/src/precedence.rsdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/precedence.rs
+++ b/crates/jrsonnet-rowan-parser/src/precedence.rs
@@ -13,8 +13,7 @@
Self::BitXor => (8, 9),
Self::BitOr => (6, 7),
Self::And => (4, 5),
- Self::NullCoaelse => (2, 3),
- Self::Or => (2, 3),
+ Self::NullCoaelse | Self::Or => (2, 3),
Self::ErrorNoOperator => (0, 1),
}
}
@@ -23,9 +22,7 @@
impl UnaryOperatorKind {
pub fn binding_power(&self) -> ((), u8) {
match self {
- Self::Minus => ((), 20),
- Self::Not => ((), 20),
- Self::BitNot => ((), 20),
+ Self::Minus | Self::Not | Self::BitNot => ((), 20),
}
}
}
crates/jrsonnet-rowan-parser/src/string_block.rsdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/string_block.rs
+++ b/crates/jrsonnet-rowan-parser/src/string_block.rs
@@ -17,6 +17,7 @@
let _ = lex_str_block(lex);
}
+#[allow(clippy::too_many_lines)]
pub fn lex_str_block(lex: &mut Lexer<SyntaxKind>) -> Result<(), StringBlockError> {
struct Context<'a> {
source: &'a str,
@@ -78,6 +79,7 @@
};
}
+ #[allow(clippy::range_plus_one)]
fn pos(&self) -> Range<usize> {
if self.index == self.source.len() {
self.offset + self.index..self.offset + self.index
@@ -120,8 +122,7 @@
let end_index = ctx
.rest()
.find("|||")
- .map(|v| v + 3)
- .unwrap_or_else(|| ctx.rest().len());
+ .map_or_else(|| ctx.rest().len(), |v| v + 3);
lex.bump(ctx.index + end_index);
}
@@ -150,7 +151,7 @@
}
// Process leading blank lines before calculating string block indent
- while let Some('\n') = ctx.peek() {
+ while ctx.peek() == Some('\n') {
ctx.next();
}
@@ -179,7 +180,7 @@
}
// Skip any blank lines
- while let Some('\n') = ctx.peek() {
+ while ctx.peek() == Some('\n') {
ctx.next();
}
@@ -187,9 +188,11 @@
num_whitespace = check_whitespace(str_block_indent, ctx.rest());
if num_whitespace == 0 {
// End of the text block
- let mut term_indent = String::with_capacity(num_whitespace);
+ // let mut term_indent = String::with_capacity(num_whitespace);
while let Some(' ' | '\t') = ctx.peek() {
- term_indent.push(ctx.next().unwrap());
+ // term_indent.push(
+ ctx.next().unwrap();
+ // );
}
if !ctx.rest().starts_with("|||") {
crates/jrsonnet-rowan-parser/src/token_set.rsdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/token_set.rs
+++ b/crates/jrsonnet-rowan-parser/src/token_set.rs
@@ -10,21 +10,23 @@
pub const EMPTY: Self = Self(0);
pub const ALL: Self = Self(u128::MAX);
- pub const fn new(kinds: &[SyntaxKind]) -> SyntaxKindSet {
+ pub const fn new(kinds: &[SyntaxKind]) -> Self {
let mut res = 0u128;
let mut i = 0;
while i < kinds.len() {
res |= mask(kinds[i]);
- i += 1
+ i += 1;
}
- SyntaxKindSet(res)
+ Self(res)
}
- pub const fn union(self, other: SyntaxKindSet) -> SyntaxKindSet {
- SyntaxKindSet(self.0 | other.0)
+ #[must_use]
+ pub const fn union(self, other: Self) -> Self {
+ Self(self.0 | other.0)
}
- pub const fn with(self, kind: SyntaxKind) -> SyntaxKindSet {
- SyntaxKindSet(self.0 | mask(kind))
+ #[must_use]
+ pub const fn with(self, kind: SyntaxKind) -> Self {
+ Self(self.0 | mask(kind))
}
pub fn contains(&self, kind: SyntaxKind) -> bool {
@@ -40,7 +42,7 @@
let mut variants = <Vec<SyntaxKind>>::new();
for i in 0..128 {
if v & 1 == 1 {
- variants.push(SyntaxKind::from_raw(i))
+ variants.push(SyntaxKind::from_raw(i));
}
v >>= 1;
if v == 0 {
@@ -65,7 +67,7 @@
let mut variants = <Vec<SyntaxKind>>::new();
for i in 0..128 {
if v & 1 == 1 {
- variants.push(SyntaxKind::from_raw(i))
+ variants.push(SyntaxKind::from_raw(i));
}
v >>= 1;
if v == 0 {
@@ -77,9 +79,7 @@
}
const fn mask(kind: SyntaxKind) -> u128 {
- if kind as u32 > 128 {
- panic!("mask for not a token kind")
- }
+ assert!(kind as u32 <= 128, "mask for not a token kind");
1u128 << (kind as u128)
}
xtask/src/sourcegen/ast.rsdiffbeforeafterboth--- a/xtask/src/sourcegen/ast.rs
+++ b/xtask/src/sourcegen/ast.rs
@@ -72,7 +72,7 @@
pub fn is_many(&self) -> bool {
matches!(
self,
- Field::Node {
+ Self::Node {
cardinality: Cardinality::Many,
..
}
@@ -81,44 +81,41 @@
pub fn token_name(&self) -> Option<String> {
match self {
- Field::Token(token) => Some(token.clone()),
- _ => None,
+ Self::Token(token) => Some(token.clone()),
+ Self::Node { .. } => None,
}
}
pub fn token_kind(&self, kinds: &KindsSrc) -> Option<TokenStream> {
match self {
- Field::Token(token) => Some(kinds.token(token).expect("token exists").reference()),
- _ => None,
+ Self::Token(token) => Some(kinds.token(token).expect("token exists").reference()),
+ Self::Node { .. } => None,
}
}
pub fn is_token_enum(&self, grammar: &AstSrc) -> bool {
match self {
- Field::Node { ty, .. } => grammar.token_enums.iter().any(|e| &e.name == ty),
- _ => false,
+ Self::Node { ty, .. } => grammar.token_enums.iter().any(|e| &e.name == ty),
+ Self::Token(_) => false,
}
}
pub fn method_name(&self, kinds: &KindsSrc) -> proc_macro2::Ident {
match self {
- Field::Token(name) => kinds.token(name).expect("token exists").method_name(),
- Field::Node { name, .. } => {
+ Self::Token(name) => kinds.token(name).expect("token exists").method_name(),
+ Self::Node { name, .. } => {
format_ident!("{}", name)
}
}
}
pub fn ty(&self) -> proc_macro2::Ident {
match self {
- Field::Token(_) => format_ident!("SyntaxToken"),
- Field::Node { ty, .. } => format_ident!("{}", ty),
+ Self::Token(_) => format_ident!("SyntaxToken"),
+ Self::Node { ty, .. } => format_ident!("{}", ty),
}
}
}
pub fn lower(kinds: &KindsSrc, grammar: &Grammar) -> AstSrc {
- let mut res = AstSrc {
- // tokens,
- ..Default::default()
- };
+ let mut res = AstSrc::default();
let nodes = grammar.iter().collect::<Vec<_>>();
@@ -135,16 +132,15 @@
};
res.enums.push(enum_src);
}
- None => match lower_token_enum(grammar, rule) {
- Some(variants) => {
+ None => {
+ if let Some(variants) = lower_token_enum(grammar, rule) {
let tokens_enum_src = AstTokenEnumSrc {
doc: Vec::new(),
name,
variants,
};
res.token_enums.push(tokens_enum_src);
- }
- None => {
+ } else {
let mut fields = Vec::new();
lower_rule(&mut fields, grammar, None, rule, false);
let mut types = HashMap::new();
@@ -173,7 +169,7 @@
fields,
});
}
- },
+ }
}
}
@@ -240,7 +236,7 @@
acc.push(field);
}
Rule::Token(token) => {
- assert!(label.is_none(), "uexpected label: {:?}", label);
+ assert!(label.is_none(), "uexpected label: {label:?}");
let name = grammar[*token].name.clone();
let field = Field::Token(name);
acc.push(field);
@@ -267,7 +263,7 @@
}
Rule::Seq(rules) | Rule::Alt(rules) => {
for rule in rules {
- lower_rule(acc, grammar, label, rule, in_optional)
+ lower_rule(acc, grammar, label, rule, in_optional);
}
}
Rule::Opt(rule) => lower_rule(acc, grammar, label, rule, true),
xtask/src/sourcegen/kinds.rsdiffbeforeafterboth--- a/xtask/src/sourcegen/kinds.rs
+++ b/xtask/src/sourcegen/kinds.rs
@@ -41,33 +41,33 @@
impl TokenKind {
pub fn grammar_name(&self) -> &str {
match self {
- TokenKind::Keyword { code, .. } => code,
- TokenKind::Literal { grammar_name, .. } => grammar_name,
- TokenKind::Meta { grammar_name, .. } => grammar_name,
- TokenKind::Error { grammar_name, .. } => grammar_name,
+ Self::Keyword { code, .. } => code,
+ Self::Literal { grammar_name, .. }
+ | Self::Meta { grammar_name, .. }
+ | Self::Error { grammar_name, .. } => grammar_name,
}
}
/// How this keyword should appear in kinds enum, screaming snake cased
pub fn name(&self) -> &str {
match self {
- TokenKind::Keyword { name, .. } => name,
- TokenKind::Literal { name, .. } => name,
- TokenKind::Meta { name, .. } => name,
- TokenKind::Error { name, .. } => name,
+ Self::Keyword { name, .. }
+ | Self::Literal { name, .. }
+ | Self::Meta { name, .. }
+ | Self::Error { name, .. } => name,
}
}
pub fn expand_kind(&self) -> TokenStream {
let name = format_ident!("{}", self.name());
let attr = match self {
- TokenKind::Keyword { code, .. } => quote! {#[token(#code)]},
- TokenKind::Literal { regex, lexer, .. } => {
+ Self::Keyword { code, .. } => quote! {#[token(#code)]},
+ Self::Literal { regex, lexer, .. } => {
let lexer = lexer
.as_deref()
.map(TokenStream::from_str)
.map(|r| r.expect("path is correct"));
quote! {#[regex(#regex, #lexer)]}
}
- TokenKind::Error {
+ Self::Error {
regex, priority, ..
} if regex.is_some() => {
let priority = priority.map(|p| quote! {, priority = #p});
@@ -82,7 +82,7 @@
}
pub fn expand_t_macros(&self) -> Option<TokenStream> {
match self {
- TokenKind::Keyword { code, name } => {
+ Self::Keyword { code, name } => {
let code = escape_token_macro(code);
let name = format_ident!("{name}");
Some(quote! {
@@ -98,29 +98,26 @@
/// Keywords are referenced with `T![_]` macro,
/// and literals are referenced directly by name
pub fn reference(&self) -> TokenStream {
- match self {
- TokenKind::Keyword { code, .. } => {
- let code = escape_token_macro(code);
- quote! {T![#code]}
- }
- _ => {
- let name = self.name();
- let ident = format_ident!("{name}");
- quote! {#ident}
- }
+ if let Self::Keyword { code, .. } = self {
+ let code = escape_token_macro(code);
+ quote! {T![#code]}
+ } else {
+ let name = self.name();
+ let ident = format_ident!("{name}");
+ quote! {#ident}
}
}
pub fn method_name(&self) -> Ident {
match self {
- TokenKind::Keyword { name, .. } => {
+ Self::Keyword { name, .. } => {
format_ident!("{}_token", name.to_lowercase())
}
- TokenKind::Literal { name, .. } => {
+ Self::Literal { name, .. } => {
format_ident!("{}_lit", name.to_lowercase())
}
- TokenKind::Meta { name, .. } => format_ident!("{}_meta", name.to_lowercase()),
- TokenKind::Error { name, .. } => format_ident!("{}_error", name.to_lowercase()),
+ Self::Meta { name, .. } => format_ident!("{}_meta", name.to_lowercase()),
+ Self::Error { name, .. } => format_ident!("{}_error", name.to_lowercase()),
}
}
}
@@ -188,15 +185,14 @@
.is_none(),
"token already defined: {}",
token.grammar_name()
- )
+ );
}
pub fn define_node(&mut self, node: &str) {
assert!(
self.defined_node_names.insert(node.to_owned()),
- "node name already defined: {}",
- node
+ "node name already defined: {node}"
);
- self.nodes.push(node.to_string())
+ self.nodes.push(node.to_string());
}
pub fn token(&self, tok: &str) -> Option<&TokenKind> {
self.defined_tokens.get(tok)
xtask/src/sourcegen/mod.rsdiffbeforeafterboth--- a/xtask/src/sourcegen/mod.rs
+++ b/xtask/src/sourcegen/mod.rs
@@ -49,27 +49,27 @@
match special {
SpecialName::Literal => panic!("literal is not defined: {name}"),
SpecialName::Meta => {
- eprintln!("implicit meta: {}", name);
+ eprintln!("implicit meta: {name}");
kinds.define_token(TokenKind::Meta {
grammar_name: token.to_owned(),
- name: format!("META_{}", name),
- })
+ name: format!("META_{name}"),
+ });
}
SpecialName::Error => {
- eprintln!("implicit error: {}", name);
+ eprintln!("implicit error: {name}");
kinds.define_token(TokenKind::Error {
grammar_name: token.to_owned(),
- name: format!("ERROR_{}", name),
+ name: format!("ERROR_{name}"),
regex: None,
priority: None,
is_lexer_error: true,
- })
+ });
}
};
continue;
};
let name = to_upper_snake_case(token);
- eprintln!("implicit kw: {}", token);
+ eprintln!("implicit kw: {token}");
kinds.define_token(TokenKind::Keyword {
code: token.to_owned(),
name: format!("{name}_KW"),
@@ -98,14 +98,14 @@
"/../crates/jrsonnet-rowan-parser/src/generated/syntax_kinds.rs",
)),
&syntax_kinds,
- )?;
+ );
ensure_file_contents(
&PathBuf::from(concat!(
env!("CARGO_MANIFEST_DIR"),
"/../crates/jrsonnet-rowan-parser/src/generated/nodes.rs",
)),
&nodes,
- )?;
+ );
Ok(())
}
@@ -189,6 +189,7 @@
reformat(&ast.to_string())
}
+#[allow(clippy::too_many_lines, clippy::cognitive_complexity)]
fn generate_nodes(kinds: &KindsSrc, grammar: &AstSrc) -> Result<String> {
let (node_defs, node_boilerplate_impls): (Vec<_>, Vec<_>) = grammar
.nodes
@@ -524,7 +525,7 @@
fn write_doc_comment(contents: &[String], dest: &mut String) {
use std::fmt::Write;
for line in contents {
- writeln!(dest, "///{}", line).unwrap();
+ writeln!(dest, "///{line}").unwrap();
}
}
xtask/src/sourcegen/util.rsdiffbeforeafterboth--- a/xtask/src/sourcegen/util.rs
+++ b/xtask/src/sourcegen/util.rs
@@ -1,3 +1,5 @@
+// FIXME: Replace various helper here with inflector?
+
use std::{fs, path::Path};
use anyhow::Result;
@@ -5,11 +7,11 @@
/// Checks that the `file` has the specified `contents`. If that is not the
/// case, updates the file and then fails the test.
-pub fn ensure_file_contents(file: &Path, contents: &str) -> Result<()> {
+pub fn ensure_file_contents(file: &Path, contents: &str) {
if let Ok(old_contents) = fs::read_to_string(file) {
if normalize_newlines(&old_contents) == normalize_newlines(contents) {
// File is already up to date.
- return Ok(());
+ return;
}
}
@@ -18,7 +20,6 @@
let _ = fs::create_dir_all(parent);
}
fs::write(file, contents).unwrap();
- Ok(())
}
// Eww, someone configured git to use crlf?
@@ -26,8 +27,9 @@
s.replace("\r\n", "\n")
}
-pub(crate) fn pluralize(s: &str) -> String {
- format!("{}s", s)
+pub fn pluralize(s: &str) -> String {
+ // FIXME: Inflector?
+ format!("{s}s")
}
pub fn to_upper_snake_case(s: &str) -> String {
@@ -35,7 +37,7 @@
let mut prev = false;
for c in s.chars() {
if c.is_ascii_uppercase() && prev {
- buf.push('_')
+ buf.push('_');
}
prev = true;
@@ -48,7 +50,7 @@
let mut prev = false;
for c in s.chars() {
if c.is_ascii_uppercase() && prev {
- buf.push('_')
+ buf.push('_');
}
prev = true;