difftreelog
refactor fix clippy warnings
in: master
27 files changed
Cargo.tomldiffbeforeafterboth--- a/Cargo.toml
+++ b/Cargo.toml
@@ -150,6 +150,9 @@
redundant_pub_crate = "allow"
# Sometimes code is fancier without that
manual_let_else = "allow"
+# Something is broken about that lint, can't be allowed for
+# codegenerated-stdlib block
+similar_names = "allow"
#[profile.test]
#opt-level = 1
cmds/jrsonnet-fmt/src/tests.rsdiffbeforeafterboth--- a/cmds/jrsonnet-fmt/src/tests.rs
+++ b/cmds/jrsonnet-fmt/src/tests.rs
@@ -1,4 +1,4 @@
-use dprint_core::formatting::{PrintOptions, PrintItems};
+use dprint_core::formatting::{PrintItems, PrintOptions};
use indoc::indoc;
use crate::Printable;
cmds/jrsonnet/src/main.rsdiffbeforeafterboth--- a/cmds/jrsonnet/src/main.rs
+++ b/cmds/jrsonnet/src/main.rs
@@ -153,7 +153,7 @@
if let Error::Evaluation(e) = e {
let mut out = String::new();
trace.write_trace(&mut out, &e).expect("format error");
- eprintln!("{out}")
+ eprintln!("{out}");
} else {
eprintln!("{e}");
}
crates/jrsonnet-cli/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-cli/src/lib.rs
+++ b/crates/jrsonnet-cli/src/lib.rs
@@ -10,7 +10,7 @@
stack::{limit_stack_depth, StackDepthLimitOverrideGuard},
FileImportResolver,
};
-use jrsonnet_gcmodule::with_thread_object_space;
+use jrsonnet_gcmodule::{with_thread_object_space, ObjectSpace};
pub use manifest::*;
pub use stdlib::*;
pub use tla::*;
@@ -88,7 +88,7 @@
impl Drop for LeakSpace {
fn drop(&mut self) {
- with_thread_object_space(|s| s.leak())
+ with_thread_object_space(ObjectSpace::leak);
}
}
@@ -102,6 +102,6 @@
let collected = jrsonnet_gcmodule::collect_thread_cycles();
eprintln!("Collected: {collected}");
}
- eprintln!("Tracked: {}", jrsonnet_gcmodule::count_thread_tracked())
+ eprintln!("Tracked: {}", jrsonnet_gcmodule::count_thread_tracked());
}
}
crates/jrsonnet-cli/src/stdlib.rsdiffbeforeafterboth--- a/crates/jrsonnet-cli/src/stdlib.rs
+++ b/crates/jrsonnet-cli/src/stdlib.rs
@@ -39,11 +39,11 @@
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
match s.find('=') {
- Some(idx) => Ok(ExtStr {
+ Some(idx) => Ok(Self {
name: s[..idx].to_owned(),
value: s[idx + 1..].to_owned(),
}),
- None => Ok(ExtStr {
+ None => Ok(Self {
name: s.to_owned(),
value: std::env::var(s).or(Err("missing env var"))?,
}),
@@ -109,16 +109,16 @@
return Ok(None);
}
let ctx = ContextInitializer::new(s.clone(), PathResolver::new_cwd_fallback());
- for ext in self.ext_str.iter() {
+ for ext in &self.ext_str {
ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());
}
- for ext in self.ext_str_file.iter() {
+ for ext in &self.ext_str_file {
ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());
}
- for ext in self.ext_code.iter() {
+ for ext in &self.ext_code {
ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;
}
- for ext in self.ext_code_file.iter() {
+ for ext in &self.ext_code_file {
ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;
}
Ok(Some(ctx))
crates/jrsonnet-evaluator/src/arr/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/arr/mod.rs
+++ b/crates/jrsonnet-evaluator/src/arr/mod.rs
@@ -42,7 +42,7 @@
Self::new(EagerArray(values))
}
- pub fn repeated(data: ArrValue, repeats: usize) -> Option<Self> {
+ pub fn repeated(data: Self, repeats: usize) -> Option<Self> {
Some(Self::new(RepeatedArray::new(data, repeats)?))
}
@@ -70,7 +70,7 @@
Ok(Self::eager(out))
}
- pub fn extended(a: ArrValue, b: ArrValue) -> Self {
+ pub fn extended(a: Self, b: Self) -> Self {
// TODO: benchmark for an optimal value, currently just a arbitrary choice
const ARR_EXTEND_THRESHOLD: usize = 100;
crates/jrsonnet-evaluator/src/function/arglike.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/function/arglike.rs
+++ b/crates/jrsonnet-evaluator/src/function/arglike.rs
@@ -61,8 +61,8 @@
impl ArgLike for TlaArg {
fn evaluate_arg(&self, ctx: Context, tailstrict: bool) -> Result<Thunk<Val>> {
match self {
- TlaArg::String(s) => Ok(Thunk::evaluated(Val::string(s.clone()))),
- TlaArg::Code(code) => Ok(if tailstrict {
+ Self::String(s) => Ok(Thunk::evaluated(Val::string(s.clone()))),
+ Self::Code(code) => Ok(if tailstrict {
Thunk::evaluated(evaluate(ctx, code)?)
} else {
Thunk::new(EvaluateThunk {
@@ -70,8 +70,8 @@
expr: code.clone(),
})
}),
- TlaArg::Val(val) => Ok(Thunk::evaluated(val.clone())),
- TlaArg::Lazy(lazy) => Ok(lazy.clone()),
+ Self::Val(val) => Ok(Thunk::evaluated(val.clone())),
+ Self::Lazy(lazy) => Ok(lazy.clone()),
}
}
}
crates/jrsonnet-evaluator/src/function/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/function/mod.rs
+++ b/crates/jrsonnet-evaluator/src/function/mod.rs
@@ -237,7 +237,7 @@
pub fn evaluate_trivial(&self) -> Option<Val> {
match self {
- FuncVal::Normal(n) => n.evaluate_trivial(),
+ Self::Normal(n) => n.evaluate_trivial(),
_ => None,
}
}
crates/jrsonnet-evaluator/src/import.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/import.rs
+++ b/crates/jrsonnet-evaluator/src/import.rs
@@ -10,7 +10,7 @@
use fs::File;
use jrsonnet_gcmodule::Trace;
use jrsonnet_interner::IBytes;
-use jrsonnet_parser::{SourceDirectory, SourceFile, SourcePath, SourceFifo};
+use jrsonnet_parser::{SourceDirectory, SourceFifo, SourceFile, SourcePath};
use crate::{
bail,
crates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/integrations/serde.rs
+++ b/crates/jrsonnet-evaluator/src/integrations/serde.rs
@@ -15,7 +15,7 @@
};
impl<'de> Deserialize<'de> for Val {
- fn deserialize<D>(deserializer: D) -> Result<Val, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
@@ -155,10 +155,10 @@
S: serde::Serializer,
{
match self {
- Val::Bool(v) => serializer.serialize_bool(*v),
- Val::Null => serializer.serialize_none(),
- Val::Str(s) => serializer.serialize_str(&s.clone().into_flat()),
- Val::Num(n) => {
+ Self::Bool(v) => serializer.serialize_bool(*v),
+ Self::Null => serializer.serialize_none(),
+ Self::Str(s) => serializer.serialize_str(&s.clone().into_flat()),
+ Self::Num(n) => {
if n.fract() == 0.0 {
let n = *n as i64;
serializer.serialize_i64(n)
@@ -167,8 +167,8 @@
}
}
#[cfg(feature = "exp-bigint")]
- Val::BigInt(b) => b.serialize(serializer),
- Val::Arr(arr) => {
+ Self::BigInt(b) => b.serialize(serializer),
+ Self::Arr(arr) => {
let mut seq = serializer.serialize_seq(Some(arr.len()))?;
for (i, element) in arr.iter().enumerate() {
let mut serde_error = None;
@@ -190,7 +190,7 @@
}
seq.end()
}
- Val::Obj(obj) => {
+ Self::Obj(obj) => {
let mut map = serializer.serialize_map(Some(obj.len()))?;
for (field, value) in obj.iter(
#[cfg(feature = "exp-preserve-order")]
@@ -215,7 +215,7 @@
}
map.end()
}
- Val::Func(_) => Err(S::Error::custom("tried to manifest function")),
+ Self::Func(_) => Err(S::Error::custom("tried to manifest function")),
}
}
}
@@ -248,9 +248,9 @@
type Ok = Val;
type Error = JrError;
- fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
+ fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
- T: Serialize,
+ T: ?Sized + Serialize,
{
let value = value.serialize(IntoValSerializer)?;
self.data.push(value);
@@ -272,9 +272,9 @@
type Ok = Val;
type Error = JrError;
- fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
+ fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
- T: Serialize,
+ T: ?Sized + Serialize,
{
SerializeSeq::serialize_element(self, value)
}
@@ -287,9 +287,9 @@
type Ok = Val;
type Error = JrError;
- fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
+ fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
- T: Serialize,
+ T: ?Sized + Serialize,
{
SerializeSeq::serialize_element(self, value)
}
@@ -302,9 +302,9 @@
type Ok = Val;
type Error = JrError;
- fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
+ fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
- T: Serialize,
+ T: ?Sized + Serialize,
{
SerializeSeq::serialize_element(self, value)
}
@@ -607,7 +607,7 @@
}
impl Val {
- pub fn from_serde(v: impl Serialize) -> Result<Val, JrError> {
+ pub fn from_serde(v: impl Serialize) -> Result<Self, JrError> {
v.serialize(IntoValSerializer)
}
}
crates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/lib.rs
+++ b/crates/jrsonnet-evaluator/src/lib.rs
@@ -45,7 +45,7 @@
#[doc(hidden)]
pub use jrsonnet_macros;
pub use jrsonnet_parser as parser;
-use jrsonnet_parser::*;
+use jrsonnet_parser::{ExprLocation, LocExpr, ParserSettings, Source, SourcePath};
pub use obj::*;
use stack::check_depth;
pub use tla::apply_tla;
crates/jrsonnet-evaluator/src/stack.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/stack.rs
+++ b/crates/jrsonnet-evaluator/src/stack.rs
@@ -24,7 +24,7 @@
pub struct StackOverflowError;
impl From<StackOverflowError> for ErrorKind {
fn from(_: StackOverflowError) -> Self {
- ErrorKind::StackOverflow
+ Self::StackOverflow
}
}
impl From<StackOverflowError> for Error {
crates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/typed/conversions.rs
+++ b/crates/jrsonnet-evaluator/src/typed/conversions.rs
@@ -358,7 +358,7 @@
};
a.iter()
.map(|r| r.and_then(T::from_untyped))
- .collect::<Result<Vec<T>>>()
+ .collect::<Result<Self>>()
}
}
@@ -381,7 +381,7 @@
Self::TYPE.check(&value)?;
let obj = value.as_obj().expect("typecheck should fail");
- let mut out = BTreeMap::new();
+ let mut out = Self::new();
if V::wants_lazy() {
for key in obj.fields_ex(
false,
@@ -623,8 +623,8 @@
fn into_untyped(value: Self) -> Result<Val> {
match value {
- IndexableVal::Str(s) => Ok(Val::string(s)),
- IndexableVal::Arr(a) => Ok(Val::Arr(a)),
+ Self::Str(s) => Ok(Val::string(s)),
+ Self::Arr(a) => Ok(Val::Arr(a)),
}
}
crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/val.rs
+++ b/crates/jrsonnet-evaluator/src/val.rs
@@ -147,7 +147,7 @@
T: ThunkValue<Output = V>,
{
fn from(value: T) -> Self {
- Thunk::new(value)
+ Self::new(value)
}
}
@@ -221,8 +221,8 @@
impl IndexableVal {
pub fn to_array(self) -> ArrValue {
match self {
- IndexableVal::Str(s) => ArrValue::chars(s.chars()),
- IndexableVal::Arr(arr) => arr,
+ Self::Str(s) => ArrValue::chars(s.chars()),
+ Self::Arr(arr) => arr,
}
}
/// Slice the value.
@@ -239,7 +239,7 @@
step: Option<BoundedUsize<1, { i32::MAX as usize }>>,
) -> Result<Self> {
match &self {
- IndexableVal::Str(s) => {
+ Self::Str(s) => {
let mut computed_len = None;
let mut get_len = || {
computed_len.map_or_else(
@@ -277,7 +277,7 @@
.into(),
))
}
- IndexableVal::Arr(arr) => {
+ Self::Arr(arr) => {
let get_idx = |pos: Option<i32>, len: usize, default| match pos {
Some(v) if v < 0 => len.saturating_sub((-v) as usize),
Some(v) => (v as usize).min(len),
@@ -307,7 +307,7 @@
Tree(Rc<(StrValue, StrValue, usize)>),
}
impl StrValue {
- pub fn concat(a: StrValue, b: StrValue) -> Self {
+ pub fn concat(a: Self, b: Self) -> Self {
// TODO: benchmark for an optimal value, currently just a arbitrary choice
const STRING_EXTEND_THRESHOLD: usize = 100;
@@ -334,8 +334,8 @@
}
}
match self {
- StrValue::Flat(f) => f,
- StrValue::Tree(_) => {
+ Self::Flat(f) => f,
+ Self::Tree(_) => {
let mut buf = String::with_capacity(self.len());
write_buf(&self, &mut buf);
buf.into()
@@ -344,8 +344,8 @@
}
pub fn len(&self) -> usize {
match self {
- StrValue::Flat(v) => v.len(),
- StrValue::Tree(t) => t.2,
+ Self::Flat(v) => v.len(),
+ Self::Tree(t) => t.2,
}
}
pub fn is_empty(&self) -> bool {
@@ -367,8 +367,8 @@
impl Display for StrValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
- StrValue::Flat(v) => write!(f, "{v}"),
- StrValue::Tree(t) => {
+ Self::Flat(v) => write!(f, "{v}"),
+ Self::Tree(t) => {
write!(f, "{}", t.0)?;
write!(f, "{}", t.1)
}
@@ -522,8 +522,8 @@
pub fn into_indexable(self) -> Result<IndexableVal> {
Ok(match self {
- Val::Str(s) => IndexableVal::Str(s.into_flat()),
- Val::Arr(arr) => IndexableVal::Arr(arr),
+ Self::Str(s) => IndexableVal::Str(s.into_flat()),
+ Self::Arr(arr) => IndexableVal::Arr(arr),
_ => bail!(ValueIsNotIndexable(self.value_type())),
})
}
crates/jrsonnet-macros/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-macros/src/lib.rs
+++ b/crates/jrsonnet-macros/src/lib.rs
@@ -1,3 +1,5 @@
+use std::string::String;
+
use proc_macro2::TokenStream;
use quote::quote;
use syn::{
@@ -205,6 +207,7 @@
}
}
+#[allow(clippy::too_many_lines)]
fn builtin_inner(
attr: BuiltinAttrs,
fun: ItemFn,
@@ -225,7 +228,7 @@
.map(|arg| ArgInfo::parse(&name, arg))
.collect::<Result<Vec<_>>>()?;
- let params_desc = args.iter().flat_map(|a| match a {
+ let params_desc = args.iter().filter_map(|a| match a {
ArgInfo::Normal {
is_option,
name,
@@ -234,8 +237,7 @@
} => {
let name = name
.as_ref()
- .map(|n| quote! {ParamName::new_static(#n)})
- .unwrap_or_else(|| quote! {None});
+ .map_or_else(|| quote! {None}, |n| quote! {ParamName::new_static(#n)});
Some(quote! {
#(#cfg_attrs)*
BuiltinParam::new(#name, #is_option),
@@ -244,15 +246,12 @@
ArgInfo::Lazy { is_option, name } => {
let name = name
.as_ref()
- .map(|n| quote! {ParamName::new_static(#n)})
- .unwrap_or_else(|| quote! {None});
+ .map_or_else(|| quote! {None}, |n| quote! {ParamName::new_static(#n)});
Some(quote! {
BuiltinParam::new(#name, #is_option),
})
}
- ArgInfo::Context => None,
- ArgInfo::Location => None,
- ArgInfo::This => None,
+ ArgInfo::Context | ArgInfo::Location | ArgInfo::This => None,
});
let mut id = 0usize;
@@ -275,7 +274,7 @@
name,
cfg_attrs,
} => {
- let name = name.as_ref().map(|v| v.as_str()).unwrap_or("<unnamed>");
+ let name = name.as_ref().map_or("<unnamed>", String::as_str);
let eval = quote! {jrsonnet_evaluator::State::push_description(
|| format!("argument <{}> evaluation", #name),
|| <#ty>::from_untyped(value.evaluate()?),
@@ -390,6 +389,7 @@
}
#[derive(Default)]
+#[allow(clippy::struct_excessive_bools)]
struct TypedAttr {
rename: Option<String>,
flatten: bool,
@@ -467,11 +467,8 @@
"this field should appear in output object, but it has no visible name",
));
};
- let (is_option, ty) = if let Some(ty) = extract_type_from_option(&field.ty)? {
- (true, ty.clone())
- } else {
- (false, field.ty.clone())
- };
+ let (is_option, ty) = extract_type_from_option(&field.ty)?
+ .map_or_else(|| (false, field.ty.clone()), |ty| (true, ty.clone()));
if is_option && attr.flatten {
if !attr.flatten_ok {
return Err(Error::new(
@@ -551,48 +548,53 @@
#ident: #value,
}
}
- fn expand_serialize(&self) -> Result<TokenStream> {
+ fn expand_serialize(&self) -> TokenStream {
let ident = &self.ident;
let ty = &self.ty;
- Ok(if let Some(name) = self.name() {
- let hide = if self.attr.hide {
- quote! {.hide()}
- } else {
- quote! {}
- };
- let add = if self.attr.add {
- quote! {.add()}
- } else {
- quote! {}
- };
- if self.is_option {
- quote! {
- if let Some(value) = self.#ident {
+ self.name().map_or_else(
+ || {
+ if self.is_option {
+ quote! {
+ if let Some(value) = self.#ident {
+ <#ty as TypedObj>::serialize(value, out)?;
+ }
+ }
+ } else {
+ quote! {
+ <#ty as TypedObj>::serialize(self.#ident, out)?;
+ }
+ }
+ },
+ |name| {
+ let hide = if self.attr.hide {
+ quote! {.hide()}
+ } else {
+ quote! {}
+ };
+ let add = if self.attr.add {
+ quote! {.add()}
+ } else {
+ quote! {}
+ };
+ if self.is_option {
+ quote! {
+ if let Some(value) = self.#ident {
+ out.field(#name)
+ #hide
+ #add
+ .try_value(<#ty as Typed>::into_untyped(value)?)?;
+ }
+ }
+ } else {
+ quote! {
out.field(#name)
#hide
#add
- .try_value(<#ty as Typed>::into_untyped(value)?)?;
+ .try_value(<#ty as Typed>::into_untyped(self.#ident)?)?;
}
}
- } else {
- quote! {
- out.field(#name)
- #hide
- #add
- .try_value(<#ty as Typed>::into_untyped(self.#ident)?)?;
- }
- }
- } else if self.is_option {
- quote! {
- if let Some(value) = self.#ident {
- <#ty as TypedObj>::serialize(value, out)?;
- }
- }
- } else {
- quote! {
- <#ty as TypedObj>::serialize(self.#ident, out)?;
- }
- })
+ },
+ )
}
}
@@ -623,7 +625,7 @@
let typed = {
let fields = fields
.iter()
- .flat_map(TypedField::expand_field)
+ .filter_map(TypedField::expand_field)
.collect::<Vec<_>>();
quote! {
impl #impl_generics Typed for #ident #ty_generics #where_clause {
@@ -650,7 +652,7 @@
let fields_serialize = fields
.iter()
.map(TypedField::expand_serialize)
- .collect::<Result<Vec<_>>>()?;
+ .collect::<Vec<_>>();
Ok(quote! {
const _: () = {
@@ -767,7 +769,7 @@
}
}
-/// IStr formatting helper
+/// `IStr` formatting helper
///
/// Using `format!("literal with no codes").into()` is slower than just `"literal with no codes".into()`
/// This macro looks for formatting codes in the input string, and uses
crates/jrsonnet-rowan-parser/src/parser.rsdiffbeforeafterboth1use std::{cell::Cell, fmt, rc::Rc};23use rowan::{GreenNode, TextRange};45use crate::{6 event::Event,7 marker::{CompletedMarker, Marker},8 nodes::{BinaryOperatorKind, Literal, Number, Text, UnaryOperatorKind},9 token_set::SyntaxKindSet,10 AstToken, SyntaxKind,11 SyntaxKind::*,12 SyntaxNode, T, TS,13};1415pub struct Parse {16 pub green_node: GreenNode,17 pub errors: Vec<LocatedSyntaxError>,18}1920pub struct Parser {21 // TODO: remove all trivia before feeding to parser?22 kinds: Vec<SyntaxKind>,23 pub offset: usize,24 pub events: Vec<Event>,25 pub entered: u32,26 pub hints: Vec<(u32, TextRange, String)>,27 pub last_error_token: usize,28 expected_syntax_tracking_state: Rc<Cell<ExpectedSyntax>>,29 steps: Cell<u64>,30}3132#[derive(Clone, Debug)]33pub enum SyntaxError {34 Unexpected {35 expected: ExpectedSyntax,36 found: SyntaxKind,37 },38 Missing {39 expected: ExpectedSyntax,40 },41 Custom {42 error: String,43 },44 Hint {45 error: String,46 },47}4849#[derive(Debug)]50pub struct LocatedSyntaxError {51 pub error: SyntaxError,52 pub range: TextRange,53}5455impl Parser {56 pub fn new(kinds: Vec<SyntaxKind>) -> Self {57 Self {58 kinds,59 offset: 0,60 events: vec![],61 entered: 0,62 last_error_token: 0,63 hints: vec![],64 expected_syntax_tracking_state: Rc::new(Cell::new(ExpectedSyntax::Unnamed(TS![]))),65 steps: Cell::new(0),66 }67 }68 pub fn clear_outdated_hints(&mut self) {69 let amount = self70 .hints71 .iter()72 .rev()73 .take_while(|h| h.0 > self.entered)74 .count();75 self.hints.truncate(self.hints.len() - amount)76 }77 fn clear_expected_syntaxes(&mut self) {78 self.expected_syntax_tracking_state79 .set(ExpectedSyntax::Unnamed(TS![]));80 }81 pub fn start(&mut self) -> Marker {82 let start_event_idx = self.events.len();83 self.events.push(Event::Pending);84 self.entered += 1;85 Marker::new(start_event_idx)86 }87 // pub fn start_ranger(&mut self) -> Ranger {88 // let pos = self.offset;89 // Ranger { pos }90 // }91 pub fn parse(mut self) -> Vec<Event> {92 let m = self.start();93 expr(&mut self);94 if !self.at(EOF) {95 let m = self.start();96 while !self.at(EOF) {97 self.bump();98 }99 m.complete_error(&mut self, "unexpected tokens after end");100 }101 m.complete(&mut self, SOURCE_FILE);102103 self.events104 }105106 pub(crate) fn expect(&mut self, kind: SyntaxKind) {107 self.expect_with_recovery_set(kind, TS![])108 }109110 pub(crate) fn expect_with_recovery_set(111 &mut self,112 kind: SyntaxKind,113 recovery_set: SyntaxKindSet,114 ) {115 if self.at(kind) {116 if kind != EOF {117 self.bump();118 }119 } else {120 self.error_with_recovery_set(recovery_set);121 }122 }123124 // pub(crate) fn expect_with_no_skip(&mut self, kind: SyntaxKind) {125 // if self.at(kind) {126 // self.bump();127 // } else {128 // self.error_with_no_skip();129 // }130 // }131 pub fn error_with_no_skip(&mut self) -> CompletedMarker {132 self.error_with_recovery_set(SyntaxKindSet::ALL)133 }134135 pub fn error_with_recovery_set(&mut self, recovery_set: SyntaxKindSet) -> CompletedMarker {136 let expected = self.expected_syntax_tracking_state.get();137 self.expected_syntax_tracking_state138 .set(ExpectedSyntax::Unnamed(TS![]));139140 if self.at_end() || self.at_ts(recovery_set) {141 let m = self.start();142 return m.complete_missing(self, expected);143 }144145 let current_token = self.current();146147 self.last_error_token = self.offset;148149 let m = self.start();150 self.bump();151 let m = m.complete_unexpected(self, expected, current_token);152 self.clear_expected_syntaxes();153 m154 }155 fn bump_assert(&mut self, kind: SyntaxKind) {156 assert!(self.at(kind), "expected {:?}", kind);157 self.bump_remap(self.current());158 }159 fn bump(&mut self) {160 self.bump_remap(self.current());161 }162 fn bump_remap(&mut self, kind: SyntaxKind) {163 assert_ne!(self.offset, self.kinds.len(), "already at end");164 self.events.push(Event::Token { kind });165 self.offset += 1;166 self.clear_expected_syntaxes();167 }168 fn step(&self) {169 use std::fmt::Write;170 let steps = self.steps.get();171 if steps >= 15000000 {172 let mut out = "seems like parsing is stuck".to_owned();173 {174 let last = 20;175 write!(out, "\n\nLast {} events:", last).unwrap();176 for (i, event) in self177 .events178 .iter()179 .skip(self.events.len().saturating_sub(last))180 .enumerate()181 {182 write!(out, "\n{i}. {event:?}").unwrap();183 }184 }185 {186 let next = 20;187 write!(out, "\n\nNext {next} tokens:").unwrap();188 for (i, tok) in self.kinds.iter().skip(self.offset).take(next).enumerate() {189 write!(out, "\n{i}. {tok:?}").unwrap();190 }191 }192 panic!("{out}")193 }194 self.steps.set(steps + 1);195 }196 fn nth(&self, i: usize) -> SyntaxKind {197 self.step();198 let mut offset = self.offset;199 for _ in 0..i {200 offset += 1;201 }202 self.kinds.get(offset).copied().unwrap_or(EOF)203 }204 fn current(&self) -> SyntaxKind {205 self.nth(0)206 }207 #[must_use]208 pub(crate) fn expected_syntax_name(&mut self, name: &'static str) -> ExpectedSyntaxGuard {209 self.expected_syntax_tracking_state210 .set(ExpectedSyntax::Named(name));211212 ExpectedSyntaxGuard::new(Rc::clone(&self.expected_syntax_tracking_state))213 }214 pub fn at(&mut self, kind: SyntaxKind) -> bool {215 self.nth_at(0, kind)216 }217 pub fn nth_at(&mut self, n: usize, kind: SyntaxKind) -> bool {218 if n == 0 {219 if let ExpectedSyntax::Unnamed(kinds) = self.expected_syntax_tracking_state.get() {220 let kinds = kinds.with(kind);221 self.expected_syntax_tracking_state222 .set(ExpectedSyntax::Unnamed(kinds))223 }224 }225 self.nth(n) == kind226 }227 pub fn at_ts(&mut self, set: SyntaxKindSet) -> bool {228 if let ExpectedSyntax::Unnamed(kinds) = self.expected_syntax_tracking_state.get() {229 let kinds = kinds.union(set);230 self.expected_syntax_tracking_state231 .set(ExpectedSyntax::Unnamed(kinds))232 }233 set.contains(self.current())234 }235 pub fn at_end(&mut self) -> bool {236 self.at(EOF)237 }238}239pub(crate) struct ExpectedSyntaxGuard {240 expected_syntax_tracking_state: Rc<Cell<ExpectedSyntax>>,241}242243impl ExpectedSyntaxGuard {244 fn new(expected_syntax_tracking_state: Rc<Cell<ExpectedSyntax>>) -> Self {245 Self {246 expected_syntax_tracking_state,247 }248 }249}250251impl Drop for ExpectedSyntaxGuard {252 fn drop(&mut self) {253 self.expected_syntax_tracking_state254 .set(ExpectedSyntax::Unnamed(TS![]));255 }256}257258#[derive(Clone, Debug, Copy)]259pub enum ExpectedSyntax {260 Named(&'static str),261 Unnamed(SyntaxKindSet),262}263impl fmt::Display for ExpectedSyntax {264 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {265 match self {266 ExpectedSyntax::Named(name) => write!(f, "{name}"),267 ExpectedSyntax::Unnamed(set) => write!(f, "{set}"),268 }269 }270}271272fn expr(p: &mut Parser) -> CompletedMarker {273 let m = p.start();274 while p.at(T![local]) || p.at(T![assert]) {275 let m = p.start();276277 if p.at(T![local]) {278 p.bump();279 loop {280 if p.at(T![;]) {281 p.bump();282 break;283 }284 bind(p);285286 if p.at(T![,]) {287 p.bump();288 continue;289 }290 p.expect(T![;]);291 break;292 }293 m.complete(p, STMT_LOCAL);294 } else {295 assertion(p);296 p.expect(T![;]);297 m.complete(p, STMT_ASSERT);298 }299 }300 match expr_binding_power(p, 0) {301 Ok(m) => m,302 Err(m) => m,303 };304 m.complete(p, EXPR)305}306fn expr_binding_power(307 p: &mut Parser,308 minimum_binding_power: u8,309) -> Result<CompletedMarker, CompletedMarker> {310 let mut lhs = lhs(p)?;311312 while let Some(op) = BinaryOperatorKind::cast(p.current())313 .or_else(|| p.at(T!['{']).then_some(BinaryOperatorKind::MetaObjectApply))314 {315 let (left_binding_power, right_binding_power) = op.binding_power();316 if left_binding_power < minimum_binding_power {317 break;318 }319320 // Object apply is not a real operator, we dont have something to bump321 if op != BinaryOperatorKind::MetaObjectApply {322 p.bump();323 }324325 let m = lhs.wrap(p, EXPR).precede(p);326 let parsed_rhs = expr_binding_power(p, right_binding_power)327 .map(|v| v.precede(p).complete(p, EXPR))328 .is_ok();329 lhs = m.complete(330 p,331 if op == BinaryOperatorKind::MetaObjectApply {332 EXPR_OBJ_EXTEND333 } else {334 EXPR_BINARY335 },336 );337338 if !parsed_rhs {339 break;340 }341 }342 Ok(lhs)343}344345const COMPSPEC: SyntaxKindSet = TS![for if];346fn compspec(p: &mut Parser) -> CompletedMarker {347 assert!(p.at_ts(COMPSPEC));348 if p.at(T![for]) {349 let m = p.start();350 p.bump();351 destruct(p);352 p.expect(T![in]);353 expr(p);354 m.complete(p, FOR_SPEC)355 } else if p.at(T![if]) {356 let m = p.start();357 p.bump();358 expr(p);359 m.complete(p, IF_SPEC)360 } else {361 unreachable!()362 }363}364365fn comma(p: &mut Parser) -> bool {366 comma_with_alternatives(p, TS![])367}368fn comma_with_alternatives(p: &mut Parser, set: SyntaxKindSet) -> bool {369 if p.at(T![,]) {370 p.bump();371 true372 } else if p.at_ts(set) {373 let _ex = p.expected_syntax_name("comma");374 p.expect_with_recovery_set(T![,], TS![]);375 true376 } else {377 false378 }379}380381fn field_name(p: &mut Parser) {382 let _e = p.expected_syntax_name("field name");383 let m = p.start();384 if p.at(T!['[']) {385 p.bump();386 expr(p);387 p.expect(T![']']);388 m.complete(p, FIELD_NAME_DYNAMIC);389 } else if p.at(IDENT) {390 name(p);391 m.complete(p, FIELD_NAME_FIXED);392 } else if Text::can_cast(p.current()) {393 text(p);394 m.complete(p, FIELD_NAME_FIXED);395 } else {396 m.forget(p);397 p.error_with_recovery_set(TS![; : :: ::: '(']);398 }399}400fn visibility(p: &mut Parser) {401 if p.at_ts(TS![: :: :::]) {402 p.bump()403 } else {404 p.error_with_recovery_set(TS![=]);405 }406}407fn assertion(p: &mut Parser) {408 let m = p.start();409 p.bump_assert(T![assert]);410 expr(p);411 if p.at(T![:]) {412 p.bump();413 expr(p);414 }415 m.complete(p, ASSERTION);416}417fn object(p: &mut Parser) -> CompletedMarker {418 let m_t = p.start();419 let m = p.start();420 p.bump_assert(T!['{']);421422 let mut elems = 0;423 let mut compspecs = Vec::new();424 let mut asserts = Vec::new();425 loop {426 if p.at(T!['}']) {427 p.bump();428 break;429 }430 if p.at_ts(TS![for]) {431 if elems == 0 {432 let m = p.start();433 m.complete_missing(p, ExpectedSyntax::Named("field definition"));434 }435 while p.at_ts(COMPSPEC) {436 compspecs.push(compspec(p));437 }438 if comma_with_alternatives(p, TS![;]) {439 continue;440 }441 p.expect(R_BRACE);442 break;443 }444 let m = p.start();445 if p.at(T![local]) {446 obj_local(p);447 m.complete(p, MEMBER_BIND_STMT);448 } else if p.at(T![assert]) {449 assertion(p);450 asserts.push(m.complete(p, MEMBER_ASSERT_STMT));451 } else {452 field_name(p);453 if p.at(T![+]) {454 p.bump();455 }456 let params = if p.at(T!['(']) {457 params_desc(p);458 visibility(p);459 expr(p);460 true461 } else if p.at_ts(TS![: :: :::]) && p.nth_at(1, T![function]) {462 visibility(p);463 p.bump_assert(T![function]);464 params_desc(p);465 expr(p);466 true467 } else {468 visibility(p);469 expr(p);470 false471 };472 elems += 1;473474 if params {475 m.complete(p, MEMBER_FIELD_METHOD)476 } else {477 m.complete(p, MEMBER_FIELD_NORMAL)478 };479 };480 while p.at_ts(COMPSPEC) {481 compspecs.push(compspec(p));482 }483 if comma_with_alternatives(p, TS![;]) {484 continue;485 }486 p.expect(R_BRACE);487 break;488 }489490 if elems > 1 && !compspecs.is_empty() {491 for errored in compspecs {492 errored.wrap_error(493 p,494 "compspec may only be used if there is only one object element",495 );496 }497 m.complete(p, OBJ_BODY_MEMBER_LIST);498 } else if !compspecs.is_empty() {499 for errored in asserts {500 errored.wrap_error(p, "asserts can't be used in object comprehensions");501 }502 m.complete(p, OBJ_BODY_COMP);503 } else {504 m.complete(p, OBJ_BODY_MEMBER_LIST);505 }506 m_t.complete(p, EXPR_OBJECT)507}508fn param(p: &mut Parser) {509 let m = p.start();510 destruct(p);511 if p.at(T![=]) {512 p.bump();513 expr(p);514 }515 m.complete(p, PARAM);516}517fn params_desc(p: &mut Parser) -> CompletedMarker {518 let m = p.start();519 p.bump_assert(T!['(']);520521 loop {522 if p.at(T![')']) {523 p.bump();524 break;525 }526 param(p);527 if comma(p) {528 continue;529 }530 p.expect(T![')']);531 break;532 }533534 m.complete(p, PARAMS_DESC)535}536fn args_desc(p: &mut Parser) {537 let m = p.start();538 p.bump_assert(T!['(']);539540 let started_named = Cell::new(false);541 let mut unnamed_after_named = Vec::new();542543 loop {544 if p.at(T![')']) {545 break;546 }547548 let m = p.start();549 if p.at(IDENT) && p.nth_at(1, T![=]) {550 name(p);551 p.bump();552 expr(p);553 m.complete(p, ARG);554 started_named.set(true);555 } else {556 expr(p);557 let arg = m.complete(p, ARG);558 if started_named.get() {559 unnamed_after_named.push(arg)560 }561 }562 if comma(p) {563 continue;564 }565 break;566 }567 p.expect(T![')']);568 if p.at(T![tailstrict]) {569 p.bump()570 }571572 for errored in unnamed_after_named {573 errored.wrap_error(p, "can't use positional arguments after named");574 }575576 m.complete(p, ARGS_DESC);577}578579fn array(p: &mut Parser) -> CompletedMarker {580 // Start the list node581 let m = p.start();582 p.bump_assert(T!['[']);583584 let mut compspecs = Vec::new();585 let mut elems = 0;586587 loop {588 if p.at(T![']']) {589 p.bump();590 break;591 }592 if elems != 0 && p.at_ts(TS![for]) {593 while p.at_ts(COMPSPEC) {594 compspecs.push(compspec(p));595 }596 if comma(p) {597 continue;598 }599 p.expect(T![']']);600 break;601 }602 expr(p);603 elems += 1;604 while p.at_ts(COMPSPEC) {605 compspecs.push(compspec(p));606 }607 if comma(p) {608 continue;609 }610 p.expect(T![']']);611 break;612 }613614 if elems > 1 && !compspecs.is_empty() {615 for spec in compspecs {616 spec.wrap_error(617 p,618 "compspec may only be used if there is only one array element",619 );620 }621622 m.complete(p, EXPR_ARRAY)623 } else if !compspecs.is_empty() {624 m.complete(p, EXPR_ARRAY_COMP)625 } else {626 m.complete(p, EXPR_ARRAY)627 }628}629/// Returns true if it was slice, false if just index630#[must_use]631fn slice_desc_or_index(p: &mut Parser) -> bool {632 let m = p.start();633 p.bump();634 // TODO: do not treat :, ::, ::: as full tokens?635 // Start636 if !p.at(T![:]) && !p.at(T![::]) {637 expr(p);638 }639 if p.at(T![:]) {640 p.bump();641 // End642 if !p.at(T![']']) {643 expr(p).wrap(p, SLICE_DESC_END);644 }645 if p.at(T![:]) {646 p.bump();647 // Step648 if !p.at(T![']']) {649 expr(p).wrap(p, SLICE_DESC_STEP);650 }651 }652 } else if p.at(T![::]) {653 p.bump();654 // End655 if !p.at(T![']']) {656 expr(p).wrap(p, SLICE_DESC_END);657 }658 } else {659 // It was not a slice660 p.expect(T![']']);661 m.forget(p);662 return false;663 }664 p.expect(T![']']);665 m.complete(p, SLICE_DESC);666 true667}668669fn suffix(p: &mut Parser) {670 loop {671 let start = p.start();672 let _marker: CompletedMarker = if p.at(T![?]) {673 p.bump();674 p.expect(T![.]);675 if p.at(IDENT) {676 name(p);677 start.complete(p, SUFFIX_INDEX)678 } else if p.at(T!['[']) {679 p.bump();680 expr(p);681 p.expect(T![']']);682 start.complete(p, SUFFIX_INDEX_EXPR)683 } else {684 start.complete_missing(p, ExpectedSyntax::Named("index"))685 }686 } else if p.at(T![.]) {687 p.bump();688 name(p);689 start.complete(p, SUFFIX_INDEX)690 } else if p.at(T!['[']) {691 if slice_desc_or_index(p) {692 start.complete(p, SUFFIX_SLICE)693 } else {694 start.complete(p, SUFFIX_INDEX_EXPR)695 }696 } else if p.at(T!['(']) {697 args_desc(p);698 start.complete(p, SUFFIX_APPLY)699 } else {700 start.forget(p);701 break;702 };703 }704}705706fn lhs(p: &mut Parser) -> Result<CompletedMarker, CompletedMarker> {707 let lhs = lhs_basic(p)?;708709 suffix(p);710711 Ok(lhs)712}713fn name(p: &mut Parser) {714 let m = p.start();715 p.expect(IDENT);716 m.complete(p, NAME);717}718fn destruct_rest(p: &mut Parser) {719 let m = p.start();720 p.bump_assert(T![...]);721 if p.at(IDENT) {722 p.bump()723 }724 m.complete(p, DESTRUCT_REST);725}726fn destruct_object_field(p: &mut Parser) {727 let m = p.start();728 name(p);729 if p.at(T![:]) {730 p.bump();731 destruct(p);732 };733 if p.at(T![=]) {734 p.bump();735 expr(p);736 }737 m.complete(p, DESTRUCT_OBJECT_FIELD);738}739fn obj_local(p: &mut Parser) {740 let m = p.start();741 p.bump_assert(T![local]);742 bind(p);743 m.complete(p, OBJ_LOCAL);744}745fn destruct(p: &mut Parser) -> CompletedMarker {746 let m = p.start();747 let _ex = p.expected_syntax_name("destruction specifier");748 if p.at(T![?]) {749 p.bump();750 m.complete(p, DESTRUCT_SKIP)751 } else if p.at(T!['[']) {752 p.bump();753 // let mut had_rest = false;754 loop {755 if p.at(T![']']) {756 p.bump();757 break;758 } else if p.at(T![...]) {759 // let m_err = p.start_ranger();760 destruct_rest(p);761 // if had_rest {762 // p.custom_error(m_err.finish(p), "only one rest can be present in array");763 // }764 // had_rest = true;765 } else {766 destruct(p);767 }768 if p.at(T![,]) {769 p.bump();770 continue;771 }772 p.expect(T![']']);773 break;774 }775 m.complete(p, DESTRUCT_ARRAY)776 } else if p.at(T!['{']) {777 p.bump();778 let mut had_rest = false;779 loop {780 if p.at(T!['}']) {781 p.bump();782 break;783 } else if p.at(T![...]) {784 // let m_err = p.start_ranger();785 destruct_rest(p);786 // if had_rest {787 // p.custom_error(m_err.finish(p), "only one rest can be present in object");788 // }789 had_rest = true;790 } else {791 if had_rest {792 p.error_with_recovery_set(TS![]);793 }794 destruct_object_field(p);795 }796 if p.at(T![,]) {797 p.bump();798 continue;799 }800 p.expect(T!['}']);801 break;802 }803 m.complete(p, DESTRUCT_OBJECT)804 } else if p.at(IDENT) {805 name(p);806 m.complete(p, DESTRUCT_FULL)807 } else {808 m.forget(p);809 p.error_with_recovery_set(TS![; , '}', '(', :])810 }811}812fn bind(p: &mut Parser) {813 let m = p.start();814 if p.at(IDENT) && p.nth_at(1, T!['(']) {815 name(p);816 params_desc(p);817 p.expect(T![=]);818 expr(p);819 m.complete(p, BIND_FUNCTION)820 } else if p.at(IDENT) && p.nth_at(1, T![=]) && p.nth_at(2, T![function]) {821 name(p);822 p.expect(T![=]);823 p.expect(T![function]);824 params_desc(p);825 expr(p);826 m.complete(p, BIND_FUNCTION)827 } else {828 destruct(p);829 p.expect(T![=]);830 expr(p);831 m.complete(p, BIND_DESTRUCT)832 };833}834fn text(p: &mut Parser) {835 assert!(Text::can_cast(p.current()));836 p.bump();837}838fn number(p: &mut Parser) {839 assert!(Number::can_cast(p.current()));840 p.bump();841}842fn literal(p: &mut Parser) {843 assert!(Literal::can_cast(p.current()));844 p.bump();845}846fn lhs_basic(p: &mut Parser) -> Result<CompletedMarker, CompletedMarker> {847 let _e = p.expected_syntax_name("expression");848 Ok(if Literal::can_cast(p.current()) {849 let m = p.start();850 literal(p);851 m.complete(p, EXPR_LITERAL)852 } else if Text::can_cast(p.current()) {853 let m = p.start();854 text(p);855 m.complete(p, EXPR_STRING)856 } else if Number::can_cast(p.current()) {857 let m = p.start();858 number(p);859 m.complete(p, EXPR_NUMBER)860 } else if p.at(IDENT) {861 let m = p.start();862 name(p);863 m.complete(p, EXPR_VAR)864 } else if p.at(T![if]) {865 let m = p.start();866 p.bump();867 expr(p);868 p.expect(T![then]);869 expr(p).wrap(p, TRUE_EXPR);870 if p.at(T![else]) {871 p.bump();872 expr(p).wrap(p, FALSE_EXPR);873 }874 m.complete(p, EXPR_IF_THEN_ELSE)875 } else if p.at(T!['[']) {876 array(p)877 } else if p.at(T!['{']) {878 object(p)879 } else if p.at(T![function]) {880 let m = p.start();881 p.bump();882 params_desc(p);883 expr(p);884 m.complete(p, EXPR_FUNCTION)885 } else if p.at(T![error]) {886 let m = p.start();887 p.bump();888 expr(p);889 m.complete(p, EXPR_ERROR)890 } else if p.at(T![import]) || p.at(T![importstr]) || p.at(T![importbin]) {891 let m = p.start();892 p.bump();893 text(p);894 m.complete(p, EXPR_IMPORT)895 } else if let Some(op) = UnaryOperatorKind::cast(p.current()) {896 let ((), right_binding_power) = op.binding_power();897898 let m = p.start();899 p.bump();900 let _ = expr_binding_power(p, right_binding_power);901 m.complete(p, EXPR_UNARY)902 } else if p.at(T!['(']) {903 let m = p.start();904 p.bump();905 expr(p);906 p.expect(T![')']);907 m.complete(p, EXPR_PARENED)908 } else {909 return Err(p.error_with_no_skip());910 })911}912913impl Parse {914 pub fn syntax(&self) -> SyntaxNode {915 SyntaxNode::new_root(self.green_node.clone())916 }917}crates/jrsonnet-stdlib/build.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/build.rs
+++ b/crates/jrsonnet-stdlib/build.rs
@@ -26,7 +26,9 @@
let dest_path = Path::new(&out_dir).join("stdlib.rs");
let mut f = File::create(dest_path).unwrap();
f.write_all(
- ("#[allow(clippy::redundant_clone)]".to_owned() + &v.to_string()).as_bytes(),
+ ("#[allow(clippy::redundant_clone, clippy::similar_names)]".to_owned()
+ + &v.to_string())
+ .as_bytes(),
)
.unwrap();
}
crates/jrsonnet-stdlib/src/arrays.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/arrays.rs
+++ b/crates/jrsonnet-stdlib/src/arrays.rs
@@ -9,7 +9,7 @@
Either, IStr, ObjValueBuilder, Result, ResultExt, Thunk, Val,
};
-pub(crate) fn eval_on_empty(on_empty: Option<Thunk<Val>>) -> Result<Val> {
+pub fn eval_on_empty(on_empty: Option<Thunk<Val>>) -> Result<Val> {
if let Some(on_empty) = on_empty {
on_empty.evaluate()
} else {
@@ -270,8 +270,8 @@
let newArrRight = arr.slice(Some(at + 1), None, None);
Ok(ArrValue::extended(
- newArrLeft.unwrap_or(ArrValue::empty()),
- newArrRight.unwrap_or(ArrValue::empty()),
+ newArrLeft.unwrap_or_else(ArrValue::empty),
+ newArrRight.unwrap_or_else(ArrValue::empty),
))
}
crates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/lib.rs
+++ b/crates/jrsonnet-stdlib/src/lib.rs
@@ -313,10 +313,10 @@
settings: Rc<RefCell<Settings>>,
}
impl ContextInitializer {
- pub fn new(_s: State, resolver: PathResolver) -> Self {
+ pub fn new(s: State, resolver: PathResolver) -> Self {
let settings = Settings {
- ext_vars: Default::default(),
- ext_natives: Default::default(),
+ ext_vars: HashMap::new(),
+ ext_natives: HashMap::new(),
trace_printer: Box::new(StdTracePrinter::new(resolver.clone())),
path_resolver: resolver,
};
@@ -324,10 +324,12 @@
let stdlib_obj = stdlib_uncached(settings.clone());
#[cfg(not(feature = "legacy-this-file"))]
let stdlib_thunk = Thunk::evaluated(Val::Obj(stdlib_obj));
+ #[cfg(feature = "legacy-this-file")]
+ let _ = s;
Self {
#[cfg(not(feature = "legacy-this-file"))]
context: {
- let mut context = ContextBuilder::with_capacity(_s, 1);
+ let mut context = ContextBuilder::with_capacity(s, 1);
context.bind("std", stdlib_thunk.clone());
context.build()
},
crates/jrsonnet-stdlib/src/manifest/toml.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/manifest/toml.rs
+++ b/crates/jrsonnet-stdlib/src/manifest/toml.rs
@@ -180,7 +180,9 @@
options.preserve_order,
) {
let value = value?;
- if !is_section(&value)? {
+ if is_section(&value)? {
+ sections.push((key, value));
+ } else {
if !first {
buf.push('\n');
}
@@ -189,8 +191,6 @@
escape_key_toml_buf(&key, buf);
buf.push_str(" = ");
manifest_value(&value, false, buf, cur_padding, options)?;
- } else {
- sections.push((key, value));
}
}
for (k, v) in sections {
crates/jrsonnet-stdlib/src/math.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/math.rs
+++ b/crates/jrsonnet-stdlib/src/math.rs
@@ -131,16 +131,19 @@
}
#[builtin]
+#[allow(clippy::float_cmp)]
pub fn builtin_is_odd(x: f64) -> bool {
builtin_round(x) % 2.0 == 1.0
}
#[builtin]
+#[allow(clippy::float_cmp)]
pub fn builtin_is_integer(x: f64) -> bool {
builtin_round(x) == x
}
#[builtin]
+#[allow(clippy::float_cmp)]
pub fn builtin_is_decimal(x: f64) -> bool {
builtin_round(x) != x
}
crates/jrsonnet-stdlib/src/misc.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/misc.rs
+++ b/crates/jrsonnet-stdlib/src/misc.rs
@@ -67,11 +67,7 @@
v => v.manifest(JsonFormat::debug())?.into(),
},
);
- if let Some(rest) = rest {
- rest.evaluate()
- } else {
- Ok(str)
- }
+ rest.map_or_else(|| Ok(str), |rest| rest.evaluate())
}
#[allow(clippy::comparison_chain)]
@@ -84,16 +80,15 @@
return Ok(false);
} else if b.len() == a.len() {
return equals(&Val::Arr(a), &Val::Arr(b));
- } else {
- for (a, b) in a.iter().take(b.len()).zip(b.iter()) {
- let a = a?;
- let b = b?;
- if !equals(&a, &b)? {
- return Ok(false);
- }
+ }
+ for (a, b) in a.iter().take(b.len()).zip(b.iter()) {
+ let a = a?;
+ let b = b?;
+ if !equals(&a, &b)? {
+ return Ok(false);
}
- true
}
+ true
}
_ => bail!("both arguments should be of the same type"),
})
@@ -109,17 +104,16 @@
return Ok(false);
} else if b.len() == a.len() {
return equals(&Val::Arr(a), &Val::Arr(b));
- } else {
- let a_len = a.len();
- for (a, b) in a.iter().skip(a_len - b.len()).zip(b.iter()) {
- let a = a?;
- let b = b?;
- if !equals(&a, &b)? {
- return Ok(false);
- }
+ }
+ let a_len = a.len();
+ for (a, b) in a.iter().skip(a_len - b.len()).zip(b.iter()) {
+ let a = a?;
+ let b = b?;
+ if !equals(&a, &b)? {
+ return Ok(false);
}
- true
}
+ true
}
_ => bail!("both arguments should be of the same type"),
})
crates/jrsonnet-stdlib/src/objects.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/objects.rs
+++ b/crates/jrsonnet-stdlib/src/objects.rs
@@ -155,7 +155,7 @@
if k == key {
continue;
}
- new_obj.field(k).value(v.unwrap())
+ new_obj.field(k).value(v.unwrap());
}
new_obj.build()
crates/jrsonnet-stdlib/src/sort.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/sort.rs
+++ b/crates/jrsonnet-stdlib/src/sort.rs
@@ -36,7 +36,7 @@
fn get_sort_type<T>(values: &[T], key_getter: impl Fn(&T) -> &Val) -> Result<SortKeyType> {
let mut sort_type = SortKeyType::Unknown;
- for i in values.iter() {
+ for i in values {
let i = key_getter(i);
match (i, sort_type) {
(Val::Str(_), SortKeyType::Unknown) => sort_type = SortKeyType::String,
crates/jrsonnet-stdlib/src/strings.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/strings.rs
+++ b/crates/jrsonnet-stdlib/src/strings.rs
@@ -75,7 +75,7 @@
.enumerate()
{
if &strb[i..i + pat.len()] == pat {
- out.push(Val::Num(ch_idx as f64))
+ out.push(Val::Num(ch_idx as f64));
}
}
out.into()
@@ -117,11 +117,6 @@
}
fn parse_nat<const BASE: u32>(raw: &str) -> Result<f64> {
- debug_assert!(
- 1 <= BASE && BASE <= 16,
- "integer base should be between 1 and 16"
- );
-
const ZERO_CODE: u32 = '0' as u32;
const UPPER_A_CODE: u32 = 'A' as u32;
const LOWER_A_CODE: u32 = 'a' as u32;
@@ -135,10 +130,17 @@
}
}
- let base = BASE as f64;
+ debug_assert!(
+ 1 <= BASE && BASE <= 16,
+ "integer base should be between 1 and 16"
+ );
+
+ let base = f64::from(BASE);
raw.chars().try_fold(0f64, |aggregate, digit| {
let digit = digit as u32;
+ // if-let-else looks better here than Option combinators
+ #[allow(clippy::option_if_let_else)]
let digit = if let Some(digit) = checked_sub_if(BASE > 10, digit, LOWER_A_CODE) {
digit + 10
} else if let Some(digit) = checked_sub_if(BASE > 10, digit, UPPER_A_CODE) {
@@ -148,7 +150,7 @@
};
if digit < BASE {
- Ok(base * aggregate + digit as f64)
+ Ok(base.mul_add(aggregate, f64::from(digit)))
} else {
bail!("{raw:?} is not a base {BASE} integer");
}
crates/jrsonnet-types/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-types/src/lib.rs
+++ b/crates/jrsonnet-types/src/lib.rs
@@ -166,9 +166,9 @@
fn print_array(a: &ComplexValType, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if *a == ComplexValType::Any {
- write!(f, "array")?
+ write!(f, "array")?;
} else {
- write!(f, "Array<{a}>")?
+ write!(f, "Array<{a}>")?;
}
Ok(())
}
@@ -176,18 +176,20 @@
impl Display for ComplexValType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
- ComplexValType::Any => write!(f, "any")?,
- ComplexValType::Simple(s) => write!(f, "{s}")?,
- ComplexValType::Char => write!(f, "char")?,
- ComplexValType::BoundedNumber(a, b) => write!(
+ Self::Any => write!(f, "any")?,
+ Self::Simple(s) => write!(f, "{s}")?,
+ Self::Char => write!(f, "char")?,
+ Self::BoundedNumber(a, b) => write!(
f,
"BoundedNumber<{}, {}>",
- a.map(|e| e.to_string()).unwrap_or_else(|| "".into()),
- b.map(|e| e.to_string()).unwrap_or_else(|| "".into())
+ a.map(|e| e.to_string())
+ .unwrap_or_else(|| "open".to_owned()),
+ b.map(|e| e.to_string())
+ .unwrap_or_else(|| "open".to_owned())
)?,
- ComplexValType::ArrayRef(a) => print_array(a, f)?,
- ComplexValType::Array(a) => print_array(a, f)?,
- ComplexValType::ObjectRef(fields) => {
+ Self::ArrayRef(a) => print_array(a, f)?,
+ Self::Array(a) => print_array(a, f)?,
+ Self::ObjectRef(fields) => {
write!(f, "{{")?;
for (i, (k, v)) in fields.iter().enumerate() {
if i != 0 {
@@ -197,18 +199,18 @@
}
write!(f, "}}")?;
}
- ComplexValType::AttrsOf(a) => {
- if matches!(a, ComplexValType::Any) {
+ Self::AttrsOf(a) => {
+ if matches!(a, Self::Any) {
write!(f, "object")?;
} else {
write!(f, "AttrsOf<{a}>")?;
}
}
- ComplexValType::Union(v) => write_union(f, true, v.iter())?,
- ComplexValType::UnionRef(v) => write_union(f, true, v.iter().copied())?,
- ComplexValType::Sum(v) => write_union(f, false, v.iter())?,
- ComplexValType::SumRef(v) => write_union(f, false, v.iter().copied())?,
- ComplexValType::Lazy(lazy) => write!(f, "Lazy<{lazy}>")?,
+ Self::Union(v) => write_union(f, true, v.iter())?,
+ Self::UnionRef(v) => write_union(f, true, v.iter().copied())?,
+ Self::Sum(v) => write_union(f, false, v.iter())?,
+ Self::SumRef(v) => write_union(f, false, v.iter().copied())?,
+ Self::Lazy(lazy) => write!(f, "Lazy<{lazy}>")?,
};
Ok(())
}
tests/suite/std_param_names.jsonnetdiffbeforeafterboth--- a/tests/suite/std_param_names.jsonnet
+++ b/tests/suite/std_param_names.jsonnet
@@ -49,6 +49,7 @@
min: ['a', 'b'],
clamp: ['x', 'minVal', 'maxVal'],
flattenArrays: ['arrs'],
+ flattenDeepArray: ['value'],
manifestIni: ['ini'],
manifestToml: ['value'],
manifestTomlEx: ['value', 'indent'],