From 100e166bb16d1e8c2a2aaff243c56a5cecbf884c Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 20 Jan 2025 19:48:55 +0200 Subject: [PATCH 01/47] Calculate drop glue and show it on hover Also fix the `needs_drop()` intrinsic. Unions also need this information (to err if they have a drop-needing field), but this will come in a follow-up PR. --- .../hir-ty/src/consteval/tests/intrinsics.rs | 35 +- crates/hir-ty/src/db.rs | 7 +- crates/hir-ty/src/drop.rs | 209 ++++++ crates/hir-ty/src/lib.rs | 2 + crates/hir-ty/src/mir/eval/shim.rs | 11 +- crates/hir/src/lib.rs | 35 +- crates/ide/src/hover.rs | 1 + crates/ide/src/hover/render.rs | 95 ++- crates/ide/src/hover/tests.rs | 594 ++++++++++++++++++ crates/ide/src/static_index.rs | 1 + crates/rust-analyzer/src/config.rs | 3 + docs/book/src/configuration_generated.md | 5 + editors/code/package.json | 10 + 13 files changed, 1002 insertions(+), 6 deletions(-) create mode 100644 crates/hir-ty/src/drop.rs diff --git a/crates/hir-ty/src/consteval/tests/intrinsics.rs b/crates/hir-ty/src/consteval/tests/intrinsics.rs index c1ac7ae173..ee375d60de 100644 --- a/crates/hir-ty/src/consteval/tests/intrinsics.rs +++ b/crates/hir-ty/src/consteval/tests/intrinsics.rs @@ -354,12 +354,43 @@ fn overflowing_add() { fn needs_drop() { check_number( r#" - //- minicore: copy, sized + //- minicore: drop, manually_drop, copy, sized + use core::mem::ManuallyDrop; extern "rust-intrinsic" { pub fn needs_drop() -> bool; } struct X; - const GOAL: bool = !needs_drop::() && needs_drop::(); + struct NeedsDrop; + impl Drop for NeedsDrop { + fn drop(&mut self) {} + } + enum Enum { + A(T), + B(X), + } + const fn val_needs_drop(_v: T) -> bool { needs_drop::() } + const fn closure_needs_drop() -> bool { + let a = NeedsDrop; + let b = X; + !val_needs_drop(|| &a) && val_needs_drop(move || &a) && !val_needs_drop(move || &b) + } + const fn opaque() -> impl Sized { + || {} + } + const fn opaque_copy() -> impl Sized + Copy { + || {} + } + trait Everything {} + impl Everything for T {} + const GOAL: bool = !needs_drop::() && !needs_drop::() + && needs_drop::() && !needs_drop::>() + && needs_drop::<[NeedsDrop; 1]>() && !needs_drop::<[NeedsDrop; 0]>() + && needs_drop::<(X, NeedsDrop)>() + && needs_drop::>() && !needs_drop::>() + && closure_needs_drop() + && !val_needs_drop(opaque()) && !val_needs_drop(opaque_copy()) + && needs_drop::<[NeedsDrop]>() && needs_drop::() + && !needs_drop::<&dyn Everything>() && !needs_drop::(); "#, 1, ); diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs index 6b05682667..76031491d9 100644 --- a/crates/hir-ty/src/db.rs +++ b/crates/hir-ty/src/db.rs @@ -13,6 +13,7 @@ use hir_def::{ ConstParamId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId, LifetimeParamId, LocalFieldId, StaticId, TraitId, TypeAliasId, TypeOrConstParamId, VariantId, }; +use hir_expand::name::Name; use la_arena::ArenaMap; use smallvec::SmallVec; use triomphe::Arc; @@ -20,6 +21,7 @@ use triomphe::Arc; use crate::{ chalk_db, consteval::ConstEvalError, + drop::DropGlue, dyn_compatibility::DynCompatibilityViolation, layout::{Layout, LayoutError}, lower::{Diagnostics, GenericDefaults, GenericPredicates}, @@ -28,7 +30,6 @@ use crate::{ Binders, ClosureId, Const, FnDefId, ImplTraitId, ImplTraits, InferenceResult, Interner, PolyFnSig, Substitution, TraitEnvironment, TraitRef, Ty, TyDefId, ValueTyDefId, }; -use hir_expand::name::Name; #[ra_salsa::query_group(HirDatabaseStorage)] pub trait HirDatabase: DefDatabase + Upcast { @@ -305,6 +306,10 @@ pub trait HirDatabase: DefDatabase + Upcast { block: Option, env: chalk_ir::Environment, ) -> chalk_ir::ProgramClauses; + + #[ra_salsa::invoke(crate::drop::has_drop_glue)] + #[ra_salsa::cycle(crate::drop::has_drop_glue_recover)] + fn has_drop_glue(&self, ty: Ty, env: Arc) -> DropGlue {} } #[test] diff --git a/crates/hir-ty/src/drop.rs b/crates/hir-ty/src/drop.rs new file mode 100644 index 0000000000..351926c86c --- /dev/null +++ b/crates/hir-ty/src/drop.rs @@ -0,0 +1,209 @@ +//! Utilities for computing drop info about types. + +use base_db::ra_salsa; +use chalk_ir::cast::Cast; +use hir_def::data::adt::StructFlags; +use hir_def::lang_item::LangItem; +use hir_def::AdtId; +use stdx::never; +use triomphe::Arc; + +use crate::{ + db::HirDatabase, method_resolution::TyFingerprint, AliasTy, Canonical, CanonicalVarKinds, + InEnvironment, Interner, ProjectionTy, TraitEnvironment, Ty, TyBuilder, TyKind, +}; +use crate::{ConcreteConst, ConstScalar, ConstValue}; + +fn has_destructor(db: &dyn HirDatabase, adt: AdtId) -> bool { + let module = match adt { + AdtId::EnumId(id) => db.lookup_intern_enum(id).container, + AdtId::StructId(id) => db.lookup_intern_struct(id).container, + AdtId::UnionId(id) => db.lookup_intern_union(id).container, + }; + let Some(drop_trait) = + db.lang_item(module.krate(), LangItem::Drop).and_then(|it| it.as_trait()) + else { + return false; + }; + let impls = match module.containing_block() { + Some(block) => match db.trait_impls_in_block(block) { + Some(it) => it, + None => return false, + }, + None => db.trait_impls_in_crate(module.krate()), + }; + let result = impls.for_trait_and_self_ty(drop_trait, TyFingerprint::Adt(adt)).next().is_some(); + result +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum DropGlue { + // Order of variants is important. + None, + /// May have a drop glue if some type parameter has it. + /// + /// For the compiler this is considered as a positive result, IDE distinguishes this from "yes". + DependOnParams, + HasDropGlue, +} + +pub(crate) fn has_drop_glue(db: &dyn HirDatabase, ty: Ty, env: Arc) -> DropGlue { + match ty.kind(Interner) { + TyKind::Adt(adt, subst) => { + if has_destructor(db, adt.0) { + return DropGlue::HasDropGlue; + } + match adt.0 { + AdtId::StructId(id) => { + if db.struct_data(id).flags.contains(StructFlags::IS_MANUALLY_DROP) { + return DropGlue::None; + } + db.field_types(id.into()) + .iter() + .map(|(_, field_ty)| { + db.has_drop_glue( + field_ty.clone().substitute(Interner, subst), + env.clone(), + ) + }) + .max() + .unwrap_or(DropGlue::None) + } + // Unions cannot have fields with destructors. + AdtId::UnionId(_) => DropGlue::None, + AdtId::EnumId(id) => db + .enum_data(id) + .variants + .iter() + .map(|&(variant, _)| { + db.field_types(variant.into()) + .iter() + .map(|(_, field_ty)| { + db.has_drop_glue( + field_ty.clone().substitute(Interner, subst), + env.clone(), + ) + }) + .max() + .unwrap_or(DropGlue::None) + }) + .max() + .unwrap_or(DropGlue::None), + } + } + TyKind::Tuple(_, subst) => subst + .iter(Interner) + .map(|ty| ty.assert_ty_ref(Interner)) + .map(|ty| db.has_drop_glue(ty.clone(), env.clone())) + .max() + .unwrap_or(DropGlue::None), + TyKind::Array(ty, len) => { + if let ConstValue::Concrete(ConcreteConst { interned: ConstScalar::Bytes(len, _) }) = + &len.data(Interner).value + { + match (&**len).try_into() { + Ok(len) => { + let len = usize::from_le_bytes(len); + if len == 0 { + // Arrays of size 0 don't have drop glue. + return DropGlue::None; + } + } + Err(_) => { + never!("const array size with non-usize len"); + } + } + } + db.has_drop_glue(ty.clone(), env) + } + TyKind::Slice(ty) => db.has_drop_glue(ty.clone(), env), + TyKind::Closure(closure_id, subst) => { + let owner = db.lookup_intern_closure((*closure_id).into()).0; + let infer = db.infer(owner); + let (captures, _) = infer.closure_info(closure_id); + let env = db.trait_environment_for_body(owner); + captures + .iter() + .map(|capture| db.has_drop_glue(capture.ty(subst), env.clone())) + .max() + .unwrap_or(DropGlue::None) + } + // FIXME: Handle coroutines. + TyKind::Coroutine(..) | TyKind::CoroutineWitness(..) => DropGlue::None, + TyKind::Ref(..) + | TyKind::Raw(..) + | TyKind::FnDef(..) + | TyKind::Str + | TyKind::Never + | TyKind::Scalar(_) + | TyKind::Function(_) + | TyKind::Foreign(_) + | TyKind::Error => DropGlue::None, + TyKind::Dyn(_) => DropGlue::HasDropGlue, + TyKind::AssociatedType(assoc_type_id, subst) => projection_has_drop_glue( + db, + env, + ProjectionTy { associated_ty_id: *assoc_type_id, substitution: subst.clone() }, + ty, + ), + TyKind::Alias(AliasTy::Projection(projection)) => { + projection_has_drop_glue(db, env, projection.clone(), ty) + } + TyKind::OpaqueType(..) | TyKind::Alias(AliasTy::Opaque(_)) => { + if is_copy(db, ty, env) { + DropGlue::None + } else { + DropGlue::HasDropGlue + } + } + TyKind::Placeholder(_) | TyKind::BoundVar(_) => { + if is_copy(db, ty, env) { + DropGlue::None + } else { + DropGlue::DependOnParams + } + } + TyKind::InferenceVar(..) => unreachable!("inference vars shouldn't exist out of inference"), + } +} + +fn projection_has_drop_glue( + db: &dyn HirDatabase, + env: Arc, + projection: ProjectionTy, + ty: Ty, +) -> DropGlue { + let normalized = db.normalize_projection(projection, env.clone()); + match normalized.kind(Interner) { + TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(..) => { + if is_copy(db, ty, env) { + DropGlue::None + } else { + DropGlue::DependOnParams + } + } + _ => db.has_drop_glue(normalized, env), + } +} + +fn is_copy(db: &dyn HirDatabase, ty: Ty, env: Arc) -> bool { + let Some(copy_trait) = db.lang_item(env.krate, LangItem::Copy).and_then(|it| it.as_trait()) + else { + return false; + }; + let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(ty).build(); + let goal = Canonical { + value: InEnvironment::new(&env.env, trait_ref.cast(Interner)), + binders: CanonicalVarKinds::empty(Interner), + }; + db.trait_solve(env.krate, env.block, goal).is_some() +} + +pub(crate) fn has_drop_glue_recover( + _db: &dyn HirDatabase, + _cycle: &ra_salsa::Cycle, + _ty: &Ty, + _env: &Arc, +) -> DropGlue { + DropGlue::None +} diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs index 55d81875a2..748016f7ce 100644 --- a/crates/hir-ty/src/lib.rs +++ b/crates/hir-ty/src/lib.rs @@ -24,6 +24,7 @@ extern crate ra_ap_rustc_pattern_analysis as rustc_pattern_analysis; mod builder; mod chalk_db; mod chalk_ext; +mod drop; mod infer; mod inhabitedness; mod interner; @@ -81,6 +82,7 @@ use crate::{ pub use autoderef::autoderef; pub use builder::{ParamKind, TyBuilder}; pub use chalk_ext::*; +pub use drop::DropGlue; pub use infer::{ cast::CastError, closure::{CaptureKind, CapturedItem}, diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs index 38b189a517..7d3376f56b 100644 --- a/crates/hir-ty/src/mir/eval/shim.rs +++ b/crates/hir-ty/src/mir/eval/shim.rs @@ -11,6 +11,7 @@ use hir_def::{ }; use hir_expand::name::Name; use intern::{sym, Symbol}; +use stdx::never; use crate::{ error_lifetime, @@ -20,6 +21,7 @@ use crate::{ LangItem, Layout, Locals, Lookup, MirEvalError, MirSpan, Mutability, Result, Substitution, Ty, TyBuilder, TyExt, }, + DropGlue, }; mod simd; @@ -853,7 +855,14 @@ impl Evaluator<'_> { "size_of generic arg is not provided".into(), )); }; - let result = !ty.clone().is_copy(self.db, locals.body.owner); + let result = match self.db.has_drop_glue(ty.clone(), self.trait_env.clone()) { + DropGlue::HasDropGlue => true, + DropGlue::None => false, + DropGlue::DependOnParams => { + never!("should be fully monomorphized now"); + true + } + }; destination.write_from_bytes(self, &[u8::from(result)]) } "ptr_guaranteed_cmp" => { diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 5923a1bc30..727d31cffb 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -152,7 +152,7 @@ pub use { layout::LayoutError, method_resolution::TyFingerprint, mir::{MirEvalError, MirLowerError}, - CastError, FnAbi, PointerCast, Safety, Variance, + CastError, DropGlue, FnAbi, PointerCast, Safety, Variance, }, // FIXME: Properly encapsulate mir hir_ty::{mir, Interner as ChalkTyInterner}, @@ -1391,6 +1391,10 @@ impl Struct { Type::from_def(db, self.id) } + pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type { + Type::from_def_placeholders(db, self.id) + } + pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type { Type::from_value_def(db, self.id) } @@ -1436,6 +1440,10 @@ impl Union { Type::from_def(db, self.id) } + pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type { + Type::from_def_placeholders(db, self.id) + } + pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type { Type::from_value_def(db, self.id) } @@ -1490,6 +1498,10 @@ impl Enum { Type::from_def(db, self.id) } + pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type { + Type::from_def_placeholders(db, self.id) + } + /// The type of the enum variant bodies. pub fn variant_body_ty(self, db: &dyn HirDatabase) -> Type { Type::new_for_crate( @@ -2929,6 +2941,10 @@ impl TypeAlias { Type::from_def(db, self.id) } + pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type { + Type::from_def_placeholders(db, self.id) + } + pub fn name(self, db: &dyn HirDatabase) -> Name { db.type_alias_data(self.id).name.clone() } @@ -4708,6 +4724,19 @@ impl Type { Type::new(db, def, ty.substitute(Interner, &substs)) } + fn from_def_placeholders(db: &dyn HirDatabase, def: impl Into + HasResolver) -> Type { + let ty = db.ty(def.into()); + let substs = TyBuilder::placeholder_subst( + db, + match def.into() { + TyDefId::AdtId(it) => GenericDefId::AdtId(it), + TyDefId::TypeAliasId(it) => GenericDefId::TypeAliasId(it), + TyDefId::BuiltinType(_) => return Type::new(db, def, ty.skip_binders().clone()), + }, + ); + Type::new(db, def, ty.substitute(Interner, &substs)) + } + fn from_value_def(db: &dyn HirDatabase, def: impl Into + HasResolver) -> Type { let Some(ty) = db.value_ty(def.into()) else { return Type::new(db, def, TyKind::Error.intern(Interner)); @@ -5737,6 +5766,10 @@ impl Type { db.layout_of_ty(self.ty.clone(), self.env.clone()) .map(|layout| Layout(layout, db.target_data_layout(self.env.krate).unwrap())) } + + pub fn drop_glue(&self, db: &dyn HirDatabase) -> DropGlue { + db.has_drop_glue(self.ty.clone(), self.env.clone()) + } } #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 95a720e7e4..9a3e77f3a9 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -38,6 +38,7 @@ pub struct HoverConfig { pub max_fields_count: Option, pub max_enum_variants_count: Option, pub max_subst_ty_len: SubstTyLen, + pub show_drop_glue: bool, } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs index c996230c3a..c5a83e58ce 100644 --- a/crates/ide/src/hover/render.rs +++ b/crates/ide/src/hover/render.rs @@ -3,7 +3,7 @@ use std::{env, mem, ops::Not}; use either::Either; use hir::{ - db::ExpandDatabase, Adt, AsAssocItem, AsExternAssocItem, CaptureKind, + db::ExpandDatabase, Adt, AsAssocItem, AsExternAssocItem, CaptureKind, DropGlue, DynCompatibilityViolation, HasCrate, HasSource, HirDisplay, Layout, LayoutError, MethodViolationCode, Name, Semantics, Symbol, Trait, Type, TypeInfo, VariantDef, }; @@ -629,6 +629,89 @@ pub(super) fn definition( _ => None, }; + let drop_info = || { + if !config.show_drop_glue { + return None; + } + let drop_info = match def { + Definition::Field(field) => { + DropInfo { drop_glue: field.ty(db).drop_glue(db), has_dtor: None } + } + Definition::Adt(Adt::Struct(strukt)) => { + let struct_drop_glue = strukt.ty_placeholders(db).drop_glue(db); + let mut fields_drop_glue = strukt + .fields(db) + .iter() + .map(|field| field.ty(db).drop_glue(db)) + .max() + .unwrap_or(DropGlue::None); + let has_dtor = match (fields_drop_glue, struct_drop_glue) { + (DropGlue::None, _) => struct_drop_glue != DropGlue::None, + (_, DropGlue::None) => { + // This is `ManuallyDrop`. + fields_drop_glue = DropGlue::None; + false + } + (_, _) => struct_drop_glue > fields_drop_glue, + }; + DropInfo { drop_glue: fields_drop_glue, has_dtor: Some(has_dtor) } + } + // Unions cannot have fields with drop glue. + Definition::Adt(Adt::Union(union)) => DropInfo { + drop_glue: DropGlue::None, + has_dtor: Some(union.ty_placeholders(db).drop_glue(db) != DropGlue::None), + }, + Definition::Adt(Adt::Enum(enum_)) => { + let enum_drop_glue = enum_.ty_placeholders(db).drop_glue(db); + let fields_drop_glue = enum_ + .variants(db) + .iter() + .map(|variant| { + variant + .fields(db) + .iter() + .map(|field| field.ty(db).drop_glue(db)) + .max() + .unwrap_or(DropGlue::None) + }) + .max() + .unwrap_or(DropGlue::None); + DropInfo { + drop_glue: fields_drop_glue, + has_dtor: Some(enum_drop_glue > fields_drop_glue), + } + } + Definition::Variant(variant) => { + let fields_drop_glue = variant + .fields(db) + .iter() + .map(|field| field.ty(db).drop_glue(db)) + .max() + .unwrap_or(DropGlue::None); + DropInfo { drop_glue: fields_drop_glue, has_dtor: None } + } + Definition::TypeAlias(type_alias) => { + DropInfo { drop_glue: type_alias.ty_placeholders(db).drop_glue(db), has_dtor: None } + } + Definition::Local(local) => { + DropInfo { drop_glue: local.ty(db).drop_glue(db), has_dtor: None } + } + _ => return None, + }; + let rendered_drop_glue = match drop_info.drop_glue { + DropGlue::None => "does not contain types with destructors (drop glue)", + DropGlue::DependOnParams => { + "may contain types with destructors (drop glue) depending on type parameters" + } + DropGlue::HasDropGlue => "contain types with destructors (drop glue)", + }; + Some(match drop_info.has_dtor { + Some(true) => format!("{}; has a destructor", rendered_drop_glue), + Some(false) => format!("{}; doesn't have a destructor", rendered_drop_glue), + None => rendered_drop_glue.to_owned(), + }) + }; + let dyn_compatibility_info = || match def { Definition::Trait(it) => { let mut dyn_compatibility_info = String::new(); @@ -661,6 +744,10 @@ pub(super) fn definition( extra.push_str("\n___\n"); extra.push_str(&dyn_compatibility_info); } + if let Some(drop_info) = drop_info() { + extra.push_str("\n___\n"); + extra.push_str(&drop_info); + } } let mut desc = String::new(); desc.push_str(&label); @@ -703,6 +790,12 @@ pub(super) fn definition( ) } +#[derive(Debug)] +struct DropInfo { + drop_glue: DropGlue, + has_dtor: Option, +} + pub(super) fn literal( sema: &Semantics<'_, RootDatabase>, token: SyntaxToken, diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index 8c32cc9720..7c720d97cb 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -21,6 +21,7 @@ const HOVER_BASE_CONFIG: HoverConfig = HoverConfig { max_fields_count: Some(5), max_enum_variants_count: Some(5), max_subst_ty_len: super::SubstTyLen::Unlimited, + show_drop_glue: true, }; fn check_hover_no_result(#[rust_analyzer::rust_fixture] ra_fixture: &str) { @@ -567,6 +568,10 @@ fn main() { --- size = 8, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -812,6 +817,10 @@ struct Foo { fiel$0d_a: u8, field_b: i32, field_c: i16 } --- size = 1, align = 1, offset = 6 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -863,6 +872,10 @@ fn main() { --- size = 4, align = 4, offset = 0 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -933,6 +946,10 @@ struct Foo$0(pub u32) where u32: Copy; --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); } @@ -959,6 +976,10 @@ struct Foo$0 { field: u32 } --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check( @@ -984,6 +1005,10 @@ struct Foo$0 where u32: Copy { field: u32 } --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); } @@ -1013,6 +1038,10 @@ fn hover_record_struct_limit() { --- size = 12 (0xC), align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_fields_limit( @@ -1036,6 +1065,10 @@ fn hover_record_struct_limit() { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_fields_limit( @@ -1062,6 +1095,10 @@ fn hover_record_struct_limit() { --- size = 16 (0x10), align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_fields_limit( @@ -1083,6 +1120,10 @@ fn hover_record_struct_limit() { --- size = 12 (0xC), align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_fields_limit( @@ -1104,6 +1145,10 @@ fn hover_record_struct_limit() { --- size = 12 (0xC), align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); @@ -1127,6 +1172,10 @@ fn hover_record_struct_limit() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); } @@ -1152,6 +1201,10 @@ fn hover_record_variant_limit() { --- size = 12 (0xC), align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); check_hover_fields_limit( @@ -1173,6 +1226,10 @@ fn hover_record_variant_limit() { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); check_hover_fields_limit( @@ -1194,6 +1251,10 @@ fn hover_record_variant_limit() { --- size = 16 (0x10), align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); check_hover_fields_limit( @@ -1215,6 +1276,10 @@ fn hover_record_variant_limit() { --- size = 12 (0xC), align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); check_hover_fields_limit( @@ -1236,6 +1301,10 @@ fn hover_record_variant_limit() { --- size = 12 (0xC), align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -1262,6 +1331,10 @@ fn hover_enum_limit() { --- size = 1, align = 1, niches = 254 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_enum_variants_limit( @@ -1284,6 +1357,10 @@ fn hover_enum_limit() { --- size = 1, align = 1, niches = 254 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_enum_variants_limit( @@ -1303,6 +1380,10 @@ fn hover_enum_limit() { --- size = 1, align = 1, niches = 254 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_enum_variants_limit( @@ -1322,6 +1403,10 @@ fn hover_enum_limit() { --- size = 1, align = 1, niches = 254 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_enum_variants_limit( @@ -1359,6 +1444,10 @@ fn hover_enum_limit() { --- size = 12 (0xC), align = 4, niches = a lot + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); } @@ -1385,6 +1474,10 @@ fn hover_union_limit() { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_fields_limit( @@ -1407,6 +1500,10 @@ fn hover_union_limit() { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_fields_limit( @@ -1426,6 +1523,10 @@ fn hover_union_limit() { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); check_hover_fields_limit( @@ -1445,6 +1546,10 @@ fn hover_union_limit() { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); } @@ -1471,6 +1576,10 @@ struct Foo$0 where u32: Copy; --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); } @@ -1493,6 +1602,10 @@ type Fo$0o: Trait = S where T: Trait; where T: Trait, ``` + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -1642,6 +1755,10 @@ fn main() { --- size = 8, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); check_hover_range( @@ -1697,6 +1814,10 @@ fn main() { let b$0ar = Some(12); } --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -1724,6 +1845,10 @@ enum Option { --- + does not contain types with destructors (drop glue) + + --- + The None variant "#]], ); @@ -1784,6 +1909,10 @@ fn hover_for_local_variable_pat() { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ) } @@ -1816,6 +1945,10 @@ fn hover_for_param_edge() { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ) } @@ -1838,6 +1971,10 @@ fn hover_for_param_with_multiple_traits() { ```rust _x: impl Deref + DerefMut ``` + + --- + + may contain types with destructors (drop glue) depending on type parameters "#]], ) } @@ -1864,6 +2001,10 @@ fn main() { let foo_$0test = Thing::new(); } --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ) } @@ -2613,6 +2754,10 @@ fn test_hover_function_pointer_show_identifiers() { --- size = 8, align = 8, niches = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -2635,6 +2780,10 @@ fn test_hover_function_pointer_no_identifier() { --- size = 8, align = 8, niches = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -2881,6 +3030,10 @@ pub struct B$0ar --- + does not contain types with destructors (drop glue); doesn't have a destructor + + --- + [external](https://www.google.com) "#]], ); @@ -2912,6 +3065,10 @@ pub struct B$0ar --- + does not contain types with destructors (drop glue); doesn't have a destructor + + --- + [baz](Baz) "#]], ); @@ -3002,6 +3159,10 @@ fn test_hover_layout_of_variant() { --- size = 4, align = 2 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -3023,6 +3184,10 @@ fn test_hover_layout_of_variant_generic() { ```rust None ``` + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -3048,6 +3213,10 @@ struct S$0(core::marker::PhantomData); --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); } @@ -3076,6 +3245,10 @@ fn test_hover_layout_of_enum() { --- size = 16 (0x10), align = 8, niches = 254 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ); } @@ -3094,6 +3267,10 @@ fn test_hover_no_memory_layout() { ```rust field_a: u8 ``` + + --- + + does not contain types with destructors (drop glue) "#]], ); @@ -4405,6 +4582,10 @@ fn main() { --- + does not contain types with destructors (drop glue) + + --- + ```rust ra_test_fixture::S ``` @@ -4416,6 +4597,10 @@ fn main() { --- size = 4, align = 4, offset = 0 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -4441,6 +4626,10 @@ struct S$0T(T); --- size = 0, align = 1 + + --- + + may contain types with destructors (drop glue) depending on type parameters; doesn't have a destructor "#]], ); } @@ -4466,6 +4655,10 @@ struct S$0T(T); --- size = 0, align = 1 + + --- + + may contain types with destructors (drop glue) depending on type parameters; doesn't have a destructor "#]], ); } @@ -4492,6 +4685,10 @@ struct S$0T(T); --- size = 0, align = 1 + + --- + + may contain types with destructors (drop glue) depending on type parameters; doesn't have a destructor "#]], ); } @@ -4516,6 +4713,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -4540,6 +4741,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -4564,6 +4769,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -4588,6 +4797,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -4612,6 +4825,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -4635,6 +4852,10 @@ impl Foo { --- size = 8, align = 8, niches = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -4659,6 +4880,10 @@ impl Foo { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -5149,6 +5374,10 @@ type Fo$0o2 = Foo<2>; --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -5202,6 +5431,10 @@ enum E { --- + does not contain types with destructors (drop glue) + + --- + This is a doc "#]], ); @@ -5231,6 +5464,10 @@ enum E { --- + does not contain types with destructors (drop glue) + + --- + This is a doc "#]], ); @@ -5261,6 +5498,10 @@ enum E { --- + does not contain types with destructors (drop glue) + + --- + This is a doc "#]], ); @@ -5291,6 +5532,10 @@ enum E { --- + does not contain types with destructors (drop glue) + + --- + This is a doc "#]], ); @@ -6219,6 +6464,10 @@ fn main() { --- size = 32 (0x20), align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -7518,6 +7767,10 @@ enum Enum { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -7544,6 +7797,10 @@ enum Enum { --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -8214,6 +8471,10 @@ fn test() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -8863,6 +9124,10 @@ fn main(notable$0: u32) {} --- size = 4, align = 4 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -8955,6 +9220,10 @@ extern "C" { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -9101,6 +9370,10 @@ struct Pedro$0<'a> { --- size = 16 (0x10), align = 8, niches = 1 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor "#]], ) } @@ -9118,6 +9391,10 @@ fn main(a$0: impl T) {} ```rust a: impl T + ?Sized ``` + + --- + + may contain types with destructors (drop glue) depending on type parameters "#]], ); } @@ -9139,6 +9416,10 @@ fn main(a$0: T) {} --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -9192,6 +9473,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -9529,6 +9814,10 @@ type A$0 = B; --- + does not contain types with destructors (drop glue) + + --- + *This is the documentation for* `struct B` Docs for B @@ -9562,6 +9851,10 @@ type A$0 = B; --- + does not contain types with destructors (drop glue) + + --- + *This is the documentation for* `struct C` Docs for C @@ -9596,6 +9889,10 @@ type A$0 = B; --- + does not contain types with destructors (drop glue) + + --- + *This is the documentation for* `struct C` Docs for C @@ -9625,6 +9922,10 @@ type A$0 = B; --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); @@ -9749,6 +10050,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); @@ -9777,6 +10082,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); @@ -9812,6 +10121,10 @@ fn main() { --- size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) "#]], ); } @@ -10134,6 +10447,10 @@ fn bar() { --- + does not contain types with destructors (drop glue) + + --- + ```rust ra_test_fixture::Foo ``` @@ -10144,6 +10461,10 @@ fn bar() { --- + may contain types with destructors (drop glue) depending on type parameters + + --- + `T` = `i32` "#]], ); @@ -10353,3 +10674,276 @@ macro_rules! str { "#]], ); } + +#[test] +fn drop_glue() { + check( + r#" +struct NoDrop$0; + "#, + expect![[r#" + *NoDrop* + + ```rust + ra_test_fixture + ``` + + ```rust + struct NoDrop + ``` + + --- + + size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor + "#]], + ); + check( + r#" +//- minicore: drop +struct NeedsDrop$0; +impl Drop for NeedsDrop { + fn drop(&mut self) {} +} + "#, + expect![[r#" + *NeedsDrop* + + ```rust + ra_test_fixture + ``` + + ```rust + struct NeedsDrop + ``` + + --- + + size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue); has a destructor + "#]], + ); + check( + r#" +//- minicore: manually_drop, drop +struct NeedsDrop; +impl Drop for NeedsDrop { + fn drop(&mut self) {} +} +type NoDrop$0 = core::mem::ManuallyDrop; + "#, + expect![[r#" + *NoDrop* + + ```rust + ra_test_fixture + ``` + + ```rust + type NoDrop = core::mem::ManuallyDrop + ``` + + --- + + size = 0, align = 1 + + --- + + does not contain types with destructors (drop glue) + "#]], + ); + check( + r#" +//- minicore: drop +struct NeedsDrop; +impl Drop for NeedsDrop { + fn drop(&mut self) {} +} +struct DropField$0 { + _x: i32, + _y: NeedsDrop, +} + "#, + expect![[r#" + *DropField* + + ```rust + ra_test_fixture + ``` + + ```rust + struct DropField { + _x: i32, + _y: NeedsDrop, + } + ``` + + --- + + size = 4, align = 4 + + --- + + contain types with destructors (drop glue); doesn't have a destructor + "#]], + ); + check( + r#" +//- minicore: sized +type Foo$0 = impl Sized; + "#, + expect![[r#" + *Foo* + + ```rust + ra_test_fixture + ``` + + ```rust + type Foo = impl Sized + ``` + + --- + + contain types with destructors (drop glue) + "#]], + ); + check( + r#" +//- minicore: drop +struct NeedsDrop; +impl Drop for NeedsDrop { + fn drop(&mut self) {} +} +enum Enum { + A$0(&'static str), + B(NeedsDrop) +} + "#, + expect![[r#" + *A* + + ```rust + ra_test_fixture::Enum + ``` + + ```rust + A(&'static str) + ``` + + --- + + size = 16 (0x10), align = 8, niches = 1 + + --- + + does not contain types with destructors (drop glue) + "#]], + ); + check( + r#" +struct Foo$0(T); + "#, + expect![[r#" + *Foo* + + ```rust + ra_test_fixture + ``` + + ```rust + struct Foo(T) + ``` + + --- + + may contain types with destructors (drop glue) depending on type parameters; doesn't have a destructor + "#]], + ); + check( + r#" +//- minicore: copy +struct Foo$0(T); + "#, + expect![[r#" + *Foo* + + ```rust + ra_test_fixture + ``` + + ```rust + struct Foo(T) + where + T: Copy, + ``` + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor + "#]], + ); + check( + r#" +//- minicore: copy +trait Trait { + type Assoc: Copy; +} +struct Foo$0(T::Assoc); + "#, + expect![[r#" + *Foo* + + ```rust + ra_test_fixture + ``` + + ```rust + struct Foo(::Assoc) + where + T: Trait, + ``` + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor + "#]], + ); + check( + r#" +#[rustc_coherence_is_core] + +#[lang = "manually_drop"] +#[repr(transparent)] +pub struct ManuallyDrop$0 { + value: T, +} + "#, + expect![[r#" + *ManuallyDrop* + + ```rust + ra_test_fixture + ``` + + ```rust + pub struct ManuallyDrop + where + T: ?Sized, + { + value: T, + } + ``` + + --- + + does not contain types with destructors (drop glue); doesn't have a destructor + "#]], + ); +} diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs index 07553a87d2..41957bad7e 100644 --- a/crates/ide/src/static_index.rs +++ b/crates/ide/src/static_index.rs @@ -187,6 +187,7 @@ impl StaticIndex<'_> { max_fields_count: Some(5), max_enum_variants_count: Some(5), max_subst_ty_len: SubstTyLen::Unlimited, + show_drop_glue: true, }; let tokens = tokens.filter(|token| { matches!( diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index d7e9a5c586..5c7b088e68 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -128,6 +128,8 @@ config_data! { /// Whether to show keyword hover popups. Only applies when /// `#rust-analyzer.hover.documentation.enable#` is set. hover_documentation_keywords_enable: bool = true, + /// Whether to show drop glue information on hover. + hover_dropGlue_enable: bool = true, /// Use markdown syntax for links on hover. hover_links_enable: bool = true, /// Whether to show what types are used as generic arguments in calls etc. on hover, and what is their max length to show such types, beyond it they will be shown with ellipsis. @@ -1630,6 +1632,7 @@ impl Config { Some(MaxSubstitutionLength::Limit(limit)) => ide::SubstTyLen::LimitTo(*limit), None => ide::SubstTyLen::Unlimited, }, + show_drop_glue: *self.hover_dropGlue_enable(), } } diff --git a/docs/book/src/configuration_generated.md b/docs/book/src/configuration_generated.md index 0c6674b140..1cbe51836f 100644 --- a/docs/book/src/configuration_generated.md +++ b/docs/book/src/configuration_generated.md @@ -559,6 +559,11 @@ also need to add the folders to Code's `files.watcherExclude`. `#rust-analyzer.hover.documentation.enable#` is set. +**rust-analyzer.hover.dropGlue.enable** (default: true) + + Whether to show drop glue information on hover. + + **rust-analyzer.hover.links.enable** (default: true) Use markdown syntax for links on hover. diff --git a/editors/code/package.json b/editors/code/package.json index 3f09033051..a7c8506a45 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -1641,6 +1641,16 @@ } } }, + { + "title": "hover", + "properties": { + "rust-analyzer.hover.dropGlue.enable": { + "markdownDescription": "Whether to show drop glue information on hover.", + "default": true, + "type": "boolean" + } + } + }, { "title": "hover", "properties": { From 03c24d7c2873c5e002a5c3c4ec78a0de62a05bc9 Mon Sep 17 00:00:00 2001 From: andylokandy Date: Fri, 21 Feb 2025 21:18:20 +0800 Subject: [PATCH 02/47] feat: update insta inline snapshot when clicks 'Update Test' runnable --- crates/ide/src/lib.rs | 2 +- crates/rust-analyzer/src/handlers/request.rs | 6 ++---- crates/rust-analyzer/src/lsp/to_proto.rs | 21 ++++++++++---------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 27a1a510b4..8ac1a96cc6 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -104,7 +104,7 @@ pub use crate::{ navigation_target::{NavigationTarget, TryToNav, UpmappingResult}, references::ReferenceSearchResult, rename::RenameError, - runnables::{Runnable, RunnableKind, TestId}, + runnables::{Runnable, RunnableKind, TestId, UpdateTest}, signature_help::SignatureHelp, static_index::{ StaticIndex, StaticIndexedFile, TokenId, TokenStaticData, VendoredLibrariesConfig, diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index 1b144d9073..b91a5dbd41 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -941,9 +941,7 @@ pub(crate) fn handle_runnables( let update_test = runnable.update_test; if let Some(mut runnable) = to_proto::runnable(&snap, runnable)? { - if let Some(runnable) = - to_proto::make_update_runnable(&runnable, &update_test.label(), &update_test.env()) - { + if let Some(runnable) = to_proto::make_update_runnable(&runnable, update_test) { res.push(runnable); } @@ -2158,7 +2156,7 @@ fn runnable_action_links( if hover_actions_config.update_test && client_commands_config.run_single { let label = update_test.label(); - if let Some(r) = to_proto::make_update_runnable(&r, &label, &update_test.env()) { + if let Some(r) = to_proto::make_update_runnable(&r, update_test) { let update_command = to_proto::command::run_single(&r, label.unwrap().as_str()); group.commands.push(to_command_link(update_command, r.label.clone())); } diff --git a/crates/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs index bff53cf98b..51ae85b1db 100644 --- a/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/crates/rust-analyzer/src/lsp/to_proto.rs @@ -14,13 +14,13 @@ use ide::{ InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayKind, LazyProperty, Markup, NavigationTarget, ReferenceCategory, RenameError, Runnable, Severity, SignatureHelp, SnippetEdit, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize, + UpdateTest, }; use ide_db::{assists, rust_doc::format_docs, FxHasher}; use itertools::Itertools; use paths::{Utf8Component, Utf8Prefix}; use semver::VersionReq; use serde_json::to_value; -use syntax::SmolStr; use vfs::AbsPath; use crate::{ @@ -1623,8 +1623,7 @@ pub(crate) fn code_lens( } if lens_config.update_test && client_commands_config.run_single { let label = update_test.label(); - let env = update_test.env(); - if let Some(r) = make_update_runnable(&r, &label, &env) { + if let Some(r) = make_update_runnable(&r, update_test) { let command = command::run_single(&r, label.unwrap().as_str()); acc.push(lsp_types::CodeLens { range: annotation_range, @@ -1871,22 +1870,22 @@ pub(crate) mod command { pub(crate) fn make_update_runnable( runnable: &lsp_ext::Runnable, - label: &Option, - env: &[(&str, &str)], + update_test: UpdateTest, ) -> Option { - if !matches!(runnable.args, lsp_ext::RunnableArgs::Cargo(_)) { - return None; - } - let label = label.as_ref()?; + let label = update_test.label()?; let mut runnable = runnable.clone(); runnable.label = format!("{} + {}", runnable.label, label); let lsp_ext::RunnableArgs::Cargo(r) = &mut runnable.args else { - unreachable!(); + return None; }; - r.environment.extend(env.iter().map(|(k, v)| (k.to_string(), v.to_string()))); + r.environment.extend(update_test.env().iter().map(|(k, v)| (k.to_string(), v.to_string()))); + + if update_test.insta { + r.cargo_args.insert(0, "insta".to_string()); + } Some(runnable) } From b59b04ffe2af0104ac52b0234fb5e0f836913019 Mon Sep 17 00:00:00 2001 From: andylokandy Date: Fri, 21 Feb 2025 21:31:23 +0800 Subject: [PATCH 03/47] fix --- crates/rust-analyzer/src/lsp/to_proto.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs index 51ae85b1db..446549c907 100644 --- a/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/crates/rust-analyzer/src/lsp/to_proto.rs @@ -1884,7 +1884,7 @@ pub(crate) fn make_update_runnable( r.environment.extend(update_test.env().iter().map(|(k, v)| (k.to_string(), v.to_string()))); if update_test.insta { - r.cargo_args.insert(0, "insta".to_string()); + r.cargo_args.insert(0, "insta".to_owned()); } Some(runnable) From 64a869c71498e8db49b910e6b264c9487ea9217e Mon Sep 17 00:00:00 2001 From: Shirayama Kazatsuyu Date: Sat, 22 Feb 2025 22:26:19 +0900 Subject: [PATCH 04/47] Allow "package/feature" format feature flag --- crates/project-model/src/cargo_workspace.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/project-model/src/cargo_workspace.rs b/crates/project-model/src/cargo_workspace.rs index b5f4e43a11..40ab8c53fa 100644 --- a/crates/project-model/src/cargo_workspace.rs +++ b/crates/project-model/src/cargo_workspace.rs @@ -594,7 +594,9 @@ impl CargoWorkspace { .filter_map(|package| { let package = &self[package]; if package.is_member { - Some(package.features.keys().cloned()) + Some(package.features.keys().cloned().chain( + package.features.keys().map(|key| format!("{}/{key}", package.name)), + )) } else { None } From 8d91f1cc17d1639c1a2bd10c5497be907c1e4cb0 Mon Sep 17 00:00:00 2001 From: Tim Hutt Date: Fri, 21 Feb 2025 20:01:33 +0000 Subject: [PATCH 05/47] Include private items in completions for local crates Don't filter out private items when completing paths in the same crate. Instead respect the `privateEditable` setting. Fixes #9850 --- crates/ide-completion/src/completions/expr.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs index e710175170..365d2dde7e 100644 --- a/crates/ide-completion/src/completions/expr.rs +++ b/crates/ide-completion/src/completions/expr.rs @@ -147,7 +147,10 @@ pub(crate) fn complete_expr_path( }); match resolution { hir::PathResolution::Def(hir::ModuleDef::Module(module)) => { - let module_scope = module.scope(ctx.db, Some(ctx.module)); + // Set visible_from to None so private items are returned. + // They will be possibly filtered out in add_path_resolution() + // via def_is_visible(). + let module_scope = module.scope(ctx.db, None); for (name, def) in module_scope { if scope_def_applicable(def) { acc.add_path_resolution( From 74e77188b6146007fd1f5f3ed162eadddb905c0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 24 Feb 2025 14:11:12 +0200 Subject: [PATCH 06/47] Downgrade to ubuntu-22.04 for aarch64-unknown-linux-gnu and arm-unknown-linux-gnueabihf builds --- .github/workflows/release.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index fe090267dc..5159ffc8fe 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -38,10 +38,10 @@ jobs: target: x86_64-unknown-linux-gnu code-target: linux-x64 container: rockylinux:8 - - os: ubuntu-latest + - os: ubuntu-22.04 target: aarch64-unknown-linux-gnu code-target: linux-arm64 - - os: ubuntu-latest + - os: ubuntu-22.04 target: arm-unknown-linux-gnueabihf code-target: linux-armhf - os: macos-13 From 604c4a989e4242082dc023985f3d48babc3bb129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 24 Feb 2025 14:25:55 +0200 Subject: [PATCH 07/47] Fix event_name check in workflows --- .github/workflows/autopublish.yaml | 2 +- .github/workflows/fuzz.yml | 2 +- .github/workflows/publish-libs.yaml | 2 +- .github/workflows/release.yaml | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/autopublish.yaml b/.github/workflows/autopublish.yaml index e4fa94643b..d3f0499e43 100644 --- a/.github/workflows/autopublish.yaml +++ b/.github/workflows/autopublish.yaml @@ -11,7 +11,7 @@ on: jobs: publish: - if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }} + if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }} name: publish runs-on: ubuntu-latest steps: diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index f88c7f95d5..7acfcbe351 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -19,7 +19,7 @@ env: jobs: rust: - if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }} + if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }} name: Rust runs-on: ubuntu-latest env: diff --git a/.github/workflows/publish-libs.yaml b/.github/workflows/publish-libs.yaml index 5023a634fd..93ae5675a7 100644 --- a/.github/workflows/publish-libs.yaml +++ b/.github/workflows/publish-libs.yaml @@ -9,7 +9,7 @@ on: jobs: publish-libs: - if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }} + if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }} name: publish runs-on: ubuntu-latest steps: diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index fe090267dc..0625fbf42b 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -22,7 +22,7 @@ env: jobs: dist: - if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }} + if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }} strategy: matrix: include: @@ -139,7 +139,7 @@ jobs: path: ./dist dist-x86_64-unknown-linux-musl: - if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }} + if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }} name: dist (x86_64-unknown-linux-musl) runs-on: ubuntu-latest env: @@ -185,7 +185,7 @@ jobs: path: ./dist publish: - if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }} + if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }} name: publish runs-on: ubuntu-latest needs: ["dist", "dist-x86_64-unknown-linux-musl"] From bd8a601ab37a8703292c9a0e4851ab2d494960b2 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 24 Feb 2025 13:52:46 +0100 Subject: [PATCH 08/47] Disable incremental on release builds --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 5060013b13..d363bb59be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,6 @@ salsa.opt-level = 3 miniz_oxide.opt-level = 3 [profile.release] -incremental = true # Set this to 1 or 2 to get more useful backtraces in debugger. debug = 0 From 9a462b7c364c0461ff293676b9ce677da8f0f2e7 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 24 Feb 2025 14:00:16 +0100 Subject: [PATCH 09/47] Vendor always-assert --- Cargo.lock | 5 +- crates/rust-analyzer/Cargo.toml | 2 +- crates/stdx/Cargo.toml | 3 +- crates/stdx/src/assert.rs | 115 ++++++++++++++++++++++++++++++++ crates/stdx/src/lib.rs | 5 +- 5 files changed, 122 insertions(+), 8 deletions(-) create mode 100644 crates/stdx/src/assert.rs diff --git a/Cargo.lock b/Cargo.lock index fc3680ce27..b4e97261d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,6 @@ name = "always-assert" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1078fa1ce1e34b1872d8611ad921196d76bdd7027e949fbe31231abde201892" -dependencies = [ - "tracing", -] [[package]] name = "anyhow" @@ -1922,13 +1919,13 @@ dependencies = [ name = "stdx" version = "0.0.0" dependencies = [ - "always-assert", "backtrace", "crossbeam-channel", "itertools", "jod-thread", "libc", "miow", + "tracing", "windows-sys 0.59.0", ] diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index b8ce2b7430..64c8afdc1f 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml @@ -94,7 +94,7 @@ syntax-bridge.workspace = true [features] jemalloc = ["jemallocator", "profile/jemalloc"] -force-always-assert = ["always-assert/force"] +force-always-assert = ["stdx/force-always-assert"] sysroot-abi = [] in-rust-tree = [ "sysroot-abi", diff --git a/crates/stdx/Cargo.toml b/crates/stdx/Cargo.toml index 1ebb48c577..62c32d68e6 100644 --- a/crates/stdx/Cargo.toml +++ b/crates/stdx/Cargo.toml @@ -14,11 +14,11 @@ doctest = false [dependencies] backtrace = { version = "0.3.67", optional = true } -always-assert = { version = "0.2.0", features = ["tracing"] } jod-thread = "0.1.2" libc.workspace = true crossbeam-channel.workspace = true itertools.workspace = true +tracing.workspace = true # Think twice before adding anything here [target.'cfg(windows)'.dependencies] @@ -28,6 +28,7 @@ windows-sys = { version = "0.59", features = ["Win32_Foundation"] } [features] # Uncomment to enable for the whole crate graph # default = [ "backtrace" ] +force-always-assert = [] [lints] workspace = true diff --git a/crates/stdx/src/assert.rs b/crates/stdx/src/assert.rs new file mode 100644 index 0000000000..91c279798c --- /dev/null +++ b/crates/stdx/src/assert.rs @@ -0,0 +1,115 @@ +// Vendored from https://github.com/matklad/always-assert/commit/4cf564eea6fcf18b30c3c3483a611004dc03afbb +//! Recoverable assertions, inspired by [the use of `assert()` in +//! SQLite](https://www.sqlite.org/assert.html). +//! +//! `never!` and `always!` return the actual value of the condition if +//! `debug_assertions` are disabled. +//! +//! Use them when terminating on assertion failure is worse than continuing. +//! +//! One example would be a critical application like a database: +//! +//! ```ignore +//! use stdx::never; +//! +//! fn apply_transaction(&mut self, tx: Transaction) -> Result<(), TransactionAborted> { +//! let delta = self.compute_delta(&tx); +//! +//! if never!(!self.check_internal_invariant(&delta)) { +//! // Ok, something in this transaction messed up our internal state. +//! // This really shouldn't be happening, and this signifies a bug. +//! // Luckily, we can recover by just rejecting the transaction. +//! return abort_transaction(tx); +//! } +//! self.commit(delta); +//! Ok(()) +//! } +//! ``` +//! +//! Another example is assertions about non-critical functionality in usual apps +//! +//! ```ignore +//! use stdx::never; +//! +//! let english_message = "super app installed!" +//! let mut local_message = localize(english_message); +//! if never!(local_message.is_empty(), "missing localization for {}", english_message) { +//! // We localized all the messages but this one slipper through the cracks? +//! // Better to show the english one then than to fail outright; +//! local_message = english_message; +//! } +//! println!("{}", local_message); +//! ``` + +/// Asserts that the condition is always true and returns its actual value. +/// +/// If the condition is true does nothing and and evaluates to true. +/// +/// If the condition is false: +/// * panics if `force` feature or `debug_assertions` are enabled, +/// * logs an error if the `tracing` feature is enabled, +/// * evaluates to false. +/// +/// Accepts `format!` style arguments. +#[macro_export] +macro_rules! always { + ($cond:expr) => { + $crate::always!($cond, "assertion failed: {}", stringify!($cond)) + }; + + ($cond:expr, $fmt:literal $($arg:tt)*) => {{ + let cond = $cond; + if cfg!(debug_assertions) || $crate::assert::__FORCE { + assert!(cond, $fmt $($arg)*); + } + if !cond { + $crate::assert::__tracing_error!($fmt $($arg)*); + } + cond + }}; +} + +/// Asserts that the condition is never true and returns its actual value. +/// +/// If the condition is false does nothing and and evaluates to false. +/// +/// If the condition is true: +/// * panics if `force` feature or `debug_assertions` are enabled, +/// * logs an error if the `tracing` feature is enabled, +/// * evaluates to true. +/// +/// Accepts `format!` style arguments. +/// +/// Empty condition is equivalent to false: +/// +/// ```ignore +/// never!("oups") ~= unreachable!("oups") +/// ``` +#[macro_export] +macro_rules! never { + (true $($tt:tt)*) => { $crate::never!((true) $($tt)*) }; + (false $($tt:tt)*) => { $crate::never!((false) $($tt)*) }; + () => { $crate::never!("assertion failed: entered unreachable code") }; + ($fmt:literal $(, $($arg:tt)*)?) => {{ + if cfg!(debug_assertions) || $crate::assert::__FORCE { + unreachable!($fmt $(, $($arg)*)?); + } + $crate::assert::__tracing_error!($fmt $(, $($arg)*)?); + }}; + + ($cond:expr) => {{ + let cond = !$crate::always!(!$cond); + cond + }}; + + ($cond:expr, $fmt:literal $($arg:tt)*) => {{ + let cond = !$crate::always!(!$cond, $fmt $($arg)*); + cond + }}; +} + +#[doc(hidden)] +pub use tracing::error as __tracing_error; + +#[doc(hidden)] +pub const __FORCE: bool = cfg!(feature = "force-always-assert"); diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs index 04c2153abf..8313e1871f 100644 --- a/crates/stdx/src/lib.rs +++ b/crates/stdx/src/lib.rs @@ -4,8 +4,10 @@ use std::io as sio; use std::process::Command; use std::{cmp::Ordering, ops, time::Instant}; -pub mod anymap; mod macros; + +pub mod anymap; +pub mod assert; pub mod non_empty_vec; pub mod panic_context; pub mod process; @@ -13,7 +15,6 @@ pub mod rand; pub mod thin_vec; pub mod thread; -pub use always_assert::{always, never}; pub use itertools; #[inline(always)] From f06f1b81bb503e1ffa3b0f622706f315e126ca8c Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Mon, 17 Feb 2025 23:36:44 +0900 Subject: [PATCH 10/47] Migrate some leftovers in `add_missing_match_arms` --- .../src/handlers/add_missing_match_arms.rs | 63 ++++--- crates/syntax/src/ast/make.rs | 2 +- .../src/ast/syntax_factory/constructors.rs | 156 ++++++++++++++++++ 3 files changed, 196 insertions(+), 25 deletions(-) diff --git a/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/crates/ide-assists/src/handlers/add_missing_match_arms.rs index 4a9e2256e9..eec1e648c0 100644 --- a/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -1,4 +1,6 @@ use std::iter::{self, Peekable}; +use std::ops::Deref; +use std::rc::Rc; use either::Either; use hir::{sym, Adt, Crate, HasAttrs, ImportPathConfig, ModuleDef, Semantics}; @@ -76,6 +78,11 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) let cfg = ctx.config.import_path_config(); + // As `make` is borrowed by the closure that builds `missing_pats`, this is needed + // to satisfy the borrow checker. + let make = Rc::new(SyntaxFactory::new()); + let make_weak = Rc::downgrade(&make); + let module = ctx.sema.scope(expr.syntax())?.module(); let (mut missing_pats, is_non_exhaustive, has_hidden_variants): ( Peekable>>, @@ -92,8 +99,9 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) let missing_pats = variants .into_iter() .filter_map(|variant| { + let make = make_weak.upgrade()?; Some(( - build_pat(ctx, module, variant, cfg)?, + build_pat(ctx, make, module, variant, cfg)?, variant.should_be_hidden(ctx.db(), module.krate()), )) }) @@ -140,14 +148,17 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .into_iter() .multi_cartesian_product() .inspect(|_| cov_mark::hit!(add_missing_match_arms_lazy_computation)) - .map(|variants| { + .filter_map(|variants| { let is_hidden = variants .iter() .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); - let patterns = - variants.into_iter().filter_map(|variant| build_pat(ctx, module, variant, cfg)); + let patterns = variants.into_iter().filter_map(|variant| { + make_weak.upgrade().and_then(|make| build_pat(ctx, make, module, variant, cfg)) + }); - (ast::Pat::from(make::tuple_pat(patterns)), is_hidden) + make_weak + .upgrade() + .map(|make| (ast::Pat::from(make.tuple_pat(patterns)), is_hidden)) }) .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat)); ( @@ -172,13 +183,17 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .into_iter() .multi_cartesian_product() .inspect(|_| cov_mark::hit!(add_missing_match_arms_lazy_computation)) - .map(|variants| { + .filter_map(|variants| { let is_hidden = variants .iter() .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); - let patterns = - variants.into_iter().filter_map(|variant| build_pat(ctx, module, variant, cfg)); - (ast::Pat::from(make::slice_pat(patterns)), is_hidden) + let patterns = variants.into_iter().filter_map(|variant| { + make_weak.upgrade().and_then(|make| build_pat(ctx, make, module, variant, cfg)) + }); + + make_weak + .upgrade() + .map(|make| (ast::Pat::from(make.slice_pat(patterns)), is_hidden)) }) .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat)); ( @@ -203,8 +218,6 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) "Fill match arms", ctx.sema.original_range(match_expr.syntax()).range, |builder| { - let make = SyntaxFactory::new(); - // having any hidden variants means that we need a catch-all arm needs_catch_all_arm |= has_hidden_variants; @@ -243,7 +256,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) if needs_catch_all_arm && !has_catch_all_arm { cov_mark::hit!(added_wildcard_pattern); - let arm = make.match_arm(make::wildcard_pat().into(), None, make::ext::expr_todo()); + let arm = make.match_arm(make.wildcard_pat().into(), None, make::ext::expr_todo()); arms.push(arm); } @@ -290,7 +303,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) } } - editor.add_mappings(make.finish_with_mappings()); + editor.add_mappings(Rc::into_inner(make).unwrap().finish_with_mappings()); builder.add_file_edits(ctx.file_id(), editor); }, ) @@ -445,6 +458,7 @@ fn resolve_array_of_enum_def( fn build_pat( ctx: &AssistContext<'_>, + make: impl Deref, module: hir::Module, var: ExtendedVariant, cfg: ImportPathConfig, @@ -455,31 +469,32 @@ fn build_pat( let edition = module.krate().edition(db); let path = mod_path_to_ast(&module.find_path(db, ModuleDef::from(var), cfg)?, edition); let fields = var.fields(db); - let pat = match var.kind(db) { + let pat: ast::Pat = match var.kind(db) { hir::StructKind::Tuple => { let mut name_generator = suggest_name::NameGenerator::new(); let pats = fields.into_iter().map(|f| { let name = name_generator.for_type(&f.ty(db), db, edition); match name { - Some(name) => make::ext::simple_ident_pat(make::name(&name)).into(), - None => make::wildcard_pat().into(), + Some(name) => make::ext::simple_ident_pat(make.name(&name)).into(), + None => make.wildcard_pat().into(), } }); - make::tuple_struct_pat(path, pats).into() + make.tuple_struct_pat(path, pats).into() } hir::StructKind::Record => { - let pats = fields + let fields = fields .into_iter() - .map(|f| make::name(f.name(db).as_str())) - .map(|name| make::ext::simple_ident_pat(name).into()); - make::record_pat(path, pats).into() + .map(|f| make.name_ref(f.name(db).as_str())) + .map(|name_ref| make.record_pat_field_shorthand(name_ref)); + let fields = make.record_pat_field_list(fields, None); + make.record_pat_with_fields(path, fields).into() } - hir::StructKind::Unit => make::path_pat(path), + hir::StructKind::Unit => make.path_pat(path), }; Some(pat) } - ExtendedVariant::True => Some(ast::Pat::from(make::literal_pat("true"))), - ExtendedVariant::False => Some(ast::Pat::from(make::literal_pat("false"))), + ExtendedVariant::True => Some(ast::Pat::from(make.literal_pat("true"))), + ExtendedVariant::False => Some(ast::Pat::from(make.literal_pat("false"))), } } diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index 9dc2d83253..231c21c38f 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs @@ -784,7 +784,7 @@ pub fn record_pat_field_shorthand(name_ref: ast::NameRef) -> ast::RecordPatField ast_from_text(&format!("fn f(S {{ {name_ref} }}: ()))")) } -/// Returns a `BindPat` if the path has just one segment, a `PathPat` otherwise. +/// Returns a `IdentPat` if the path has just one segment, a `PathPat` otherwise. pub fn path_pat(path: ast::Path) -> ast::Pat { return from_text(&path.to_string()); fn from_text(text: &str) -> ast::Pat { diff --git a/crates/syntax/src/ast/syntax_factory/constructors.rs b/crates/syntax/src/ast/syntax_factory/constructors.rs index 572622db54..044d68b528 100644 --- a/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -156,6 +156,32 @@ impl SyntaxFactory { make::literal_pat(text).clone_for_update() } + pub fn slice_pat(&self, pats: impl IntoIterator) -> ast::SlicePat { + let (pats, input) = iterator_input(pats); + let ast = make::slice_pat(pats).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(input.into_iter(), ast.pats().map(|it| it.syntax().clone())); + builder.finish(&mut mapping); + } + + ast + } + + pub fn tuple_pat(&self, pats: impl IntoIterator) -> ast::TuplePat { + let (pats, input) = iterator_input(pats); + let ast = make::tuple_pat(pats).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); + builder.finish(&mut mapping); + } + + ast + } + pub fn tuple_struct_pat( &self, path: ast::Path, @@ -174,6 +200,96 @@ impl SyntaxFactory { ast } + pub fn record_pat_with_fields( + &self, + path: ast::Path, + fields: ast::RecordPatFieldList, + ) -> ast::RecordPat { + let ast = make::record_pat_with_fields(path.clone(), fields.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(path.syntax().clone(), ast.path().unwrap().syntax().clone()); + builder.map_node( + fields.syntax().clone(), + ast.record_pat_field_list().unwrap().syntax().clone(), + ); + builder.finish(&mut mapping); + } + + ast + } + + pub fn record_pat_field_list( + &self, + fields: impl IntoIterator, + rest_pat: Option, + ) -> ast::RecordPatFieldList { + let (fields, input) = iterator_input(fields); + let ast = make::record_pat_field_list(fields, rest_pat.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); + if let Some(rest_pat) = rest_pat { + builder + .map_node(rest_pat.syntax().clone(), ast.rest_pat().unwrap().syntax().clone()); + } + builder.finish(&mut mapping); + } + + ast + } + + pub fn record_pat_field(self, name_ref: ast::NameRef, pat: ast::Pat) -> ast::RecordPatField { + let ast = make::record_pat_field(name_ref.clone(), pat.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(name_ref.syntax().clone(), ast.name_ref().unwrap().syntax().clone()); + builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn record_pat_field_shorthand(&self, name_ref: ast::NameRef) -> ast::RecordPatField { + let ast = make::record_pat_field_shorthand(name_ref.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(name_ref.syntax().clone(), ast.pat().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn path_pat(&self, path: ast::Path) -> ast::Pat { + let ast = make::path_pat(path.clone()).clone_for_update(); + + match &ast { + ast::Pat::PathPat(ast) => { + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(path.syntax().clone(), ast.path().unwrap().syntax().clone()); + builder.finish(&mut mapping) + } + } + ast::Pat::IdentPat(ast) => { + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(path.syntax().clone(), ast.name().unwrap().syntax().clone()); + builder.finish(&mut mapping) + } + } + _ => unreachable!(), + } + + ast + } + pub fn block_expr( &self, statements: impl IntoIterator, @@ -214,6 +330,21 @@ impl SyntaxFactory { make::expr_empty_block().clone_for_update() } + pub fn expr_paren(&self, expr: ast::Expr) -> ast::ParenExpr { + // FIXME: `make::expr_paren` should return a `MethodCallExpr`, not just an `Expr` + let ast::Expr::ParenExpr(ast) = make::expr_paren(expr.clone()).clone_for_update() else { + unreachable!() + }; + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + pub fn expr_tuple(&self, fields: impl IntoIterator) -> ast::TupleExpr { let (fields, input) = iterator_input(fields); let ast = make::expr_tuple(fields).clone_for_update(); @@ -292,6 +423,31 @@ impl SyntaxFactory { ast } + pub fn expr_method_call( + &self, + receiver: ast::Expr, + method: ast::NameRef, + arg_list: ast::ArgList, + ) -> ast::MethodCallExpr { + // FIXME: `make::expr_method_call` should return a `MethodCallExpr`, not just an `Expr` + let ast::Expr::MethodCallExpr(ast) = + make::expr_method_call(receiver.clone(), method.clone(), arg_list.clone()) + .clone_for_update() + else { + unreachable!() + }; + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(receiver.syntax().clone(), ast.receiver().unwrap().syntax().clone()); + builder.map_node(method.syntax().clone(), ast.name_ref().unwrap().syntax().clone()); + builder.map_node(arg_list.syntax().clone(), ast.arg_list().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + pub fn arg_list(&self, args: impl IntoIterator) -> ast::ArgList { let (args, input) = iterator_input(args); let ast = make::arg_list(args).clone_for_update(); From bf0c3944f8c41545dfd26b4eb98cda4f5e758adf Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Tue, 18 Feb 2025 04:09:27 +0900 Subject: [PATCH 11/47] Migrate `apply_demorgan` to `SyntaxEditor` --- .../src/handlers/apply_demorgan.rs | 120 ++++++++++++------ .../src/handlers/convert_bool_then.rs | 4 +- .../src/handlers/convert_to_guarded_return.rs | 4 +- .../src/handlers/convert_while_to_loop.rs | 4 +- crates/ide-assists/src/handlers/invert_if.rs | 4 +- crates/ide-assists/src/utils.rs | 78 +++++++++++- 6 files changed, 162 insertions(+), 52 deletions(-) diff --git a/crates/ide-assists/src/handlers/apply_demorgan.rs b/crates/ide-assists/src/handlers/apply_demorgan.rs index 491727a30a..83c049d461 100644 --- a/crates/ide-assists/src/handlers/apply_demorgan.rs +++ b/crates/ide-assists/src/handlers/apply_demorgan.rs @@ -3,12 +3,12 @@ use std::collections::VecDeque; use ide_db::{ assists::GroupLabel, famous_defs::FamousDefs, - source_change::SourceChangeBuilder, syntax_helpers::node_ext::{for_each_tail_expr, walk_expr}, }; use syntax::{ - ast::{self, make, AstNode, Expr::BinExpr, HasArgList}, - ted, SyntaxKind, T, + ast::{self, syntax_factory::SyntaxFactory, AstNode, Expr::BinExpr, HasArgList}, + syntax_editor::{Position, SyntaxEditor}, + SyntaxKind, SyntaxNode, T, }; use crate::{utils::invert_boolean_expression, AssistContext, AssistId, AssistKind, Assists}; @@ -58,9 +58,12 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti _ => return None, }; - let demorganed = bin_expr.clone_subtree().clone_for_update(); + let make = SyntaxFactory::new(); + + let demorganed = bin_expr.clone_subtree(); + let mut editor = SyntaxEditor::new(demorganed.syntax().clone()); + editor.replace(demorganed.op_token()?, make.token(inv_token)); - ted::replace(demorganed.op_token()?, ast::make::token(inv_token)); let mut exprs = VecDeque::from([ (bin_expr.lhs()?, demorganed.lhs()?), (bin_expr.rhs()?, demorganed.rhs()?), @@ -70,35 +73,39 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti if let BinExpr(bin_expr) = &expr { if let BinExpr(cbin_expr) = &dm { if op == bin_expr.op_kind()? { - ted::replace(cbin_expr.op_token()?, ast::make::token(inv_token)); + editor.replace(cbin_expr.op_token()?, make.token(inv_token)); exprs.push_back((bin_expr.lhs()?, cbin_expr.lhs()?)); exprs.push_back((bin_expr.rhs()?, cbin_expr.rhs()?)); } else { - let mut inv = invert_boolean_expression(expr); - if inv.needs_parens_in(dm.syntax().parent()?) { - inv = ast::make::expr_paren(inv).clone_for_update(); + let mut inv = invert_boolean_expression(&make, expr); + if needs_parens_in_place_of(&inv, &dm.syntax().parent()?, &dm) { + inv = make.expr_paren(inv).into(); } - ted::replace(dm.syntax(), inv.syntax()); + editor.replace(dm.syntax(), inv.syntax()); } } else { return None; } } else { - let mut inv = invert_boolean_expression(dm.clone_subtree()).clone_for_update(); - if inv.needs_parens_in(dm.syntax().parent()?) { - inv = ast::make::expr_paren(inv).clone_for_update(); + let mut inv = invert_boolean_expression(&make, dm.clone()); + if needs_parens_in_place_of(&inv, &dm.syntax().parent()?, &dm) { + inv = make.expr_paren(inv).into(); } - ted::replace(dm.syntax(), inv.syntax()); + editor.replace(dm.syntax(), inv.syntax()); } } + editor.add_mappings(make.finish_with_mappings()); + let edit = editor.finish(); + let demorganed = ast::Expr::cast(edit.new_root().clone())?; + acc.add_group( &GroupLabel("Apply De Morgan's law".to_owned()), AssistId("apply_demorgan", AssistKind::RefactorRewrite), "Apply De Morgan's law", op_range, - |edit| { - let demorganed = ast::Expr::BinExpr(demorganed); + |builder| { + let make = SyntaxFactory::new(); let paren_expr = bin_expr.syntax().parent().and_then(ast::ParenExpr::cast); let neg_expr = paren_expr .clone() @@ -107,24 +114,32 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti .filter(|prefix_expr| matches!(prefix_expr.op_kind(), Some(ast::UnaryOp::Not))) .map(ast::Expr::PrefixExpr); + let mut editor; if let Some(paren_expr) = paren_expr { if let Some(neg_expr) = neg_expr { cov_mark::hit!(demorgan_double_negation); let parent = neg_expr.syntax().parent(); + editor = builder.make_editor(neg_expr.syntax()); if parent.is_some_and(|parent| demorganed.needs_parens_in(parent)) { cov_mark::hit!(demorgan_keep_parens_for_op_precedence2); - edit.replace_ast(neg_expr, make::expr_paren(demorganed)); + editor.replace(neg_expr.syntax(), make.expr_paren(demorganed).syntax()); } else { - edit.replace_ast(neg_expr, demorganed); + editor.replace(neg_expr.syntax(), demorganed.syntax()); }; } else { cov_mark::hit!(demorgan_double_parens); - edit.replace_ast(paren_expr.into(), add_bang_paren(demorganed)); + editor = builder.make_editor(paren_expr.syntax()); + + editor.replace(paren_expr.syntax(), add_bang_paren(&make, demorganed).syntax()); } } else { - edit.replace_ast(bin_expr.into(), add_bang_paren(demorganed)); + editor = builder.make_editor(bin_expr.syntax()); + editor.replace(bin_expr.syntax(), add_bang_paren(&make, demorganed).syntax()); } + + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.file_id(), editor); }, ) } @@ -161,7 +176,7 @@ pub(crate) fn apply_demorgan_iterator(acc: &mut Assists, ctx: &AssistContext<'_> let (name, arg_expr) = validate_method_call_expr(ctx, &method_call)?; let ast::Expr::ClosureExpr(closure_expr) = arg_expr else { return None }; - let closure_body = closure_expr.body()?; + let closure_body = closure_expr.body()?.clone_for_update(); let op_range = method_call.syntax().text_range(); let label = format!("Apply De Morgan's law to `Iterator::{}`", name.text().as_str()); @@ -170,18 +185,19 @@ pub(crate) fn apply_demorgan_iterator(acc: &mut Assists, ctx: &AssistContext<'_> AssistId("apply_demorgan_iterator", AssistKind::RefactorRewrite), label, op_range, - |edit| { + |builder| { + let make = SyntaxFactory::new(); + let mut editor = builder.make_editor(method_call.syntax()); // replace the method name let new_name = match name.text().as_str() { - "all" => make::name_ref("any"), - "any" => make::name_ref("all"), + "all" => make.name_ref("any"), + "any" => make.name_ref("all"), _ => unreachable!(), - } - .clone_for_update(); - edit.replace_ast(name, new_name); + }; + editor.replace(name.syntax(), new_name.syntax()); // negate all tail expressions in the closure body - let tail_cb = &mut |e: &_| tail_cb_impl(edit, e); + let tail_cb = &mut |e: &_| tail_cb_impl(&mut editor, &make, e); walk_expr(&closure_body, &mut |expr| { if let ast::Expr::ReturnExpr(ret_expr) = expr { if let Some(ret_expr_arg) = &ret_expr.expr() { @@ -198,15 +214,15 @@ pub(crate) fn apply_demorgan_iterator(acc: &mut Assists, ctx: &AssistContext<'_> .and_then(ast::PrefixExpr::cast) .filter(|prefix_expr| matches!(prefix_expr.op_kind(), Some(ast::UnaryOp::Not))) { - edit.delete( - prefix_expr - .op_token() - .expect("prefix expression always has an operator") - .text_range(), + editor.delete( + prefix_expr.op_token().expect("prefix expression always has an operator"), ); } else { - edit.insert(method_call.syntax().text_range().start(), "!"); + editor.insert(Position::before(method_call.syntax()), make.token(SyntaxKind::BANG)); } + + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.file_id(), editor); }, ) } @@ -233,26 +249,50 @@ fn validate_method_call_expr( it_type.impls_trait(sema.db, iter_trait, &[]).then_some((name_ref, arg_expr)) } -fn tail_cb_impl(edit: &mut SourceChangeBuilder, e: &ast::Expr) { +fn tail_cb_impl(editor: &mut SyntaxEditor, make: &SyntaxFactory, e: &ast::Expr) { match e { ast::Expr::BreakExpr(break_expr) => { if let Some(break_expr_arg) = break_expr.expr() { - for_each_tail_expr(&break_expr_arg, &mut |e| tail_cb_impl(edit, e)) + for_each_tail_expr(&break_expr_arg, &mut |e| tail_cb_impl(editor, make, e)) } } ast::Expr::ReturnExpr(_) => { // all return expressions have already been handled by the walk loop } e => { - let inverted_body = invert_boolean_expression(e.clone()); - edit.replace(e.syntax().text_range(), inverted_body.syntax().text()); + let inverted_body = invert_boolean_expression(make, e.clone()); + editor.replace(e.syntax(), inverted_body.syntax()); } } } /// Add bang and parentheses to the expression. -fn add_bang_paren(expr: ast::Expr) -> ast::Expr { - make::expr_prefix(T![!], make::expr_paren(expr)).into() +fn add_bang_paren(make: &SyntaxFactory, expr: ast::Expr) -> ast::Expr { + make.expr_prefix(T![!], make.expr_paren(expr).into()).into() +} + +fn needs_parens_in_place_of( + this: &ast::Expr, + parent: &SyntaxNode, + in_place_of: &ast::Expr, +) -> bool { + assert_eq!(Some(parent), in_place_of.syntax().parent().as_ref()); + + let child_idx = parent + .children() + .enumerate() + .find_map(|(i, it)| if &it == in_place_of.syntax() { Some(i) } else { None }) + .unwrap(); + let parent = parent.clone_subtree(); + let subtree_place = parent.children().nth(child_idx).unwrap(); + + let mut editor = SyntaxEditor::new(parent); + editor.replace(subtree_place, this.syntax()); + let edit = editor.finish(); + + let replaced = edit.new_root().children().nth(child_idx).unwrap(); + let replaced = ast::Expr::cast(replaced).unwrap(); + replaced.needs_parens_in(edit.new_root().clone()) } #[cfg(test)] diff --git a/crates/ide-assists/src/handlers/convert_bool_then.rs b/crates/ide-assists/src/handlers/convert_bool_then.rs index eb784cd122..8d391c64ce 100644 --- a/crates/ide-assists/src/handlers/convert_bool_then.rs +++ b/crates/ide-assists/src/handlers/convert_bool_then.rs @@ -13,7 +13,7 @@ use syntax::{ }; use crate::{ - utils::{invert_boolean_expression, unwrap_trivial_block}, + utils::{invert_boolean_expression_legacy, unwrap_trivial_block}, AssistContext, AssistId, AssistKind, Assists, }; @@ -119,7 +119,7 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_> | ast::Expr::WhileExpr(_) | ast::Expr::YieldExpr(_) ); - let cond = if invert_cond { invert_boolean_expression(cond) } else { cond }; + let cond = if invert_cond { invert_boolean_expression_legacy(cond) } else { cond }; let cond = if parenthesize { make::expr_paren(cond) } else { cond }; let arg_list = make::arg_list(Some(make::expr_closure(None, closure_body))); let mcall = make::expr_method_call(cond, make::name_ref("then"), arg_list); diff --git a/crates/ide-assists/src/handlers/convert_to_guarded_return.rs b/crates/ide-assists/src/handlers/convert_to_guarded_return.rs index e1966d476c..b7a7764449 100644 --- a/crates/ide-assists/src/handlers/convert_to_guarded_return.rs +++ b/crates/ide-assists/src/handlers/convert_to_guarded_return.rs @@ -17,7 +17,7 @@ use syntax::{ use crate::{ assist_context::{AssistContext, Assists}, - utils::invert_boolean_expression, + utils::invert_boolean_expression_legacy, AssistId, AssistKind, }; @@ -139,7 +139,7 @@ fn if_expr_to_guarded_return( let new_expr = { let then_branch = make::block_expr(once(make::expr_stmt(early_expression).into()), None); - let cond = invert_boolean_expression(cond_expr); + let cond = invert_boolean_expression_legacy(cond_expr); make::expr_if(cond, then_branch, None).indent(if_indent_level) }; new_expr.syntax().clone_for_update() diff --git a/crates/ide-assists/src/handlers/convert_while_to_loop.rs b/crates/ide-assists/src/handlers/convert_while_to_loop.rs index 0b92beefbc..beec64d13b 100644 --- a/crates/ide-assists/src/handlers/convert_while_to_loop.rs +++ b/crates/ide-assists/src/handlers/convert_while_to_loop.rs @@ -13,7 +13,7 @@ use syntax::{ use crate::{ assist_context::{AssistContext, Assists}, - utils::invert_boolean_expression, + utils::invert_boolean_expression_legacy, AssistId, AssistKind, }; @@ -63,7 +63,7 @@ pub(crate) fn convert_while_to_loop(acc: &mut Assists, ctx: &AssistContext<'_>) let stmts = iter::once(make::expr_stmt(if_expr.into()).into()); make::block_expr(stmts, None) } else { - let if_cond = invert_boolean_expression(while_cond); + let if_cond = invert_boolean_expression_legacy(while_cond); let if_expr = make::expr_if(if_cond, break_block, None).syntax().clone().into(); let elements = while_body.stmt_list().map_or_else( || Either::Left(iter::empty()), diff --git a/crates/ide-assists/src/handlers/invert_if.rs b/crates/ide-assists/src/handlers/invert_if.rs index 547158e297..ac710503d8 100644 --- a/crates/ide-assists/src/handlers/invert_if.rs +++ b/crates/ide-assists/src/handlers/invert_if.rs @@ -6,7 +6,7 @@ use syntax::{ use crate::{ assist_context::{AssistContext, Assists}, - utils::invert_boolean_expression, + utils::invert_boolean_expression_legacy, AssistId, AssistKind, }; @@ -48,7 +48,7 @@ pub(crate) fn invert_if(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<() }; acc.add(AssistId("invert_if", AssistKind::RefactorRewrite), "Invert if", if_range, |edit| { - let flip_cond = invert_boolean_expression(cond.clone()); + let flip_cond = invert_boolean_expression_legacy(cond.clone()); edit.replace_ast(cond, flip_cond); let else_node = else_block.syntax(); diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs index c1332d99bf..39686f065a 100644 --- a/crates/ide-assists/src/utils.rs +++ b/crates/ide-assists/src/utils.rs @@ -17,7 +17,9 @@ use syntax::{ self, edit::{AstNodeEdit, IndentLevel}, edit_in_place::{AttrsOwnerEdit, Indent, Removable}, - make, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace, + make, + syntax_factory::SyntaxFactory, + HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace, }, ted, AstNode, AstToken, Direction, Edition, NodeOrToken, SourceFile, SyntaxKind::*, @@ -245,11 +247,79 @@ pub(crate) fn vis_offset(node: &SyntaxNode) -> TextSize { .unwrap_or_else(|| node.text_range().start()) } -pub(crate) fn invert_boolean_expression(expr: ast::Expr) -> ast::Expr { - invert_special_case(&expr).unwrap_or_else(|| make::expr_prefix(T![!], expr).into()) +pub(crate) fn invert_boolean_expression(make: &SyntaxFactory, expr: ast::Expr) -> ast::Expr { + invert_special_case(make, &expr).unwrap_or_else(|| make.expr_prefix(T![!], expr).into()) } -fn invert_special_case(expr: &ast::Expr) -> Option { +// FIXME: Migrate usages of this function to the above function and remove this. +pub(crate) fn invert_boolean_expression_legacy(expr: ast::Expr) -> ast::Expr { + invert_special_case_legacy(&expr).unwrap_or_else(|| make::expr_prefix(T![!], expr).into()) +} + +fn invert_special_case(make: &SyntaxFactory, expr: &ast::Expr) -> Option { + match expr { + ast::Expr::BinExpr(bin) => { + let op_kind = bin.op_kind()?; + let rev_kind = match op_kind { + ast::BinaryOp::CmpOp(ast::CmpOp::Eq { negated }) => { + ast::BinaryOp::CmpOp(ast::CmpOp::Eq { negated: !negated }) + } + ast::BinaryOp::CmpOp(ast::CmpOp::Ord { ordering: ast::Ordering::Less, strict }) => { + ast::BinaryOp::CmpOp(ast::CmpOp::Ord { + ordering: ast::Ordering::Greater, + strict: !strict, + }) + } + ast::BinaryOp::CmpOp(ast::CmpOp::Ord { + ordering: ast::Ordering::Greater, + strict, + }) => ast::BinaryOp::CmpOp(ast::CmpOp::Ord { + ordering: ast::Ordering::Less, + strict: !strict, + }), + // Parenthesize other expressions before prefixing `!` + _ => { + return Some( + make.expr_prefix(T![!], make.expr_paren(expr.clone()).into()).into(), + ); + } + }; + + Some(make.expr_bin(bin.lhs()?, rev_kind, bin.rhs()?).into()) + } + ast::Expr::MethodCallExpr(mce) => { + let receiver = mce.receiver()?; + let method = mce.name_ref()?; + let arg_list = mce.arg_list()?; + + let method = match method.text().as_str() { + "is_some" => "is_none", + "is_none" => "is_some", + "is_ok" => "is_err", + "is_err" => "is_ok", + _ => return None, + }; + + Some(make.expr_method_call(receiver, make.name_ref(method), arg_list).into()) + } + ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::UnaryOp::Not => match pe.expr()? { + ast::Expr::ParenExpr(parexpr) => { + parexpr.expr().map(|e| e.clone_subtree().clone_for_update()) + } + _ => pe.expr().map(|e| e.clone_subtree().clone_for_update()), + }, + ast::Expr::Literal(lit) => match lit.kind() { + ast::LiteralKind::Bool(b) => match b { + true => Some(ast::Expr::Literal(make.expr_literal("false"))), + false => Some(ast::Expr::Literal(make.expr_literal("true"))), + }, + _ => None, + }, + _ => None, + } +} + +fn invert_special_case_legacy(expr: &ast::Expr) -> Option { match expr { ast::Expr::BinExpr(bin) => { let bin = bin.clone_for_update(); From a0b9931832ce92bc047b146cba53d9eaa6468671 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Tue, 18 Feb 2025 23:58:18 +0900 Subject: [PATCH 12/47] Add `take()` method to `SyntaxEditor` --- .../src/handlers/add_missing_match_arms.rs | 38 +++++++------------ crates/syntax/src/ast/syntax_factory.rs | 5 +++ .../src/ast/syntax_factory/constructors.rs | 2 +- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/crates/ide-assists/src/handlers/add_missing_match_arms.rs index eec1e648c0..37f5f44dfa 100644 --- a/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -1,6 +1,4 @@ use std::iter::{self, Peekable}; -use std::ops::Deref; -use std::rc::Rc; use either::Either; use hir::{sym, Adt, Crate, HasAttrs, ImportPathConfig, ModuleDef, Semantics}; @@ -78,10 +76,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) let cfg = ctx.config.import_path_config(); - // As `make` is borrowed by the closure that builds `missing_pats`, this is needed - // to satisfy the borrow checker. - let make = Rc::new(SyntaxFactory::new()); - let make_weak = Rc::downgrade(&make); + let make = SyntaxFactory::new(); let module = ctx.sema.scope(expr.syntax())?.module(); let (mut missing_pats, is_non_exhaustive, has_hidden_variants): ( @@ -99,9 +94,8 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) let missing_pats = variants .into_iter() .filter_map(|variant| { - let make = make_weak.upgrade()?; Some(( - build_pat(ctx, make, module, variant, cfg)?, + build_pat(ctx, &make, module, variant, cfg)?, variant.should_be_hidden(ctx.db(), module.krate()), )) }) @@ -148,17 +142,15 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .into_iter() .multi_cartesian_product() .inspect(|_| cov_mark::hit!(add_missing_match_arms_lazy_computation)) - .filter_map(|variants| { + .map(|variants| { let is_hidden = variants .iter() .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); - let patterns = variants.into_iter().filter_map(|variant| { - make_weak.upgrade().and_then(|make| build_pat(ctx, make, module, variant, cfg)) - }); + let patterns = variants + .into_iter() + .filter_map(|variant| build_pat(ctx, &make, module, variant, cfg)); - make_weak - .upgrade() - .map(|make| (ast::Pat::from(make.tuple_pat(patterns)), is_hidden)) + (ast::Pat::from(make.tuple_pat(patterns)), is_hidden) }) .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat)); ( @@ -183,17 +175,15 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .into_iter() .multi_cartesian_product() .inspect(|_| cov_mark::hit!(add_missing_match_arms_lazy_computation)) - .filter_map(|variants| { + .map(|variants| { let is_hidden = variants .iter() .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); - let patterns = variants.into_iter().filter_map(|variant| { - make_weak.upgrade().and_then(|make| build_pat(ctx, make, module, variant, cfg)) - }); + let patterns = variants + .into_iter() + .filter_map(|variant| build_pat(ctx, &make, module, variant, cfg)); - make_weak - .upgrade() - .map(|make| (ast::Pat::from(make.slice_pat(patterns)), is_hidden)) + (ast::Pat::from(make.slice_pat(patterns)), is_hidden) }) .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat)); ( @@ -303,7 +293,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) } } - editor.add_mappings(Rc::into_inner(make).unwrap().finish_with_mappings()); + editor.add_mappings(make.take()); builder.add_file_edits(ctx.file_id(), editor); }, ) @@ -458,7 +448,7 @@ fn resolve_array_of_enum_def( fn build_pat( ctx: &AssistContext<'_>, - make: impl Deref, + make: &SyntaxFactory, module: hir::Module, var: ExtendedVariant, cfg: ImportPathConfig, diff --git a/crates/syntax/src/ast/syntax_factory.rs b/crates/syntax/src/ast/syntax_factory.rs index 73bbe49105..1c517ac2c7 100644 --- a/crates/syntax/src/ast/syntax_factory.rs +++ b/crates/syntax/src/ast/syntax_factory.rs @@ -33,6 +33,11 @@ impl SyntaxFactory { self.mappings.unwrap_or_default().into_inner() } + /// Take all of the tracked syntax mappings, leaving `SyntaxMapping::default()` in its place, if any. + pub fn take(&self) -> SyntaxMapping { + self.mappings.as_ref().map(|mappings| mappings.take()).unwrap_or_default() + } + fn mappings(&self) -> Option> { self.mappings.as_ref().map(|it| it.borrow_mut()) } diff --git a/crates/syntax/src/ast/syntax_factory/constructors.rs b/crates/syntax/src/ast/syntax_factory/constructors.rs index 044d68b528..19c5c64e21 100644 --- a/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -331,7 +331,7 @@ impl SyntaxFactory { } pub fn expr_paren(&self, expr: ast::Expr) -> ast::ParenExpr { - // FIXME: `make::expr_paren` should return a `MethodCallExpr`, not just an `Expr` + // FIXME: `make::expr_paren` should return a `ParenExpr`, not just an `Expr` let ast::Expr::ParenExpr(ast) = make::expr_paren(expr.clone()).clone_for_update() else { unreachable!() }; From 6739652af7499d26def900b63d1b04c56a340a50 Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Mon, 24 Feb 2025 13:37:06 -0500 Subject: [PATCH 13/47] minor: Add tabstop to impl body in `generate_trait_impl` assist --- .../ide-assists/src/handlers/generate_impl.rs | 26 +++++++++++-------- crates/ide-assists/src/tests/generated.rs | 2 +- docs/book/src/assists_generated.md | 4 +-- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/crates/ide-assists/src/handlers/generate_impl.rs b/crates/ide-assists/src/handlers/generate_impl.rs index 7b7dac9a3d..4439830947 100644 --- a/crates/ide-assists/src/handlers/generate_impl.rs +++ b/crates/ide-assists/src/handlers/generate_impl.rs @@ -78,7 +78,7 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio // data: T, // } // -// impl ${0:_} for Ctx {} +// impl ${1:_} for Ctx {$0} // ``` pub(crate) fn generate_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let nominal = ctx.find_node_at_offset::()?; @@ -102,6 +102,10 @@ pub(crate) fn generate_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> if let Some(trait_) = impl_.trait_() { edit.add_placeholder_snippet(cap, trait_); } + + if let Some(l_curly) = impl_.assoc_item_list().and_then(|it| it.l_curly_token()) { + edit.add_tabstop_after_token(cap, l_curly); + } } insert_impl(impl_, &edit.make_mut(nominal)); @@ -278,7 +282,7 @@ mod tests { r#" struct Foo {} - impl ${0:_} for Foo {} + impl ${1:_} for Foo {$0} "#, ); } @@ -293,7 +297,7 @@ mod tests { r#" struct Foo {} - impl ${0:_} for Foo {} + impl ${1:_} for Foo {$0} "#, ); } @@ -308,7 +312,7 @@ mod tests { r#" struct Foo<'a, T: Foo<'a>> {} - impl<'a, T: Foo<'a>> ${0:_} for Foo<'a, T> {} + impl<'a, T: Foo<'a>> ${1:_} for Foo<'a, T> {$0} "#, ); } @@ -326,7 +330,7 @@ mod tests { struct Foo<'a, T: Foo<'a>> {} #[cfg(feature = "foo")] - impl<'a, T: Foo<'a>> ${0:_} for Foo<'a, T> {} + impl<'a, T: Foo<'a>> ${1:_} for Foo<'a, T> {$0} "#, ); } @@ -341,7 +345,7 @@ mod tests { r#" struct Defaulted {} - impl ${0:_} for Defaulted {} + impl ${1:_} for Defaulted {$0} "#, ); } @@ -356,7 +360,7 @@ mod tests { r#" struct Defaulted<'a, 'b: 'a, T: Debug + Clone + 'a + 'b = String, const S: usize> {} - impl<'a, 'b: 'a, T: Debug + Clone + 'a + 'b, const S: usize> ${0:_} for Defaulted<'a, 'b, T, S> {} + impl<'a, 'b: 'a, T: Debug + Clone + 'a + 'b, const S: usize> ${1:_} for Defaulted<'a, 'b, T, S> {$0} "#, ); } @@ -371,7 +375,7 @@ mod tests { r#" struct Defaulted {} - impl ${0:_} for Defaulted {} + impl ${1:_} for Defaulted {$0} "#, ); } @@ -398,10 +402,10 @@ mod tests { inner: T, } - impl ${0:_} for Struct + impl ${1:_} for Struct where T: Trait, - { + {$0 } "#, ); @@ -476,7 +480,7 @@ mod tests { mod foo { struct Bar {} - impl ${0:_} for Bar {} + impl ${1:_} for Bar {$0} } "#, ); diff --git a/crates/ide-assists/src/tests/generated.rs b/crates/ide-assists/src/tests/generated.rs index 0662527a38..74ae126ada 100644 --- a/crates/ide-assists/src/tests/generated.rs +++ b/crates/ide-assists/src/tests/generated.rs @@ -1961,7 +1961,7 @@ struct Ctx { data: T, } -impl ${0:_} for Ctx {} +impl ${1:_} for Ctx {$0} "#####, ) } diff --git a/docs/book/src/assists_generated.md b/docs/book/src/assists_generated.md index 9d68a873ff..52da98dbd2 100644 --- a/docs/book/src/assists_generated.md +++ b/docs/book/src/assists_generated.md @@ -280,7 +280,7 @@ fn main() { ### `apply_demorgan_iterator` -**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L132) +**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L147) Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws) to `Iterator::all` and `Iterator::any`. @@ -2161,7 +2161,7 @@ struct Ctx { data: T, } -impl ${0:_} for Ctx {} +impl ${1:_} for Ctx {┃} ``` From 9526d8bfe9cb5cdd6b911e6d0ed1284a4a67cad0 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 24 Feb 2025 23:20:26 +0530 Subject: [PATCH 14/47] doc: remove nit from setup.md --- docs/book/src/contributing/setup.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/book/src/contributing/setup.md b/docs/book/src/contributing/setup.md index d8a7840d37..eab65e779e 100644 --- a/docs/book/src/contributing/setup.md +++ b/docs/book/src/contributing/setup.md @@ -17,10 +17,13 @@ Since rust-analyzer is a Rust project, you will need to install Rust. You can do **Step 04**: Install the language server locally by running the following command: ```sh -cargo xtask install --server --code-bin code-insiders --dev-rel +# Install only the language server +cargo xtask install --server \ + --code-bin code-insiders \ # Target a specific editor (code, code-exploration, code-insiders, codium, or code-oss) + --dev-rel # Build in release mode with debug info level 2 ``` -In the output of this command, there should be a file path provided to the installed binary on your local machine. +In the output of this command, there should be a file path provided to the installed binary on your local machine. It should look something like the following output below: ``` @@ -48,9 +51,12 @@ An example debugging statement could go into the `main_loop.rs` file which can b ```rs eprintln!("Hello, world!"); ``` +Now, run the following commands to check the project and reinstall the server: -Now we run `cargo build` and `sh -cargo xtask install --server --code-bin code-insiders --dev-rel` to reinstall the server. +```sh +cargo check +cargo xtask install --server --code-bin code-insiders --dev-rel +``` Now on Visual Studio Code Insiders, we should be able to open the Output tab on our terminal and switch to Rust Analyzer Language Server to see the `eprintln!` statement we just wrote. From 87ed04bac0beaf0569a478f3bd4788527abf830f Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 25 Feb 2025 04:50:26 +0200 Subject: [PATCH 15/47] Support target features implications in target_feature 1.1 We vendor the list of implications, which isn't nice, but t-compiler doesn't want to make rustc_target available to us. --- crates/hir-ty/src/lib.rs | 6 +- crates/hir-ty/src/target_feature.rs | 259 ++++++++++++++++++ crates/hir-ty/src/utils.rs | 37 +-- .../src/handlers/missing_unsafe.rs | 2 +- 4 files changed, 268 insertions(+), 36 deletions(-) create mode 100644 crates/hir-ty/src/target_feature.rs diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs index 302be4836d..707c437772 100644 --- a/crates/hir-ty/src/lib.rs +++ b/crates/hir-ty/src/lib.rs @@ -36,6 +36,7 @@ mod inhabitedness; mod interner; mod lower; mod mapping; +mod target_feature; mod tls; mod utils; @@ -107,10 +108,9 @@ pub use mapping::{ to_foreign_def_id, to_placeholder_idx, }; pub use method_resolution::check_orphan_rules; +pub use target_feature::TargetFeatures; pub use traits::TraitEnvironment; -pub use utils::{ - all_super_traits, direct_super_traits, is_fn_unsafe_to_call, TargetFeatures, Unsafety, -}; +pub use utils::{all_super_traits, direct_super_traits, is_fn_unsafe_to_call, Unsafety}; pub use variance::Variance; pub use chalk_ir::{ diff --git a/crates/hir-ty/src/target_feature.rs b/crates/hir-ty/src/target_feature.rs new file mode 100644 index 0000000000..17a1b8efee --- /dev/null +++ b/crates/hir-ty/src/target_feature.rs @@ -0,0 +1,259 @@ +//! Stuff for handling `#[target_feature]` (needed for unsafe check). + +use std::sync::LazyLock; + +use hir_def::attr::Attrs; +use hir_def::tt; +use intern::{sym, Symbol}; +use rustc_hash::{FxHashMap, FxHashSet}; + +#[derive(Debug, Default)] +pub struct TargetFeatures { + pub(crate) enabled: FxHashSet, +} + +impl TargetFeatures { + pub fn from_attrs(attrs: &Attrs) -> Self { + let mut result = TargetFeatures::from_attrs_no_implications(attrs); + result.expand_implications(); + result + } + + fn expand_implications(&mut self) { + let all_implications = LazyLock::force(&TARGET_FEATURE_IMPLICATIONS); + let mut queue = self.enabled.iter().cloned().collect::>(); + while let Some(feature) = queue.pop() { + if let Some(implications) = all_implications.get(&feature) { + for implication in implications { + if self.enabled.insert(implication.clone()) { + queue.push(implication.clone()); + } + } + } + } + } + + /// Retrieves the target features from the attributes, and does not expand the target features implied by them. + pub(crate) fn from_attrs_no_implications(attrs: &Attrs) -> Self { + let enabled = attrs + .by_key(&sym::target_feature) + .tt_values() + .filter_map(|tt| { + match tt.token_trees().flat_tokens() { + [ + tt::TokenTree::Leaf(tt::Leaf::Ident(enable_ident)), + tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '=', .. })), + tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { kind: tt::LitKind::Str, symbol: features, .. })), + ] if enable_ident.sym == sym::enable => Some(features), + _ => None, + } + }) + .flat_map(|features| features.as_str().split(',').map(Symbol::intern)) + .collect(); + Self { enabled } + } +} + +// List of the target features each target feature implies. +// Ideally we'd depend on rustc for this, but rustc_target doesn't compile on stable, +// and t-compiler prefers for it to stay this way. + +static TARGET_FEATURE_IMPLICATIONS: LazyLock>> = + LazyLock::new(|| { + let mut result = FxHashMap::>::default(); + for &(feature_str, implications) in TARGET_FEATURE_IMPLICATIONS_RAW { + let feature = Symbol::intern(feature_str); + let implications = implications.iter().copied().map(Symbol::intern); + // Some target features appear in two archs, e.g. Arm and x86. + // Sometimes they contain different implications, e.g. `aes`. + // We should probably choose by the active arch, but for now just merge them. + result.entry(feature).or_default().extend(implications); + } + let mut result = result + .into_iter() + .map(|(feature, implications)| (feature, Box::from_iter(implications))) + .collect::>(); + result.shrink_to_fit(); + result + }); + +const TARGET_FEATURE_IMPLICATIONS_RAW: &[(&str, &[&str])] = &[ + // Arm + ("aes", &["neon"]), + ("dotprod", &["neon"]), + ("fp-armv8", &["vfp4"]), + ("fp16", &["neon"]), + ("i8mm", &["neon"]), + ("neon", &["vfp3"]), + ("sha2", &["neon"]), + ("v6", &["v5te"]), + ("v6k", &["v6"]), + ("v6t2", &["v6k", "thumb2"]), + ("v7", &["v6t2"]), + ("v8", &["v7"]), + ("vfp3", &["vfp2", "d32"]), + ("vfp4", &["vfp3"]), + // Aarch64 + ("aes", &["neon"]), + ("dotprod", &["neon"]), + ("dpb2", &["dpb"]), + ("f32mm", &["sve"]), + ("f64mm", &["sve"]), + ("fcma", &["neon"]), + ("fhm", &["fp16"]), + ("fp16", &["neon"]), + ("fp8", &["faminmax", "lut", "bf16"]), + ("fp8dot2", &["fp8dot4"]), + ("fp8dot4", &["fp8fma"]), + ("fp8fma", &["fp8"]), + ("jsconv", &["neon"]), + ("lse128", &["lse"]), + ("rcpc2", &["rcpc"]), + ("rcpc3", &["rcpc2"]), + ("rdm", &["neon"]), + ("sha2", &["neon"]), + ("sha3", &["sha2"]), + ("sm4", &["neon"]), + ("sme", &["bf16"]), + ("sme-b16b16", &["bf16", "sme2", "sve-b16b16"]), + ("sme-f16f16", &["sme2"]), + ("sme-f64f64", &["sme"]), + ("sme-f8f16", &["sme-f8f32"]), + ("sme-f8f32", &["sme2", "fp8"]), + ("sme-fa64", &["sme", "sve2"]), + ("sme-i16i64", &["sme"]), + ("sme2", &["sme"]), + ("sme2p1", &["sme2"]), + ("ssve-fp8dot2", &["ssve-fp8dot4"]), + ("ssve-fp8dot4", &["ssve-fp8fma"]), + ("ssve-fp8fma", &["sme2", "fp8"]), + ("sve", &["neon"]), + ("sve-b16b16", &["bf16"]), + ("sve2", &["sve"]), + ("sve2-aes", &["sve2", "aes"]), + ("sve2-bitperm", &["sve2"]), + ("sve2-sha3", &["sve2", "sha3"]), + ("sve2-sm4", &["sve2", "sm4"]), + ("sve2p1", &["sve2"]), + ("v8.1a", &["crc", "lse", "rdm", "pan", "lor", "vh"]), + ("v8.2a", &["v8.1a", "ras", "dpb"]), + ("v8.3a", &["v8.2a", "rcpc", "paca", "pacg", "jsconv"]), + ("v8.4a", &["v8.3a", "dotprod", "dit", "flagm"]), + ("v8.5a", &["v8.4a", "ssbs", "sb", "dpb2", "bti"]), + ("v8.6a", &["v8.5a", "bf16", "i8mm"]), + ("v8.7a", &["v8.6a", "wfxt"]), + ("v8.8a", &["v8.7a", "hbc", "mops"]), + ("v8.9a", &["v8.8a", "cssc"]), + ("v9.1a", &["v9a", "v8.6a"]), + ("v9.2a", &["v9.1a", "v8.7a"]), + ("v9.3a", &["v9.2a", "v8.8a"]), + ("v9.4a", &["v9.3a", "v8.9a"]), + ("v9.5a", &["v9.4a"]), + ("v9a", &["v8.5a", "sve2"]), + // x86 + ("aes", &["sse2"]), + ("amx-bf16", &["amx-tile"]), + ("amx-complex", &["amx-tile"]), + ("amx-fp16", &["amx-tile"]), + ("amx-int8", &["amx-tile"]), + ("avx", &["sse4.2"]), + ("avx2", &["avx"]), + ("avx512bf16", &["avx512bw"]), + ("avx512bitalg", &["avx512bw"]), + ("avx512bw", &["avx512f"]), + ("avx512cd", &["avx512f"]), + ("avx512dq", &["avx512f"]), + ("avx512f", &["avx2", "fma", "f16c"]), + ("avx512fp16", &["avx512bw", "avx512vl", "avx512dq"]), + ("avx512ifma", &["avx512f"]), + ("avx512vbmi", &["avx512bw"]), + ("avx512vbmi2", &["avx512bw"]), + ("avx512vl", &["avx512f"]), + ("avx512vnni", &["avx512f"]), + ("avx512vp2intersect", &["avx512f"]), + ("avx512vpopcntdq", &["avx512f"]), + ("avxifma", &["avx2"]), + ("avxneconvert", &["avx2"]), + ("avxvnni", &["avx2"]), + ("avxvnniint16", &["avx2"]), + ("avxvnniint8", &["avx2"]), + ("f16c", &["avx"]), + ("fma", &["avx"]), + ("gfni", &["sse2"]), + ("kl", &["sse2"]), + ("pclmulqdq", &["sse2"]), + ("sha", &["sse2"]), + ("sha512", &["avx2"]), + ("sm3", &["avx"]), + ("sm4", &["avx2"]), + ("sse2", &["sse"]), + ("sse3", &["sse2"]), + ("sse4.1", &["ssse3"]), + ("sse4.2", &["sse4.1"]), + ("sse4a", &["sse3"]), + ("ssse3", &["sse3"]), + ("vaes", &["avx2", "aes"]), + ("vpclmulqdq", &["avx", "pclmulqdq"]), + ("widekl", &["kl"]), + ("xop", &[/*"fma4", */ "avx", "sse4a"]), + ("xsavec", &["xsave"]), + ("xsaveopt", &["xsave"]), + ("xsaves", &["xsave"]), + // Hexagon + ("hvx-length128b", &["hvx"]), + // PowerPC + ("power10-vector", &["power9-vector"]), + ("power8-altivec", &["altivec"]), + ("power8-crypto", &["power8-altivec"]), + ("power8-vector", &["vsx", "power8-altivec"]), + ("power9-altivec", &["power8-altivec"]), + ("power9-vector", &["power8-vector", "power9-altivec"]), + ("vsx", &["altivec"]), + // MIPS + // RISC-V + ("a", &["zaamo", "zalrsc"]), + ("d", &["f"]), + ("zabha", &["zaamo"]), + ("zdinx", &["zfinx"]), + ("zfh", &["zfhmin"]), + ("zfhmin", &["f"]), + ("zhinx", &["zhinxmin"]), + ("zhinxmin", &["zfinx"]), + ("zk", &["zkn", "zkr", "zkt"]), + ("zkn", &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]), + ("zks", &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]), + // WASM + ("relaxed-simd", &["simd128"]), + // BPF + ("alu32", &[]), + // CSKY + ("10e60", &["7e10"]), + ("2e3", &["e2"]), + ("3e3r2", &["3e3r1", "doloop"]), + ("3e3r3", &["doloop"]), + ("3e7", &["2e3"]), + ("7e10", &["3e7"]), + ("e1", &["elrw"]), + ("e2", &["e2"]), + ("mp", &["2e3"]), + ("mp1e2", &["3e7"]), + // LoongArch + ("d", &["f"]), + ("lasx", &["lsx"]), + ("lsx", &["d"]), + // IBM Z + ("nnp-assist", &["vector"]), + ("vector-enhancements-1", &["vector"]), + ("vector-enhancements-2", &["vector-enhancements-1"]), + ("vector-packed-decimal", &["vector"]), + ("vector-packed-decimal-enhancement", &["vector-packed-decimal"]), + ("vector-packed-decimal-enhancement-2", &["vector-packed-decimal-enhancement"]), + // SPARC + // m68k + ("isa-68010", &["isa-68000"]), + ("isa-68020", &["isa-68010"]), + ("isa-68030", &["isa-68020"]), + ("isa-68040", &["isa-68030", "isa-68882"]), + ("isa-68060", &["isa-68040"]), + ("isa-68882", &["isa-68881"]), +]; diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs index c131e97bc4..89d89fe223 100644 --- a/crates/hir-ty/src/utils.rs +++ b/crates/hir-ty/src/utils.rs @@ -9,18 +9,16 @@ use chalk_ir::{ DebruijnIndex, }; use hir_def::{ - attr::Attrs, db::DefDatabase, generics::{WherePredicate, WherePredicateTypeTarget}, lang_item::LangItem, resolver::{HasResolver, TypeNs}, - tt, type_ref::{TraitBoundModifier, TypeRef}, EnumId, EnumVariantId, FunctionId, Lookup, OpaqueInternableThing, TraitId, TypeAliasId, TypeOrConstParamId, }; use hir_expand::name::Name; -use intern::{sym, Symbol}; +use intern::sym; use rustc_abi::TargetDataLayout; use rustc_hash::FxHashSet; use smallvec::{smallvec, SmallVec}; @@ -32,8 +30,8 @@ use crate::{ db::HirDatabase, layout::{Layout, TagEncoding}, mir::pad16, - ChalkTraitId, Const, ConstScalar, GenericArg, Interner, Substitution, TraitRef, TraitRefExt, - Ty, WhereClause, + ChalkTraitId, Const, ConstScalar, GenericArg, Interner, Substitution, TargetFeatures, TraitRef, + TraitRefExt, Ty, WhereClause, }; pub(crate) fn fn_traits( @@ -267,32 +265,6 @@ impl<'a> ClosureSubst<'a> { } } -#[derive(Debug, Default)] -pub struct TargetFeatures { - enabled: FxHashSet, -} - -impl TargetFeatures { - pub fn from_attrs(attrs: &Attrs) -> Self { - let enabled = attrs - .by_key(&sym::target_feature) - .tt_values() - .filter_map(|tt| { - match tt.token_trees().flat_tokens() { - [ - tt::TokenTree::Leaf(tt::Leaf::Ident(enable_ident)), - tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '=', .. })), - tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { kind: tt::LitKind::Str, symbol: features, .. })), - ] if enable_ident.sym == sym::enable => Some(features), - _ => None, - } - }) - .flat_map(|features| features.as_str().split(',').map(Symbol::intern)) - .collect(); - Self { enabled } - } -} - #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Unsafety { Safe, @@ -314,7 +286,8 @@ pub fn is_fn_unsafe_to_call( if data.has_target_feature() { // RFC 2396 . - let callee_target_features = TargetFeatures::from_attrs(&db.attrs(func.into())); + let callee_target_features = + TargetFeatures::from_attrs_no_implications(&db.attrs(func.into())); if !caller_target_features.enabled.is_superset(&callee_target_features.enabled) { return Unsafety::Unsafe; } diff --git a/crates/ide-diagnostics/src/handlers/missing_unsafe.rs b/crates/ide-diagnostics/src/handlers/missing_unsafe.rs index 323a5723d4..040aa2949a 100644 --- a/crates/ide-diagnostics/src/handlers/missing_unsafe.rs +++ b/crates/ide-diagnostics/src/handlers/missing_unsafe.rs @@ -854,7 +854,7 @@ fn main() { #[target_feature(enable = "avx")] fn foo() {} -#[target_feature(enable = "avx,avx2")] +#[target_feature(enable = "avx2")] fn bar() { foo(); } From 7c5524c8548392a4d45b22800b89335211e69621 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 25 Feb 2025 05:00:49 +0200 Subject: [PATCH 16/47] Disable typos checker for the target feature names --- .typos.toml | 2 ++ crates/hir-ty/src/target_feature.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.typos.toml b/.typos.toml index 0f2f9b1b27..e938bddd4b 100644 --- a/.typos.toml +++ b/.typos.toml @@ -18,6 +18,8 @@ extend-ignore-re = [ "INOUT", "optin", "=Pn", + # ignore `// spellchecker:off` until `// spellchecker:on` + "(?s)(#|//)\\s*spellchecker:off.*?\\n\\s*(#|//)\\s*spellchecker:on", ] [default.extend-words] diff --git a/crates/hir-ty/src/target_feature.rs b/crates/hir-ty/src/target_feature.rs index 17a1b8efee..fe9416c6cf 100644 --- a/crates/hir-ty/src/target_feature.rs +++ b/crates/hir-ty/src/target_feature.rs @@ -77,6 +77,7 @@ static TARGET_FEATURE_IMPLICATIONS: LazyLock>> = result }); +// spellchecker:off const TARGET_FEATURE_IMPLICATIONS_RAW: &[(&str, &[&str])] = &[ // Arm ("aes", &["neon"]), @@ -257,3 +258,4 @@ const TARGET_FEATURE_IMPLICATIONS_RAW: &[(&str, &[&str])] = &[ ("isa-68060", &["isa-68040"]), ("isa-68882", &["isa-68881"]), ]; +// spellchecker:on From b4f2d62952f768639812b160841cb52000946b6d Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Fri, 10 Jan 2025 14:33:21 -0600 Subject: [PATCH 17/47] internal: Improve reporting of intersecting changes --- crates/syntax/src/syntax_editor.rs | 59 +++++++++++++ crates/syntax/src/syntax_editor/edit_algo.rs | 87 ++++++++++++++++++-- crates/test-utils/src/lib.rs | 4 +- 3 files changed, 142 insertions(+), 8 deletions(-) diff --git a/crates/syntax/src/syntax_editor.rs b/crates/syntax/src/syntax_editor.rs index b82181ae13..48c160b9a9 100644 --- a/crates/syntax/src/syntax_editor.rs +++ b/crates/syntax/src/syntax_editor.rs @@ -5,6 +5,7 @@ //! [`SyntaxEditor`]: https://github.com/dotnet/roslyn/blob/43b0b05cc4f492fd5de00f6f6717409091df8daa/src/Workspaces/Core/Portable/Editing/SyntaxEditor.cs use std::{ + fmt, num::NonZeroU32, ops::RangeInclusive, sync::atomic::{AtomicU32, Ordering}, @@ -282,6 +283,64 @@ enum ChangeKind { Replace, } +impl fmt::Display for Change { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Change::Insert(position, node_or_token) => { + let parent = position.parent(); + let mut parent_str = parent.to_string(); + let target_range = self.target_range().start() - parent.text_range().start(); + + parent_str.insert_str( + target_range.into(), + &format!("\x1b[42m{node_or_token}\x1b[0m\x1b[K"), + ); + f.write_str(&parent_str) + } + Change::InsertAll(position, vec) => { + let parent = position.parent(); + let mut parent_str = parent.to_string(); + let target_range = self.target_range().start() - parent.text_range().start(); + let insertion: String = vec.iter().map(|it| it.to_string()).collect(); + + parent_str + .insert_str(target_range.into(), &format!("\x1b[42m{insertion}\x1b[0m\x1b[K")); + f.write_str(&parent_str) + } + Change::Replace(old, new) => { + if let Some(new) = new { + write!(f, "\x1b[41m{old}\x1b[42m{new}\x1b[0m\x1b[K") + } else { + write!(f, "\x1b[41m{old}\x1b[0m\x1b[K") + } + } + Change::ReplaceWithMany(old, vec) => { + let new: String = vec.iter().map(|it| it.to_string()).collect(); + write!(f, "\x1b[41m{old}\x1b[42m{new}\x1b[0m\x1b[K") + } + Change::ReplaceAll(range, vec) => { + let parent = range.start().parent().unwrap(); + let parent_str = parent.to_string(); + let pre_range = + TextRange::new(parent.text_range().start(), range.start().text_range().start()); + let old_range = TextRange::new( + range.start().text_range().start(), + range.end().text_range().end(), + ); + let post_range = + TextRange::new(range.end().text_range().end(), parent.text_range().end()); + + let pre_str = &parent_str[pre_range - parent.text_range().start()]; + let old_str = &parent_str[old_range - parent.text_range().start()]; + let post_str = &parent_str[post_range - parent.text_range().start()]; + let new: String = vec.iter().map(|it| it.to_string()).collect(); + + write!(f, "{pre_str}\x1b[41m{old_str}\x1b[42m{new}\x1b[0m\x1b[K{post_str}") + } + } + } +} + /// Utility trait to allow calling syntax editor functions with references or owned /// nodes. Do not use outside of this module. pub trait Element { diff --git a/crates/syntax/src/syntax_editor/edit_algo.rs b/crates/syntax/src/syntax_editor/edit_algo.rs index 57ecbe5701..d6d903715d 100644 --- a/crates/syntax/src/syntax_editor/edit_algo.rs +++ b/crates/syntax/src/syntax_editor/edit_algo.rs @@ -1,9 +1,14 @@ //! Implementation of applying changes to a syntax tree. -use std::{cmp::Ordering, collections::VecDeque, ops::RangeInclusive}; +use std::{ + cmp::Ordering, + collections::VecDeque, + ops::{Range, RangeInclusive}, +}; use rowan::TextRange; use rustc_hash::FxHashMap; +use stdx::format_to; use crate::{ syntax_editor::{mapping::MissingMapping, Change, ChangeKind, PositionRepr}, @@ -76,11 +81,9 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { || (l.target_range().end() <= r.target_range().start()) }); - if stdx::never!( - !disjoint_replaces_ranges, - "some replace change ranges intersect: {:?}", - changes - ) { + if !disjoint_replaces_ranges { + report_intersecting_changes(&changes, get_node_depth, &root); + return SyntaxEdit { old_root: root.clone(), new_root: root, @@ -293,6 +296,78 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { } } +fn report_intersecting_changes( + changes: &[Change], + mut get_node_depth: impl FnMut(rowan::SyntaxNode) -> usize, + root: &rowan::SyntaxNode, +) { + let intersecting_changes = changes + .iter() + .zip(changes.iter().skip(1)) + .filter(|(l, r)| { + // We only care about checking for disjoint replace ranges. + matches!( + (l.change_kind(), r.change_kind()), + ( + ChangeKind::Replace | ChangeKind::ReplaceRange, + ChangeKind::Replace | ChangeKind::ReplaceRange + ) + ) + }) + .filter(|(l, r)| { + get_node_depth(l.target_parent()) == get_node_depth(r.target_parent()) + && (l.target_range().end() > r.target_range().start()) + }); + + let mut error_msg = String::from("some replace change ranges intersect!\n"); + + let parent_str = root.to_string(); + + for (l, r) in intersecting_changes { + let mut highlighted_str = parent_str.clone(); + let l_range = l.target_range(); + let r_range = r.target_range(); + + let i_range = l_range.intersect(r_range).unwrap(); + let i_str = format!("\x1b[46m{}", &parent_str[i_range]); + + let pre_range: Range = l_range.start().into()..i_range.start().into(); + let pre_str = format!("\x1b[44m{}", &parent_str[pre_range]); + + let (highlight_range, highlight_str) = if l_range == r_range { + format_to!(error_msg, "\x1b[46mleft change:\x1b[0m {l:?} {l}\n"); + format_to!(error_msg, "\x1b[46mequals\x1b[0m\n"); + format_to!(error_msg, "\x1b[46mright change:\x1b[0m {r:?} {r}\n"); + let i_highlighted = format!("{i_str}\x1b[0m\x1b[K"); + let total_range: Range = i_range.into(); + (total_range, i_highlighted) + } else { + format_to!(error_msg, "\x1b[44mleft change:\x1b[0m {l:?} {l}\n"); + let range_end = if l_range.contains_range(r_range) { + format_to!(error_msg, "\x1b[46mcovers\x1b[0m\n"); + format_to!(error_msg, "\x1b[46mright change:\x1b[0m {r:?} {r}\n"); + l_range.end() + } else { + format_to!(error_msg, "\x1b[46mintersects\x1b[0m\n"); + format_to!(error_msg, "\x1b[42mright change:\x1b[0m {r:?} {r}\n"); + r_range.end() + }; + + let post_range: Range = i_range.end().into()..range_end.into(); + + let post_str = format!("\x1b[42m{}", &parent_str[post_range]); + let result = format!("{pre_str}{i_str}{post_str}\x1b[0m\x1b[K"); + let total_range: Range = l_range.start().into()..range_end.into(); + (total_range, result) + }; + highlighted_str.replace_range(highlight_range, &highlight_str); + + format_to!(error_msg, "{highlighted_str}\n"); + } + + stdx::always!(false, "{}", error_msg); +} + fn to_owning_node(element: &SyntaxElement) -> SyntaxNode { match element { SyntaxElement::Node(node) => node.clone(), diff --git a/crates/test-utils/src/lib.rs b/crates/test-utils/src/lib.rs index e7279fa1f6..d3afac8501 100644 --- a/crates/test-utils/src/lib.rs +++ b/crates/test-utils/src/lib.rs @@ -421,8 +421,8 @@ pub fn format_diff(chunks: Vec>) -> String { for chunk in chunks { let formatted = match chunk { dissimilar::Chunk::Equal(text) => text.into(), - dissimilar::Chunk::Delete(text) => format!("\x1b[41m{text}\x1b[0m"), - dissimilar::Chunk::Insert(text) => format!("\x1b[42m{text}\x1b[0m"), + dissimilar::Chunk::Delete(text) => format!("\x1b[41m{text}\x1b[0m\x1b[K"), + dissimilar::Chunk::Insert(text) => format!("\x1b[42m{text}\x1b[0m\x1b[K"), }; buf.push_str(&formatted); } From daca6b88c4ed76b26c420cf0099da62f3b080a9f Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:34:37 -0600 Subject: [PATCH 18/47] internal: Migrate `remove_mut` assist to `SyntaxEditor` --- crates/ide-assists/src/handlers/remove_mut.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/crates/ide-assists/src/handlers/remove_mut.rs b/crates/ide-assists/src/handlers/remove_mut.rs index 0b299e8349..43740a5a6d 100644 --- a/crates/ide-assists/src/handlers/remove_mut.rs +++ b/crates/ide-assists/src/handlers/remove_mut.rs @@ -1,4 +1,4 @@ -use syntax::{SyntaxKind, TextRange, T}; +use syntax::{SyntaxKind, T}; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -19,11 +19,6 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; // ``` pub(crate) fn remove_mut(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let mut_token = ctx.find_token_syntax_at_offset(T![mut])?; - let delete_from = mut_token.text_range().start(); - let delete_to = match mut_token.next_token() { - Some(it) if it.kind() == SyntaxKind::WHITESPACE => it.text_range().end(), - _ => mut_token.text_range().end(), - }; let target = mut_token.text_range(); acc.add( @@ -31,7 +26,13 @@ pub(crate) fn remove_mut(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( "Remove `mut` keyword", target, |builder| { - builder.delete(TextRange::new(delete_from, delete_to)); + let mut editor = builder.make_editor(&mut_token.parent().unwrap()); + match mut_token.next_token() { + Some(it) if it.kind() == SyntaxKind::WHITESPACE => editor.delete(it), + _ => (), + } + editor.delete(mut_token); + builder.add_file_edits(ctx.file_id(), editor); }, ) } From 6dda2e81c6dcc243afdba87c02265e2fede5eaad Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Wed, 4 Dec 2024 19:51:15 -0500 Subject: [PATCH 19/47] internal: Migrate `remove_parentheses` assist to `SyntaxEditor` --- .../src/handlers/remove_parentheses.rs | 17 +++++++++++++---- docs/book/src/assists_generated.md | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/crates/ide-assists/src/handlers/remove_parentheses.rs b/crates/ide-assists/src/handlers/remove_parentheses.rs index f74fc26112..143d5e5424 100644 --- a/crates/ide-assists/src/handlers/remove_parentheses.rs +++ b/crates/ide-assists/src/handlers/remove_parentheses.rs @@ -1,4 +1,8 @@ -use syntax::{ast, AstNode, SyntaxKind, T}; +use syntax::{ + ast::{self, syntax_factory::SyntaxFactory}, + syntax_editor::Position, + AstNode, SyntaxKind, T, +}; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -40,6 +44,7 @@ pub(crate) fn remove_parentheses(acc: &mut Assists, ctx: &AssistContext<'_>) -> "Remove redundant parentheses", target, |builder| { + let mut editor = builder.make_editor(parens.syntax()); let prev_token = parens.syntax().first_token().and_then(|it| it.prev_token()); let need_to_add_ws = match prev_token { Some(it) => { @@ -48,9 +53,13 @@ pub(crate) fn remove_parentheses(acc: &mut Assists, ctx: &AssistContext<'_>) -> } None => false, }; - let expr = if need_to_add_ws { format!(" {expr}") } else { expr.to_string() }; - - builder.replace(parens.syntax().text_range(), expr) + if need_to_add_ws { + let make = SyntaxFactory::new(); + editor.insert(Position::before(parens.syntax()), make.whitespace(" ")); + editor.add_mappings(make.finish_with_mappings()); + } + editor.replace(parens.syntax(), expr.syntax()); + builder.add_file_edits(ctx.file_id(), editor); }, ) } diff --git a/docs/book/src/assists_generated.md b/docs/book/src/assists_generated.md index 52da98dbd2..a05536e2d2 100644 --- a/docs/book/src/assists_generated.md +++ b/docs/book/src/assists_generated.md @@ -2974,7 +2974,7 @@ impl Walrus { ### `remove_parentheses` -**Source:** [remove_parentheses.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_parentheses.rs#L5) +**Source:** [remove_parentheses.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_parentheses.rs#L9) Removes redundant parentheses. From 93c9f068704197791ee0e92c8863ba03673021f0 Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Wed, 4 Dec 2024 19:53:22 -0500 Subject: [PATCH 20/47] fix: Properly handle removals in `SyntaxEditor` --- crates/syntax/src/syntax_editor/edit_algo.rs | 24 +++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/crates/syntax/src/syntax_editor/edit_algo.rs b/crates/syntax/src/syntax_editor/edit_algo.rs index d6d903715d..fa51fb6eef 100644 --- a/crates/syntax/src/syntax_editor/edit_algo.rs +++ b/crates/syntax/src/syntax_editor/edit_algo.rs @@ -102,6 +102,7 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { let mut changed_ancestors: VecDeque = VecDeque::new(); let mut dependent_changes = vec![]; let mut independent_changes = vec![]; + let mut outdated_changes = vec![]; for (change_index, change) in changes.iter().enumerate() { // Check if this change is dependent on another change (i.e. it's contained within another range) @@ -116,10 +117,14 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { // FIXME: Resolve changes that depend on a range of elements let ancestor = &changed_ancestors[index]; - dependent_changes.push(DependentChange { - parent: ancestor.change_index as u32, - child: change_index as u32, - }); + if let Change::Replace(_, None) = changes[ancestor.change_index] { + outdated_changes.push(change_index as u32); + } else { + dependent_changes.push(DependentChange { + parent: ancestor.change_index as u32, + child: change_index as u32, + }); + } } else { // This change is independent of any other change @@ -195,8 +200,9 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { Change::Replace(target, Some(new_target)) => { (to_owning_node(target), to_owning_node(new_target)) } - // Silently drop outdated change - Change::Replace(_, None) => continue, + Change::Replace(_, None) => { + unreachable!("deletions should not generate dependent changes") + } Change::ReplaceAll(_, _) | Change::ReplaceWithMany(_, _) => { unimplemented!("cannot resolve changes that depend on replacing many elements") } @@ -234,6 +240,12 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { } } + // We reverse here since we pushed to this in ascending order, + // and we want to remove elements in descending order + for idx in outdated_changes.into_iter().rev() { + changes.remove(idx as usize); + } + // Apply changes let mut root = tree_mutator.mutable_clone; From f155aef64d10d9ce36135588b1c1ee92b8111480 Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Wed, 4 Dec 2024 19:55:16 -0500 Subject: [PATCH 21/47] internal: Migrate `remove_unused_param` assist to `SyntaxEditor` --- .../src/handlers/remove_unused_param.rs | 62 ++++++++++++++----- crates/syntax/src/algo.rs | 24 ++++++- docs/book/src/assists_generated.md | 2 +- 3 files changed, 71 insertions(+), 17 deletions(-) diff --git a/crates/ide-assists/src/handlers/remove_unused_param.rs b/crates/ide-assists/src/handlers/remove_unused_param.rs index 75120768da..5ddb17b207 100644 --- a/crates/ide-assists/src/handlers/remove_unused_param.rs +++ b/crates/ide-assists/src/handlers/remove_unused_param.rs @@ -1,8 +1,9 @@ use ide_db::{defs::Definition, search::FileReference, EditionedFileId}; use syntax::{ - algo::find_node_at_range, + algo::{find_node_at_range, least_common_ancestor_element}, ast::{self, HasArgList}, - AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, T, + syntax_editor::Element, + AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, T, }; use SyntaxKind::WHITESPACE; @@ -74,15 +75,21 @@ pub(crate) fn remove_unused_param(acc: &mut Assists, ctx: &AssistContext<'_>) -> cov_mark::hit!(keep_used); return None; } + let parent = param.syntax().parent()?; acc.add( AssistId("remove_unused_param", AssistKind::Refactor), "Remove unused parameter", param.syntax().text_range(), |builder| { - builder.delete(range_to_remove(param.syntax())); + let mut editor = builder.make_editor(&parent); + let elements = elements_to_remove(param.syntax()); + for element in elements { + editor.delete(element); + } for (file_id, references) in fn_def.usages(&ctx.sema).all() { process_usages(ctx, builder, file_id, references, param_position, is_self_present); } + builder.add_file_edits(ctx.file_id(), editor); }, ) } @@ -96,20 +103,24 @@ fn process_usages( is_self_present: bool, ) { let source_file = ctx.sema.parse(file_id); - builder.edit_file(file_id); let possible_ranges = references .into_iter() .filter_map(|usage| process_usage(&source_file, usage, arg_to_remove, is_self_present)); - let mut ranges_to_delete: Vec = vec![]; - for range in possible_ranges { - if !ranges_to_delete.iter().any(|it| it.contains_range(range)) { - ranges_to_delete.push(range) + for element_range in possible_ranges { + let Some(SyntaxElement::Node(parent)) = element_range + .iter() + .cloned() + .reduce(|a, b| least_common_ancestor_element(&a, &b).unwrap().syntax_element()) + else { + continue; + }; + let mut editor = builder.make_editor(&parent); + for element in element_range { + editor.delete(element); } - } - for range in ranges_to_delete { - builder.delete(range) + builder.add_file_edits(file_id, editor); } } @@ -118,7 +129,7 @@ fn process_usage( FileReference { range, .. }: FileReference, mut arg_to_remove: usize, is_self_present: bool, -) -> Option { +) -> Option> { let call_expr_opt: Option = find_node_at_range(source_file.syntax(), range); if let Some(call_expr) = call_expr_opt { let call_expr_range = call_expr.expr()?.syntax().text_range(); @@ -127,7 +138,7 @@ fn process_usage( } let arg = call_expr.arg_list()?.args().nth(arg_to_remove)?; - return Some(range_to_remove(arg.syntax())); + return Some(elements_to_remove(arg.syntax())); } let method_call_expr_opt: Option = @@ -143,7 +154,7 @@ fn process_usage( } let arg = method_call_expr.arg_list()?.args().nth(arg_to_remove)?; - return Some(range_to_remove(arg.syntax())); + return Some(elements_to_remove(arg.syntax())); } None @@ -174,6 +185,29 @@ pub(crate) fn range_to_remove(node: &SyntaxNode) -> TextRange { } } +pub(crate) fn elements_to_remove(node: &SyntaxNode) -> Vec { + let up_to_comma = next_prev().find_map(|dir| { + node.siblings_with_tokens(dir) + .filter_map(|it| it.into_token()) + .find(|it| it.kind() == T![,]) + .map(|it| (dir, it)) + }); + if let Some((dir, token)) = up_to_comma { + let after = token.siblings_with_tokens(dir).nth(1).unwrap(); + let mut result: Vec<_> = + node.siblings_with_tokens(dir).take_while(|it| it != &after).collect(); + if node.next_sibling().is_some() { + result.extend( + token.siblings_with_tokens(dir).skip(1).take_while(|it| it.kind() == WHITESPACE), + ); + } + + result + } else { + vec![node.syntax_element()] + } +} + #[cfg(test)] mod tests { use crate::tests::{check_assist, check_assist_not_applicable}; diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs index 2acb215831..3b85b137aa 100644 --- a/crates/syntax/src/algo.rs +++ b/crates/syntax/src/algo.rs @@ -3,8 +3,8 @@ use itertools::Itertools; use crate::{ - AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, - TextSize, + syntax_editor::Element, AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, + SyntaxToken, TextRange, TextSize, }; /// Returns ancestors of the node at the offset, sorted by length. This should @@ -89,6 +89,26 @@ pub fn least_common_ancestor(u: &SyntaxNode, v: &SyntaxNode) -> Option Option { + let u = u.syntax_element(); + let v = v.syntax_element(); + if u == v { + return match u { + NodeOrToken::Node(node) => Some(node), + NodeOrToken::Token(token) => token.parent(), + }; + } + + let u_depth = u.ancestors().count(); + let v_depth = v.ancestors().count(); + let keep = u_depth.min(v_depth); + + let u_candidates = u.ancestors().skip(u_depth - keep); + let v_candidates = v.ancestors().skip(v_depth - keep); + let (res, _) = u_candidates.zip(v_candidates).find(|(x, y)| x == y)?; + Some(res) +} + pub fn neighbor(me: &T, direction: Direction) -> Option { me.syntax().siblings(direction).skip(1).find_map(T::cast) } diff --git a/docs/book/src/assists_generated.md b/docs/book/src/assists_generated.md index a05536e2d2..2d233ca62a 100644 --- a/docs/book/src/assists_generated.md +++ b/docs/book/src/assists_generated.md @@ -3015,7 +3015,7 @@ mod foo { ### `remove_unused_param` -**Source:** [remove_unused_param.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_unused_param.rs#L15) +**Source:** [remove_unused_param.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_unused_param.rs#L16) Removes unused function parameter. From e039ae794daaddd5babef7aed0894a30dbccf119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Wed, 26 Feb 2025 12:35:48 +0200 Subject: [PATCH 22/47] Use cargo zigbuild for releases --- .github/workflows/release.yaml | 55 ++++++++++++++++------------------ xtask/src/dist.rs | 29 ++++++++++++------ xtask/src/flags.rs | 3 ++ xtask/src/release.rs | 2 +- 4 files changed, 49 insertions(+), 40 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 3687c84bea..9ab4a0b9d2 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -17,8 +17,8 @@ env: RUSTUP_MAX_RETRIES: 10 FETCH_DEPTH: 0 # pull in the tags for the version string MACOSX_DEPLOYMENT_TARGET: 13.0 - CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc - CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc + ZIG_VERSION: 0.13.0 + ZIGBUILD_VERSION: 0.19.8 jobs: dist: @@ -36,13 +36,15 @@ jobs: code-target: win32-arm64 - os: ubuntu-latest target: x86_64-unknown-linux-gnu + zig_target: x86_64-unknown-linux-gnu.2.28 code-target: linux-x64 - container: rockylinux:8 - - os: ubuntu-22.04 + - os: ubuntu-latest target: aarch64-unknown-linux-gnu + zig_target: aarch64-unknown-linux-gnu.2.28 code-target: linux-arm64 - - os: ubuntu-22.04 + - os: ubuntu-latest target: arm-unknown-linux-gnueabihf + zig_target: arm-unknown-linux-gnueabihf.2.28 code-target: linux-armhf - os: macos-13 target: x86_64-apple-darwin @@ -64,40 +66,33 @@ jobs: with: fetch-depth: ${{ env.FETCH_DEPTH }} - - name: Install toolchain dependencies - if: matrix.container == 'rockylinux:8' - shell: bash - run: | - dnf install -y gcc - curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL "https://sh.rustup.rs" | sh -s -- --profile minimal --default-toolchain none -y - echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> $GITHUB_PATH + - name: Install Node.js toolchain + uses: actions/setup-node@v4 + with: + node-version: 20 - name: Install Rust toolchain run: | rustup update --no-self-update stable - rustup target add ${{ matrix.target }} rustup component add rust-src + rustup target add ${{ matrix.target }} - - name: Install Node.js - uses: actions/setup-node@v4 - with: - node-version: 18 + - name: Install Zig toolchain + if: ${{ matrix.zig_target }} + run: | + which cargo + curl -L "https://ziglang.org/download/${ZIG_VERSION}/zig-linux-$(uname -m)-${ZIG_VERSION}.tar.xz" | sudo tar JxC /usr/local + sudo ln -s "/usr/local/zig-linux-$(uname -m)-${ZIG_VERSION}/zig" /usr/local/bin/zig + curl -L "https://github.com/rust-cross/cargo-zigbuild/releases/download/v${ZIGBUILD_VERSION}/cargo-zigbuild-v${ZIGBUILD_VERSION}.x86_64-unknown-linux-musl.tar.gz" | tar zxC ~/.cargo/bin - - name: Update apt repositories - if: matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'arm-unknown-linux-gnueabihf' - run: sudo apt-get update - - - name: Install AArch64 target toolchain - if: matrix.target == 'aarch64-unknown-linux-gnu' - run: sudo apt-get install gcc-aarch64-linux-gnu - - - name: Install ARM target toolchain - if: matrix.target == 'arm-unknown-linux-gnueabihf' - run: sudo apt-get install gcc-arm-linux-gnueabihf - - - name: Dist + - name: Dist (plain) + if: ${{ !matrix.zig_target }} run: cargo xtask dist --client-patch-version ${{ github.run_number }} + - name: Dist (using zigbuild) + if: ${{ matrix.zig_target }} + run: RA_TARGET=${{ matrix.zig_target}} cargo xtask dist --client-patch-version ${{ github.run_number }} --zig + - run: npm ci working-directory: editors/code diff --git a/xtask/src/dist.rs b/xtask/src/dist.rs index c6a0be8aeb..99483f4a5d 100644 --- a/xtask/src/dist.rs +++ b/xtask/src/dist.rs @@ -38,11 +38,11 @@ impl flags::Dist { // A hack to make VS Code prefer nightly over stable. format!("{VERSION_NIGHTLY}.{patch_version}") }; - dist_server(sh, &format!("{version}-standalone"), &target, allocator)?; + dist_server(sh, &format!("{version}-standalone"), &target, allocator, self.zig)?; let release_tag = if stable { date_iso(sh)? } else { "nightly".to_owned() }; dist_client(sh, &version, &release_tag, &target)?; } else { - dist_server(sh, "0.0.0-standalone", &target, allocator)?; + dist_server(sh, "0.0.0-standalone", &target, allocator, self.zig)?; } Ok(()) } @@ -83,6 +83,7 @@ fn dist_server( release: &str, target: &Target, allocator: Malloc, + zig: bool, ) -> anyhow::Result<()> { let _e = sh.push_env("CFG_RELEASE", release); let _e = sh.push_env("CARGO_PROFILE_RELEASE_LTO", "thin"); @@ -92,13 +93,14 @@ fn dist_server( // * on Linux, this blows up the binary size from 8MB to 43MB, which is unreasonable. // let _e = sh.push_env("CARGO_PROFILE_RELEASE_DEBUG", "1"); - if target.name.contains("-linux-") { - env::set_var("CC", "clang"); - } - - let target_name = &target.name; + let linux_target = target.is_linux(); + let target_name = match &target.libc_suffix { + Some(libc_suffix) if zig => format!("{}.{libc_suffix}", target.name), + _ => target.name.to_owned(), + }; let features = allocator.to_features(); - cmd!(sh, "cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --target {target_name} {features...} --release").run()?; + let command = if linux_target && zig { "zigbuild" } else { "build" }; + cmd!(sh, "cargo {command} --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --target {target_name} {features...} --release").run()?; let dst = Path::new("dist").join(&target.artifact_name); if target_name.contains("-windows-") { @@ -156,6 +158,7 @@ fn zip(src_path: &Path, symbols_path: Option<&PathBuf>, dest_path: &Path) -> any struct Target { name: String, + libc_suffix: Option, server_path: PathBuf, symbols_path: Option, artifact_name: String, @@ -177,6 +180,10 @@ impl Target { } } }; + let (name, libc_suffix) = match name.split_once('.') { + Some((l, r)) => (l.to_owned(), Some(r.to_owned())), + None => (name, None), + }; let out_path = project_root.join("target").join(&name).join("release"); let (exe_suffix, symbols_path) = if name.contains("-windows-") { (".exe".into(), Some(out_path.join("rust_analyzer.pdb"))) @@ -185,7 +192,11 @@ impl Target { }; let server_path = out_path.join(format!("rust-analyzer{exe_suffix}")); let artifact_name = format!("rust-analyzer-{name}{exe_suffix}"); - Self { name, server_path, symbols_path, artifact_name } + Self { name, libc_suffix, server_path, symbols_path, artifact_name } + } + + fn is_linux(&self) -> bool { + self.name.contains("-linux-") } } diff --git a/xtask/src/flags.rs b/xtask/src/flags.rs index ebb9e71a4f..d03e2f8437 100644 --- a/xtask/src/flags.rs +++ b/xtask/src/flags.rs @@ -57,6 +57,8 @@ xflags::xflags! { /// Use jemalloc allocator for server optional --jemalloc optional --client-patch-version version: String + /// Use cargo-zigbuild + optional --zig } /// Read a changelog AsciiDoc file and update the GitHub Releases entry in Markdown. cmd publish-release-notes { @@ -144,6 +146,7 @@ pub struct Dist { pub mimalloc: bool, pub jemalloc: bool, pub client_patch_version: Option, + pub zig: bool, } #[derive(Debug)] diff --git a/xtask/src/release.rs b/xtask/src/release.rs index 8e56ce439c..9f65c40295 100644 --- a/xtask/src/release.rs +++ b/xtask/src/release.rs @@ -50,7 +50,7 @@ impl flags::Release { .unwrap_or_default(); let tags = cmd!(sh, "git tag --list").read()?; - let prev_tag = tags.lines().filter(|line| is_release_tag(line)).last().unwrap(); + let prev_tag = tags.lines().filter(|line| is_release_tag(line)).next_back().unwrap(); let contents = changelog::get_changelog(sh, changelog_n, &commit, prev_tag, &today)?; let path = changelog_dir.join(format!("{today}-changelog-{changelog_n}.adoc")); From ca5a35e97ffa2e1dd9e4e2eccaeee7287d2b15b0 Mon Sep 17 00:00:00 2001 From: David Richey Date: Tue, 4 Feb 2025 13:20:01 -0600 Subject: [PATCH 23/47] Allow rust-project.json to specify sysroot workspace --- crates/project-model/src/lib.rs | 1 + crates/project-model/src/project_json.rs | 12 +- crates/project-model/src/sysroot.rs | 11 +- crates/project-model/src/workspace.rs | 172 +++++++++++++++-------- 4 files changed, 135 insertions(+), 61 deletions(-) diff --git a/crates/project-model/src/lib.rs b/crates/project-model/src/lib.rs index 0c73447468..d7c00b9179 100644 --- a/crates/project-model/src/lib.rs +++ b/crates/project-model/src/lib.rs @@ -262,6 +262,7 @@ fn parse_cfg(s: &str) -> Result { #[derive(Clone, Debug, PartialEq, Eq)] pub enum RustSourceWorkspaceConfig { CargoMetadata(CargoMetadataConfig), + Json(ProjectJson), Stitched, } diff --git a/crates/project-model/src/project_json.rs b/crates/project-model/src/project_json.rs index 2f9612e3a4..0282a71464 100644 --- a/crates/project-model/src/project_json.rs +++ b/crates/project-model/src/project_json.rs @@ -65,6 +65,8 @@ pub struct ProjectJson { pub(crate) sysroot: Option, /// e.g. `path/to/sysroot/lib/rustlib/src/rust/library` pub(crate) sysroot_src: Option, + /// A nested project describing the layout of the sysroot + pub(crate) sysroot_project: Option>, project_root: AbsPathBuf, /// The path to the rust-project.json file. May be None if this /// data was generated by the discoverConfig command. @@ -91,9 +93,16 @@ impl ProjectJson { data: ProjectJsonData, ) -> ProjectJson { let absolutize_on_base = |p| base.absolutize(p); + let sysroot_src = data.sysroot_src.map(absolutize_on_base); + let sysroot_project = + data.sysroot_project.zip(sysroot_src.clone()).map(|(sysroot_data, sysroot_src)| { + Box::new(ProjectJson::new(None, &sysroot_src, *sysroot_data)) + }); + ProjectJson { sysroot: data.sysroot.map(absolutize_on_base), - sysroot_src: data.sysroot_src.map(absolutize_on_base), + sysroot_src, + sysroot_project, project_root: base.to_path_buf(), manifest, runnables: data.runnables.into_iter().map(Runnable::from).collect(), @@ -330,6 +339,7 @@ pub enum RunnableKind { pub struct ProjectJsonData { sysroot: Option, sysroot_src: Option, + sysroot_project: Option>, #[serde(default)] cfg_groups: FxHashMap, crates: Vec, diff --git a/crates/project-model/src/sysroot.rs b/crates/project-model/src/sysroot.rs index fb752fe47b..77332bfa13 100644 --- a/crates/project-model/src/sysroot.rs +++ b/crates/project-model/src/sysroot.rs @@ -21,7 +21,7 @@ use stdx::format_to; use toolchain::{probe_for_binary, Tool}; use crate::{ - cargo_workspace::CargoMetadataConfig, utf8_stdout, CargoWorkspace, ManifestPath, + cargo_workspace::CargoMetadataConfig, utf8_stdout, CargoWorkspace, ManifestPath, ProjectJson, RustSourceWorkspaceConfig, }; @@ -36,6 +36,7 @@ pub struct Sysroot { #[derive(Debug, Clone, Eq, PartialEq)] pub enum RustLibSrcWorkspace { Workspace(CargoWorkspace), + Json(ProjectJson), Stitched(Stitched), Empty, } @@ -114,6 +115,7 @@ impl Sysroot { pub fn is_rust_lib_src_empty(&self) -> bool { match &self.workspace { RustLibSrcWorkspace::Workspace(ws) => ws.packages().next().is_none(), + RustLibSrcWorkspace::Json(project_json) => project_json.n_crates() == 0, RustLibSrcWorkspace::Stitched(stitched) => stitched.crates.is_empty(), RustLibSrcWorkspace::Empty => true, } @@ -126,6 +128,7 @@ impl Sysroot { pub fn num_packages(&self) -> usize { match &self.workspace { RustLibSrcWorkspace::Workspace(ws) => ws.packages().count(), + RustLibSrcWorkspace::Json(project_json) => project_json.n_crates(), RustLibSrcWorkspace::Stitched(c) => c.crates().count(), RustLibSrcWorkspace::Empty => 0, } @@ -252,6 +255,8 @@ impl Sysroot { return Some(loaded); } } + } else if let RustSourceWorkspaceConfig::Json(project_json) = sysroot_source_config { + return Some(RustLibSrcWorkspace::Json(project_json.clone())); } tracing::debug!("Stitching sysroot library: {src_root}"); @@ -308,6 +313,10 @@ impl Sysroot { RustLibSrcWorkspace::Workspace(ws) => { ws.packages().any(|p| ws[p].name == "core") } + RustLibSrcWorkspace::Json(project_json) => project_json + .crates() + .filter_map(|(_, krate)| krate.display_name.clone()) + .any(|name| name.canonical_name().as_str() == "core"), RustLibSrcWorkspace::Stitched(stitched) => stitched.by_name("core").is_some(), RustLibSrcWorkspace::Empty => true, }; diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index 16b5bb11af..7b964d201b 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -69,6 +69,7 @@ pub struct ProjectWorkspace { } #[derive(Clone)] +#[allow(clippy::large_enum_variant)] pub enum ProjectWorkspaceKind { /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. Cargo { @@ -400,20 +401,17 @@ impl ProjectWorkspace { } pub fn load_inline( - project_json: ProjectJson, + mut project_json: ProjectJson, config: &CargoConfig, progress: &dyn Fn(String), ) -> ProjectWorkspace { progress("Discovering sysroot".to_owned()); let mut sysroot = Sysroot::new(project_json.sysroot.clone(), project_json.sysroot_src.clone()); - let loaded_sysroot = sysroot.load_workspace(&RustSourceWorkspaceConfig::Stitched); - if let Some(loaded_sysroot) = loaded_sysroot { - sysroot.set_workspace(loaded_sysroot); - } tracing::info!(workspace = %project_json.manifest_or_root(), src_root = ?sysroot.rust_lib_src_root(), root = ?sysroot.root(), "Using sysroot"); progress("Querying project metadata".to_owned()); + let sysroot_project = project_json.sysroot_project.take(); let query_config = QueryConfig::Rustc(&sysroot, project_json.path().as_ref()); let targets = target_tuple::get(query_config, config.target.as_deref(), &config.extra_env) .unwrap_or_default(); @@ -435,14 +433,31 @@ impl ProjectWorkspace { &config.extra_env, ) }); - thread::Result::Ok((toolchain.join()?, rustc_cfg.join()?, data_layout.join()?)) + let loaded_sysroot = s.spawn(|| { + if let Some(sysroot_project) = sysroot_project { + sysroot.load_workspace(&RustSourceWorkspaceConfig::Json(*sysroot_project)) + } else { + sysroot.load_workspace(&RustSourceWorkspaceConfig::Stitched) + } + }); + + thread::Result::Ok(( + toolchain.join()?, + rustc_cfg.join()?, + data_layout.join()?, + loaded_sysroot.join()?, + )) }); - let (toolchain, rustc_cfg, target_layout) = match join { + let (toolchain, rustc_cfg, target_layout, loaded_sysroot) = match join { Ok(it) => it, Err(e) => std::panic::resume_unwind(e), }; + if let Some(loaded_sysroot) = loaded_sysroot { + sysroot.set_workspace(loaded_sysroot); + } + ProjectWorkspace { kind: ProjectWorkspaceKind::Json(project_json), sysroot, @@ -667,6 +682,14 @@ impl ProjectWorkspace { Some(PackageRoot { is_local: false, include, exclude }) }) .collect(), + RustLibSrcWorkspace::Json(project_json) => project_json + .crates() + .map(|(_, krate)| PackageRoot { + is_local: false, + include: krate.include.clone(), + exclude: krate.exclude.clone(), + }) + .collect(), RustLibSrcWorkspace::Stitched(_) | RustLibSrcWorkspace::Empty => vec![], }; @@ -1490,6 +1513,65 @@ impl SysrootPublicDeps { } } +fn extend_crate_graph_with_sysroot( + crate_graph: &mut CrateGraph, + mut sysroot_crate_graph: CrateGraph, + mut sysroot_proc_macros: ProcMacroPaths, +) -> (SysrootPublicDeps, Option) { + let mut pub_deps = vec![]; + let mut libproc_macro = None; + let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag(sym::test.clone())]).unwrap(); + for (cid, c) in sysroot_crate_graph.iter_mut() { + // uninject `test` flag so `core` keeps working. + Arc::make_mut(&mut c.cfg_options).apply_diff(diff.clone()); + // patch the origin + if c.origin.is_local() { + let lang_crate = LangCrateOrigin::from( + c.display_name.as_ref().map_or("", |it| it.canonical_name().as_str()), + ); + c.origin = CrateOrigin::Lang(lang_crate); + match lang_crate { + LangCrateOrigin::Test + | LangCrateOrigin::Alloc + | LangCrateOrigin::Core + | LangCrateOrigin::Std => pub_deps.push(( + CrateName::normalize_dashes(&lang_crate.to_string()), + cid, + !matches!(lang_crate, LangCrateOrigin::Test | LangCrateOrigin::Alloc), + )), + LangCrateOrigin::ProcMacro => libproc_macro = Some(cid), + LangCrateOrigin::Other => (), + } + } + } + + let mut marker_set = vec![]; + for &(_, cid, _) in pub_deps.iter() { + marker_set.extend(sysroot_crate_graph.transitive_deps(cid)); + } + if let Some(cid) = libproc_macro { + marker_set.extend(sysroot_crate_graph.transitive_deps(cid)); + } + + marker_set.sort(); + marker_set.dedup(); + + // Remove all crates except the ones we are interested in to keep the sysroot graph small. + let removed_mapping = sysroot_crate_graph.remove_crates_except(&marker_set); + let mapping = crate_graph.extend(sysroot_crate_graph, &mut sysroot_proc_macros); + + // Map the id through the removal mapping first, then through the crate graph extension mapping. + pub_deps.iter_mut().for_each(|(_, cid, _)| { + *cid = mapping[&removed_mapping[cid.into_raw().into_u32() as usize].unwrap()] + }); + if let Some(libproc_macro) = &mut libproc_macro { + *libproc_macro = + mapping[&removed_mapping[libproc_macro.into_raw().into_u32() as usize].unwrap()]; + } + + (SysrootPublicDeps { deps: pub_deps }, libproc_macro) +} + fn sysroot_to_crate_graph( crate_graph: &mut CrateGraph, sysroot: &Sysroot, @@ -1499,7 +1581,7 @@ fn sysroot_to_crate_graph( let _p = tracing::info_span!("sysroot_to_crate_graph").entered(); match sysroot.workspace() { RustLibSrcWorkspace::Workspace(cargo) => { - let (mut cg, mut pm) = cargo_to_crate_graph( + let (cg, pm) = cargo_to_crate_graph( load, None, cargo, @@ -1520,58 +1602,30 @@ fn sysroot_to_crate_graph( false, ); - let mut pub_deps = vec![]; - let mut libproc_macro = None; - let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag(sym::test.clone())]).unwrap(); - for (cid, c) in cg.iter_mut() { - // uninject `test` flag so `core` keeps working. - Arc::make_mut(&mut c.cfg_options).apply_diff(diff.clone()); - // patch the origin - if c.origin.is_local() { - let lang_crate = LangCrateOrigin::from( - c.display_name.as_ref().map_or("", |it| it.canonical_name().as_str()), - ); - c.origin = CrateOrigin::Lang(lang_crate); - match lang_crate { - LangCrateOrigin::Test - | LangCrateOrigin::Alloc - | LangCrateOrigin::Core - | LangCrateOrigin::Std => pub_deps.push(( - CrateName::normalize_dashes(&lang_crate.to_string()), - cid, - !matches!(lang_crate, LangCrateOrigin::Test | LangCrateOrigin::Alloc), - )), - LangCrateOrigin::ProcMacro => libproc_macro = Some(cid), - LangCrateOrigin::Other => (), - } - } - } + extend_crate_graph_with_sysroot(crate_graph, cg, pm) + } + RustLibSrcWorkspace::Json(project_json) => { + let (cg, pm) = project_json_to_crate_graph( + rustc_cfg, + load, + project_json, + &Sysroot::empty(), + &FxHashMap::default(), + &CfgOverrides { + global: CfgDiff::new( + vec![ + CfgAtom::Flag(sym::debug_assertions.clone()), + CfgAtom::Flag(sym::miri.clone()), + ], + vec![], + ) + .unwrap(), + ..Default::default() + }, + false, + ); - let mut marker_set = vec![]; - for &(_, cid, _) in pub_deps.iter() { - marker_set.extend(cg.transitive_deps(cid)); - } - if let Some(cid) = libproc_macro { - marker_set.extend(cg.transitive_deps(cid)); - } - - marker_set.sort(); - marker_set.dedup(); - - // Remove all crates except the ones we are interested in to keep the sysroot graph small. - let removed_mapping = cg.remove_crates_except(&marker_set); - let mapping = crate_graph.extend(cg, &mut pm); - - // Map the id through the removal mapping first, then through the crate graph extension mapping. - pub_deps.iter_mut().for_each(|(_, cid, _)| { - *cid = mapping[&removed_mapping[cid.into_raw().into_u32() as usize].unwrap()] - }); - if let Some(libproc_macro) = &mut libproc_macro { - *libproc_macro = mapping - [&removed_mapping[libproc_macro.into_raw().into_u32() as usize].unwrap()]; - } - - (SysrootPublicDeps { deps: pub_deps }, libproc_macro) + extend_crate_graph_with_sysroot(crate_graph, cg, pm) } RustLibSrcWorkspace::Stitched(stitched) => { let cfg_options = Arc::new({ From 18a678e69389faf49b5fee3da039755b8b757b5b Mon Sep 17 00:00:00 2001 From: David Richey Date: Thu, 6 Feb 2025 10:21:31 -0600 Subject: [PATCH 24/47] Drop support for stitched sysroot --- crates/project-model/src/lib.rs | 1 - crates/project-model/src/sysroot.rs | 136 +---- crates/project-model/src/tests.rs | 14 - crates/project-model/src/workspace.rs | 61 +-- .../test_data/is-proc-macro-project.json | 13 - .../output/rust_project_cfg_groups.txt | 501 +----------------- ...rust_project_hello_world_project_model.txt | 454 +--------------- 7 files changed, 12 insertions(+), 1168 deletions(-) delete mode 100644 crates/project-model/test_data/is-proc-macro-project.json diff --git a/crates/project-model/src/lib.rs b/crates/project-model/src/lib.rs index d7c00b9179..21a993c5a5 100644 --- a/crates/project-model/src/lib.rs +++ b/crates/project-model/src/lib.rs @@ -263,7 +263,6 @@ fn parse_cfg(s: &str) -> Result { pub enum RustSourceWorkspaceConfig { CargoMetadata(CargoMetadataConfig), Json(ProjectJson), - Stitched, } impl Default for RustSourceWorkspaceConfig { diff --git a/crates/project-model/src/sysroot.rs b/crates/project-model/src/sysroot.rs index 77332bfa13..1e3c5a9478 100644 --- a/crates/project-model/src/sysroot.rs +++ b/crates/project-model/src/sysroot.rs @@ -4,17 +4,10 @@ //! but we can't process `.rlib` and need source code instead. The source code //! is typically installed with `rustup component add rust-src` command. -use std::{ - env, fs, - ops::{self, Not}, - path::Path, - process::Command, -}; +use std::{env, fs, ops::Not, path::Path, process::Command}; use anyhow::{format_err, Result}; -use base_db::CrateName; use itertools::Itertools; -use la_arena::{Arena, Idx}; use paths::{AbsPath, AbsPathBuf, Utf8PathBuf}; use rustc_hash::FxHashMap; use stdx::format_to; @@ -37,58 +30,9 @@ pub struct Sysroot { pub enum RustLibSrcWorkspace { Workspace(CargoWorkspace), Json(ProjectJson), - Stitched(Stitched), Empty, } -#[derive(Debug, Clone, Eq, PartialEq)] -pub struct Stitched { - crates: Arena, -} - -impl ops::Index for Stitched { - type Output = RustLibSrcCrateData; - fn index(&self, index: RustLibSrcCrate) -> &RustLibSrcCrateData { - &self.crates[index] - } -} - -impl Stitched { - pub(crate) fn public_deps( - &self, - ) -> impl Iterator + '_ { - // core is added as a dependency before std in order to - // mimic rustcs dependency order - [("core", true), ("alloc", false), ("std", true), ("test", false)].into_iter().filter_map( - move |(name, prelude)| { - Some((CrateName::new(name).unwrap(), self.by_name(name)?, prelude)) - }, - ) - } - - pub(crate) fn proc_macro(&self) -> Option { - self.by_name("proc_macro") - } - - pub(crate) fn crates(&self) -> impl ExactSizeIterator + '_ { - self.crates.iter().map(|(id, _data)| id) - } - - fn by_name(&self, name: &str) -> Option { - let (id, _data) = self.crates.iter().find(|(_id, data)| data.name == name)?; - Some(id) - } -} - -pub(crate) type RustLibSrcCrate = Idx; - -#[derive(Debug, Clone, Eq, PartialEq)] -pub(crate) struct RustLibSrcCrateData { - pub(crate) name: String, - pub(crate) root: ManifestPath, - pub(crate) deps: Vec, -} - impl Sysroot { pub const fn empty() -> Sysroot { Sysroot { @@ -116,7 +60,6 @@ impl Sysroot { match &self.workspace { RustLibSrcWorkspace::Workspace(ws) => ws.packages().next().is_none(), RustLibSrcWorkspace::Json(project_json) => project_json.n_crates() == 0, - RustLibSrcWorkspace::Stitched(stitched) => stitched.crates.is_empty(), RustLibSrcWorkspace::Empty => true, } } @@ -129,7 +72,6 @@ impl Sysroot { match &self.workspace { RustLibSrcWorkspace::Workspace(ws) => ws.packages().count(), RustLibSrcWorkspace::Json(project_json) => project_json.n_crates(), - RustLibSrcWorkspace::Stitched(c) => c.crates().count(), RustLibSrcWorkspace::Empty => 0, } } @@ -258,51 +200,8 @@ impl Sysroot { } else if let RustSourceWorkspaceConfig::Json(project_json) = sysroot_source_config { return Some(RustLibSrcWorkspace::Json(project_json.clone())); } - tracing::debug!("Stitching sysroot library: {src_root}"); - let mut stitched = Stitched { crates: Arena::default() }; - - for path in SYSROOT_CRATES.trim().lines() { - let name = path.split('/').last().unwrap(); - let root = [format!("{path}/src/lib.rs"), format!("lib{path}/lib.rs")] - .into_iter() - .map(|it| src_root.join(it)) - .filter_map(|it| ManifestPath::try_from(it).ok()) - .find(|it| fs::metadata(it).is_ok()); - - if let Some(root) = root { - stitched.crates.alloc(RustLibSrcCrateData { - name: name.into(), - root, - deps: Vec::new(), - }); - } - } - - if let Some(std) = stitched.by_name("std") { - for dep in STD_DEPS.trim().lines() { - if let Some(dep) = stitched.by_name(dep) { - stitched.crates[std].deps.push(dep) - } - } - } - - if let Some(alloc) = stitched.by_name("alloc") { - for dep in ALLOC_DEPS.trim().lines() { - if let Some(dep) = stitched.by_name(dep) { - stitched.crates[alloc].deps.push(dep) - } - } - } - - if let Some(proc_macro) = stitched.by_name("proc_macro") { - for dep in PROC_MACRO_DEPS.trim().lines() { - if let Some(dep) = stitched.by_name(dep) { - stitched.crates[proc_macro].deps.push(dep) - } - } - } - Some(RustLibSrcWorkspace::Stitched(stitched)) + None } pub fn set_workspace(&mut self, workspace: RustLibSrcWorkspace) { @@ -317,7 +216,6 @@ impl Sysroot { .crates() .filter_map(|(_, krate)| krate.display_name.clone()) .any(|name| name.canonical_name().as_str() == "core"), - RustLibSrcWorkspace::Stitched(stitched) => stitched.by_name("core").is_some(), RustLibSrcWorkspace::Empty => true, }; if !has_core { @@ -493,33 +391,3 @@ fn get_rust_lib_src(sysroot_path: &AbsPath) -> Option { None } } - -const SYSROOT_CRATES: &str = " -alloc -backtrace -core -panic_abort -panic_unwind -proc_macro -profiler_builtins -std -stdarch/crates/std_detect -test -unwind"; - -const ALLOC_DEPS: &str = "core"; - -const STD_DEPS: &str = " -alloc -panic_unwind -panic_abort -core -profiler_builtins -unwind -std_detect -test"; - -// core is required for our builtin derives to work in the proc_macro lib currently -const PROC_MACRO_DEPS: &str = " -std -core"; diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs index 54eb0e3478..cfc666970b 100644 --- a/crates/project-model/src/tests.rs +++ b/crates/project-model/src/tests.rs @@ -1,5 +1,3 @@ -use std::ops::Deref; - use base_db::{CrateGraph, ProcMacroPaths}; use cargo_metadata::Metadata; use cfg::{CfgAtom, CfgDiff}; @@ -225,18 +223,6 @@ fn rust_project_cfg_groups() { check_crate_graph(crate_graph, expect_file!["../test_data/output/rust_project_cfg_groups.txt"]); } -#[test] -fn rust_project_is_proc_macro_has_proc_macro_dep() { - let (crate_graph, _proc_macros) = load_rust_project("is-proc-macro-project.json"); - // Since the project only defines one crate (outside the sysroot crates), - // it should be the one with the biggest Id. - let crate_id = crate_graph.iter().max().unwrap(); - let crate_data = &crate_graph[crate_id]; - // Assert that the project crate with `is_proc_macro` has a dependency - // on the proc_macro sysroot crate. - crate_data.dependencies.iter().find(|&dep| *dep.name.deref() == sym::proc_macro).unwrap(); -} - #[test] fn crate_graph_dedup_identical() { let (mut crate_graph, proc_macros) = load_cargo("regex-metadata.json"); diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index 7b964d201b..6b6fb5f9ec 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -23,7 +23,7 @@ use crate::{ cargo_workspace::{CargoMetadataConfig, DepKind, PackageData, RustLibSource}, env::{cargo_config_env, inject_cargo_env, inject_cargo_package_env, inject_rustc_tool_env}, project_json::{Crate, CrateArrayIdx}, - sysroot::{RustLibSrcCrate, RustLibSrcWorkspace}, + sysroot::RustLibSrcWorkspace, toolchain_info::{rustc_cfg, target_data_layout, target_tuple, version, QueryConfig}, CargoConfig, CargoWorkspace, CfgOverrides, InvocationStrategy, ManifestPath, Package, ProjectJson, ProjectManifest, RustSourceWorkspaceConfig, Sysroot, TargetData, TargetKind, @@ -437,7 +437,9 @@ impl ProjectWorkspace { if let Some(sysroot_project) = sysroot_project { sysroot.load_workspace(&RustSourceWorkspaceConfig::Json(*sysroot_project)) } else { - sysroot.load_workspace(&RustSourceWorkspaceConfig::Stitched) + sysroot.load_workspace(&RustSourceWorkspaceConfig::CargoMetadata( + sysroot_metadata_config(&config.extra_env, &targets), + )) } }); @@ -690,7 +692,7 @@ impl ProjectWorkspace { exclude: krate.exclude.clone(), }) .collect(), - RustLibSrcWorkspace::Stitched(_) | RustLibSrcWorkspace::Empty => vec![], + RustLibSrcWorkspace::Empty => vec![], }; r.push(PackageRoot { @@ -1627,60 +1629,7 @@ fn sysroot_to_crate_graph( extend_crate_graph_with_sysroot(crate_graph, cg, pm) } - RustLibSrcWorkspace::Stitched(stitched) => { - let cfg_options = Arc::new({ - let mut cfg_options = CfgOptions::default(); - cfg_options.extend(rustc_cfg); - cfg_options.insert_atom(sym::debug_assertions.clone()); - cfg_options.insert_atom(sym::miri.clone()); - cfg_options - }); - let sysroot_crates: FxHashMap = stitched - .crates() - .filter_map(|krate| { - let file_id = load(&stitched[krate].root)?; - let display_name = CrateDisplayName::from_canonical_name(&stitched[krate].name); - let crate_id = crate_graph.add_crate_root( - file_id, - Edition::CURRENT_FIXME, - Some(display_name), - None, - cfg_options.clone(), - None, - Env::default(), - CrateOrigin::Lang(LangCrateOrigin::from(&*stitched[krate].name)), - false, - None, - ); - Some((krate, crate_id)) - }) - .collect(); - - for from in stitched.crates() { - for &to in stitched[from].deps.iter() { - let name = CrateName::new(&stitched[to].name).unwrap(); - if let (Some(&from), Some(&to)) = - (sysroot_crates.get(&from), sysroot_crates.get(&to)) - { - add_dep(crate_graph, from, name, to); - } - } - } - - let public_deps = SysrootPublicDeps { - deps: stitched - .public_deps() - .filter_map(|(name, idx, prelude)| { - Some((name, *sysroot_crates.get(&idx)?, prelude)) - }) - .collect::>(), - }; - - let libproc_macro = - stitched.proc_macro().and_then(|it| sysroot_crates.get(&it).copied()); - (public_deps, libproc_macro) - } RustLibSrcWorkspace::Empty => (SysrootPublicDeps { deps: vec![] }, None), } } diff --git a/crates/project-model/test_data/is-proc-macro-project.json b/crates/project-model/test_data/is-proc-macro-project.json deleted file mode 100644 index 5d500a4729..0000000000 --- a/crates/project-model/test_data/is-proc-macro-project.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "sysroot_src": null, - "crates": [ - { - "display_name": "is_proc_macro", - "root_module": "$ROOT$src/lib.rs", - "edition": "2018", - "deps": [], - "is_workspace_member": true, - "is_proc_macro": true - } - ] -} diff --git a/crates/project-model/test_data/output/rust_project_cfg_groups.txt b/crates/project-model/test_data/output/rust_project_cfg_groups.txt index 9b4be19c41..28ca4eb534 100644 --- a/crates/project-model/test_data/output/rust_project_cfg_groups.txt +++ b/crates/project-model/test_data/output/rust_project_cfg_groups.txt @@ -3,417 +3,6 @@ root_file_id: FileId( 1, ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "alloc", - ), - canonical_name: "alloc", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [ - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - Alloc, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 1: CrateData { - root_file_id: FileId( - 2, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "core", - ), - canonical_name: "core", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Core, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 2: CrateData { - root_file_id: FileId( - 3, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "panic_abort", - ), - canonical_name: "panic_abort", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 3: CrateData { - root_file_id: FileId( - 4, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "panic_unwind", - ), - canonical_name: "panic_unwind", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 4: CrateData { - root_file_id: FileId( - 5, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "proc_macro", - ), - canonical_name: "proc_macro", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [ - Dependency { - crate_id: Idx::(6), - name: CrateName( - "std", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - ProcMacro, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 5: CrateData { - root_file_id: FileId( - 6, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "profiler_builtins", - ), - canonical_name: "profiler_builtins", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 6: CrateData { - root_file_id: FileId( - 7, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "std", - ), - canonical_name: "std", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [ - Dependency { - crate_id: Idx::(0), - name: CrateName( - "alloc", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(3), - name: CrateName( - "panic_unwind", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(2), - name: CrateName( - "panic_abort", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(5), - name: CrateName( - "profiler_builtins", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(9), - name: CrateName( - "unwind", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(7), - name: CrateName( - "std_detect", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(8), - name: CrateName( - "test", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - Std, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 7: CrateData { - root_file_id: FileId( - 8, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "std_detect", - ), - canonical_name: "std_detect", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 8: CrateData { - root_file_id: FileId( - 9, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "test", - ), - canonical_name: "test", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Test, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 9: CrateData { - root_file_id: FileId( - 10, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "unwind", - ), - canonical_name: "unwind", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 10: CrateData { - root_file_id: FileId( - 11, - ), edition: Edition2018, version: None, display_name: Some( @@ -438,48 +27,7 @@ env: Env { entries: {}, }, - dependencies: [ - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(0), - name: CrateName( - "alloc", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(6), - name: CrateName( - "std", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(8), - name: CrateName( - "test", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "proc_macro", - ), - prelude: false, - sysroot: true, - }, - ], + dependencies: [], origin: Local { repo: None, name: Some( @@ -489,9 +37,9 @@ is_proc_macro: false, proc_macro_cwd: None, }, - 11: CrateData { + 1: CrateData { root_file_id: FileId( - 11, + 1, ), edition: Edition2018, version: None, @@ -517,48 +65,7 @@ env: Env { entries: {}, }, - dependencies: [ - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(0), - name: CrateName( - "alloc", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(6), - name: CrateName( - "std", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(8), - name: CrateName( - "test", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "proc_macro", - ), - prelude: false, - sysroot: true, - }, - ], + dependencies: [], origin: Local { repo: None, name: Some( diff --git a/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt b/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt index 4c8e66e8e9..dde8d3023d 100644 --- a/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt +++ b/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt @@ -3,417 +3,6 @@ root_file_id: FileId( 1, ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "alloc", - ), - canonical_name: "alloc", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [ - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - Alloc, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 1: CrateData { - root_file_id: FileId( - 2, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "core", - ), - canonical_name: "core", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Core, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 2: CrateData { - root_file_id: FileId( - 3, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "panic_abort", - ), - canonical_name: "panic_abort", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 3: CrateData { - root_file_id: FileId( - 4, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "panic_unwind", - ), - canonical_name: "panic_unwind", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 4: CrateData { - root_file_id: FileId( - 5, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "proc_macro", - ), - canonical_name: "proc_macro", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [ - Dependency { - crate_id: Idx::(6), - name: CrateName( - "std", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - ProcMacro, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 5: CrateData { - root_file_id: FileId( - 6, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "profiler_builtins", - ), - canonical_name: "profiler_builtins", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 6: CrateData { - root_file_id: FileId( - 7, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "std", - ), - canonical_name: "std", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [ - Dependency { - crate_id: Idx::(0), - name: CrateName( - "alloc", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(3), - name: CrateName( - "panic_unwind", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(2), - name: CrateName( - "panic_abort", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(5), - name: CrateName( - "profiler_builtins", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(9), - name: CrateName( - "unwind", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(7), - name: CrateName( - "std_detect", - ), - prelude: true, - sysroot: false, - }, - Dependency { - crate_id: Idx::(8), - name: CrateName( - "test", - ), - prelude: true, - sysroot: false, - }, - ], - origin: Lang( - Std, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 7: CrateData { - root_file_id: FileId( - 8, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "std_detect", - ), - canonical_name: "std_detect", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 8: CrateData { - root_file_id: FileId( - 9, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "test", - ), - canonical_name: "test", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Test, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 9: CrateData { - root_file_id: FileId( - 10, - ), - edition: Edition2021, - version: None, - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "unwind", - ), - canonical_name: "unwind", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "miri", - "true", - ], - ), - potential_cfg_options: None, - env: Env { - entries: {}, - }, - dependencies: [], - origin: Lang( - Other, - ), - is_proc_macro: false, - proc_macro_cwd: None, - }, - 10: CrateData { - root_file_id: FileId( - 11, - ), edition: Edition2018, version: None, display_name: Some( @@ -435,48 +24,7 @@ env: Env { entries: {}, }, - dependencies: [ - Dependency { - crate_id: Idx::(1), - name: CrateName( - "core", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(0), - name: CrateName( - "alloc", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(6), - name: CrateName( - "std", - ), - prelude: true, - sysroot: true, - }, - Dependency { - crate_id: Idx::(8), - name: CrateName( - "test", - ), - prelude: false, - sysroot: true, - }, - Dependency { - crate_id: Idx::(4), - name: CrateName( - "proc_macro", - ), - prelude: false, - sysroot: true, - }, - ], + dependencies: [], origin: Local { repo: None, name: Some( From 6d24962cb8bcc20b12c4a05d24d4209286d7f8be Mon Sep 17 00:00:00 2001 From: LuuuXXX Date: Thu, 27 Feb 2025 11:43:03 +0800 Subject: [PATCH 25/47] Cofigurate out ohos target to avoid compilation crashes --- crates/profile/Cargo.toml | 2 +- crates/profile/src/stop_watch.rs | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/profile/Cargo.toml b/crates/profile/Cargo.toml index 3179c810f6..65eec868af 100644 --- a/crates/profile/Cargo.toml +++ b/crates/profile/Cargo.toml @@ -17,7 +17,7 @@ cfg-if = "1.0.0" libc.workspace = true jemalloc-ctl = { version = "0.5.0", package = "tikv-jemalloc-ctl", optional = true } -[target.'cfg(target_os = "linux")'.dependencies] +[target.'cfg(all(target_os = "linux", not(target_env = "ohos")))'.dependencies] perf-event = "=0.4.7" [target.'cfg(windows)'.dependencies] diff --git a/crates/profile/src/stop_watch.rs b/crates/profile/src/stop_watch.rs index 0a803959ee..9f3e636ef8 100644 --- a/crates/profile/src/stop_watch.rs +++ b/crates/profile/src/stop_watch.rs @@ -11,7 +11,7 @@ use crate::MemoryUsage; pub struct StopWatch { time: Instant, - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", not(target_env = "ohos")))] counter: Option, memory: MemoryUsage, } @@ -24,7 +24,7 @@ pub struct StopWatchSpan { impl StopWatch { pub fn start() -> StopWatch { - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", not(target_env = "ohos")))] let counter = { // When debugging rust-analyzer using rr, the perf-related syscalls cause it to abort. // We allow disabling perf by setting the env var `RA_DISABLE_PERF`. @@ -51,7 +51,7 @@ impl StopWatch { let time = Instant::now(); StopWatch { time, - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", not(target_env = "ohos")))] counter, memory, } @@ -60,10 +60,12 @@ impl StopWatch { pub fn elapsed(&mut self) -> StopWatchSpan { let time = self.time.elapsed(); - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", not(target_env = "ohos")))] let instructions = self.counter.as_mut().and_then(|it| { it.read().map_err(|err| eprintln!("Failed to read perf counter: {err}")).ok() }); + #[cfg(all(target_os = "linux", target_env = "ohos"))] + let instructions = None; #[cfg(not(target_os = "linux"))] let instructions = None; From d81341372befd030502643e6023ddddbeb12507b Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 27 Feb 2025 11:55:22 +0100 Subject: [PATCH 26/47] Fix sysroot crate-graph construction not mapping crate-ids for proc-macros --- crates/project-model/src/workspace.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index 6b6fb5f9ec..2c9f41e828 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -1094,8 +1094,7 @@ fn cargo_to_crate_graph( ) -> (CrateGraph, ProcMacroPaths) { let _p = tracing::info_span!("cargo_to_crate_graph").entered(); let mut res = (CrateGraph::default(), ProcMacroPaths::default()); - let crate_graph = &mut res.0; - let proc_macros = &mut res.1; + let (crate_graph, proc_macros) = &mut res; let (public_deps, libproc_macro) = sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load); @@ -1560,6 +1559,10 @@ fn extend_crate_graph_with_sysroot( // Remove all crates except the ones we are interested in to keep the sysroot graph small. let removed_mapping = sysroot_crate_graph.remove_crates_except(&marker_set); + sysroot_proc_macros = sysroot_proc_macros + .into_iter() + .filter_map(|(k, v)| Some((removed_mapping[k.into_raw().into_u32() as usize]?, v))) + .collect(); let mapping = crate_graph.extend(sysroot_crate_graph, &mut sysroot_proc_macros); // Map the id through the removal mapping first, then through the crate graph extension mapping. From bd7375a58fe39b79bcdbb86782a70d361227c07e Mon Sep 17 00:00:00 2001 From: BenjaminBrienen Date: Thu, 27 Feb 2025 00:59:02 +0100 Subject: [PATCH 27/47] enable doctest --- crates/base-db/Cargo.toml | 1 - crates/cfg/Cargo.toml | 1 - crates/hir-expand/Cargo.toml | 1 - crates/hir-ty/Cargo.toml | 1 - crates/hir/Cargo.toml | 1 - crates/ide-assists/Cargo.toml | 1 - crates/ide-completion/Cargo.toml | 1 - crates/ide-db/Cargo.toml | 1 - crates/ide-diagnostics/Cargo.toml | 1 - crates/ide-ssr/Cargo.toml | 1 - crates/ide/Cargo.toml | 1 - crates/intern/Cargo.toml | 1 - crates/mbe/Cargo.toml | 1 - crates/parser/Cargo.toml | 1 - crates/paths/Cargo.toml | 1 - crates/proc-macro-api/Cargo.toml | 1 - crates/proc-macro-srv/Cargo.toml | 1 - crates/proc-macro-srv/proc-macro-test/Cargo.toml | 1 - crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml | 1 - crates/profile/Cargo.toml | 1 - crates/project-model/Cargo.toml | 1 - crates/rust-analyzer/Cargo.toml | 1 - crates/stdx/Cargo.toml | 1 - crates/syntax-bridge/Cargo.toml | 1 - crates/syntax/Cargo.toml | 1 - crates/test-utils/Cargo.toml | 1 - crates/toolchain/Cargo.toml | 1 - crates/tt/Cargo.toml | 1 - crates/vfs-notify/Cargo.toml | 1 - crates/vfs/Cargo.toml | 1 - 30 files changed, 30 deletions(-) diff --git a/crates/base-db/Cargo.toml b/crates/base-db/Cargo.toml index 788ceb8857..042dd36488 100644 --- a/crates/base-db/Cargo.toml +++ b/crates/base-db/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] lz4_flex = { version = "0.11", default-features = false } diff --git a/crates/cfg/Cargo.toml b/crates/cfg/Cargo.toml index 040bddbd7f..e887368ef2 100644 --- a/crates/cfg/Cargo.toml +++ b/crates/cfg/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] rustc-hash.workspace = true diff --git a/crates/hir-expand/Cargo.toml b/crates/hir-expand/Cargo.toml index b193a34a01..7d561e0527 100644 --- a/crates/hir-expand/Cargo.toml +++ b/crates/hir-expand/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/crates/hir-ty/Cargo.toml b/crates/hir-ty/Cargo.toml index 4d36de0b38..27849f3b44 100644 --- a/crates/hir-ty/Cargo.toml +++ b/crates/hir-ty/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/crates/hir/Cargo.toml b/crates/hir/Cargo.toml index c68ff706e4..2af3c2e4c3 100644 --- a/crates/hir/Cargo.toml +++ b/crates/hir/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] rustc-hash.workspace = true diff --git a/crates/ide-assists/Cargo.toml b/crates/ide-assists/Cargo.toml index ba21586871..3768c2257c 100644 --- a/crates/ide-assists/Cargo.toml +++ b/crates/ide-assists/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/crates/ide-completion/Cargo.toml b/crates/ide-completion/Cargo.toml index 1bef82af5a..68cc7a0b9a 100644 --- a/crates/ide-completion/Cargo.toml +++ b/crates/ide-completion/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/crates/ide-db/Cargo.toml b/crates/ide-db/Cargo.toml index c8a8a2d169..641998c3da 100644 --- a/crates/ide-db/Cargo.toml +++ b/crates/ide-db/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/crates/ide-diagnostics/Cargo.toml b/crates/ide-diagnostics/Cargo.toml index 281a08e542..483cb6df86 100644 --- a/crates/ide-diagnostics/Cargo.toml +++ b/crates/ide-diagnostics/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/crates/ide-ssr/Cargo.toml b/crates/ide-ssr/Cargo.toml index 2561467628..fa75e5a421 100644 --- a/crates/ide-ssr/Cargo.toml +++ b/crates/ide-ssr/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/crates/ide/Cargo.toml b/crates/ide/Cargo.toml index 7c66b36dc8..9af56c40e9 100644 --- a/crates/ide/Cargo.toml +++ b/crates/ide/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/crates/intern/Cargo.toml b/crates/intern/Cargo.toml index c0358ef929..397eba0929 100644 --- a/crates/intern/Cargo.toml +++ b/crates/intern/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] diff --git a/crates/mbe/Cargo.toml b/crates/mbe/Cargo.toml index b37d57f280..e6fbb298eb 100644 --- a/crates/mbe/Cargo.toml +++ b/crates/mbe/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index 48436ec71f..a36a39dbee 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] drop_bomb = "0.1.5" diff --git a/crates/paths/Cargo.toml b/crates/paths/Cargo.toml index f0dafab70c..4cc70726da 100644 --- a/crates/paths/Cargo.toml +++ b/crates/paths/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] camino.workspace = true diff --git a/crates/proc-macro-api/Cargo.toml b/crates/proc-macro-api/Cargo.toml index dac8e09435..f5ba40a994 100644 --- a/crates/proc-macro-api/Cargo.toml +++ b/crates/proc-macro-api/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] serde.workspace = true diff --git a/crates/proc-macro-srv/Cargo.toml b/crates/proc-macro-srv/Cargo.toml index 191535ac55..d3b56b402e 100644 --- a/crates/proc-macro-srv/Cargo.toml +++ b/crates/proc-macro-srv/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] object.workspace = true diff --git a/crates/proc-macro-srv/proc-macro-test/Cargo.toml b/crates/proc-macro-srv/proc-macro-test/Cargo.toml index 7c6a1ba46b..16fcc92962 100644 --- a/crates/proc-macro-srv/proc-macro-test/Cargo.toml +++ b/crates/proc-macro-srv/proc-macro-test/Cargo.toml @@ -7,7 +7,6 @@ edition = "2021" license = "MIT OR Apache-2.0" [lib] -doctest = false [build-dependencies] cargo_metadata = "0.18.1" diff --git a/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml b/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml index fa189752b7..fb98d758a8 100644 --- a/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml +++ b/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml @@ -6,7 +6,6 @@ edition = "2021" publish = false [lib] -doctest = false proc-macro = true [dependencies] diff --git a/crates/profile/Cargo.toml b/crates/profile/Cargo.toml index 65eec868af..9384fe2655 100644 --- a/crates/profile/Cargo.toml +++ b/crates/profile/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cfg-if = "1.0.0" diff --git a/crates/project-model/Cargo.toml b/crates/project-model/Cargo.toml index ed647950e6..83def0e6b2 100644 --- a/crates/project-model/Cargo.toml +++ b/crates/project-model/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] anyhow.workspace = true diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 64c8afdc1f..6c81c238fd 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml @@ -13,7 +13,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [[bin]] name = "rust-analyzer" diff --git a/crates/stdx/Cargo.toml b/crates/stdx/Cargo.toml index 62c32d68e6..3727d0c956 100644 --- a/crates/stdx/Cargo.toml +++ b/crates/stdx/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] backtrace = { version = "0.3.67", optional = true } diff --git a/crates/syntax-bridge/Cargo.toml b/crates/syntax-bridge/Cargo.toml index f9a9f40541..3e663422a0 100644 --- a/crates/syntax-bridge/Cargo.toml +++ b/crates/syntax-bridge/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] rustc-hash.workspace = true diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml index 51eaea5434..3fe6e01dc3 100644 --- a/crates/syntax/Cargo.toml +++ b/crates/syntax/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] cov-mark = "2.0.0-pre.1" diff --git a/crates/test-utils/Cargo.toml b/crates/test-utils/Cargo.toml index b1457722a9..b99a2c4bd7 100644 --- a/crates/test-utils/Cargo.toml +++ b/crates/test-utils/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] # Avoid adding deps here, this crate is widely used in tests it should compile fast! diff --git a/crates/toolchain/Cargo.toml b/crates/toolchain/Cargo.toml index 87e8efb20f..38daacdf95 100644 --- a/crates/toolchain/Cargo.toml +++ b/crates/toolchain/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] home = "0.5.4" diff --git a/crates/tt/Cargo.toml b/crates/tt/Cargo.toml index 82e7c24668..529fad3244 100644 --- a/crates/tt/Cargo.toml +++ b/crates/tt/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] arrayvec.workspace = true diff --git a/crates/vfs-notify/Cargo.toml b/crates/vfs-notify/Cargo.toml index bc54d7168f..48b4d22de2 100644 --- a/crates/vfs-notify/Cargo.toml +++ b/crates/vfs-notify/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] tracing.workspace = true diff --git a/crates/vfs/Cargo.toml b/crates/vfs/Cargo.toml index e8a6195036..546195481c 100644 --- a/crates/vfs/Cargo.toml +++ b/crates/vfs/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] rustc-hash.workspace = true From b19ef6b04676e8c39ff53902f6ce0aa9e73c9e36 Mon Sep 17 00:00:00 2001 From: BenjaminBrienen Date: Thu, 27 Feb 2025 00:59:13 +0100 Subject: [PATCH 28/47] fix doc tests --- crates/hir-def/Cargo.toml | 1 - crates/hir-def/src/dyn_map.rs | 4 +++- crates/hir-def/src/item_tree.rs | 6 +++--- crates/hir-def/src/nameres/mod_resolution.rs | 2 +- crates/hir-def/src/resolver.rs | 5 +++-- crates/hir-expand/src/builtin/attr_macro.rs | 2 +- crates/hir-ty/src/display.rs | 2 +- crates/hir-ty/src/infer.rs | 9 +++++---- crates/hir/src/semantics/source_to_def.rs | 2 +- crates/hir/src/term_search/expr.rs | 2 +- .../src/handlers/convert_comment_from_or_to_doc.rs | 6 +++--- .../ide-assists/src/handlers/extract_function.rs | 4 ++-- .../ide-assists/src/handlers/generate_function.rs | 2 +- .../ide-assists/src/handlers/inline_type_alias.rs | 2 +- crates/ide-completion/src/context.rs | 4 ++-- crates/ide-completion/src/context/analysis.rs | 5 +++-- crates/ide-completion/src/item.rs | 14 +++++++------- crates/ide-completion/src/lib.rs | 2 +- crates/ide-db/src/path_transform.rs | 2 +- crates/ide-db/src/source_change.rs | 2 +- crates/ide-db/src/syntax_helpers/suggest_name.rs | 4 +++- crates/ide-diagnostics/src/lib.rs | 2 +- crates/mbe/src/parser.rs | 4 ++-- crates/parser/src/input.rs | 2 +- crates/parser/src/lib.rs | 2 +- crates/parser/src/output.rs | 5 +++-- crates/rust-analyzer/src/op_queue.rs | 2 +- crates/rust-analyzer/src/tracing/config.rs | 4 ++-- crates/rust-analyzer/src/tracing/hprof.rs | 3 ++- crates/rust-analyzer/src/tracing/json.rs | 3 ++- crates/stdx/src/anymap.rs | 3 ++- crates/stdx/src/macros.rs | 2 +- crates/syntax/src/algo.rs | 2 +- crates/syntax/src/ast/edit.rs | 4 ++-- crates/test-utils/src/assert_linear.rs | 2 +- crates/test-utils/src/fixture.rs | 12 ++++++++---- crates/vfs/src/anchored_path.rs | 2 +- 37 files changed, 75 insertions(+), 61 deletions(-) diff --git a/crates/hir-def/Cargo.toml b/crates/hir-def/Cargo.toml index 9a448ec14e..a22961c26c 100644 --- a/crates/hir-def/Cargo.toml +++ b/crates/hir-def/Cargo.toml @@ -10,7 +10,6 @@ license.workspace = true rust-version.workspace = true [lib] -doctest = false [dependencies] arrayvec.workspace = true diff --git a/crates/hir-def/src/dyn_map.rs b/crates/hir-def/src/dyn_map.rs index e9318d146d..8868bc0cd9 100644 --- a/crates/hir-def/src/dyn_map.rs +++ b/crates/hir-def/src/dyn_map.rs @@ -5,7 +5,9 @@ //! //! It is used like this: //! -//! ``` +//! ```ignore +//! # use hir_def::dyn_map::DynMap; +//! # use hir_def::dyn_map::Key; //! // keys define submaps of a `DynMap` //! const STRING_TO_U32: Key = Key::new(); //! const U32_TO_VEC: Key> = Key::new(); diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index 8d5b3eeb28..382afbcb1d 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -883,20 +883,20 @@ pub struct UseTree { #[derive(Debug, Clone, Eq, PartialEq)] pub enum UseTreeKind { - /// ``` + /// ```ignore /// use path::to::Item; /// use path::to::Item as Renamed; /// use path::to::Trait as _; /// ``` Single { path: Interned, alias: Option }, - /// ``` + /// ```ignore /// use *; // (invalid, but can occur in nested tree) /// use path::*; /// ``` Glob { path: Option> }, - /// ``` + /// ```ignore /// use prefix::{self, Item, ...}; /// ``` Prefixed { prefix: Option>, list: Box<[UseTree]> }, diff --git a/crates/hir-def/src/nameres/mod_resolution.rs b/crates/hir-def/src/nameres/mod_resolution.rs index afee42ecec..17d09bcbd0 100644 --- a/crates/hir-def/src/nameres/mod_resolution.rs +++ b/crates/hir-def/src/nameres/mod_resolution.rs @@ -134,7 +134,7 @@ impl DirPath { /// So this is the case which doesn't really work I think if we try to be /// 100% platform agnostic: /// - /// ``` + /// ```ignore /// mod a { /// #[path="C://sad/face"] /// mod b { mod c; } diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs index 9dfb6e3cc4..e5774b4804 100644 --- a/crates/hir-def/src/resolver.rs +++ b/crates/hir-def/src/resolver.rs @@ -532,16 +532,17 @@ impl Resolver { /// Note that in Rust one name can be bound to several items: /// /// ``` + /// # #![allow(non_camel_case_types)] /// macro_rules! t { () => (()) } /// type t = t!(); - /// const t: t = t!() + /// const t: t = t!(); /// ``` /// /// That's why we return a multimap. /// /// The shadowing is accounted for: in /// - /// ``` + /// ```ignore /// let it = 92; /// { /// let it = 92; diff --git a/crates/hir-expand/src/builtin/attr_macro.rs b/crates/hir-expand/src/builtin/attr_macro.rs index f250620e77..e9dc17a28f 100644 --- a/crates/hir-expand/src/builtin/attr_macro.rs +++ b/crates/hir-expand/src/builtin/attr_macro.rs @@ -101,7 +101,7 @@ fn dummy_gate_test_expand( /// somewhat inconsistently resolve derive attributes. /// /// As such, we expand `#[derive(Foo, bar::Bar)]` into -/// ``` +/// ```ignore /// #![Foo] /// #![bar::Bar] /// ``` diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index ae8fbe2ce6..49f061813d 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -95,7 +95,7 @@ pub struct HirFormatter<'a> { enum BoundsFormattingCtx { Entered { /// We can have recursive bounds like the following case: - /// ```rust + /// ```ignore /// where /// T: Foo, /// T::FooAssoc: Baz<::BarAssoc> + Bar diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index 0cb7002f44..556091c404 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -335,7 +335,7 @@ impl Default for InternedStandardTypes { /// sized struct to a dynamically sized one. E.g., &[i32; 4] -> &[i32] is /// represented by: /// -/// ``` +/// ```ignore /// Deref(None) -> [i32; 4], /// Borrow(AutoBorrow::Ref) -> &[i32; 4], /// Unsize -> &[i32], @@ -481,9 +481,10 @@ pub struct InferenceResult { /// or pattern can have multiple binding modes. For example: /// ``` /// fn foo(mut slice: &[u32]) -> usize { - /// slice = match slice { - /// [0, rest @ ..] | rest => rest, - /// }; + /// slice = match slice { + /// [0, rest @ ..] | rest => rest, + /// }; + /// 0 /// } /// ``` /// the first `rest` has implicit `ref` binding mode, but the second `rest` binding mode is `move`. diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index 4481b8855f..18cbaa15ae 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs @@ -5,7 +5,7 @@ //! //! This module solves the following problem: //! -//! Given a piece of syntax, find the corresponding semantic definition (def). +//! > Given a piece of syntax, find the corresponding semantic definition (def). //! //! This problem is a part of more-or-less every IDE feature implemented. Every //! IDE functionality (like goto to definition), conceptually starts with a diff --git a/crates/hir/src/term_search/expr.rs b/crates/hir/src/term_search/expr.rs index 6ad074e8e5..d2070f0e18 100644 --- a/crates/hir/src/term_search/expr.rs +++ b/crates/hir/src/term_search/expr.rs @@ -40,7 +40,7 @@ fn mod_item_path_str( /// Type tree shows how can we get from set of types to some type. /// /// Consider the following code as an example -/// ``` +/// ```ignore /// fn foo(x: i32, y: bool) -> Option { None } /// fn bar() { /// let a = 1; diff --git a/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs b/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs index c7b1314c86..5a9db67a5f 100644 --- a/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs +++ b/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs @@ -136,7 +136,7 @@ fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacem /// Not all comments are valid candidates for conversion into doc comments. For example, the /// comments in the code: -/// ```rust +/// ```ignore /// // Brilliant module right here /// /// // Really good right @@ -148,7 +148,7 @@ fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacem /// mod nice_module {} /// ``` /// can be converted to doc comments. However, the comments in this example: -/// ```rust +/// ```ignore /// fn foo_bar(foo: Foo /* not bar yet */) -> Bar { /// foo.into_bar() /// // Nicely done @@ -162,7 +162,7 @@ fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacem /// are not allowed to become doc comments. Moreover, some comments _are_ allowed, but aren't common /// style in Rust. For example, the following comments are allowed to be doc comments, but it is not /// common style for them to be: -/// ```rust +/// ```ignore /// fn foo_bar(foo: Foo) -> Bar { /// // this could be an inner comment with //! /// foo.into_bar() diff --git a/crates/ide-assists/src/handlers/extract_function.rs b/crates/ide-assists/src/handlers/extract_function.rs index 967da41c15..751e4a5a57 100644 --- a/crates/ide-assists/src/handlers/extract_function.rs +++ b/crates/ide-assists/src/handlers/extract_function.rs @@ -272,7 +272,7 @@ fn make_function_name(semantics_scope: &hir::SemanticsScope<'_>) -> ast::NameRef /// * We want whole node, like `loop {}`, `2 + 2`, `{ let n = 1; }` exprs. /// Then we can use `ast::Expr` /// * We want a few statements for a block. E.g. -/// ```rust,no_run +/// ```ignore /// fn foo() -> i32 { /// let m = 1; /// $0 @@ -386,7 +386,7 @@ struct ContainerInfo { /// Control flow that is exported from extracted function /// /// E.g.: -/// ```rust,no_run +/// ```ignore /// loop { /// $0 /// if 42 == 42 { diff --git a/crates/ide-assists/src/handlers/generate_function.rs b/crates/ide-assists/src/handlers/generate_function.rs index 8f5daa4125..91e248a1de 100644 --- a/crates/ide-assists/src/handlers/generate_function.rs +++ b/crates/ide-assists/src/handlers/generate_function.rs @@ -1037,7 +1037,7 @@ fn filter_bounds_in_scope( /// Makes duplicate argument names unique by appending incrementing numbers. /// -/// ``` +/// ```ignore /// let mut names: Vec = /// vec!["foo".into(), "foo".into(), "bar".into(), "baz".into(), "bar".into()]; /// deduplicate_arg_names(&mut names); diff --git a/crates/ide-assists/src/handlers/inline_type_alias.rs b/crates/ide-assists/src/handlers/inline_type_alias.rs index 66dffde505..76d465b011 100644 --- a/crates/ide-assists/src/handlers/inline_type_alias.rs +++ b/crates/ide-assists/src/handlers/inline_type_alias.rs @@ -276,7 +276,7 @@ impl ConstAndTypeMap { /// 1. Map the provided instance's generic args to the type alias's generic /// params: /// -/// ``` +/// ```ignore /// type A<'a, const N: usize, T = u64> = &'a [T; N]; /// ^ alias generic params /// let a: A<100>; diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs index 7862b25878..919b30f7f9 100644 --- a/crates/ide-completion/src/context.rs +++ b/crates/ide-completion/src/context.rs @@ -249,8 +249,8 @@ pub(crate) enum Qualified { /// This would be None, if path is not solely made of /// `super` segments, e.g. /// - /// ```rust - /// use super::foo; + /// ```ignore + /// use super::foo; /// ``` /// /// Otherwise it should be Some(count of `super`) diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs index eecd412bc4..1a34548f70 100644 --- a/crates/ide-completion/src/context/analysis.rs +++ b/crates/ide-completion/src/context/analysis.rs @@ -97,7 +97,8 @@ fn token_at_offset_ignore_whitespace(file: &SyntaxNode, offset: TextSize) -> Opt /// We do this by recursively expanding all macros and picking the best possible match. We cannot just /// choose the first expansion each time because macros can expand to something that does not include /// our completion marker, e.g.: -/// ``` +/// +/// ```ignore /// macro_rules! helper { ($v:ident) => {} } /// macro_rules! my_macro { /// ($v:ident) => { @@ -106,7 +107,7 @@ fn token_at_offset_ignore_whitespace(file: &SyntaxNode, offset: TextSize) -> Opt /// }; /// } /// -/// my_macro!(complete_me_here) +/// my_macro!(complete_me_here); /// ``` /// If we would expand the first thing we encounter only (which in fact this method used to do), we would /// be unable to complete here, because we would be walking directly into the void. So we instead try diff --git a/crates/ide-completion/src/item.rs b/crates/ide-completion/src/item.rs index 41a8240959..b3dd8a8d06 100644 --- a/crates/ide-completion/src/item.rs +++ b/crates/ide-completion/src/item.rs @@ -149,9 +149,9 @@ pub struct CompletionRelevance { /// This is set when the identifier being completed matches up with the name that is expected, /// like in a function argument. /// - /// ``` + /// ```ignore /// fn f(spam: String) {} - /// fn main { + /// fn main() { /// let spam = 92; /// f($0) // name of local matches the name of param /// } @@ -161,7 +161,7 @@ pub struct CompletionRelevance { pub type_match: Option, /// Set for local variables. /// - /// ``` + /// ```ignore /// fn foo(a: u32) { /// let b = 0; /// $0 // `a` and `b` are local @@ -195,7 +195,7 @@ pub struct CompletionRelevanceTraitInfo { pub enum CompletionRelevanceTypeMatch { /// This is set in cases like these: /// - /// ``` + /// ```ignore /// enum Option { Some(T), None } /// fn f(a: Option) {} /// fn main { @@ -205,9 +205,9 @@ pub enum CompletionRelevanceTypeMatch { CouldUnify, /// This is set in cases where the type matches the expected type, like: /// - /// ``` + /// ```ignore /// fn f(spam: String) {} - /// fn main { + /// fn main() { /// let foo = String::new(); /// f($0) // type of local matches the type of param /// } @@ -221,7 +221,7 @@ pub enum CompletionRelevancePostfixMatch { NonExact, /// This is set in cases like these: /// - /// ``` + /// ```ignore /// (a > b).not$0 /// ``` /// diff --git a/crates/ide-completion/src/lib.rs b/crates/ide-completion/src/lib.rs index a1f2eaeb1b..a990b39481 100644 --- a/crates/ide-completion/src/lib.rs +++ b/crates/ide-completion/src/lib.rs @@ -143,7 +143,7 @@ impl CompletionFieldsToResolve { /// already present, it should give all possible variants for the identifier at /// the caret. In other words, for /// -/// ```no_run +/// ```ignore /// fn f() { /// let foo = 92; /// let _ = bar$0 diff --git a/crates/ide-db/src/path_transform.rs b/crates/ide-db/src/path_transform.rs index f045e44dd3..126b30470b 100644 --- a/crates/ide-db/src/path_transform.rs +++ b/crates/ide-db/src/path_transform.rs @@ -32,7 +32,7 @@ type DefaultedParam = Either; /// block), you generally want to appropriately qualify the names, and sometimes /// you might want to substitute generic parameters as well: /// -/// ``` +/// ```ignore /// mod x { /// pub struct A; /// pub trait T { fn foo(&self, _: U) -> A; } diff --git a/crates/ide-db/src/source_change.rs b/crates/ide-db/src/source_change.rs index 27ff91dc19..34642d7eaf 100644 --- a/crates/ide-db/src/source_change.rs +++ b/crates/ide-db/src/source_change.rs @@ -493,7 +493,7 @@ pub enum Snippet { Placeholder(TextRange), /// A group of placeholder snippets, e.g. /// - /// ```no_run + /// ```ignore /// let ${0:new_var} = 4; /// fun(1, 2, 3, ${0:new_var}); /// ``` diff --git a/crates/ide-db/src/syntax_helpers/suggest_name.rs b/crates/ide-db/src/syntax_helpers/suggest_name.rs index 0a7141c19b..e085bf15cb 100644 --- a/crates/ide-db/src/syntax_helpers/suggest_name.rs +++ b/crates/ide-db/src/syntax_helpers/suggest_name.rs @@ -79,7 +79,9 @@ const USELESS_METHODS: &[&str] = &[ /// the name, e.g. `a`, `a1`, `a2`, ... /// /// # Examples -/// ```rust +/// +/// ``` +/// # use ide_db::syntax_helpers::suggest_name::NameGenerator; /// let mut generator = NameGenerator::new(); /// assert_eq!(generator.suggest_name("a"), "a"); /// assert_eq!(generator.suggest_name("a"), "a1"); diff --git a/crates/ide-diagnostics/src/lib.rs b/crates/ide-diagnostics/src/lib.rs index 3ea41aa7e8..0a55b6e9be 100644 --- a/crates/ide-diagnostics/src/lib.rs +++ b/crates/ide-diagnostics/src/lib.rs @@ -697,7 +697,7 @@ struct SeverityAttr { /// #[warn(non_snake_case)] /// mod foo { /// #[allow(nonstandard_style)] - /// mod bar; + /// mod bar {} /// } /// ``` /// We want to not warn on non snake case inside `bar`. If we are traversing this for the first diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs index 16d55492a0..0a670053c9 100644 --- a/crates/mbe/src/parser.rs +++ b/crates/mbe/src/parser.rs @@ -13,8 +13,8 @@ use crate::ParseError; /// Consider /// /// ``` -/// macro_rules! an_macro { -/// ($x:expr + $y:expr) => ($y * $x) +/// macro_rules! a_macro { +/// ($x:expr, $y:expr) => ($y * $x) /// } /// ``` /// diff --git a/crates/parser/src/input.rs b/crates/parser/src/input.rs index c90b358cfb..cabdff214d 100644 --- a/crates/parser/src/input.rs +++ b/crates/parser/src/input.rs @@ -36,7 +36,7 @@ impl Input { /// the *previous* token was joint, with mbe, you know whether the *current* /// one is joint. This API allows for styles of usage: /// - /// ``` + /// ```ignore /// // In text: /// tokens.was_joint(prev_joint); /// tokens.push(curr); diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index e461492cc6..398ad7cf66 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -59,7 +59,7 @@ pub use crate::{ /// /// That is, for something like /// -/// ``` +/// ```ignore /// quick_check! { /// fn prop() {} /// } diff --git a/crates/parser/src/output.rs b/crates/parser/src/output.rs index 386d03a62c..0ea15a656c 100644 --- a/crates/parser/src/output.rs +++ b/crates/parser/src/output.rs @@ -16,8 +16,9 @@ pub struct Output { /// 32-bit encoding of events. If LSB is zero, then that's an index into the /// error vector. Otherwise, it's one of the thee other variants, with data encoded as /// - /// |16 bit kind|8 bit n_input_tokens|4 bit tag|4 bit leftover| - /// + /// ```text + /// |16 bit kind|8 bit n_input_tokens|4 bit tag|4 bit leftover| + /// `````` event: Vec, error: Vec, } diff --git a/crates/rust-analyzer/src/op_queue.rs b/crates/rust-analyzer/src/op_queue.rs index 123f20605a..709d99bda7 100644 --- a/crates/rust-analyzer/src/op_queue.rs +++ b/crates/rust-analyzer/src/op_queue.rs @@ -6,7 +6,7 @@ pub(crate) type Cause = String; /// A single-item queue that allows callers to request an operation to /// be performed later. /// -/// ``` +/// ```ignore /// let queue = OpQueue::default(); /// /// // Request work to be done. diff --git a/crates/rust-analyzer/src/tracing/config.rs b/crates/rust-analyzer/src/tracing/config.rs index 02ae4186ab..4f208b6c5d 100644 --- a/crates/rust-analyzer/src/tracing/config.rs +++ b/crates/rust-analyzer/src/tracing/config.rs @@ -31,7 +31,7 @@ pub struct Config { /// that specify level. pub chalk_filter: Option, /// Filtering syntax, set in a shell: - /// ``` + /// ```text /// env RA_PROFILE=* // dump everything /// env RA_PROFILE=foo|bar|baz // enabled only selected entries /// env RA_PROFILE=*@3>10 // dump everything, up to depth 3, if it takes more than 10 @@ -39,7 +39,7 @@ pub struct Config { pub profile_filter: Option, /// Filtering syntax, set in a shell: - /// ``` + /// ```text /// env RA_PROFILE_JSON=foo|bar|baz /// ``` pub json_profile_filter: Option, diff --git a/crates/rust-analyzer/src/tracing/hprof.rs b/crates/rust-analyzer/src/tracing/hprof.rs index d466acef01..5b18762bb9 100644 --- a/crates/rust-analyzer/src/tracing/hprof.rs +++ b/crates/rust-analyzer/src/tracing/hprof.rs @@ -6,7 +6,8 @@ //! //! Usage: //! -//! ```rust +//! ```ignore +//! # use tracing_subscriber::Registry; //! let layer = hprof::SpanTree::default(); //! Registry::default().with(layer).init(); //! ``` diff --git a/crates/rust-analyzer/src/tracing/json.rs b/crates/rust-analyzer/src/tracing/json.rs index 9e35990a5b..f5394d023a 100644 --- a/crates/rust-analyzer/src/tracing/json.rs +++ b/crates/rust-analyzer/src/tracing/json.rs @@ -2,7 +2,8 @@ //! //! Usage: //! -//! ```rust +//! ```ignore +//! # use tracing_subscriber::Registry; //! let layer = json::TimingLayer::new(std::io::stderr); //! Registry::default().with(layer).init(); //! ``` diff --git a/crates/stdx/src/anymap.rs b/crates/stdx/src/anymap.rs index 91fab8e923..faf2e6c717 100644 --- a/crates/stdx/src/anymap.rs +++ b/crates/stdx/src/anymap.rs @@ -83,7 +83,8 @@ pub type RawMap = hash_map::HashMap, BuildHasherDefault[anymap::Map][Map]::<[core::any::Any]>::new() instead if desired.) /// -/// ```rust +/// ``` +/// # use stdx::anymap; #[doc = "let mut data = anymap::AnyMap::new();"] /// assert_eq!(data.get(), None::<&i32>); /// ``` diff --git a/crates/stdx/src/macros.rs b/crates/stdx/src/macros.rs index 85d9008fe1..880e2da70f 100644 --- a/crates/stdx/src/macros.rs +++ b/crates/stdx/src/macros.rs @@ -34,7 +34,7 @@ macro_rules! format_to_acc { /// /// # Example /// -/// ```rust +/// ```ignore /// impl_from!(Struct, Union, Enum for Adt); /// ``` #[macro_export] diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs index 3b85b137aa..a8a8389394 100644 --- a/crates/syntax/src/algo.rs +++ b/crates/syntax/src/algo.rs @@ -25,7 +25,7 @@ pub fn ancestors_at_offset( /// imprecise: if the cursor is strictly between two nodes of the desired type, /// as in /// -/// ```no_run +/// ```ignore /// struct Foo {}|struct Bar; /// ``` /// diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs index 579f3ba8b4..052d018e5c 100644 --- a/crates/syntax/src/ast/edit.rs +++ b/crates/syntax/src/ast/edit.rs @@ -72,9 +72,9 @@ impl IndentLevel { } /// XXX: this intentionally doesn't change the indent of the very first token. - /// Ie, in something like + /// For example, in something like: /// ``` - /// fn foo() { + /// fn foo() -> i32 { /// 92 /// } /// ``` diff --git a/crates/test-utils/src/assert_linear.rs b/crates/test-utils/src/assert_linear.rs index 15c30c52a5..f78bf59a2f 100644 --- a/crates/test-utils/src/assert_linear.rs +++ b/crates/test-utils/src/assert_linear.rs @@ -11,7 +11,7 @@ //! Ideally, we should use a proper "model selection" to directly compare //! quadratic and linear models, but that sounds rather complicated: //! -//! https://stats.stackexchange.com/questions/21844/selecting-best-model-based-on-linear-quadratic-and-cubic-fit-of-data +//! > https://stats.stackexchange.com/questions/21844/selecting-best-model-based-on-linear-quadratic-and-cubic-fit-of-data //! //! We might get false positives on a VM, but never false negatives. So, if the //! first round fails, we repeat the ordeal three more times and fail only if diff --git a/crates/test-utils/src/fixture.rs b/crates/test-utils/src/fixture.rs index 7fe26d53bf..daeb56c583 100644 --- a/crates/test-utils/src/fixture.rs +++ b/crates/test-utils/src/fixture.rs @@ -6,7 +6,8 @@ //! Use this to test functionality local to one file. //! //! Simple Example: -//! ``` +//! +//! ```ignore //! r#" //! fn main() { //! println!("Hello World") @@ -19,7 +20,8 @@ //! which is also how to define multiple files in a single test fixture //! //! Example using two files in the same crate: -//! ``` +//! +//! ```ignore //! " //! //- /main.rs //! mod foo; @@ -33,7 +35,8 @@ //! ``` //! //! Example using two crates with one file each, with one crate depending on the other: -//! ``` +//! +//! ```ignore //! r#" //! //- /main.rs crate:a deps:b //! fn main() { @@ -51,7 +54,8 @@ //! for the syntax. //! //! Example using some available metadata: -//! ``` +//! +//! ```ignore //! " //! //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo //! fn insert_source_code_here() {} diff --git a/crates/vfs/src/anchored_path.rs b/crates/vfs/src/anchored_path.rs index db15a2a21c..1b9fb355b4 100644 --- a/crates/vfs/src/anchored_path.rs +++ b/crates/vfs/src/anchored_path.rs @@ -2,7 +2,7 @@ //! //! The primary goal of this is to losslessly represent paths like //! -//! ``` +//! ```ignore //! #[path = "./bar.rs"] //! mod foo; //! ``` From 57411897509d1228d94cd4e856aad30c63bb20e0 Mon Sep 17 00:00:00 2001 From: BenjaminBrienen Date: Thu, 27 Feb 2025 15:57:08 +0100 Subject: [PATCH 29/47] ignore doc test that only fails on windows --- crates/paths/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/paths/src/lib.rs b/crates/paths/src/lib.rs index 0084244161..3d722b1ff1 100644 --- a/crates/paths/src/lib.rs +++ b/crates/paths/src/lib.rs @@ -232,7 +232,7 @@ impl AbsPath { /// - Removes trailing slashes: `/a/b/` becomes `/a/b`. /// /// # Example - /// ``` + /// ```ignore /// # use paths::AbsPathBuf; /// let abs_path_buf = AbsPathBuf::assert("/a/../../b/.//c//".into()); /// let normalized = abs_path_buf.normalize(); From 07bf55f017534ceef6bf4772dfb469b74d1cb586 Mon Sep 17 00:00:00 2001 From: BenjaminBrienen Date: Thu, 27 Feb 2025 16:09:00 +0100 Subject: [PATCH 30/47] ignore another test that fails on windows --- crates/vfs/src/vfs_path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/vfs/src/vfs_path.rs b/crates/vfs/src/vfs_path.rs index 3c8e37413f..cce8595cc4 100644 --- a/crates/vfs/src/vfs_path.rs +++ b/crates/vfs/src/vfs_path.rs @@ -59,7 +59,7 @@ impl VfsPath { /// /// # Example /// - /// ``` + /// ```ignore /// # use vfs::{AbsPathBuf, VfsPath}; /// let mut path = VfsPath::from(AbsPathBuf::assert("/foo/bar".into())); /// assert!(path.pop()); From 00726cf697271617945b02baa932d2915ebce8b7 Mon Sep 17 00:00:00 2001 From: BenjaminBrienen Date: Wed, 26 Feb 2025 17:17:07 +0100 Subject: [PATCH 31/47] Update Node.js, vscode, and ts deps --- .github/workflows/ci.yaml | 2 +- .github/workflows/release.yaml | 4 +- editors/code/.eslintignore | 2 - editors/code/.eslintrc.js | 46 - editors/code/.prettierrc.js | 5 - editors/code/eslint.config.mts | 48 + editors/code/package-lock.json | 3670 +++++++++++++--------- editors/code/package.json | 51 +- editors/code/prettier.config.mts | 12 + editors/code/src/bootstrap.ts | 4 +- editors/code/src/client.ts | 531 ++-- editors/code/src/commands.ts | 12 +- editors/code/src/config.ts | 28 +- editors/code/src/ctx.ts | 41 +- editors/code/src/debug.ts | 9 +- editors/code/src/diagnostics.ts | 35 +- editors/code/src/lang_client.ts | 2 + editors/code/src/lsp_ext.ts | 1 + editors/code/src/main.ts | 1 + editors/code/src/persistent_state.ts | 1 + editors/code/src/snippets.ts | 4 +- editors/code/src/syntax_tree_provider.ts | 2 + editors/code/src/test_explorer.ts | 2 +- editors/code/src/toolchain.ts | 20 +- editors/code/src/util.ts | 18 +- editors/code/tests/unit/index.ts | 3 +- editors/code/tests/unit/tasks.test.ts | 5 +- editors/code/tsconfig.eslint.json | 2 +- editors/code/tsconfig.json | 11 +- 29 files changed, 2715 insertions(+), 1857 deletions(-) delete mode 100644 editors/code/.eslintignore delete mode 100644 editors/code/.eslintrc.js delete mode 100644 editors/code/.prettierrc.js create mode 100644 editors/code/eslint.config.mts create mode 100644 editors/code/prettier.config.mts diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 81b55712d7..bc770dbe71 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -174,7 +174,7 @@ jobs: - name: Install Nodejs uses: actions/setup-node@v4 with: - node-version: 18 + node-version: 22 if: needs.changes.outputs.typescript == 'true' - name: Install xvfb diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 9ab4a0b9d2..c8e6de72ce 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -69,7 +69,7 @@ jobs: - name: Install Node.js toolchain uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 - name: Install Rust toolchain run: | @@ -188,7 +188,7 @@ jobs: - name: Install Nodejs uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 - run: echo "TAG=$(date --iso -u)" >> $GITHUB_ENV if: github.ref == 'refs/heads/release' diff --git a/editors/code/.eslintignore b/editors/code/.eslintignore deleted file mode 100644 index 3a1e8e186f..0000000000 --- a/editors/code/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -.eslintrc.js diff --git a/editors/code/.eslintrc.js b/editors/code/.eslintrc.js deleted file mode 100644 index 9705c5f5ec..0000000000 --- a/editors/code/.eslintrc.js +++ /dev/null @@ -1,46 +0,0 @@ -module.exports = { - env: { - es6: true, - node: true, - }, - extends: ["prettier"], - parser: "@typescript-eslint/parser", - parserOptions: { - project: true, - tsconfigRootDir: __dirname, - sourceType: "module", - }, - plugins: ["@typescript-eslint"], - rules: { - camelcase: ["error"], - eqeqeq: ["error", "always", { null: "ignore" }], - curly: ["error", "multi-line"], - "no-console": ["error", { allow: ["warn", "error"] }], - "prefer-const": "error", - "@typescript-eslint/member-delimiter-style": [ - "error", - { - multiline: { - delimiter: "semi", - requireLast: true, - }, - singleline: { - delimiter: "semi", - requireLast: false, - }, - }, - ], - "@typescript-eslint/semi": ["error", "always"], - "@typescript-eslint/no-unnecessary-type-assertion": "error", - "@typescript-eslint/no-floating-promises": "error", - - "@typescript-eslint/consistent-type-imports": [ - "error", - { - prefer: "type-imports", - fixStyle: "inline-type-imports", - }, - ], - "@typescript-eslint/no-import-type-side-effects": "error", - }, -}; diff --git a/editors/code/.prettierrc.js b/editors/code/.prettierrc.js deleted file mode 100644 index cafb12f0e6..0000000000 --- a/editors/code/.prettierrc.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - // use 100 because it's Rustfmt's default - // https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#max_width - printWidth: 100, -}; diff --git a/editors/code/eslint.config.mts b/editors/code/eslint.config.mts new file mode 100644 index 0000000000..3520593eef --- /dev/null +++ b/editors/code/eslint.config.mts @@ -0,0 +1,48 @@ +import eslintConfigPrettier from "eslint-config-prettier"; +import stylistic from "@stylistic/eslint-plugin"; +import eslint from "@eslint/js"; +import tseslint from "typescript-eslint"; +import stylisticJs from "@stylistic/eslint-plugin-js"; +import { type FlatESLintConfig } from "eslint-define-config"; + +const config: FlatESLintConfig[] = [ + eslintConfigPrettier, + eslint.configs.recommended, + stylisticJs.configs["disable-legacy"], + ...tseslint.configs.recommended, + stylistic.configs.customize({ + indent: 4, + quotes: "double", + semi: true, + braceStyle: "1tbs", + arrowParens: true, + }), + { + rules: { + "no-console": "warn", + "@typescript-eslint/no-unused-vars": [ + "error", + { + args: "all", + argsIgnorePattern: "^_", + caughtErrors: "all", + caughtErrorsIgnorePattern: "^_", + destructuredArrayIgnorePattern: "^_", + varsIgnorePattern: "^_", + ignoreRestSiblings: true, + }, + ], + // the following stylistic lints conflict with prettier + "@stylistic/operator-linebreak": "off", + "@stylistic/indent-binary-ops": "off", + "@stylistic/indent": "off", + "@stylistic/brace-style": "off", + "@stylistic/quotes": "off", + }, + }, + { + ignores: ["out/", ".vscode-test/", "node_modules/"], + }, +]; + +export default config; diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json index 86a066454a..11a37c218f 100644 --- a/editors/code/package-lock.json +++ b/editors/code/package-lock.json @@ -9,39 +9,36 @@ "version": "0.5.0-dev", "license": "MIT OR Apache-2.0", "dependencies": { - "@hpcc-js/wasm": "^2.13.0", - "anser": "^2.1.1", - "d3": "^7.8.5", - "d3-graphviz": "^5.0.2", + "@hpcc-js/wasm": "^2.22.4", + "anser": "^2.3.2", + "d3": "^7.9.0", + "d3-graphviz": "^5.6.0", + "jiti": "^2.4.2", "vscode-languageclient": "^9.0.1" }, "devDependencies": { - "@tsconfig/strictest": "^2.0.1", - "@types/node": "~16.11.7", - "@types/vscode": "~1.83", - "@typescript-eslint/eslint-plugin": "^6.0.0", - "@typescript-eslint/parser": "^6.0.0", - "@vscode/test-electron": "^2.3.8", - "@vscode/vsce": "^3.0.0", + "@eslint/js": "^9.21.0", + "@stylistic/eslint-plugin": "^4.1.0", + "@stylistic/eslint-plugin-js": "^4.1.0", + "@tsconfig/strictest": "^2.0.5", + "@types/node": "~22.13.4", + "@types/vscode": "~1.93.0", + "@typescript-eslint/eslint-plugin": "^8.25.0", + "@typescript-eslint/parser": "^8.25.0", + "@vscode/test-electron": "^2.4.1", + "@vscode/vsce": "^3.2.2", "esbuild": "^0.25.0", - "eslint": "^8.44.0", - "eslint-config-prettier": "^8.8.0", - "ovsx": "^0.8.2", - "prettier": "^3.0.0", - "tslib": "^2.6.0", - "typescript": "^5.6.0" + "eslint": "^9.21.0", + "eslint-config-prettier": "^10.0.2", + "eslint-define-config": "^2.1.0", + "ovsx": "0.10.1", + "prettier": "^3.5.2", + "tslib": "^2.8.1", + "typescript": "^5.7.3", + "typescript-eslint": "^8.25.0" }, "engines": { - "vscode": "^1.83.0" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "vscode": "^1.93.0" } }, "node_modules/@azure/abort-controller": { @@ -92,16 +89,16 @@ } }, "node_modules/@azure/core-rest-pipeline": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.17.0.tgz", - "integrity": "sha512-62Vv8nC+uPId3j86XJ0WI+sBf0jlqTqPUFCBNrGtlaUeQUIXWV/D8GE5A1d+Qx8H7OQojn2WguC8kChD6v0shA==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.19.0.tgz", + "integrity": "sha512-bM3308LRyg5g7r3Twprtqww0R/r7+GyVxj4BafcmVPo4WQoGt5JXuaqxHEFjw2o3rvFZcUPiqJMg6WuvEEeVUA==", "dev": true, "license": "MIT", "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-auth": "^1.8.0", "@azure/core-tracing": "^1.0.1", - "@azure/core-util": "^1.9.0", + "@azure/core-util": "^1.11.0", "@azure/logger": "^1.0.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", @@ -111,47 +108,6 @@ "node": ">=18.0.0" } }, - "node_modules/@azure/core-rest-pipeline/node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@azure/core-rest-pipeline/node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@azure/core-rest-pipeline/node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/@azure/core-tracing": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.2.0.tgz", @@ -180,9 +136,9 @@ } }, "node_modules/@azure/identity": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.5.0.tgz", - "integrity": "sha512-EknvVmtBuSIic47xkOqyNabAme0RYTw52BTMz8eBgU1ysTyMrD1uOoM+JdS0J/4Yfp98IBT3osqq3BfwSaNaGQ==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.7.0.tgz", + "integrity": "sha512-6z/S2KorkbKaZ0DgZFVRdu7RCuATmMSTjKpuhj7YpjxkJ0vnJ7kTM3cpNgzFgk9OPYfZ31wrBEtC/iwAS4jQDA==", "dev": true, "license": "MIT", "dependencies": { @@ -193,11 +149,11 @@ "@azure/core-tracing": "^1.0.0", "@azure/core-util": "^1.11.0", "@azure/logger": "^1.0.0", - "@azure/msal-browser": "^3.26.1", - "@azure/msal-node": "^2.15.0", + "@azure/msal-browser": "^4.2.0", + "@azure/msal-node": "^3.2.1", "events": "^3.0.0", "jws": "^4.0.0", - "open": "^8.0.0", + "open": "^10.1.0", "stoppable": "^1.1.0", "tslib": "^2.2.0" }, @@ -219,22 +175,22 @@ } }, "node_modules/@azure/msal-browser": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.26.1.tgz", - "integrity": "sha512-y78sr9g61aCAH9fcLO1um+oHFXc1/5Ap88RIsUSuzkm0BHzFnN+PXGaQeuM1h5Qf5dTnWNOd6JqkskkMPAhh7Q==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.4.0.tgz", + "integrity": "sha512-rU6juYXk67CKQmpgi6fDgZoPQ9InZ1760z1BSAH7RbeIc4lHZM/Tu+H0CyRk7cnrfvTkexyYE4pjYhMghpzheA==", "dev": true, "license": "MIT", "dependencies": { - "@azure/msal-common": "14.15.0" + "@azure/msal-common": "15.2.0" }, "engines": { "node": ">=0.8.0" } }, "node_modules/@azure/msal-common": { - "version": "14.15.0", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.15.0.tgz", - "integrity": "sha512-ImAQHxmpMneJ/4S8BRFhjt1MZ3bppmpRPYYNyzeQPeFN288YKbb8TmmISQEbtfkQ1BPASvYZU5doIZOPBAqENQ==", + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.2.0.tgz", + "integrity": "sha512-HiYfGAKthisUYqHG1nImCf/uzcyS31wng3o+CycWLIM9chnYJ9Lk6jZ30Y6YiYYpTQ9+z/FGUpiKKekd3Arc0A==", "dev": true, "license": "MIT", "engines": { @@ -242,13 +198,13 @@ } }, "node_modules/@azure/msal-node": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.15.0.tgz", - "integrity": "sha512-gVPW8YLz92ZeCibQH2QUw96odJoiM3k/ZPH3f2HxptozmH6+OnyyvKXo/Egg39HAM230akarQKHf0W74UHlh0Q==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.2.3.tgz", + "integrity": "sha512-0eaPqBIWEAizeYiXdeHb09Iq0tvHJ17ztvNEaLdr/KcJJhJxbpkkEQf09DB+vKlFE0tzYi7j4rYLTXtES/InEQ==", "dev": true, "license": "MIT", "dependencies": { - "@azure/msal-common": "14.15.0", + "@azure/msal-common": "15.2.0", "jsonwebtoken": "^9.0.0", "uuid": "^8.3.0" }, @@ -682,45 +638,30 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", "dev": true, + "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", - "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -728,38 +669,198 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/js": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", - "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/core": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", + "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", + "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.21.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.21.0.tgz", + "integrity": "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", + "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.12.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@hpcc-js/wasm": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-2.13.0.tgz", - "integrity": "sha512-MvnUPnyMlN3/2IONCXwl/SBVWIfVOFJqvw+kFfI1QcwKjNmkwTAtG+9/m3nvofTymkASUUxNULbBmRDIr2uzIA==", + "version": "2.22.4", + "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-2.22.4.tgz", + "integrity": "sha512-58JkRkxZffiBAbZhc7z+9iaaAOmn1cyxLL3rRwsUvco/I0Wwb7uVAlHM9HiU6XASe2k11jrIjCFff1t9QKjlqg==", + "license": "Apache-2.0", "dependencies": { "yargs": "17.7.2" }, "bin": { - "dot-wasm": "bin/dot-wasm.js" + "dot-wasm": "node ./node_modules/@hpcc-js/wasm-graphviz-cli/bin/index.js" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" }, "engines": { - "node": ">=10.10.0" + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@humanwhocodes/module-importer": { @@ -767,6 +868,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -775,11 +877,19 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true + "node_modules/@humanwhocodes/retry": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", + "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@isaacs/cliui": { "version": "8.0.2", @@ -799,96 +909,12 @@ "node": ">=12" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -902,6 +928,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -911,6 +938,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -919,121 +947,148 @@ "node": ">= 8" } }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "node_modules/@stylistic/eslint-plugin": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-4.1.0.tgz", + "integrity": "sha512-bytbL7qiici7yPyEiId0fGPK9kjQbzcPMj2aftPfzTCyJ/CRSKdtI+iVjM0LSGzGxfunflI+MDDU9vyIIeIpoQ==", "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.23.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, "engines": { - "node": ">= 6" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0" + } + }, + "node_modules/@stylistic/eslint-plugin-js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-4.1.0.tgz", + "integrity": "sha512-YOe+dChNoR26JVVt+7BjyebsPIQF05OLNmHCXivq8lLZ4ZeVs4+wXaW+pREVboDiAaSRznauAdAU8f+iQouw6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0" } }, "node_modules/@tsconfig/strictest": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/strictest/-/strictest-2.0.1.tgz", - "integrity": "sha512-7JHHCbyCsGUxLd0pDbp24yz3zjxw2t673W5oAP6HCEdr/UUhaRhYd3SSnUsGCk+VnPVJVA4mXROzbhI+nyIk+w==", - "dev": true + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@tsconfig/strictest/-/strictest-2.0.5.tgz", + "integrity": "sha512-ec4tjL2Rr0pkZ5hww65c+EEPYwxOi4Ryv+0MtjeaSQRJyq322Q27eOQiFbuNgw2hpL4hB1/W/HBGk3VKS43osg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" }, "node_modules/@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", - "dev": true + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { - "version": "16.11.68", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.68.tgz", - "integrity": "sha512-JkRpuVz3xCNCWaeQ5EHLR/6woMbHZz/jZ7Kmc63AkU+1HxnoUugzSWMck7dsR4DvNYX8jp9wTi9K7WvnxOIQZQ==", - "dev": true - }, - "node_modules/@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", - "dev": true + "version": "22.13.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz", + "integrity": "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } }, "node_modules/@types/vscode": { - "version": "1.83.3", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.83.3.tgz", - "integrity": "sha512-ZPp5+OQNYrCSFoT4jWOZKdcuXijj+JdN2BJNDhWH4pPbVL6PRQycG9NT8C4a94oul1tFMbkVbXXa9HasI7cLUg==", - "dev": true + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.93.0.tgz", + "integrity": "sha512-kUK6jAHSR5zY8ps42xuW89NLcBpw1kOabah7yv38J8MyiYuOHxLQBi0e7zeXbQgVefDy/mZZetqEFC+Fl5eIEQ==", + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.0.0.tgz", - "integrity": "sha512-xuv6ghKGoiq856Bww/yVYnXGsKa588kY3M0XK7uUW/3fJNNULKRfZfSBkMTSpqGG/8ZCXCadfh8G/z/B4aqS/A==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.25.0.tgz", + "integrity": "sha512-VM7bpzAe7JO/BFf40pIT1lJqS/z1F8OaSsUB3rpFJucQA4cOSuH2RVVVkFULN+En0Djgr29/jb4EQnedUo95KA==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.5.0", - "@typescript-eslint/scope-manager": "6.0.0", - "@typescript-eslint/type-utils": "6.0.0", - "@typescript-eslint/utils": "6.0.0", - "@typescript-eslint/visitor-keys": "6.0.0", - "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.25.0", + "@typescript-eslint/type-utils": "8.25.0", + "@typescript-eslint/utils": "8.25.0", + "@typescript-eslint/visitor-keys": "8.25.0", "graphemer": "^1.4.0", - "ignore": "^5.2.4", + "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.5.0", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^2.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.0.0.tgz", - "integrity": "sha512-TNaufYSPrr1U8n+3xN+Yp9g31vQDJqhXzzPSHfQDLcaO4tU+mCfODPxCwf4H530zo7aUBE3QIdxCXamEnG04Tg==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.25.0.tgz", + "integrity": "sha512-4gbs64bnbSzu4FpgMiQ1A+D+urxkoJk/kqlDJ2W//5SygaEiAP2B4GoS7TEdxgwol2el03gckFV9lJ4QOMiiHg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "6.0.0", - "@typescript-eslint/types": "6.0.0", - "@typescript-eslint/typescript-estree": "6.0.0", - "@typescript-eslint/visitor-keys": "6.0.0", + "@typescript-eslint/scope-manager": "8.25.0", + "@typescript-eslint/types": "8.25.0", + "@typescript-eslint/typescript-estree": "8.25.0", + "@typescript-eslint/visitor-keys": "8.25.0", "debug": "^4.3.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.0.0.tgz", - "integrity": "sha512-o4q0KHlgCZTqjuaZ25nw5W57NeykZT9LiMEG4do/ovwvOcPnDO1BI5BQdCsUkjxFyrCL0cSzLjvIMfR9uo7cWg==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.25.0.tgz", + "integrity": "sha512-6PPeiKIGbgStEyt4NNXa2ru5pMzQ8OYKO1hX1z53HMomrmiSB+R5FmChgQAP1ro8jMtNawz+TRQo/cSXrauTpg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.0.0", - "@typescript-eslint/visitor-keys": "6.0.0" + "@typescript-eslint/types": "8.25.0", + "@typescript-eslint/visitor-keys": "8.25.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1041,39 +1096,37 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.0.0.tgz", - "integrity": "sha512-ah6LJvLgkoZ/pyJ9GAdFkzeuMZ8goV6BH7eC9FPmojrnX9yNCIsfjB+zYcnex28YO3RFvBkV6rMV6WpIqkPvoQ==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.25.0.tgz", + "integrity": "sha512-d77dHgHWnxmXOPJuDWO4FDWADmGQkN5+tt6SFRZz/RtCWl4pHgFl3+WdYCn16+3teG09DY6XtEpf3gGD0a186g==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "6.0.0", - "@typescript-eslint/utils": "6.0.0", + "@typescript-eslint/typescript-estree": "8.25.0", + "@typescript-eslint/utils": "8.25.0", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^2.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/types": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.0.0.tgz", - "integrity": "sha512-Zk9KDggyZM6tj0AJWYYKgF0yQyrcnievdhG0g5FqyU3Y2DRxJn4yWY21sJC0QKBckbsdKKjYDV2yVrrEvuTgxg==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.25.0.tgz", + "integrity": "sha512-+vUe0Zb4tkNgznQwicsvLUJgZIRs6ITeWSCclX1q85pR1iOiaj+4uZJIUp//Z27QWu5Cseiw3O3AR8hVpax7Aw==", "dev": true, + "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1081,69 +1134,68 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.0.0.tgz", - "integrity": "sha512-2zq4O7P6YCQADfmJ5OTDQTP3ktajnXIRrYAtHM9ofto/CJZV3QfJ89GEaM2BNGeSr1KgmBuLhEkz5FBkS2RQhQ==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.25.0.tgz", + "integrity": "sha512-ZPaiAKEZ6Blt/TPAx5Ot0EIB/yGtLI2EsGoY6F7XKklfMxYQyvtL+gT/UCqkMzO0BVFHLDlzvFqQzurYahxv9Q==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.0.0", - "@typescript-eslint/visitor-keys": "6.0.0", + "@typescript-eslint/types": "8.25.0", + "@typescript-eslint/visitor-keys": "8.25.0", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", - "semver": "^7.5.0", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.0.0.tgz", - "integrity": "sha512-SOr6l4NB6HE4H/ktz0JVVWNXqCJTOo/mHnvIte1ZhBQ0Cvd04x5uKZa3zT6tiodL06zf5xxdK8COiDvPnQ27JQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.3.0", - "@types/json-schema": "^7.0.11", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "6.0.0", - "@typescript-eslint/types": "6.0.0", - "@typescript-eslint/typescript-estree": "6.0.0", - "eslint-scope": "^5.1.1", - "semver": "^7.5.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.25.0.tgz", + "integrity": "sha512-syqRbrEv0J1wywiLsK60XzHnQe/kRViI3zwFALrNEgnntn1l24Ra2KvOAWwWbWZ1lBZxZljPDGOq967dsl6fkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.25.0", + "@typescript-eslint/types": "8.25.0", + "@typescript-eslint/typescript-estree": "8.25.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.0.0.tgz", - "integrity": "sha512-cvJ63l8c0yXdeT5POHpL0Q1cZoRcmRKFCtSjNGJxPkcP571EfZMcNbzWAc7oK3D1dRzm/V5EwtkANTZxqvuuUA==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.25.0.tgz", + "integrity": "sha512-kCYXKAum9CecGVHGij7muybDfTS2sD3t0L4bJsEZLkyrXUImiCTq1M3LG2SRtOhiHFwMR9wAFplpT6XHYjTkwQ==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.0.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "8.25.0", + "eslint-visitor-keys": "^4.2.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1151,24 +1203,26 @@ } }, "node_modules/@vscode/test-electron": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.3.8.tgz", - "integrity": "sha512-b4aZZsBKtMGdDljAsOPObnAi7+VWIaYl3ylCz1jTs+oV6BZ4TNHcVNC3xUn0azPeszBmwSBDQYfFESIaUQnrOg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.4.1.tgz", + "integrity": "sha512-Gc6EdaLANdktQ1t+zozoBVRynfIsMKMc94Svu1QreOBC8y76x4tvaK32TljrLi1LI2+PK58sDVbL7ALdqf3VRQ==", "dev": true, + "license": "MIT", "dependencies": { - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", "jszip": "^3.10.1", - "semver": "^7.5.2" + "ora": "^7.0.1", + "semver": "^7.6.2" }, "engines": { "node": ">=16" } }, "node_modules/@vscode/vsce": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-3.1.1.tgz", - "integrity": "sha512-N62Ca9ElRPLUUzf7l9CeEBlLrYzFPRQq7huKk4pVW+LjIOSXfFIPudixn5QvZcz+yXDOh15IopI3K2o3y9666Q==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-3.2.2.tgz", + "integrity": "sha512-4TqdUq/yKlQTHcQMk/DamR632bq/+IJDomSbexOMee/UAYWqYm0XHWA6scGslsCpzY+sCWEhhl0nqdOB0XW1kw==", "dev": true, "license": "MIT", "dependencies": { @@ -1178,7 +1232,7 @@ "chalk": "^2.4.2", "cheerio": "^1.0.0-rc.9", "cockatiel": "^3.1.2", - "commander": "^6.2.1", + "commander": "^12.1.0", "form-data": "^4.0.0", "glob": "^11.0.0", "hosted-git-info": "^4.0.2", @@ -1208,9 +1262,9 @@ } }, "node_modules/@vscode/vsce-sign": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vscode/vsce-sign/-/vsce-sign-2.0.4.tgz", - "integrity": "sha512-0uL32egStKYfy60IqnynAChMTbL0oqpqk0Ew0YHiIb+fayuGZWADuIPHWUcY1GCnAA+VgchOPDMxnc2R3XGWEA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign/-/vsce-sign-2.0.5.tgz", + "integrity": "sha512-GfYWrsT/vypTMDMgWDm75iDmAOMe7F71sZECJ+Ws6/xyIfmB3ELVnVN+LwMFAvmXY+e6eWhR2EzNGF/zAhWY3Q==", "dev": true, "hasInstallScript": true, "license": "SEE LICENSE IN LICENSE.txt", @@ -1352,141 +1406,36 @@ "win32" ] }, - "node_modules/@vscode/vsce/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@vscode/vsce/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@vscode/vsce/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@vscode/vsce/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@vscode/vsce/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@vscode/vsce/node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@vscode/vsce/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@vscode/vsce/node_modules/glob": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", - "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "node_modules/@vscode/vsce/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^4.0.1", - "minimatch": "^10.0.0", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" - }, - "bin": { - "glob": "dist/esm/bin.mjs" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@vscode/vsce/node_modules/glob/node_modules/minimatch": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", - "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@vscode/vsce/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@vscode/vsce/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" + "node": "*" } }, "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -1499,20 +1448,19 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", "dev": true, - "dependencies": { - "debug": "4" - }, + "license": "MIT", "engines": { - "node": ">= 6.0.0" + "node": ">= 14" } }, "node_modules/ajv": { @@ -1520,6 +1468,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1532,46 +1481,43 @@ } }, "node_modules/anser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/anser/-/anser-2.1.1.tgz", - "integrity": "sha512-nqLm4HxOTpeLOxcmB3QWmV5TcDFhW9y/fyQ+hivtDFcK4OQ+pQ5fzPnXHM1Mfcm0VkLtvVi1TCPr++Qy0Q/3EQ==" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/anser/-/anser-2.3.2.tgz", + "integrity": "sha512-PMqBCBvrOVDRqLGooQb+z+t1Q0PiPyurUQeZRR5uHBOVZcW8B04KMmnT12USnhpNX2wCPagWzLVppQMUG3u0Dw==", + "license": "MIT" }, "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "color-convert": "^1.9.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=4" } }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "engines": { - "node": ">=8" - } + "license": "Python-2.0" }, "node_modules/asynckit": { "version": "0.4.0", @@ -1594,7 +1540,8 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", @@ -1615,26 +1562,26 @@ "url": "https://feross.org/support" } ], - "optional": true + "license": "MIT" }, "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", "dev": true, - "optional": true, + "license": "MIT", "dependencies": { - "buffer": "^5.5.0", + "buffer": "^6.0.3", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, - "optional": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -1648,16 +1595,16 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { @@ -1665,6 +1612,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -1673,9 +1621,9 @@ } }, "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "dev": true, "funding": [ { @@ -1691,10 +1639,10 @@ "url": "https://feross.org/support" } ], - "optional": true, + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "ieee754": "^1.2.1" } }, "node_modules/buffer-crc32": { @@ -1702,6 +1650,7 @@ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -1713,18 +1662,45 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "dev": true, "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0", "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -1738,42 +1714,47 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=4" } }, "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", + "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", "dev": true, + "license": "MIT", "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" + "domutils": "^3.1.0", + "encoding-sniffer": "^0.2.0", + "htmlparser2": "^9.1.0", + "parse5": "^7.1.2", + "parse5-htmlparser2-tree-adapter": "^7.0.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^6.19.5", + "whatwg-mimetype": "^4.0.0" }, "engines": { - "node": ">= 6" + "node": ">=18.17" }, "funding": { "url": "https://github.com/cheeriojs/cheerio?sponsor=1" @@ -1784,6 +1765,7 @@ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", @@ -1801,18 +1783,50 @@ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "dev": true, + "license": "ISC", "optional": true }, "node_modules/ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -1822,6 +1836,97 @@ "node": ">=12" } }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cliui/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/cockatiel": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/cockatiel/-/cockatiel-3.2.1.tgz", @@ -1833,20 +1938,21 @@ } }, "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "color-name": "1.1.3" } }, "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", @@ -1862,30 +1968,35 @@ } }, "node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 10" + "node": ">=18" } }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1900,6 +2011,7 @@ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", @@ -1916,6 +2028,7 @@ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">= 6" }, @@ -1924,9 +2037,10 @@ } }, "node_modules/d3": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz", - "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "license": "ISC", "dependencies": { "d3-array": "3", "d3-axis": "3", @@ -1964,9 +2078,10 @@ } }, "node_modules/d3-array": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.2.tgz", - "integrity": "sha512-yEEyEAbDrF8C6Ob2myOBLjwBLck1Z89jMGFee0oPsn95GqjerpaOA4ch+vc2l0FNFFwMD5N7OCSEN5eAlsUbgQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", "dependencies": { "internmap": "1 - 2" }, @@ -1978,6 +2093,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "license": "ISC", "engines": { "node": ">=12" } @@ -1986,6 +2102,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", @@ -2001,6 +2118,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "license": "ISC", "dependencies": { "d3-path": "1 - 3" }, @@ -2012,6 +2130,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2020,6 +2139,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "license": "ISC", "dependencies": { "d3-array": "^3.2.0" }, @@ -2028,9 +2148,10 @@ } }, "node_modules/d3-delaunay": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.2.tgz", - "integrity": "sha512-IMLNldruDQScrcfT+MWnazhHbDJhcRJyOEBAJfwQnHle1RPh6WDuLvxNArUju2VSMSUuKlY5BGHRJ2cYyoFLQQ==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", "dependencies": { "delaunator": "5" }, @@ -2042,6 +2163,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2050,6 +2172,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", "d3-selection": "3" @@ -2062,6 +2185,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "license": "ISC", "dependencies": { "commander": "7", "iconv-lite": "0.6", @@ -2082,10 +2206,20 @@ "node": ">=12" } }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, "node_modules/d3-ease": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", "engines": { "node": ">=12" } @@ -2094,6 +2228,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "license": "ISC", "dependencies": { "d3-dsv": "1 - 3" }, @@ -2105,6 +2240,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", "d3-quadtree": "1 - 3", @@ -2118,14 +2254,16 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/d3-geo": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz", - "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "license": "ISC", "dependencies": { "d3-array": "2.5.0 - 3" }, @@ -2134,11 +2272,12 @@ } }, "node_modules/d3-graphviz": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/d3-graphviz/-/d3-graphviz-5.0.2.tgz", - "integrity": "sha512-EVRow9rnFgm/L1trbbnu2PGOND11IcSEdWXbrDbz9hH0/Kj3YM2AqMkkTN/EAWgawD5/zryyCy+3Vm05oSJ1Kg==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/d3-graphviz/-/d3-graphviz-5.6.0.tgz", + "integrity": "sha512-46OOyRv5Ioo9kZBc919FVIYPD/ObtdSZxOK1hv+qwmD7TunpPvvmsI1dSdxhVgH4GragJxFZ31+TQC5aOuXzzw==", + "license": "BSD-3-Clause", "dependencies": { - "@hpcc-js/wasm": "2.5.0", + "@hpcc-js/wasm": "^2.20.0", "d3-dispatch": "^3.0.1", "d3-format": "^3.1.0", "d3-interpolate": "^3.0.1", @@ -2154,38 +2293,11 @@ "d3-selection": "^3.0.0" } }, - "node_modules/d3-graphviz/node_modules/@hpcc-js/wasm": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-2.5.0.tgz", - "integrity": "sha512-G26BamgaHW46f6P8bmkygapgNcy+tTDMwIvCzmMzdp39sxUS1u4gaT/vR2SSDc4x3SfL5RE4B2B8ef/wd429Hg==", - "dependencies": { - "yargs": "17.6.2" - }, - "bin": { - "dot-wasm": "bin/dot-wasm.js" - } - }, - "node_modules/d3-graphviz/node_modules/yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/d3-hierarchy": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2194,6 +2306,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", "dependencies": { "d3-color": "1 - 3" }, @@ -2205,6 +2318,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2213,6 +2327,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2221,6 +2336,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2229,6 +2345,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2237,6 +2354,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", @@ -2249,9 +2367,10 @@ } }, "node_modules/d3-scale-chromatic": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", - "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", "dependencies": { "d3-color": "1 - 3", "d3-interpolate": "1 - 3" @@ -2264,6 +2383,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2272,6 +2392,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", "dependencies": { "d3-path": "^3.1.0" }, @@ -2283,6 +2404,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", "dependencies": { "d3-array": "2 - 3" }, @@ -2294,6 +2416,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", "dependencies": { "d3-time": "1 - 3" }, @@ -2305,6 +2428,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", "engines": { "node": ">=12" } @@ -2313,6 +2437,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", "dependencies": { "d3-color": "1 - 3", "d3-dispatch": "1 - 3", @@ -2331,6 +2456,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", @@ -2343,12 +2469,13 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -2364,6 +2491,7 @@ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "mimic-response": "^3.1.0" @@ -2380,6 +2508,7 @@ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=4.0.0" @@ -2389,42 +2518,59 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", "dev": true, "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/delaunator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz", - "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "license": "ISC", "dependencies": { - "robust-predicates": "^3.0.0" + "robust-predicates": "^3.0.2" } }, "node_modules/delayed-stream": { @@ -2438,44 +2584,22 @@ } }, "node_modules/detect-libc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", - "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", "dev": true, + "license": "Apache-2.0", "optional": true, "engines": { "node": ">=8" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -2495,13 +2619,15 @@ "type": "github", "url": "https://github.com/sponsors/fb55" } - ] + ], + "license": "BSD-2-Clause" }, "node_modules/domhandler": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" }, @@ -2513,19 +2639,35 @@ } }, "node_modules/domutils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", - "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", - "domhandler": "^5.0.1" + "domhandler": "^5.0.3" }, "funding": { "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -2544,25 +2686,43 @@ } }, "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/encoding-sniffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", + "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "once": "^1.4.0" } }, "node_modules/entities": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", - "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -2571,14 +2731,11 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -2593,6 +2750,35 @@ "node": ">= 0.4" } }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.25.0", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", @@ -2635,18 +2821,219 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "9.21.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.21.0.tgz", + "integrity": "sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.2", + "@eslint/core": "^0.12.0", + "@eslint/eslintrc": "^3.3.0", + "@eslint/js": "9.21.0", + "@eslint/plugin-kit": "^0.2.7", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.2.tgz", + "integrity": "sha512-1105/17ZIMjmCOJOPNfVdbXafLCLj3hPmkmB7dLgt7XsQ/zkxSuDerE/xgO3RxoHysR1N1whmquY0lSn2O0VLg==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "build/bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-define-config": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-define-config/-/eslint-define-config-2.1.0.tgz", + "integrity": "sha512-QUp6pM9pjKEVannNAbSJNeRuYwW3LshejfyBBpjeMGaJjaDUpVps4C6KVR8R7dWZnD3i0synmrE36znjTkJvdQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/Shinigami92" + }, + { + "type": "paypal", + "url": "https://www.paypal.com/donate/?hosted_button_id=L7GY729FBKTZY" + } + ], + "license": "MIT", + "engines": { + "node": ">=18.0.0", + "npm": ">=9.0.0", + "pnpm": ">=8.6.0" + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -2654,146 +3041,66 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz", - "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==", + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.1.0", - "@eslint/js": "8.44.0", - "@humanwhocodes/config-array": "^0.11.10", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.6.0", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": "*" } }, - "node_modules/eslint-config-prettier": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", - "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { + "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "has-flag": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" + "node": ">=8" } }, "node_modules/espree": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", - "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -2801,20 +3108,12 @@ "node": ">=0.10" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -2822,20 +3121,12 @@ "node": ">=4.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { + "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -2845,6 +3136,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -2864,6 +3156,7 @@ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", "dev": true, + "license": "(MIT OR WTFPL)", "optional": true, "engines": { "node": ">=6" @@ -2873,19 +3166,21 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", - "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -2896,6 +3191,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -2907,19 +3203,22 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz", + "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -2929,20 +3228,22 @@ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, + "license": "MIT", "dependencies": { "pend": "~1.2.0" } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, + "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/fill-range": { @@ -2950,6 +3251,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2962,6 +3264,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -2974,28 +3277,30 @@ } }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, + "license": "MIT", "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "dev": true, "funding": [ { @@ -3003,6 +3308,7 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -3030,14 +3336,15 @@ } }, "node_modules/form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", "mime-types": "^2.1.12" }, "engines": { @@ -3049,14 +3356,9 @@ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "dev": true, + "license": "MIT", "optional": true }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -3071,22 +3373,28 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -3095,28 +3403,47 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz", + "integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==", "dev": true, + "license": "ISC", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": "*" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -3127,6 +3454,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -3134,92 +3462,39 @@ "node": ">=10.13.0" } }, - "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "node_modules/glob/node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", "dev": true, + "license": "ISC", "dependencies": { - "type-fest": "^0.20.2" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=8" + "node": "20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, "license": "MIT", "engines": { @@ -3229,12 +3504,45 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, "engines": { "node": ">= 0.4" }, @@ -3260,6 +3568,7 @@ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -3268,9 +3577,9 @@ } }, "node_modules/htmlparser2": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", - "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", @@ -3279,44 +3588,47 @@ "url": "https://github.com/sponsors/fb55" } ], + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "entities": "^4.3.0" + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" } }, "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, + "license": "MIT", "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, + "license": "MIT", "dependencies": { - "agent-base": "6", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -3343,13 +3655,14 @@ "url": "https://feross.org/support" } ], - "optional": true + "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -3358,13 +3671,15 @@ "version": "3.0.6", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -3381,37 +3696,31 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true, + "license": "ISC", "optional": true }, "node_modules/internmap": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", "engines": { "node": ">=12" } @@ -3421,6 +3730,7 @@ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "dev": true, + "license": "MIT", "dependencies": { "ci-info": "^2.0.0" }, @@ -3429,16 +3739,16 @@ } }, "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", "dev": true, "license": "MIT", "bin": { "is-docker": "cli.js" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -3449,6 +3759,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -3457,6 +3768,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { "node": ">=8" } @@ -3466,6 +3778,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -3473,53 +3786,95 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", "dev": true, "license": "MIT", "dependencies": { - "is-docker": "^2.0.0" + "is-inside-container": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/jackspeak": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", - "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.0.tgz", + "integrity": "sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -3532,11 +3887,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -3544,23 +3909,33 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" }, "node_modules/jsonwebtoken": { "version": "9.0.2", @@ -3613,6 +3988,7 @@ "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", "dev": true, + "license": "(MIT OR GPL-3.0-or-later)", "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", @@ -3649,17 +4025,29 @@ "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "dependencies": { "node-addon-api": "^4.3.0", "prebuild-install": "^7.0.1" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3669,6 +4057,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -3682,6 +4071,7 @@ "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", "dev": true, + "license": "MIT", "dependencies": { "immediate": "~3.0.5" } @@ -3701,6 +4091,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -3757,7 +4148,8 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.once": { "version": "4.1.1", @@ -3766,10 +4158,42 @@ "dev": true, "license": "MIT" }, + "node_modules/log-symbols": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", + "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.0.0", + "is-unicode-supported": "^1.1.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -3795,6 +4219,16 @@ "markdown-it": "bin/markdown-it.mjs" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", @@ -3807,6 +4241,7 @@ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -3825,11 +4260,25 @@ "node": ">=8.6" } }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -3860,11 +4309,22 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/mimic-response": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=10" @@ -3874,22 +4334,27 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, + "license": "MIT", "optional": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3910,44 +4375,44 @@ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "node_modules/mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-abi": { - "version": "3.31.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.31.0.tgz", - "integrity": "sha512-eSKV6s+APenqVh8ubJyiu/YhZgxQpGP66ntzUb3lY1xB9ukSRaGnx0AIxI+IM+1+IVYC1oWobgG5L3Lt9ARykQ==", + "version": "3.74.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz", + "integrity": "sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "semver": "^7.3.5" @@ -3961,6 +4426,7 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/nth-check": { @@ -3968,6 +4434,7 @@ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0" }, @@ -3976,9 +4443,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, "license": "MIT", "engines": { @@ -3993,251 +4460,180 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", + "optional": true, "dependencies": { "wrappy": "1" } }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "license": "MIT", "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" + "mimic-fn": "^2.1.0" }, "engines": { - "node": ">=12" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" } }, - "node_modules/ovsx": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.8.2.tgz", - "integrity": "sha512-btDXZorXlmwN9+9Un3khrVygCXmhwbrtg8gifNXw92rZPXcRBAiLG/L09Kb6srhGEratsFt42AktfD8t9XhzoA==", + "node_modules/ora": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-7.0.1.tgz", + "integrity": "sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==", "dev": true, + "license": "MIT", "dependencies": { - "@vscode/vsce": "^2.19.0", - "commander": "^6.1.0", + "chalk": "^5.3.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.9.0", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^1.3.0", + "log-symbols": "^5.1.0", + "stdin-discarder": "^0.1.0", + "string-width": "^6.1.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ora/node_modules/string-width": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-6.1.0.tgz", + "integrity": "sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^10.2.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ovsx": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.10.1.tgz", + "integrity": "sha512-8i7+MJMMeq73m1zPEIClSFe17SNuuzU5br7G77ZIfOC24elB4pGQs0N1qRd+gnnbyhL5Qu96G21nFOVOBa2OBg==", + "dev": true, + "license": "EPL-2.0", + "dependencies": { + "@vscode/vsce": "^3.2.1", + "commander": "^6.2.1", "follow-redirects": "^1.14.6", "is-ci": "^2.0.0", "leven": "^3.1.0", - "semver": "^7.5.2", - "tmp": "^0.2.1" + "semver": "^7.6.0", + "tmp": "^0.2.3", + "yauzl": "^3.1.3" }, "bin": { "ovsx": "lib/ovsx" }, "engines": { - "node": ">= 14" + "node": ">= 20" } }, - "node_modules/ovsx/node_modules/@vscode/vsce": { - "version": "2.32.0", - "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-2.32.0.tgz", - "integrity": "sha512-3EFJfsgrSftIqt3EtdRcAygy/OJ3hstyI1cDmIgkU9CFZW5C+3djr6mfosndCUqcVYuyjmxOK1xmFp/Bq7+NIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@azure/identity": "^4.1.0", - "@vscode/vsce-sign": "^2.0.0", - "azure-devops-node-api": "^12.5.0", - "chalk": "^2.4.2", - "cheerio": "^1.0.0-rc.9", - "cockatiel": "^3.1.2", - "commander": "^6.2.1", - "form-data": "^4.0.0", - "glob": "^7.0.6", - "hosted-git-info": "^4.0.2", - "jsonc-parser": "^3.2.0", - "leven": "^3.1.0", - "markdown-it": "^12.3.2", - "mime": "^1.3.4", - "minimatch": "^3.0.3", - "parse-semver": "^1.1.1", - "read": "^1.0.7", - "semver": "^7.5.2", - "tmp": "^0.2.1", - "typed-rest-client": "^1.8.4", - "url-join": "^4.0.1", - "xml2js": "^0.5.0", - "yauzl": "^2.3.1", - "yazl": "^2.2.2" - }, - "bin": { - "vsce": "vsce" - }, - "engines": { - "node": ">= 16" - }, - "optionalDependencies": { - "keytar": "^7.7.0" - } - }, - "node_modules/ovsx/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ovsx/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ovsx/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/ovsx/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, "node_modules/ovsx/node_modules/commander": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, - "node_modules/ovsx/node_modules/entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", - "dev": true, - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/ovsx/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ovsx/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/ovsx/node_modules/linkify-it": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", - "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "node_modules/ovsx/node_modules/yauzl": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.2.0.tgz", + "integrity": "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w==", "dev": true, "license": "MIT", "dependencies": { - "uc.micro": "^1.0.1" - } - }, - "node_modules/ovsx/node_modules/markdown-it": { - "version": "12.3.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", - "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1", - "entities": "~2.1.0", - "linkify-it": "^3.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - }, - "bin": { - "markdown-it": "bin/markdown-it.js" - } - }, - "node_modules/ovsx/node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true, - "license": "MIT" - }, - "node_modules/ovsx/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" + "buffer-crc32": "~0.2.3", + "pend": "~1.2.0" }, "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/ovsx/node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true, - "license": "MIT" - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -4253,6 +4649,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -4274,13 +4671,15 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true + "dev": true, + "license": "(MIT AND Zlib)" }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -4293,6 +4692,7 @@ "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", "integrity": "sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^5.1.0" } @@ -4302,29 +4702,45 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver" } }, "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", "dev": true, + "license": "MIT", "dependencies": { - "entities": "^4.4.0" + "entities": "^4.5.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" } }, "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", "dev": true, + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "dev": true, + "license": "MIT", "dependencies": { - "domhandler": "^5.0.2", "parse5": "^7.0.0" }, "funding": { @@ -4336,24 +4752,17 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4376,47 +4785,41 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz", - "integrity": "sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", + "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", "dev": true, "license": "ISC", "engines": { "node": "20 || >=22" } }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/prebuild-install": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", - "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "detect-libc": "^2.0.0", @@ -4424,7 +4827,7 @@ "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", + "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", @@ -4444,15 +4847,17 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", - "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.2.tgz", + "integrity": "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -4467,13 +4872,15 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "end-of-stream": "^1.1.0", @@ -4481,10 +4888,11 @@ } }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4500,13 +4908,13 @@ } }, "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.6" + "side-channel": "^1.1.0" }, "engines": { "node": ">=0.6" @@ -4533,13 +4941,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "optional": true, "dependencies": { "deep-extend": "^0.6.0", @@ -4556,6 +4966,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -4566,6 +4977,7 @@ "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", "dev": true, + "license": "ISC", "dependencies": { "mute-stream": "~0.0.4" }, @@ -4578,6 +4990,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -4588,10 +5001,18 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4601,40 +5022,65 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, - "node_modules/rimraf": { + "node_modules/robust-predicates": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", + "license": "Unlicense" + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "license": "MIT", + "engines": { + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/robust-predicates": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.1.tgz", - "integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==" - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -4654,6 +5100,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -4661,32 +5108,48 @@ "node_modules/rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" }, "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" }, "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "dev": true, + "license": "ISC" }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -4694,35 +5157,19 @@ "node": ">=10" } }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -4735,21 +5182,79 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -4790,6 +5295,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "optional": true }, "node_modules/simple-get": { @@ -4811,6 +5317,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "optional": true, "dependencies": { "decompress-response": "^6.0.0", @@ -4818,13 +5325,20 @@ "simple-concat": "^1.0.0" } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/stdin-discarder": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.1.0.tgz", + "integrity": "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==", "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^5.0.0" + }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/stoppable": { @@ -4843,21 +5357,34 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/string-width-cjs": { @@ -4876,10 +5403,29 @@ "node": ">=8" } }, - "node_modules/strip-ansi": { + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -4887,6 +5433,22 @@ "node": ">=8" } }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", @@ -4901,11 +5463,22 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -4914,22 +5487,24 @@ } }, "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "has-flag": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz", + "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "chownr": "^1.1.1", @@ -4943,6 +5518,7 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "bl": "^4.0.3", @@ -4955,11 +5531,51 @@ "node": ">=6" } }, - "node_modules/tar-stream/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "node_modules/tar-stream/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/tar-stream/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", "optional": true, "dependencies": { "inherits": "^2.0.3", @@ -4970,12 +5586,6 @@ "node": ">= 6" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, "node_modules/tmp": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", @@ -4991,6 +5601,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -4999,21 +5610,22 @@ } }, "node_modules/ts-api-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", - "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", + "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", "dev": true, + "license": "MIT", "engines": { - "node": ">=16.13.0" + "node": ">=18.12" }, "peerDependencies": { - "typescript": ">=4.2.0" + "typescript": ">=4.8.4" } }, "node_modules/tslib": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", - "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, "license": "0BSD" }, @@ -5032,6 +5644,7 @@ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dev": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "safe-buffer": "^5.0.1" @@ -5045,6 +5658,7 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -5052,18 +5666,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/typed-rest-client": { "version": "1.8.11", "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz", @@ -5077,9 +5679,9 @@ } }, "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -5090,6 +5692,29 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.25.0.tgz", + "integrity": "sha512-TxRdQQLH4g7JkoFlYG3caW5v1S6kEkz8rqt80iQJZUYPq1zD1Ra7HfQBJJ88ABRaMvHAXnwRvRB4V+6sQ9xN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.25.0", + "@typescript-eslint/parser": "8.25.0", + "@typescript-eslint/utils": "8.25.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, "node_modules/uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", @@ -5104,11 +5729,29 @@ "dev": true, "license": "MIT" }, + "node_modules/undici": { + "version": "6.21.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz", + "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -5117,13 +5760,15 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/uuid": { "version": "8.3.2", @@ -5139,6 +5784,7 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "license": "MIT", "engines": { "node": ">=14.0.0" } @@ -5147,6 +5793,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-9.0.1.tgz", "integrity": "sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA==", + "license": "MIT", "dependencies": { "minimatch": "^5.1.0", "semver": "^7.3.7", @@ -5156,18 +5803,11 @@ "vscode": "^1.82.0" } }, - "node_modules/vscode-languageclient/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/vscode-languageclient/node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -5179,6 +5819,7 @@ "version": "3.17.5", "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "license": "MIT", "dependencies": { "vscode-jsonrpc": "8.2.0", "vscode-languageserver-types": "3.17.5" @@ -5187,13 +5828,38 @@ "node_modules/vscode-languageserver-types": { "version": "3.17.5", "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", - "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==" + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "license": "MIT" + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -5204,17 +5870,29 @@ "node": ">= 8" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" @@ -5239,11 +5917,107 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC", + "optional": true }, "node_modules/xml2js": { "version": "0.5.0", @@ -5264,6 +6038,7 @@ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4.0" } @@ -5272,6 +6047,7 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", "engines": { "node": ">=10" } @@ -5279,12 +6055,15 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -5302,15 +6081,58 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", "engines": { "node": ">=12" } }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, + "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" @@ -5321,6 +6143,7 @@ "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", "dev": true, + "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3" } @@ -5330,6 +6153,7 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, diff --git a/editors/code/package.json b/editors/code/package.json index a7c8506a45..587ae92520 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -7,6 +7,7 @@ "version": "0.5.0-dev", "releaseTag": null, "publisher": "rust-lang", + "type": "commonjs", "repository": { "url": "https://github.com/rust-lang/rust-analyzer.git", "type": "git" @@ -27,45 +28,51 @@ } }, "engines": { - "vscode": "^1.83.0" + "vscode": "^1.93.0" }, "enabledApiProposals": [], "scripts": { "vscode:prepublish": "npm run build-base -- --minify", "package": "vsce package -o rust-analyzer.vsix", - "build-base": "esbuild ./src/main.ts --bundle --outfile=out/main.js --external:vscode --format=cjs --platform=node --target=node16", + "build-base": "esbuild ./src/main.ts --bundle --outfile=out/main.js --external:vscode --format=cjs --platform=node --target=node20", "build": "npm run build-base -- --sourcemap", "watch": "npm run build-base -- --sourcemap --watch", - "format": "prettier --write .", - "format:check": "prettier --check .", - "lint": "eslint -c .eslintrc.js --ext ts ./src ./tests", + "format": "node --experimental-strip-types node_modules/prettier/bin/prettier.cjs . --write", + "format:check": "node --experimental-strip-types node_modules/prettier/bin/prettier.cjs . --check", + "lint": "eslint .", "lint:fix": "npm run lint -- --fix", "typecheck": "tsc", "pretest": "npm run typecheck && npm run build", "test": "node ./out/tests/runTests.js" }, "dependencies": { - "@hpcc-js/wasm": "^2.13.0", - "anser": "^2.1.1", - "d3": "^7.8.5", - "d3-graphviz": "^5.0.2", + "@hpcc-js/wasm": "^2.22.4", + "anser": "^2.3.2", + "d3": "^7.9.0", + "d3-graphviz": "^5.6.0", + "jiti": "^2.4.2", "vscode-languageclient": "^9.0.1" }, "devDependencies": { - "@tsconfig/strictest": "^2.0.1", - "@types/node": "~16.11.7", - "@types/vscode": "~1.83", - "@typescript-eslint/eslint-plugin": "^6.0.0", - "@typescript-eslint/parser": "^6.0.0", - "@vscode/test-electron": "^2.3.8", - "@vscode/vsce": "^3.0.0", + "@eslint/js": "^9.21.0", + "@stylistic/eslint-plugin": "^4.1.0", + "@stylistic/eslint-plugin-js": "^4.1.0", + "@tsconfig/strictest": "^2.0.5", + "@types/node": "~22.13.4", + "@types/vscode": "~1.93.0", + "@typescript-eslint/eslint-plugin": "^8.25.0", + "@typescript-eslint/parser": "^8.25.0", + "@vscode/test-electron": "^2.4.1", + "@vscode/vsce": "^3.2.2", "esbuild": "^0.25.0", - "eslint": "^8.44.0", - "eslint-config-prettier": "^8.8.0", - "ovsx": "^0.8.2", - "prettier": "^3.0.0", - "tslib": "^2.6.0", - "typescript": "^5.6.0" + "eslint": "^9.21.0", + "eslint-config-prettier": "^10.0.2", + "eslint-define-config": "^2.1.0", + "ovsx": "0.10.1", + "prettier": "^3.5.2", + "tslib": "^2.8.1", + "typescript": "^5.7.3", + "typescript-eslint": "^8.25.0" }, "activationEvents": [ "workspaceContains:Cargo.toml", diff --git a/editors/code/prettier.config.mts b/editors/code/prettier.config.mts new file mode 100644 index 0000000000..45cb3874ee --- /dev/null +++ b/editors/code/prettier.config.mts @@ -0,0 +1,12 @@ +import { type Config } from "prettier"; + +const config: Config = { + // use 4 because it's Rustfmt's default + // https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#%5C34%20%5C%20%5C(default%5C)%5C%3A + tabWidth: 4, + // use 100 because it's Rustfmt's default + // https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#max_width + printWidth: 100, +}; + +export default config; diff --git a/editors/code/src/bootstrap.ts b/editors/code/src/bootstrap.ts index 8fc9f09324..bccae73c9a 100644 --- a/editors/code/src/bootstrap.ts +++ b/editors/code/src/bootstrap.ts @@ -177,9 +177,9 @@ async function hasToolchainFileWithRaDeclared(uri: vscode.Uri): Promise await vscode.workspace.fs.readFile(uri), ); return ( - toolchainFileContents.match(/components\s*=\s*\[.*\"rust-analyzer\".*\]/g)?.length === 1 + toolchainFileContents.match(/components\s*=\s*\[.*"rust-analyzer".*\]/g)?.length === 1 ); - } catch (e) { + } catch (_) { return false; } } diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index eac7b849fd..cdeea7333a 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -18,282 +18,263 @@ export async function createClient( config: Config, unlinkedFiles: vscode.Uri[], ): Promise { + const raMiddleware: lc.Middleware = { + workspace: { + // HACK: This is a workaround, when the client has been disposed, VSCode + // continues to emit events to the client and the default one for this event + // attempt to restart the client for no reason + async didChangeWatchedFile(event, next) { + if (client.isRunning()) { + await next(event); + } + }, + async configuration( + params: lc.ConfigurationParams, + token: vscode.CancellationToken, + next: lc.ConfigurationRequest.HandlerSignature, + ) { + const resp = await next(params, token); + if (resp && Array.isArray(resp)) { + return resp.map((val) => { + return prepareVSCodeConfig(val); + }); + } else { + return resp; + } + }, + }, + async handleDiagnostics( + uri: vscode.Uri, + diagnosticList: vscode.Diagnostic[], + next: lc.HandleDiagnosticsSignature, + ) { + const preview = config.previewRustcOutput; + const errorCode = config.useRustcErrorCode; + diagnosticList.forEach((diag, idx) => { + const value = + typeof diag.code === "string" || typeof diag.code === "number" + ? diag.code + : diag.code?.value; + if ( + // FIXME: We currently emit this diagnostic way too early, before we have + // loaded the project fully + // value === "unlinked-file" && + value === "temporary-disabled" && + !unlinkedFiles.includes(uri) && + (diag.message === "file not included in crate hierarchy" || + diag.message.startsWith("This file is not included in any crates")) + ) { + const config = vscode.workspace.getConfiguration("rust-analyzer"); + if (config.get("showUnlinkedFileNotification")) { + unlinkedFiles.push(uri); + const folder = vscode.workspace.getWorkspaceFolder(uri)?.uri.fsPath; + if (folder) { + const parentBackslash = uri.fsPath.lastIndexOf(pathSeparator + "src"); + const parent = uri.fsPath.substring(0, parentBackslash); + + if (parent.startsWith(folder)) { + const path = vscode.Uri.file(parent + pathSeparator + "Cargo.toml"); + void vscode.workspace.fs.stat(path).then(async () => { + const choice = await vscode.window.showInformationMessage( + `This rust file does not belong to a loaded cargo project. It looks like it might belong to the workspace at ${path.path}, do you want to add it to the linked Projects?`, + "Yes", + "No", + "Don't show this again", + ); + switch (choice) { + case undefined: + break; + case "No": + break; + case "Yes": { + const pathToInsert = + "." + + parent.substring(folder.length) + + pathSeparator + + "Cargo.toml"; + const value = config + // eslint-disable-next-line @typescript-eslint/no-explicit-any + .get("linkedProjects") + ?.concat(pathToInsert); + await config.update("linkedProjects", value, false); + break; + } + case "Don't show this again": + await config.update( + "showUnlinkedFileNotification", + false, + false, + ); + break; + } + }); + } + } + } + } + + // Abuse the fact that VSCode leaks the LSP diagnostics data field through the + // Diagnostic class, if they ever break this we are out of luck and have to go + // back to the worst diagnostics experience ever:) + + // We encode the rendered output of a rustc diagnostic in the rendered field of + // the data payload of the lsp diagnostic. If that field exists, overwrite the + // diagnostic code such that clicking it opens the diagnostic in a readonly + // text editor for easy inspection + const rendered = (diag as unknown as { data?: { rendered?: string } }).data + ?.rendered; + if (rendered) { + if (preview) { + const decolorized = anser.ansiToText(rendered); + const index = decolorized.match(/^(note|help):/m)?.index || rendered.length; + diag.message = decolorized + .substring(0, index) + .replace(/^ -->[^\n]+\n/m, ""); + } + diag.code = { + target: vscode.Uri.from({ + scheme: diagnostics.URI_SCHEME, + path: `/diagnostic message [${idx.toString()}]`, + fragment: uri.toString(), + query: idx.toString(), + }), + value: errorCode && value ? value : "Click for full compiler diagnostic", + }; + } + }); + return next(uri, diagnosticList); + }, + async provideHover( + document: vscode.TextDocument, + position: vscode.Position, + token: vscode.CancellationToken, + _next: lc.ProvideHoverSignature, + ) { + const editor = vscode.window.activeTextEditor; + const positionOrRange = editor?.selection?.contains(position) + ? client.code2ProtocolConverter.asRange(editor.selection) + : client.code2ProtocolConverter.asPosition(position); + const params = { + textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document), + position: positionOrRange, + }; + return client.sendRequest(ra.hover, params, token).then( + (result) => { + if (!result) return null; + const hover = client.protocol2CodeConverter.asHover(result); + if (result.actions) { + hover.contents.push(renderHoverActions(result.actions)); + } + return hover; + }, + (error) => { + client.handleFailedRequest(lc.HoverRequest.type, token, error, null); + return Promise.resolve(null); + }, + ); + }, + // Using custom handling of CodeActions to support action groups and snippet edits. + // Note that this means we have to re-implement lazy edit resolving ourselves as well. + async provideCodeActions( + document: vscode.TextDocument, + range: vscode.Range, + context: vscode.CodeActionContext, + token: vscode.CancellationToken, + _next: lc.ProvideCodeActionsSignature, + ) { + const params: lc.CodeActionParams = { + textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document), + range: client.code2ProtocolConverter.asRange(range), + context: await client.code2ProtocolConverter.asCodeActionContext(context, token), + }; + const callback = async ( + values: (lc.Command | lc.CodeAction)[] | null, + ): Promise<(vscode.Command | vscode.CodeAction)[] | undefined> => { + if (values === null) return undefined; + const result: (vscode.CodeAction | vscode.Command)[] = []; + const groups = new Map(); + for (const item of values) { + // In our case we expect to get code edits only from diagnostics + if (lc.CodeAction.is(item)) { + assert(!item.command, "We don't expect to receive commands in CodeActions"); + const action = await client.protocol2CodeConverter.asCodeAction( + item, + token, + ); + result.push(action); + continue; + } + assert( + isCodeActionWithoutEditsAndCommands(item), + "We don't expect edits or commands here", + ); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const kind = client.protocol2CodeConverter.asCodeActionKind((item as any).kind); + const action = new vscode.CodeAction(item.title, kind); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const group = (item as any).group; + action.command = { + command: "rust-analyzer.resolveCodeAction", + title: item.title, + arguments: [item], + }; + + // Set a dummy edit, so that VS Code doesn't try to resolve this. + action.edit = new WorkspaceEdit(); + + if (group) { + let entry = groups.get(group); + if (!entry) { + entry = { index: result.length, items: [] }; + groups.set(group, entry); + result.push(action); + } + entry.items.push(action); + } else { + result.push(action); + } + } + for (const [group, { index, items }] of groups) { + if (items.length === 1) { + const item = unwrapUndefinable(items[0]); + result[index] = item; + } else { + const action = new vscode.CodeAction(group); + const item = unwrapUndefinable(items[0]); + action.kind = item.kind; + action.command = { + command: "rust-analyzer.applyActionGroup", + title: "", + arguments: [ + items.map((item) => { + return { + label: item.title, + arguments: item.command!.arguments![0], + }; + }), + ], + }; + + // Set a dummy edit, so that VS Code doesn't try to resolve this. + action.edit = new WorkspaceEdit(); + + result[index] = action; + } + } + return result; + }; + return client + .sendRequest(lc.CodeActionRequest.type, params, token) + .then(callback, (_error) => undefined); + }, + }; const clientOptions: lc.LanguageClientOptions = { documentSelector: [{ scheme: "file", language: "rust" }], initializationOptions, diagnosticCollectionName: "rustc", traceOutputChannel, outputChannel, - middleware: { - workspace: { - // HACK: This is a workaround, when the client has been disposed, VSCode - // continues to emit events to the client and the default one for this event - // attempt to restart the client for no reason - async didChangeWatchedFile(event, next) { - if (client.isRunning()) { - await next(event); - } - }, - async configuration( - params: lc.ConfigurationParams, - token: vscode.CancellationToken, - next: lc.ConfigurationRequest.HandlerSignature, - ) { - const resp = await next(params, token); - if (resp && Array.isArray(resp)) { - return resp.map((val) => { - return prepareVSCodeConfig(val); - }); - } else { - return resp; - } - }, - }, - async handleDiagnostics( - uri: vscode.Uri, - diagnosticList: vscode.Diagnostic[], - next: lc.HandleDiagnosticsSignature, - ) { - const preview = config.previewRustcOutput; - const errorCode = config.useRustcErrorCode; - diagnosticList.forEach((diag, idx) => { - const value = - typeof diag.code === "string" || typeof diag.code === "number" - ? diag.code - : diag.code?.value; - if ( - // FIXME: We currently emit this diagnostic way too early, before we have - // loaded the project fully - // value === "unlinked-file" && - value === "temporary-disabled" && - !unlinkedFiles.includes(uri) && - (diag.message === "file not included in crate hierarchy" || - diag.message.startsWith("This file is not included in any crates")) - ) { - const config = vscode.workspace.getConfiguration("rust-analyzer"); - if (config.get("showUnlinkedFileNotification")) { - unlinkedFiles.push(uri); - const folder = vscode.workspace.getWorkspaceFolder(uri)?.uri.fsPath; - if (folder) { - const parentBackslash = uri.fsPath.lastIndexOf( - pathSeparator + "src", - ); - const parent = uri.fsPath.substring(0, parentBackslash); - - if (parent.startsWith(folder)) { - const path = vscode.Uri.file( - parent + pathSeparator + "Cargo.toml", - ); - void vscode.workspace.fs.stat(path).then(async () => { - const choice = await vscode.window.showInformationMessage( - `This rust file does not belong to a loaded cargo project. It looks like it might belong to the workspace at ${path.path}, do you want to add it to the linked Projects?`, - "Yes", - "No", - "Don't show this again", - ); - switch (choice) { - case undefined: - break; - case "No": - break; - case "Yes": - const pathToInsert = - "." + - parent.substring(folder.length) + - pathSeparator + - "Cargo.toml"; - await config.update( - "linkedProjects", - config - .get("linkedProjects") - ?.concat(pathToInsert), - false, - ); - break; - case "Don't show this again": - await config.update( - "showUnlinkedFileNotification", - false, - false, - ); - break; - } - }); - } - } - } - } - - // Abuse the fact that VSCode leaks the LSP diagnostics data field through the - // Diagnostic class, if they ever break this we are out of luck and have to go - // back to the worst diagnostics experience ever:) - - // We encode the rendered output of a rustc diagnostic in the rendered field of - // the data payload of the lsp diagnostic. If that field exists, overwrite the - // diagnostic code such that clicking it opens the diagnostic in a readonly - // text editor for easy inspection - const rendered = (diag as unknown as { data?: { rendered?: string } }).data - ?.rendered; - if (rendered) { - if (preview) { - const decolorized = anser.ansiToText(rendered); - const index = - decolorized.match(/^(note|help):/m)?.index || rendered.length; - diag.message = decolorized - .substring(0, index) - .replace(/^ -->[^\n]+\n/m, ""); - } - diag.code = { - target: vscode.Uri.from({ - scheme: diagnostics.URI_SCHEME, - path: `/diagnostic message [${idx.toString()}]`, - fragment: uri.toString(), - query: idx.toString(), - }), - value: - errorCode && value ? value : "Click for full compiler diagnostic", - }; - } - }); - return next(uri, diagnosticList); - }, - async provideHover( - document: vscode.TextDocument, - position: vscode.Position, - token: vscode.CancellationToken, - _next: lc.ProvideHoverSignature, - ) { - const editor = vscode.window.activeTextEditor; - const positionOrRange = editor?.selection?.contains(position) - ? client.code2ProtocolConverter.asRange(editor.selection) - : client.code2ProtocolConverter.asPosition(position); - return client - .sendRequest( - ra.hover, - { - textDocument: - client.code2ProtocolConverter.asTextDocumentIdentifier(document), - position: positionOrRange, - }, - token, - ) - .then( - (result) => { - if (!result) return null; - const hover = client.protocol2CodeConverter.asHover(result); - if (!!result.actions) { - hover.contents.push(renderHoverActions(result.actions)); - } - return hover; - }, - (error) => { - client.handleFailedRequest(lc.HoverRequest.type, token, error, null); - return Promise.resolve(null); - }, - ); - }, - // Using custom handling of CodeActions to support action groups and snippet edits. - // Note that this means we have to re-implement lazy edit resolving ourselves as well. - async provideCodeActions( - document: vscode.TextDocument, - range: vscode.Range, - context: vscode.CodeActionContext, - token: vscode.CancellationToken, - _next: lc.ProvideCodeActionsSignature, - ) { - const params: lc.CodeActionParams = { - textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document), - range: client.code2ProtocolConverter.asRange(range), - context: await client.code2ProtocolConverter.asCodeActionContext( - context, - token, - ), - }; - return client.sendRequest(lc.CodeActionRequest.type, params, token).then( - async (values) => { - if (values === null) return undefined; - const result: (vscode.CodeAction | vscode.Command)[] = []; - const groups = new Map< - string, - { index: number; items: vscode.CodeAction[] } - >(); - for (const item of values) { - // In our case we expect to get code edits only from diagnostics - if (lc.CodeAction.is(item)) { - assert( - !item.command, - "We don't expect to receive commands in CodeActions", - ); - const action = await client.protocol2CodeConverter.asCodeAction( - item, - token, - ); - result.push(action); - continue; - } - assert( - isCodeActionWithoutEditsAndCommands(item), - "We don't expect edits or commands here", - ); - const kind = client.protocol2CodeConverter.asCodeActionKind( - (item as any).kind, - ); - const action = new vscode.CodeAction(item.title, kind); - const group = (item as any).group; - action.command = { - command: "rust-analyzer.resolveCodeAction", - title: item.title, - arguments: [item], - }; - - // Set a dummy edit, so that VS Code doesn't try to resolve this. - action.edit = new WorkspaceEdit(); - - if (group) { - let entry = groups.get(group); - if (!entry) { - entry = { index: result.length, items: [] }; - groups.set(group, entry); - result.push(action); - } - entry.items.push(action); - } else { - result.push(action); - } - } - for (const [group, { index, items }] of groups) { - if (items.length === 1) { - const item = unwrapUndefinable(items[0]); - result[index] = item; - } else { - const action = new vscode.CodeAction(group); - const item = unwrapUndefinable(items[0]); - action.kind = item.kind; - action.command = { - command: "rust-analyzer.applyActionGroup", - title: "", - arguments: [ - items.map((item) => { - return { - label: item.title, - arguments: item.command!.arguments![0], - }; - }), - ], - }; - - // Set a dummy edit, so that VS Code doesn't try to resolve this. - action.edit = new WorkspaceEdit(); - - result[index] = action; - } - } - return result; - }, - (_error) => undefined, - ); - }, - }, + middleware: raMiddleware, markdown: { supportHtml: true, }, @@ -319,9 +300,11 @@ class ExperimentalFeatures implements lc.StaticFeature { constructor(config: Config) { this.testExplorer = config.testExplorer || false; } + getState(): lc.FeatureState { return { kind: "static" }; } + fillClientCapabilities(capabilities: lc.ClientCapabilities): void { capabilities.experimental = { snippetTextEdit: true, @@ -345,11 +328,14 @@ class ExperimentalFeatures implements lc.StaticFeature { ...capabilities.experimental, }; } + initialize( _capabilities: lc.ServerCapabilities, _documentSelector: lc.DocumentSelector | undefined, ): void {} + dispose(): void {} + clear(): void {} } @@ -357,6 +343,7 @@ class OverrideFeatures implements lc.StaticFeature { getState(): lc.FeatureState { return { kind: "static" }; } + fillClientCapabilities(capabilities: lc.ClientCapabilities): void { // Force disable `augmentsSyntaxTokens`, VSCode's textmate grammar is somewhat incomplete // making the experience generally worse @@ -365,14 +352,18 @@ class OverrideFeatures implements lc.StaticFeature { caps.augmentsSyntaxTokens = false; } } + initialize( _capabilities: lc.ServerCapabilities, _documentSelector: lc.DocumentSelector | undefined, ): void {} + dispose(): void {} + clear(): void {} } +// eslint-disable-next-line @typescript-eslint/no-explicit-any function isCodeActionWithoutEditsAndCommands(value: any): boolean { const candidate: lc.CodeAction = value; return ( diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index eee623ecae..4e614d3205 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts @@ -78,6 +78,7 @@ export function memoryUsage(ctx: CtxInit): Cmd { provideTextDocumentContent(_uri: vscode.Uri): vscode.ProviderResult { if (!vscode.window.activeTextEditor) return ""; + // eslint-disable-next-line @typescript-eslint/no-explicit-any return ctx.client.sendRequest(ra.memoryUsage).then((mem: any) => { return "Per-query memory usage:\n" + mem + "\n(note: database has been cleared)"; }); @@ -161,7 +162,7 @@ export function joinLines(ctx: CtxInit): Cmd { }); const textEdits = await client.protocol2CodeConverter.asTextEdits(items); await editor.edit((builder) => { - textEdits.forEach((edit: any) => { + textEdits.forEach((edit: vscode.TextEdit) => { builder.replace(edit.range, edit.newText); }); }); @@ -209,6 +210,7 @@ export function onEnter(ctx: CtxInit): Cmd { ), position: client.code2ProtocolConverter.asPosition(editor.selection.active), }) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .catch((_error: any) => { // client.handleFailedRequest(OnEnterRequest.type, error, null); return null; @@ -528,6 +530,7 @@ function viewFileUsingTextDocumentContentProvider( void sleep(10).then(() => this.eventEmitter.fire(this.uri)); } } + private onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) { if (editor && isRustEditor(editor) && shouldUpdate) { this.eventEmitter.fire(this.uri); @@ -620,6 +623,7 @@ export function viewFileText(ctx: CtxInit): Cmd { void sleep(10).then(() => this.eventEmitter.fire(this.uri)); } } + private onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) { if (editor && isRustEditor(editor)) { this.eventEmitter.fire(this.uri); @@ -683,6 +687,7 @@ export function viewItemTree(ctx: CtxInit): Cmd { void sleep(10).then(() => this.eventEmitter.fire(this.uri)); } } + private onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) { if (editor && isRustEditor(editor)) { this.eventEmitter.fire(this.uri); @@ -1001,9 +1006,8 @@ export function resolveCodeAction(ctx: CtxInit): Cmd { ...itemEdit, documentChanges: itemEdit.documentChanges?.filter((change) => "kind" in change), }; - const fileSystemEdit = await client.protocol2CodeConverter.asWorkspaceEdit( - lcFileSystemEdit, - ); + const fileSystemEdit = + await client.protocol2CodeConverter.asWorkspaceEdit(lcFileSystemEdit); await vscode.workspace.applyEdit(fileSystemEdit); // replace all text edits so that we can convert snippet text edits into `vscode.SnippetTextEdit`s diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index d1467a4e82..2ae3291345 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -13,12 +13,7 @@ export type RunnableEnvCfgItem = { }; export type RunnableEnvCfg = Record | RunnableEnvCfgItem[]; -type ShowStatusBar = - | "always" - | "never" - | { - documentSelector: vscode.DocumentSelector; - }; +type ShowStatusBar = "always" | "never" | { documentSelector: vscode.DocumentSelector }; export class Config { readonly extensionId = "rust-lang.rust-analyzer"; @@ -145,13 +140,13 @@ export class Config { { // Parent doc single-line comment // e.g. //!| - beforeText: /^\s*\/{2}\!.*$/, + beforeText: /^\s*\/{2}!.*$/, action: { indentAction, appendText: "//! " }, }, { // Begins an auto-closed multi-line comment (standard or parent doc) // e.g. /** | */ or /*! | */ - beforeText: /^\s*\/\*(\*|\!)(?!\/)([^\*]|\*(?!\/))*$/, + beforeText: /^\s*\/\*(\*|!)(?!\/)([^*]|\*(?!\/))*$/, afterText: /^\s*\*\/$/, action: { indentAction: vscode.IndentAction.IndentOutdent, @@ -161,19 +156,19 @@ export class Config { { // Begins a multi-line comment (standard or parent doc) // e.g. /** ...| or /*! ...| - beforeText: /^\s*\/\*(\*|\!)(?!\/)([^\*]|\*(?!\/))*$/, + beforeText: /^\s*\/\*(\*|!)(?!\/)([^*]|\*(?!\/))*$/, action: { indentAction, appendText: " * " }, }, { // Continues a multi-line comment // e.g. * ...| - beforeText: /^(\ \ )*\ \*(\ ([^\*]|\*(?!\/))*)?$/, + beforeText: /^( {2})* \*( ([^*]|\*(?!\/))*)?$/, action: { indentAction, appendText: "* " }, }, { // Dedents after closing a multi-line comment // e.g. */| - beforeText: /^(\ \ )*\ \*\/\s*$/, + beforeText: /^( {2})* \*\/\s*$/, action: { indentAction, removeText: 1 }, }, ]; @@ -227,9 +222,11 @@ export class Config { ), ); } + get checkOnSave() { return this.get("checkOnSave") ?? false; } + async toggleCheckOnSave() { const config = this.cfg.inspect("checkOnSave") ?? { key: "checkOnSave" }; let overrideInLanguage; @@ -269,8 +266,10 @@ export class Config { } runnablesExtraEnv(label: string): Record | undefined { + // eslint-disable-next-line @typescript-eslint/no-explicit-any const item = this.get("runnables.extraEnv") ?? this.get("runnableEnv"); if (!item) return undefined; + // eslint-disable-next-line @typescript-eslint/no-explicit-any const fixRecord = (r: Record) => { for (const key in r) { if (typeof r[key] !== "string") { @@ -339,6 +338,7 @@ export class Config { gotoTypeDef: this.get("hover.actions.gotoTypeDef.enable"), }; } + get previewRustcOutput() { return this.get("diagnostics.previewRustcOutput"); } @@ -370,6 +370,7 @@ export class Config { get askBeforeUpdateTest() { return this.get("runnables.askBeforeUpdateTest"); } + async setAskBeforeUpdateTest(value: boolean) { await this.cfg.update("runnables.askBeforeUpdateTest", value, true); } @@ -378,11 +379,13 @@ export class Config { export function prepareVSCodeConfig(resp: T): T { if (Is.string(resp)) { return substituteVSCodeVariableInString(resp) as T; + // eslint-disable-next-line @typescript-eslint/no-explicit-any } else if (resp && Is.array(resp)) { return resp.map((val) => { return prepareVSCodeConfig(val); }) as T; } else if (resp && typeof resp === "object") { + // eslint-disable-next-line @typescript-eslint/no-explicit-any const res: { [key: string]: any } = {}; for (const key in resp) { const val = resp[key]; @@ -489,8 +492,7 @@ function computeVscodeVar(varName: string): string | null { // TODO: support for remote workspaces? const fsPath: string = folder === undefined - ? // no workspace opened - "" + ? "" // no workspace opened : // could use currently opened document to detect the correct // workspace. However, that would be determined by the document // user has opened on Editor startup. Could lead to diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index 4248305d5c..ac73f2ae6b 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -34,13 +34,8 @@ import type { RustAnalyzerExtensionApi } from "./main"; export type Workspace = | { kind: "Empty" } - | { - kind: "Workspace Folder"; - } - | { - kind: "Detached Files"; - files: vscode.TextDocument[]; - }; + | { kind: "Workspace Folder" } + | { kind: "Detached Files"; files: vscode.TextDocument[] }; export function fetchWorkspace(): Workspace { const folders = (vscode.workspace.workspaceFolders || []).filter( @@ -53,10 +48,7 @@ export function fetchWorkspace(): Workspace { return folders.length === 0 ? rustDocuments.length === 0 ? { kind: "Empty" } - : { - kind: "Detached Files", - files: rustDocuments, - } + : { kind: "Detached Files", files: rustDocuments } : { kind: "Workspace Folder" }; } @@ -89,6 +81,7 @@ export class Ctx implements RustAnalyzerExtensionApi { private _dependencyTreeView: | vscode.TreeView | undefined; + private _syntaxTreeProvider: SyntaxTreeProvider | undefined; private _syntaxTreeView: vscode.TreeView | undefined; private lastStatus: ServerStatusParams | { health: "stopped" } = { health: "stopped" }; @@ -267,7 +260,7 @@ export class Ctx implements RustAnalyzerExtensionApi { let message = "bootstrap error. "; message += - 'See the logs in "OUTPUT > Rust Analyzer Client" (should open automatically). '; + 'See the logs in "OUTPUT > Rust Analyzer Client" (should open automatically).'; message += 'To enable verbose logs, click the gear icon in the "OUTPUT" tab and select "Debug".'; @@ -476,9 +469,11 @@ export class Ctx implements RustAnalyzerExtensionApi { this.lastStatus = status; this.updateStatusBarItem(); } + refreshServerStatus() { this.updateStatusBarItem(); } + private updateStatusBarItem() { let icon = ""; const status = this.lastStatus; @@ -533,19 +528,14 @@ export class Ctx implements RustAnalyzerExtensionApi { const toggleCheckOnSave = this.config.checkOnSave ? "Disable" : "Enable"; statusBar.tooltip.appendMarkdown( - `[Extension Info](command:rust-analyzer.serverVersion "Show version and server binary info"): Version ${this.version}, Server Version ${this._serverVersion}` + - "\n\n---\n\n" + - '[$(terminal) Open Logs](command:rust-analyzer.openLogs "Open the server logs")' + - "\n\n" + - `[$(settings) ${toggleCheckOnSave} Check on Save](command:rust-analyzer.toggleCheckOnSave "Temporarily ${toggleCheckOnSave.toLowerCase()} check on save functionality")` + - "\n\n" + - '[$(refresh) Reload Workspace](command:rust-analyzer.reloadWorkspace "Reload and rediscover workspaces")' + - "\n\n" + - '[$(symbol-property) Rebuild Build Dependencies](command:rust-analyzer.rebuildProcMacros "Rebuild build scripts and proc-macros")' + - "\n\n" + - '[$(stop-circle) Stop server](command:rust-analyzer.stopServer "Stop the server")' + - "\n\n" + - '[$(debug-restart) Restart server](command:rust-analyzer.restartServer "Restart the server")', + `[Extension Info](command:rust-analyzer.serverVersion "Show version and server binary info"): Version ${this.version}, Server Version ${this._serverVersion}\n\n` + + `---\n\n` + + `[$(terminal) Open Logs](command:rust-analyzer.openLogs "Open the server logs")\n\n` + + `[$(settings) ${toggleCheckOnSave} Check on Save](command:rust-analyzer.toggleCheckOnSave "Temporarily ${toggleCheckOnSave.toLowerCase()} check on save functionality")\n\n` + + `[$(refresh) Reload Workspace](command:rust-analyzer.reloadWorkspace "Reload and rediscover workspaces")\n\n` + + `[$(symbol-property) Rebuild Build Dependencies](command:rust-analyzer.rebuildProcMacros "Rebuild build scripts and proc-macros")\n\n` + + `[$(stop-circle) Stop server](command:rust-analyzer.stopServer "Stop the server")\n\n` + + `[$(debug-restart) Restart server](command:rust-analyzer.restartServer "Restart the server")`, ); if (!status.quiescent) icon = "$(loading~spin) "; statusBar.text = `${icon}rust-analyzer`; @@ -580,4 +570,5 @@ export interface Disposable { dispose(): void; } +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type Cmd = (...args: any[]) => unknown; diff --git a/editors/code/src/debug.ts b/editors/code/src/debug.ts index f21ca2e8f9..72a9aabc04 100644 --- a/editors/code/src/debug.ts +++ b/editors/code/src/debug.ts @@ -22,6 +22,7 @@ export async function makeDebugConfig(ctx: Ctx, runnable: ra.Runnable): Promise< if (!debugConfig) return; const wsLaunchSection = vscode.workspace.getConfiguration("launch", scope); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const configurations = wsLaunchSection.get("configurations") || []; const index = configurations.findIndex((c) => c.name === debugConfig.name); @@ -46,6 +47,7 @@ export async function startDebugSession(ctx: Ctx, runnable: ra.Runnable): Promis let message = ""; const wsLaunchSection = vscode.workspace.getConfiguration("launch"); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const configurations = wsLaunchSection.get("configurations") || []; // The runnable label is the name of the test with the "test prefix" @@ -121,7 +123,7 @@ async function getDebugConfiguration( debugOutput.show(true); } // folder exists or RA is not active. - // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + const workspaceFolders = vscode.workspace.workspaceFolders!; const isMultiFolderWorkspace = workspaceFolders.length > 1; const firstWorkspace = workspaceFolders[0]; @@ -189,8 +191,9 @@ async function getDebugConfiguration( sourceFileMap, ); if (debugConfig.type in debugOptions.engineSettings) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any const settingsMap = (debugOptions.engineSettings as any)[debugConfig.type]; - for (var key in settingsMap) { + for (const key in settingsMap) { debugConfig[key] = settingsMap[key]; } } @@ -409,7 +412,7 @@ function quote(xs: string[]) { return "'" + s.replace(/(['\\])/g, "\\$1") + "'"; } if (/["'\s]/.test(s)) { - return '"' + s.replace(/(["\\$`!])/g, "\\$1") + '"'; + return `"${s.replace(/(["\\$`!])/g, "\\$1")}"`; } return s.replace(/([A-Za-z]:)?([#!"$&'()*,:;<=>?@[\\\]^`{|}])/g, "$1\\$2"); }) diff --git a/editors/code/src/diagnostics.ts b/editors/code/src/diagnostics.ts index 9fb2993d12..73621dda9c 100644 --- a/editors/code/src/diagnostics.ts +++ b/editors/code/src/diagnostics.ts @@ -104,10 +104,7 @@ export class AnsiDecorationProvider implements vscode.Disposable { for (const [lineNumber, line] of lines.entries()) { const totalEscapeLength = 0; - - // eslint-disable-next-line camelcase const parsed = anser.ansiToJson(line, { use_classes: true }); - let offset = 0; for (const span of parsed) { @@ -162,23 +159,23 @@ export class AnsiDecorationProvider implements vscode.Disposable { // NOTE: This could just be a kebab-case to camelCase conversion, but I think it's // a short enough list to just write these by hand static readonly _anserToThemeColor: Record = { - "ansi-black": "ansiBlack", - "ansi-white": "ansiWhite", - "ansi-red": "ansiRed", - "ansi-green": "ansiGreen", - "ansi-yellow": "ansiYellow", - "ansi-blue": "ansiBlue", - "ansi-magenta": "ansiMagenta", - "ansi-cyan": "ansiCyan", + "ansi-black": new ThemeColor("terminal.ansiBlack"), + "ansi-white": new ThemeColor("terminal.ansiWhite"), + "ansi-red": new ThemeColor("terminal.ansiRed"), + "ansi-green": new ThemeColor("terminal.ansiGreen"), + "ansi-yellow": new ThemeColor("terminal.ansiYellow"), + "ansi-blue": new ThemeColor("terminal.ansiBlue"), + "ansi-magenta": new ThemeColor("terminal.ansiMagenta"), + "ansi-cyan": new ThemeColor("terminal.ansiCyan"), - "ansi-bright-black": "ansiBrightBlack", - "ansi-bright-white": "ansiBrightWhite", - "ansi-bright-red": "ansiBrightRed", - "ansi-bright-green": "ansiBrightGreen", - "ansi-bright-yellow": "ansiBrightYellow", - "ansi-bright-blue": "ansiBrightBlue", - "ansi-bright-magenta": "ansiBrightMagenta", - "ansi-bright-cyan": "ansiBrightCyan", + "ansi-bright-black": new ThemeColor("terminal.ansiBrightBlack"), + "ansi-bright-white": new ThemeColor("terminal.ansiBrightWhite"), + "ansi-bright-red": new ThemeColor("terminal.ansiBrightRed"), + "ansi-bright-green": new ThemeColor("terminal.ansiBrightGreen"), + "ansi-bright-yellow": new ThemeColor("terminal.ansiBrightYellow"), + "ansi-bright-blue": new ThemeColor("terminal.ansiBrightBlue"), + "ansi-bright-magenta": new ThemeColor("terminal.ansiBrightMagenta"), + "ansi-bright-cyan": new ThemeColor("terminal.ansiBrightCyan"), }; private static _convertColor( diff --git a/editors/code/src/lang_client.ts b/editors/code/src/lang_client.ts index 09d64efc04..dc448f554c 100644 --- a/editors/code/src/lang_client.ts +++ b/editors/code/src/lang_client.ts @@ -5,6 +5,8 @@ export class RaLanguageClient extends lc.LanguageClient { override handleFailedRequest( type: lc.MessageSignature, token: vscode.CancellationToken | undefined, + // declared as `any` in vscode-languageclient + // eslint-disable-next-line @typescript-eslint/no-explicit-any error: any, defaultValue: T, showNotification?: boolean | undefined, diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts index af86d9efd1..af5129ac96 100644 --- a/editors/code/src/lsp_ext.ts +++ b/editors/code/src/lsp_ext.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-empty-object-type */ /** * This file mirrors `crates/rust-analyzer/src/lsp_ext.rs` declarations. */ diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index c84b69b66c..451294e26f 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -214,6 +214,7 @@ function checkConflictingExtensions() { "both plugins to not work correctly. You should disable one of them.", "Got it", ) + // eslint-disable-next-line no-console .then(() => {}, console.error); } } diff --git a/editors/code/src/persistent_state.ts b/editors/code/src/persistent_state.ts index cebd16a3c9..3f90cd3bb9 100644 --- a/editors/code/src/persistent_state.ts +++ b/editors/code/src/persistent_state.ts @@ -14,6 +14,7 @@ export class PersistentState { get serverVersion(): string | undefined { return this.globalState.get("serverVersion"); } + async updateServerVersion(value: string | undefined) { await this.globalState.update("serverVersion", value); } diff --git a/editors/code/src/snippets.ts b/editors/code/src/snippets.ts index a469a9cd1f..e3f43a8067 100644 --- a/editors/code/src/snippets.ts +++ b/editors/code/src/snippets.ts @@ -24,9 +24,7 @@ export async function applySnippetWorkspaceEdit( for (const indel of edits) { assert( !(indel instanceof vscode.SnippetTextEdit), - `bad ws edit: snippet received with multiple edits: ${JSON.stringify( - edit, - )}`, + `bad ws edit: snippet received with multiple edits: ${JSON.stringify(edit)}`, ); builder.replace(indel.range, indel.newText); } diff --git a/editors/code/src/syntax_tree_provider.ts b/editors/code/src/syntax_tree_provider.ts index 3f7e30f13a..b86f8cbc70 100644 --- a/editors/code/src/syntax_tree_provider.ts +++ b/editors/code/src/syntax_tree_provider.ts @@ -7,8 +7,10 @@ import * as ra from "./lsp_ext"; export class SyntaxTreeProvider implements vscode.TreeDataProvider { private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); + readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; + ctx: CtxInit; root: SyntaxNode | undefined; hideWhitespace: boolean = false; diff --git a/editors/code/src/test_explorer.ts b/editors/code/src/test_explorer.ts index de41d2a57e..e45f828294 100644 --- a/editors/code/src/test_explorer.ts +++ b/editors/code/src/test_explorer.ts @@ -133,7 +133,7 @@ export const prepareTestExplorer = ( } if (scope) { const recursivelyRemove = (tests: vscode.TestItemCollection) => { - for (const [_, test] of tests) { + for (const [, test] of tests) { if (!testSet.has(test.id)) { deleteTest(test, tests); } else { diff --git a/editors/code/src/toolchain.ts b/editors/code/src/toolchain.ts index e8bab9c3d8..bb06144295 100644 --- a/editors/code/src/toolchain.ts +++ b/editors/code/src/toolchain.ts @@ -18,6 +18,22 @@ export interface ArtifactSpec { filter?: (artifacts: CompilationArtifact[]) => CompilationArtifact[]; } +interface CompilerMessage { + reason: string; + executable?: string; + target: { + crate_types: [string, ...string[]]; + kind: [string, ...string[]]; + name: string; + }; + profile: { + test: boolean; + }; + message: { + rendered: string; + }; +} + export class Cargo { constructor( readonly rootFolder: string, @@ -109,7 +125,7 @@ export class Cargo { private async runCargo( cargoArgs: string[], - onStdoutJson: (obj: any) => void, + onStdoutJson: (obj: CompilerMessage) => void, onStderrString: (data: string) => void, env?: Record, ): Promise { @@ -131,7 +147,7 @@ export class Cargo { onStdoutJson(message); }); - cargo.on("exit", (exitCode, _) => { + cargo.on("exit", (exitCode) => { if (exitCode === 0) resolve(exitCode); else reject(new Error(`exit code: ${exitCode}.`)); }); diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts index d7ca6b3557..2f7702baeb 100644 --- a/editors/code/src/util.ts +++ b/editors/code/src/util.ts @@ -104,6 +104,7 @@ export function isDocumentInWorkspace(document: RustDocument): boolean { } /** Sets ['when'](https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts) clause contexts */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any export function setContextValue(key: string, value: any): Thenable { return vscode.commands.executeCommand("setContext", key, value); } @@ -167,27 +168,35 @@ export class LazyOutputChannel implements vscode.OutputChannel { append(value: string): void { this.channel.append(value); } + appendLine(value: string): void { this.channel.appendLine(value); } + replace(value: string): void { this.channel.replace(value); } + clear(): void { if (this._channel) { this._channel.clear(); } } - show(preserveFocus?: boolean): void; - show(column?: vscode.ViewColumn, preserveFocus?: boolean): void; - show(column?: any, preserveFocus?: any): void { - this.channel.show(column, preserveFocus); + + show(columnOrPreserveFocus?: vscode.ViewColumn | boolean, preserveFocus?: boolean): void { + if (typeof columnOrPreserveFocus === "boolean") { + this.channel.show(columnOrPreserveFocus); + } else { + this.channel.show(columnOrPreserveFocus, preserveFocus); + } } + hide(): void { if (this._channel) { this._channel.hide(); } } + dispose(): void { if (this._channel) { this._channel.dispose(); @@ -276,6 +285,7 @@ export async function spawnAsync( stderr: res.stderr, status: res.status, }; + // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (e: any) { return { stdout: e.stdout, diff --git a/editors/code/tests/unit/index.ts b/editors/code/tests/unit/index.ts index 8ad46546ab..bf74060c73 100644 --- a/editors/code/tests/unit/index.ts +++ b/editors/code/tests/unit/index.ts @@ -1,6 +1,7 @@ import * as assert from "node:assert/strict"; import { readdir } from "fs/promises"; import * as path from "path"; +import { pathToFileURL } from "url"; class Test { readonly name: string; @@ -67,7 +68,7 @@ export async function run(): Promise { ); for (const testFile of testFiles) { try { - const testModule = require(path.resolve(__dirname, testFile)); + const testModule = await import(pathToFileURL(path.resolve(__dirname, testFile)).href); await testModule.getTests(context); } catch (e) { error(`${e}`); diff --git a/editors/code/tests/unit/tasks.test.ts b/editors/code/tests/unit/tasks.test.ts index 9bccaaf3d4..9b5d98ee7e 100644 --- a/editors/code/tests/unit/tasks.test.ts +++ b/editors/code/tests/unit/tasks.test.ts @@ -114,6 +114,7 @@ function f(task: vscode.Task): { execution, }; } + function executionToSimple( taskExecution: vscode.ProcessExecution | vscode.ShellExecution | vscode.CustomExecution, ): { @@ -122,8 +123,8 @@ function executionToSimple( const exec = taskExecution as vscode.ProcessExecution | vscode.ShellExecution; if (exec instanceof vscode.ShellExecution) { return { - command: typeof exec.command === "string" ? exec.command : exec.command.value, - args: exec.args.map((arg) => { + command: typeof exec.command === "string" ? exec.command : (exec.command?.value ?? ""), + args: (exec.args ?? []).map((arg) => { if (typeof arg === "string") { return arg; } diff --git a/editors/code/tsconfig.eslint.json b/editors/code/tsconfig.eslint.json index 5e2b33ca39..eceffeef59 100644 --- a/editors/code/tsconfig.eslint.json +++ b/editors/code/tsconfig.eslint.json @@ -6,6 +6,6 @@ "src", "tests", // these are the eslint-only inclusions - ".eslintrc.js" + "eslint.config.mts" ] } diff --git a/editors/code/tsconfig.json b/editors/code/tsconfig.json index 87cfd1b2ee..a13afab170 100644 --- a/editors/code/tsconfig.json +++ b/editors/code/tsconfig.json @@ -2,18 +2,17 @@ "extends": "@tsconfig/strictest/tsconfig.json", "compilerOptions": { "esModuleInterop": false, - "module": "Node16", - "moduleResolution": "Node16", - "target": "ES2021", + "module": "NodeNext", + "moduleResolution": "nodenext", + "target": "ES2024", "outDir": "out", - "lib": ["ES2021"], + "lib": ["ES2024"], "sourceMap": true, "rootDir": ".", "newLine": "lf", - // FIXME: https://github.com/rust-lang/rust-analyzer/issues/15253 "exactOptionalPropertyTypes": false }, - "exclude": ["node_modules", ".vscode-test"], + "exclude": ["node_modules", ".vscode-test", "out"], "include": ["src", "tests"] } From 15207a0474f9af0926fcd379b597e0a2127d741c Mon Sep 17 00:00:00 2001 From: Nicholas Crothers Date: Thu, 27 Feb 2025 16:39:07 -0600 Subject: [PATCH 32/47] Add anchor for intra-doc links to associated items --- crates/ide/src/doc_links.rs | 14 ++--- crates/ide/src/doc_links/tests.rs | 92 +++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 7 deletions(-) diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index e35e47e747..d88f7c5033 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs @@ -379,13 +379,15 @@ fn rewrite_intra_doc_link( let resolved = resolve_doc_path_for_def(db, def, link, ns)?; let mut url = get_doc_base_urls(db, resolved, None, None).0?; - let (_, file, _) = filename_and_frag_for_def(db, resolved)?; + let (_, file, frag) = filename_and_frag_for_def(db, resolved)?; if let Some(path) = mod_path_of_def(db, resolved) { url = url.join(&path).ok()?; } + let frag = anchor.or(frag.as_deref()); + url = url.join(&file).ok()?; - url.set_fragment(anchor); + url.set_fragment(frag); Some((url.into(), strip_prefixes_suffixes(title).to_owned())) } @@ -621,11 +623,9 @@ fn filename_and_frag_for_def( format!("fn.{}.html", f.name(db).as_str()) } Definition::Variant(ev) => { - format!( - "enum.{}.html#variant.{}", - ev.parent_enum(db).name(db).as_str(), - ev.name(db).as_str() - ) + let def = Definition::Adt(ev.parent_enum(db).into()); + let (_, file, _) = filename_and_frag_for_def(db, def)?; + return Some((def, file, Some(format!("variant.{}", ev.name(db).as_str())))); } Definition::Const(c) => { format!("const.{}.html", c.name(db)?.as_str()) diff --git a/crates/ide/src/doc_links/tests.rs b/crates/ide/src/doc_links/tests.rs index d7291c4b9f..b09e3a3c80 100644 --- a/crates/ide/src/doc_links/tests.rs +++ b/crates/ide/src/doc_links/tests.rs @@ -686,3 +686,95 @@ fn rewrite_intra_doc_link_with_anchor() { expect!["[PartialEq#derivable](https://doc.rust-lang.org/stable/core/cmp/trait.PartialEq.html#derivable)"], ); } + +#[test] +fn rewrite_intra_doc_link_to_associated_item() { + check_rewrite( + r#" +//- /main.rs crate:foo +/// [Foo::bar] +pub struct $0Foo; + +impl Foo { + fn bar() {} +} +"#, + expect![[r#"[Foo::bar](https://docs.rs/foo/*/foo/struct.Foo.html#method.bar)"#]], + ); + check_rewrite( + r#" +//- /main.rs crate:foo +/// [Foo::bar] +pub struct $0Foo { + bar: () +} +"#, + expect![[r#"[Foo::bar](https://docs.rs/foo/*/foo/struct.Foo.html#structfield.bar)"#]], + ); + check_rewrite( + r#" +//- /main.rs crate:foo +/// [Foo::Bar] +pub enum $0Foo { + Bar +} +"#, + expect![[r#"[Foo::Bar](https://docs.rs/foo/*/foo/enum.Foo.html#variant.Bar)"#]], + ); + check_rewrite( + r#" +//- /main.rs crate:foo +/// [Foo::BAR] +pub struct $0Foo; + +impl Foo { + const BAR: () = (); +} +"#, + expect![[ + r#"[Foo::BAR](https://docs.rs/foo/*/foo/struct.Foo.html#associatedconstant.BAR)"# + ]], + ); + check_rewrite( + r#" +//- /main.rs crate:foo +/// [Foo::bar] +pub trait $0Foo { + fn bar(); +} +"#, + expect![[r#"[Foo::bar](https://docs.rs/foo/*/foo/trait.Foo.html#tymethod.bar)"#]], + ); + check_rewrite( + r#" +//- /main.rs crate:foo +/// [Foo::Bar] +pub trait $0Foo { + type Bar; +} +"#, + expect![[r#"[Foo::Bar](https://docs.rs/foo/*/foo/trait.Foo.html#associatedtype.Bar)"#]], + ); + check_rewrite( + r#" +//- /main.rs crate:foo +/// [Foo::bar#anchor] +pub struct $0Foo { + bar: (), +} +"#, + expect![[r#"[Foo::bar#anchor](https://docs.rs/foo/*/foo/struct.Foo.html#anchor)"#]], + ); + check_rewrite( + r#" +//- /main.rs crate:foo +/// [method](Foo::bar) +pub struct $0Foo; + +impl Foo { + fn bar() {} +} +"#, + expect![[r#"[method](https://docs.rs/foo/*/foo/struct.Foo.html#method.bar)"#]], + ); +} From 09315ef3191019e482540a17287c127702fd2126 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 26 Feb 2025 20:24:37 +0530 Subject: [PATCH 33/47] Avoid suggesting redundant borrowing in completion results --- crates/ide-completion/src/render.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index dc7eacbfba..d9f3fe1326 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -628,11 +628,9 @@ fn compute_ref_match( let expected_type = ctx.expected_type.as_ref()?; let expected_without_ref = expected_type.remove_ref(); let completion_without_ref = completion_ty.remove_ref(); - - if completion_ty == expected_type { + if expected_type.could_unify_with(ctx.db, completion_ty) { return None; } - if let Some(expected_without_ref) = &expected_without_ref { if completion_ty.autoderef(ctx.db).any(|ty| ty == *expected_without_ref) { cov_mark::hit!(suggest_ref); From dcb25b1a8c2993d9377fdcb4e86838383197df04 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 26 Feb 2025 22:19:22 +0530 Subject: [PATCH 34/47] add test --- crates/ide-completion/src/render.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index d9f3fe1326..4f6c4cb663 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -2005,6 +2005,30 @@ fn f() { ); } + #[test] + fn test_avoid_redundant_suggestion() { + check_relevance( + r#" +struct aa([u8]); + +impl aa { + fn from_bytes(bytes: &[u8]) -> &Self { + unsafe { &*(bytes as *const [u8] as *const aa) } + } +} + +fn bb()-> &'static aa { + let bytes = b"hello"; + aa::$0 +} +"#, + expect![[r#" + ex bb() [type] + fn from_bytes(…) fn(&[u8]) -> &aa [type_could_unify] + "#]], + ); + } + #[test] fn suggest_ref_mut() { cov_mark::check!(suggest_ref); From f655062cb0a676714ac61a1a36f8343a187f058c Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 28 Feb 2025 09:45:24 +0100 Subject: [PATCH 35/47] Fix prefix adjustment hints unnecessarily introducing parens --- crates/ide/src/inlay_hints/adjustment.rs | 14 +++++++++++--- crates/syntax/src/ast/prec.rs | 21 ++++++++++++--------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/crates/ide/src/inlay_hints/adjustment.rs b/crates/ide/src/inlay_hints/adjustment.rs index d3b95750f7..40156ace26 100644 --- a/crates/ide/src/inlay_hints/adjustment.rs +++ b/crates/ide/src/inlay_hints/adjustment.rs @@ -260,7 +260,7 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, if postfix { // postfix ops have higher precedence than any other operator, so we need to wrap // any inner expression that is below (except for jumps if they don't have a value) - let needs_inner_parens = prec < ExprPrecedence::Unambiguous && { + let needs_inner_parens = prec < ExprPrecedence::Postfix && { prec != ExprPrecedence::Jump || !expr.is_ret_like_with_no_value() }; // given we are the higher precedence, no parent expression will have stronger requirements @@ -276,9 +276,12 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, // if we are already wrapped, great, no need to wrap again .filter(|it| !matches!(it, ast::Expr::ParenExpr(_))) .map(|it| it.precedence()); + // if we have no parent, we don't need outer parens to disambiguate // otherwise anything with higher precedence than what we insert needs to wrap us - let needs_outer_parens = parent.is_some_and(|prec| prec > ExprPrecedence::Prefix); + // that means only postfix ops + let needs_outer_parens = + parent.is_some_and(|parent_prec| parent_prec == ExprPrecedence::Postfix); (needs_outer_parens, needs_inner_parens) } } @@ -291,7 +294,7 @@ mod tests { }; #[test] - fn adjustment_hints() { + fn adjustment_hints_prefix() { check_with_config( InlayHintsConfig { adjustment_hints: AdjustmentHints::Always, ..DISABLED_CONFIG }, r#" @@ -381,6 +384,8 @@ fn main() { &mut Struct[0]; //^^^^^^(&mut $ //^^^^^^) + let _: (&mut (),) = (&mut (),); + //^^^^^^^&mut * } #[derive(Copy, Clone)] @@ -472,6 +477,9 @@ fn main() { //^^^^^^.& &mut Struct[0]; //^^^^^^.&mut + let _: (&mut (),) = (&mut (),); + //^^^^^^^( + //^^^^^^^).*.&mut } #[derive(Copy, Clone)] diff --git a/crates/syntax/src/ast/prec.rs b/crates/syntax/src/ast/prec.rs index 5d33f132ac..a7f1a3788c 100644 --- a/crates/syntax/src/ast/prec.rs +++ b/crates/syntax/src/ast/prec.rs @@ -35,7 +35,9 @@ pub enum ExprPrecedence { Cast, // unary - * ! & &mut Prefix, - // paths, loops, function calls, array indexing, field expressions, method calls + // function calls, array indexing, field expressions, method calls + Postfix, + // paths, loops, Unambiguous, } @@ -57,6 +59,7 @@ pub fn precedence(expr: &ast::Expr) -> ExprPrecedence { }, Expr::BreakExpr(_) + | Expr::BecomeExpr(_) | Expr::ContinueExpr(_) | Expr::ReturnExpr(_) | Expr::YeetExpr(_) @@ -89,27 +92,27 @@ pub fn precedence(expr: &ast::Expr) -> ExprPrecedence { Expr::LetExpr(_) | Expr::PrefixExpr(_) | Expr::RefExpr(_) => ExprPrecedence::Prefix, - Expr::ArrayExpr(_) - | Expr::AsmExpr(_) - | Expr::AwaitExpr(_) - | Expr::BecomeExpr(_) - | Expr::BlockExpr(_) + Expr::AwaitExpr(_) | Expr::CallExpr(_) | Expr::FieldExpr(_) + | Expr::IndexExpr(_) + | Expr::MethodCallExpr(_) + | Expr::TryExpr(_) => ExprPrecedence::Postfix, + + Expr::ArrayExpr(_) + | Expr::AsmExpr(_) + | Expr::BlockExpr(_) | Expr::ForExpr(_) | Expr::FormatArgsExpr(_) | Expr::IfExpr(_) - | Expr::IndexExpr(_) | Expr::Literal(_) | Expr::LoopExpr(_) | Expr::MacroExpr(_) | Expr::MatchExpr(_) - | Expr::MethodCallExpr(_) | Expr::OffsetOfExpr(_) | Expr::ParenExpr(_) | Expr::PathExpr(_) | Expr::RecordExpr(_) - | Expr::TryExpr(_) | Expr::TupleExpr(_) | Expr::UnderscoreExpr(_) | Expr::WhileExpr(_) => ExprPrecedence::Unambiguous, From e92dc3fd80142d426cbf4bfb3b1915b9efe460d3 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 28 Feb 2025 09:45:24 +0100 Subject: [PATCH 36/47] Have inline_local_variable use precedence calculation for parentheses --- .../src/handlers/inline_const_as_literal.rs | 23 ++------ .../src/handlers/inline_local_variable.rs | 59 ++++++++----------- crates/ide/src/inlay_hints/adjustment.rs | 12 ++-- crates/syntax/src/ast/prec.rs | 13 +++- crates/syntax/src/ast/token_ext.rs | 4 +- 5 files changed, 44 insertions(+), 67 deletions(-) diff --git a/crates/ide-assists/src/handlers/inline_const_as_literal.rs b/crates/ide-assists/src/handlers/inline_const_as_literal.rs index c92c22378f..139078eee7 100644 --- a/crates/ide-assists/src/handlers/inline_const_as_literal.rs +++ b/crates/ide-assists/src/handlers/inline_const_as_literal.rs @@ -39,25 +39,10 @@ pub(crate) fn inline_const_as_literal(acc: &mut Assists, ctx: &AssistContext<'_> // FIXME: Add support to handle type aliases for builtin scalar types. validate_type_recursively(ctx, Some(&konst_ty), false, fuel)?; - let expr = konst.value(ctx.sema.db)?; - - let value = match expr { - ast::Expr::BlockExpr(_) - | ast::Expr::Literal(_) - | ast::Expr::RefExpr(_) - | ast::Expr::ArrayExpr(_) - | ast::Expr::TupleExpr(_) - | ast::Expr::IfExpr(_) - | ast::Expr::ParenExpr(_) - | ast::Expr::MatchExpr(_) - | ast::Expr::MacroExpr(_) - | ast::Expr::BinExpr(_) - | ast::Expr::CallExpr(_) => konst - .eval(ctx.sema.db) - .ok()? - .render(ctx.sema.db, konst.krate(ctx.sema.db).edition(ctx.sema.db)), - _ => return None, - }; + let value = konst + .eval(ctx.sema.db) + .ok()? + .render(ctx.sema.db, konst.krate(ctx.sema.db).edition(ctx.sema.db)); let id = AssistId("inline_const_as_literal", AssistKind::RefactorInline); diff --git a/crates/ide-assists/src/handlers/inline_local_variable.rs b/crates/ide-assists/src/handlers/inline_local_variable.rs index b9fc075ae8..5d4fbfc10a 100644 --- a/crates/ide-assists/src/handlers/inline_local_variable.rs +++ b/crates/ide-assists/src/handlers/inline_local_variable.rs @@ -5,7 +5,11 @@ use ide_db::{ EditionedFileId, RootDatabase, }; use syntax::{ - ast::{self, AstNode, AstToken, HasName}, + ast::{ + self, + prec::{precedence, ExprPrecedence}, + AstNode, AstToken, HasName, + }, SyntaxElement, TextRange, }; @@ -79,33 +83,16 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>) Some(u) => u, None => return Some((range, name_ref, false)), }; - let initializer = matches!( - initializer_expr, - ast::Expr::CallExpr(_) - | ast::Expr::IndexExpr(_) - | ast::Expr::MethodCallExpr(_) - | ast::Expr::FieldExpr(_) - | ast::Expr::TryExpr(_) - | ast::Expr::Literal(_) - | ast::Expr::TupleExpr(_) - | ast::Expr::ArrayExpr(_) - | ast::Expr::ParenExpr(_) - | ast::Expr::PathExpr(_) - | ast::Expr::BlockExpr(_), - ); - let parent = matches!( - usage_parent, - ast::Expr::TupleExpr(_) - | ast::Expr::ArrayExpr(_) - | ast::Expr::ParenExpr(_) - | ast::Expr::ForExpr(_) - | ast::Expr::WhileExpr(_) - | ast::Expr::BreakExpr(_) - | ast::Expr::ReturnExpr(_) - | ast::Expr::MatchExpr(_) - | ast::Expr::BlockExpr(_) - ); - Some((range, name_ref, !(initializer || parent))) + let initializer = precedence(&initializer_expr); + let parent = precedence(&usage_parent); + Some(( + range, + name_ref, + parent != ExprPrecedence::Unambiguous + && initializer < parent + // initializer == ExprPrecedence::Prefix -> parent != ExprPrecedence::Jump + && (initializer != ExprPrecedence::Prefix || parent != ExprPrecedence::Jump), + )) }) .collect::>>()?; @@ -281,11 +268,11 @@ fn foo() { r" fn bar(a: usize) {} fn foo() { - (1 + 1) + 1; - if (1 + 1) > 10 { + 1 + 1 + 1; + if 1 + 1 > 10 { } - while (1 + 1) > 10 { + while 1 + 1 > 10 { } let b = (1 + 1) * 10; @@ -350,14 +337,14 @@ fn foo() { r" fn bar(a: usize) -> usize { a } fn foo() { - (bar(1) as u64) + 1; - if (bar(1) as u64) > 10 { + bar(1) as u64 + 1; + if bar(1) as u64 > 10 { } - while (bar(1) as u64) > 10 { + while bar(1) as u64 > 10 { } - let b = (bar(1) as u64) * 10; + let b = bar(1) as u64 * 10; bar(bar(1) as u64); }", ); @@ -574,7 +561,7 @@ fn foo() { r" fn foo() { let bar = 10; - let b = (&bar) * 10; + let b = &bar * 10; }", ); } diff --git a/crates/ide/src/inlay_hints/adjustment.rs b/crates/ide/src/inlay_hints/adjustment.rs index 40156ace26..6b2e41f42b 100644 --- a/crates/ide/src/inlay_hints/adjustment.rs +++ b/crates/ide/src/inlay_hints/adjustment.rs @@ -259,10 +259,8 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, let prec = expr.precedence(); if postfix { // postfix ops have higher precedence than any other operator, so we need to wrap - // any inner expression that is below (except for jumps if they don't have a value) - let needs_inner_parens = prec < ExprPrecedence::Postfix && { - prec != ExprPrecedence::Jump || !expr.is_ret_like_with_no_value() - }; + // any inner expression that is below + let needs_inner_parens = prec < ExprPrecedence::Postfix; // given we are the higher precedence, no parent expression will have stronger requirements let needs_outer_parens = false; (needs_outer_parens, needs_inner_parens) @@ -275,13 +273,13 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, .and_then(ast::Expr::cast) // if we are already wrapped, great, no need to wrap again .filter(|it| !matches!(it, ast::Expr::ParenExpr(_))) - .map(|it| it.precedence()); + .map(|it| it.precedence()) + .filter(|&prec| prec != ExprPrecedence::Unambiguous); // if we have no parent, we don't need outer parens to disambiguate // otherwise anything with higher precedence than what we insert needs to wrap us - // that means only postfix ops let needs_outer_parens = - parent.is_some_and(|parent_prec| parent_prec == ExprPrecedence::Postfix); + parent.is_some_and(|parent_prec| parent_prec > ExprPrecedence::Prefix); (needs_outer_parens, needs_inner_parens) } } diff --git a/crates/syntax/src/ast/prec.rs b/crates/syntax/src/ast/prec.rs index a7f1a3788c..2a47b3bea5 100644 --- a/crates/syntax/src/ast/prec.rs +++ b/crates/syntax/src/ast/prec.rs @@ -7,7 +7,7 @@ use crate::{ #[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] pub enum ExprPrecedence { - // return, break, yield, closures + // return val, break val, yield val, closures Jump, // = += -= *= /= %= &= |= ^= <<= >>= Assign, @@ -58,12 +58,18 @@ pub fn precedence(expr: &ast::Expr) -> ExprPrecedence { Some(_) => ExprPrecedence::Unambiguous, }, + Expr::BreakExpr(e) if e.expr().is_some() => ExprPrecedence::Jump, + Expr::BecomeExpr(e) if e.expr().is_some() => ExprPrecedence::Jump, + Expr::ReturnExpr(e) if e.expr().is_some() => ExprPrecedence::Jump, + Expr::YeetExpr(e) if e.expr().is_some() => ExprPrecedence::Jump, + Expr::YieldExpr(e) if e.expr().is_some() => ExprPrecedence::Jump, + Expr::BreakExpr(_) | Expr::BecomeExpr(_) - | Expr::ContinueExpr(_) | Expr::ReturnExpr(_) | Expr::YeetExpr(_) - | Expr::YieldExpr(_) => ExprPrecedence::Jump, + | Expr::YieldExpr(_) + | Expr::ContinueExpr(_) => ExprPrecedence::Unambiguous, Expr::RangeExpr(..) => ExprPrecedence::Range, @@ -387,6 +393,7 @@ impl Expr { BreakExpr(e) => e.expr().is_none(), ContinueExpr(_) => true, YieldExpr(e) => e.expr().is_none(), + BecomeExpr(e) => e.expr().is_none(), _ => false, } } diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs index 7d5ca27043..df851ab5b2 100644 --- a/crates/syntax/src/ast/token_ext.rs +++ b/crates/syntax/src/ast/token_ext.rs @@ -269,7 +269,7 @@ impl ast::ByteString { } (Ok(c), true) => { buf.reserve_exact(text.len()); - buf.extend_from_slice(text[..prev_end].as_bytes()); + buf.extend_from_slice(&text.as_bytes()[..prev_end]); buf.push(c as u8); } (Err(e), _) => has_error = Some(e), @@ -333,7 +333,7 @@ impl ast::CString { } (Ok(u), true) => { buf.reserve_exact(text.len()); - buf.extend(text[..prev_end].as_bytes()); + buf.extend(&text.as_bytes()[..prev_end]); extend_unit(&mut buf, u); } (Err(e), _) => has_error = Some(e), From 37822d5917429b95943d839b31c4bbd3a35062ac Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Sat, 1 Mar 2025 03:57:58 +0900 Subject: [PATCH 37/47] Migrate `convert_bool_then` to `SyntaxEditor` Update assist docs --- .../src/handlers/convert_bool_then.rs | 82 +++++++---- .../src/ast/syntax_factory/constructors.rs | 138 +++++++++++++++--- crates/syntax/src/syntax_editor/mapping.rs | 6 +- docs/book/src/assists_generated.md | 8 +- 4 files changed, 174 insertions(+), 60 deletions(-) diff --git a/crates/ide-assists/src/handlers/convert_bool_then.rs b/crates/ide-assists/src/handlers/convert_bool_then.rs index 8d391c64ce..151c71c0a7 100644 --- a/crates/ide-assists/src/handlers/convert_bool_then.rs +++ b/crates/ide-assists/src/handlers/convert_bool_then.rs @@ -8,12 +8,13 @@ use ide_db::{ }; use itertools::Itertools; use syntax::{ - ast::{self, edit::AstNodeEdit, make, HasArgList}, - ted, AstNode, SyntaxNode, + ast::{self, edit::AstNodeEdit, syntax_factory::SyntaxFactory, HasArgList}, + syntax_editor::SyntaxEditor, + AstNode, SyntaxNode, }; use crate::{ - utils::{invert_boolean_expression_legacy, unwrap_trivial_block}, + utils::{invert_boolean_expression, unwrap_trivial_block}, AssistContext, AssistId, AssistKind, Assists, }; @@ -76,9 +77,9 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_> "Convert `if` expression to `bool::then` call", target, |builder| { - let closure_body = closure_body.clone_for_update(); + let closure_body = closure_body.clone_subtree(); + let mut editor = SyntaxEditor::new(closure_body.syntax().clone()); // Rewrite all `Some(e)` in tail position to `e` - let mut replacements = Vec::new(); for_each_tail_expr(&closure_body, &mut |e| { let e = match e { ast::Expr::BreakExpr(e) => e.expr(), @@ -88,12 +89,16 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_> if let Some(ast::Expr::CallExpr(call)) = e { if let Some(arg_list) = call.arg_list() { if let Some(arg) = arg_list.args().next() { - replacements.push((call.syntax().clone(), arg.syntax().clone())); + editor.replace(call.syntax(), arg.syntax()); } } } }); - replacements.into_iter().for_each(|(old, new)| ted::replace(old, new)); + let edit = editor.finish(); + let closure_body = ast::Expr::cast(edit.new_root().clone()).unwrap(); + + let mut editor = builder.make_editor(expr.syntax()); + let make = SyntaxFactory::new(); let closure_body = match closure_body { ast::Expr::BlockExpr(block) => unwrap_trivial_block(block), e => e, @@ -119,11 +124,18 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_> | ast::Expr::WhileExpr(_) | ast::Expr::YieldExpr(_) ); - let cond = if invert_cond { invert_boolean_expression_legacy(cond) } else { cond }; - let cond = if parenthesize { make::expr_paren(cond) } else { cond }; - let arg_list = make::arg_list(Some(make::expr_closure(None, closure_body))); - let mcall = make::expr_method_call(cond, make::name_ref("then"), arg_list); - builder.replace(target, mcall.to_string()); + let cond = if invert_cond { + invert_boolean_expression(&make, cond) + } else { + cond.clone_for_update() + }; + let cond = if parenthesize { make.expr_paren(cond).into() } else { cond }; + let arg_list = make.arg_list(Some(make.expr_closure(None, closure_body).into())); + let mcall = make.expr_method_call(cond, make.name_ref("then"), arg_list); + editor.replace(expr.syntax(), mcall.syntax()); + + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.file_id(), editor); }, ) } @@ -173,16 +185,17 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_> "Convert `bool::then` call to `if`", target, |builder| { - let closure_body = match closure_body { + let mapless_make = SyntaxFactory::without_mappings(); + let closure_body = match closure_body.reset_indent() { ast::Expr::BlockExpr(block) => block, - e => make::block_expr(None, Some(e)), + e => mapless_make.block_expr(None, Some(e)), }; - let closure_body = closure_body.clone_for_update(); + let closure_body = closure_body.clone_subtree(); + let mut editor = SyntaxEditor::new(closure_body.syntax().clone()); // Wrap all tails in `Some(...)` - let none_path = make::expr_path(make::ext::ident_path("None")); - let some_path = make::expr_path(make::ext::ident_path("Some")); - let mut replacements = Vec::new(); + let none_path = mapless_make.expr_path(mapless_make.ident_path("None")); + let some_path = mapless_make.expr_path(mapless_make.ident_path("Some")); for_each_tail_expr(&ast::Expr::BlockExpr(closure_body.clone()), &mut |e| { let e = match e { ast::Expr::BreakExpr(e) => e.expr(), @@ -190,28 +203,37 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_> _ => Some(e.clone()), }; if let Some(expr) = e { - replacements.push(( + editor.replace( expr.syntax().clone(), - make::expr_call(some_path.clone(), make::arg_list(Some(expr))) + mapless_make + .expr_call(some_path.clone(), mapless_make.arg_list(Some(expr))) .syntax() - .clone_for_update(), - )); + .clone(), + ); } }); - replacements.into_iter().for_each(|(old, new)| ted::replace(old, new)); + let edit = editor.finish(); + let closure_body = ast::BlockExpr::cast(edit.new_root().clone()).unwrap(); + + let mut editor = builder.make_editor(mcall.syntax()); + let make = SyntaxFactory::new(); let cond = match &receiver { ast::Expr::ParenExpr(expr) => expr.expr().unwrap_or(receiver), _ => receiver, }; - let if_expr = make::expr_if( - cond, - closure_body.reset_indent(), - Some(ast::ElseBranch::Block(make::block_expr(None, Some(none_path)))), - ) - .indent(mcall.indent_level()); + let if_expr = make + .expr_if( + cond, + closure_body, + Some(ast::ElseBranch::Block(make.block_expr(None, Some(none_path)))), + ) + .indent(mcall.indent_level()) + .clone_for_update(); + editor.replace(mcall.syntax().clone(), if_expr.syntax().clone()); - builder.replace(target, if_expr.to_string()); + editor.add_mappings(make.finish_with_mappings()); + builder.add_file_edits(ctx.file_id(), editor); }, ) } diff --git a/crates/syntax/src/ast/syntax_factory/constructors.rs b/crates/syntax/src/ast/syntax_factory/constructors.rs index 19c5c64e21..85393ca5b4 100644 --- a/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -129,7 +129,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.segments().map(|it| it.syntax().clone())); + builder.map_children(input, ast.segments().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -162,7 +162,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.pats().map(|it| it.syntax().clone())); + builder.map_children(input, ast.pats().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -175,7 +175,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); + builder.map_children(input, ast.fields().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -193,7 +193,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); builder.map_node(path.syntax().clone(), ast.path().unwrap().syntax().clone()); - builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); + builder.map_children(input, ast.fields().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -230,7 +230,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); + builder.map_children(input, ast.fields().map(|it| it.syntax().clone())); if let Some(rest_pat) = rest_pat { builder .map_node(rest_pat.syntax().clone(), ast.rest_pat().unwrap().syntax().clone()); @@ -315,10 +315,7 @@ impl SyntaxFactory { builder.map_node(last_stmt, ast_tail.syntax().clone()); } - builder.map_children( - input.into_iter(), - stmt_list.statements().map(|it| it.syntax().clone()), - ); + builder.map_children(input, stmt_list.statements().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -351,7 +348,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); + builder.map_children(input, ast.fields().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -454,7 +451,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax.clone()); - builder.map_children(input.into_iter(), ast.args().map(|it| it.syntax().clone())); + builder.map_children(input, ast.args().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -476,6 +473,31 @@ impl SyntaxFactory { ast.into() } + pub fn expr_closure( + &self, + pats: impl IntoIterator, + expr: ast::Expr, + ) -> ast::ClosureExpr { + let (args, input) = iterator_input(pats); + // FIXME: `make::expr_paren` should return a `ClosureExpr`, not just an `Expr` + let ast::Expr::ClosureExpr(ast) = make::expr_closure(args, expr.clone()).clone_for_update() + else { + unreachable!() + }; + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax.clone()); + builder.map_children( + input, + ast.param_list().unwrap().params().map(|param| param.syntax().clone()), + ); + builder.map_node(expr.syntax().clone(), ast.body().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + pub fn expr_return(&self, expr: Option) -> ast::ReturnExpr { let ast::Expr::ReturnExpr(ast) = make::expr_return(expr.clone()).clone_for_update() else { unreachable!() @@ -604,7 +626,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.arms().map(|it| it.syntax().clone())); + builder.map_children(input, ast.arms().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -727,6 +749,19 @@ impl SyntaxFactory { ast } + pub fn param(&self, pat: ast::Pat, ty: ast::Type) -> ast::Param { + let ast = make::param(pat.clone(), ty.clone()); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone()); + builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + pub fn generic_arg_list( &self, generic_args: impl IntoIterator, @@ -741,10 +776,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children( - input.into_iter(), - ast.generic_args().map(|arg| arg.syntax().clone()), - ); + builder.map_children(input, ast.generic_args().map(|arg| arg.syntax().clone())); builder.finish(&mut mapping); } @@ -761,7 +793,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); + builder.map_children(input, ast.fields().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -806,7 +838,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone())); + builder.map_children(input, ast.fields().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -901,7 +933,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children(input.into_iter(), ast.variants().map(|it| it.syntax().clone())); + builder.map_children(input, ast.variants().map(|it| it.syntax().clone())); builder.finish(&mut mapping); } @@ -953,6 +985,69 @@ impl SyntaxFactory { ast } + pub fn fn_( + &self, + visibility: Option, + fn_name: ast::Name, + type_params: Option, + where_clause: Option, + params: ast::ParamList, + body: ast::BlockExpr, + ret_type: Option, + is_async: bool, + is_const: bool, + is_unsafe: bool, + is_gen: bool, + ) -> ast::Fn { + let ast = make::fn_( + visibility.clone(), + fn_name.clone(), + type_params.clone(), + where_clause.clone(), + params.clone(), + body.clone(), + ret_type.clone(), + is_async, + is_const, + is_unsafe, + is_gen, + ); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + + if let Some(visibility) = visibility { + builder.map_node( + visibility.syntax().clone(), + ast.visibility().unwrap().syntax().clone(), + ); + } + builder.map_node(fn_name.syntax().clone(), ast.name().unwrap().syntax().clone()); + if let Some(type_params) = type_params { + builder.map_node( + type_params.syntax().clone(), + ast.generic_param_list().unwrap().syntax().clone(), + ); + } + if let Some(where_clause) = where_clause { + builder.map_node( + where_clause.syntax().clone(), + ast.where_clause().unwrap().syntax().clone(), + ); + } + builder.map_node(params.syntax().clone(), ast.param_list().unwrap().syntax().clone()); + builder.map_node(body.syntax().clone(), ast.body().unwrap().syntax().clone()); + if let Some(ret_type) = ret_type { + builder + .map_node(ret_type.syntax().clone(), ast.ret_type().unwrap().syntax().clone()); + } + + builder.finish(&mut mapping); + } + + ast + } + pub fn token_tree( &self, delimiter: SyntaxKind, @@ -965,10 +1060,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - builder.map_children( - input.into_iter(), - ast.token_trees_and_tokens().filter_map(only_nodes), - ); + builder.map_children(input, ast.token_trees_and_tokens().filter_map(only_nodes)); builder.finish(&mut mapping); } diff --git a/crates/syntax/src/syntax_editor/mapping.rs b/crates/syntax/src/syntax_editor/mapping.rs index 16bc55ed2d..f71925a795 100644 --- a/crates/syntax/src/syntax_editor/mapping.rs +++ b/crates/syntax/src/syntax_editor/mapping.rs @@ -239,10 +239,10 @@ impl SyntaxMappingBuilder { pub fn map_children( &mut self, - input: impl Iterator, - output: impl Iterator, + input: impl IntoIterator, + output: impl IntoIterator, ) { - for pairs in input.zip_longest(output) { + for pairs in input.into_iter().zip_longest(output) { let (input, output) = match pairs { itertools::EitherOrBoth::Both(l, r) => (l, r), itertools::EitherOrBoth::Left(_) => { diff --git a/docs/book/src/assists_generated.md b/docs/book/src/assists_generated.md index 2d233ca62a..72cecc2b02 100644 --- a/docs/book/src/assists_generated.md +++ b/docs/book/src/assists_generated.md @@ -419,7 +419,7 @@ Converts comments to documentation. ### `convert_bool_then_to_if` -**Source:** [convert_bool_then.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_then.rs#L131) +**Source:** [convert_bool_then.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_then.rs#L143) Converts a `bool::then` method call to an equivalent if expression. @@ -443,7 +443,7 @@ fn main() { ### `convert_closure_to_fn` -**Source:** [convert_closure_to_fn.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_closure_to_fn.rs#L25) +**Source:** [convert_closure_to_fn.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_closure_to_fn.rs#L27) This converts a closure to a freestanding function, changing all captures to parameters. @@ -527,7 +527,7 @@ impl TryFrom for Thing { ### `convert_if_to_bool_then` -**Source:** [convert_bool_then.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_then.rs#L20) +**Source:** [convert_bool_then.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_then.rs#L21) Converts an if expression into a corresponding `bool::then` call. @@ -2258,7 +2258,7 @@ fn bar() { ### `inline_local_variable` -**Source:** [inline_local_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_local_variable.rs#L17) +**Source:** [inline_local_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_local_variable.rs#L21) Inlines a local variable. From 487d68220467ff1b705ff4bde1590225450da4fd Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 1 Mar 2025 16:54:40 +0100 Subject: [PATCH 38/47] Cleanup highlighting macro-def handling --- crates/hir/src/semantics.rs | 19 +- crates/ide/src/syntax_highlighting.rs | 341 ++++++++---------- crates/ide/src/syntax_highlighting/escape.rs | 21 +- crates/ide/src/syntax_highlighting/format.rs | 6 +- .../ide/src/syntax_highlighting/highlight.rs | 18 +- crates/ide/src/syntax_highlighting/macro_.rs | 128 ------- .../test_data/highlight_doctest.html | 2 +- .../test_data/highlight_general.html | 2 +- 8 files changed, 197 insertions(+), 340 deletions(-) delete mode 100644 crates/ide/src/syntax_highlighting/macro_.rs diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index c9145f7d21..bb67fa63a1 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -508,9 +508,7 @@ impl<'db> SemanticsImpl<'db> { }) } - pub fn is_derive_annotated(&self, adt: &ast::Adt) -> bool { - let file_id = self.find_file(adt.syntax()).file_id; - let adt = InFile::new(file_id, adt); + pub fn is_derive_annotated(&self, adt: InFile<&ast::Adt>) -> bool { self.with_ctx(|ctx| ctx.has_derives(adt)) } @@ -551,10 +549,8 @@ impl<'db> SemanticsImpl<'db> { res.is_empty().not().then_some(res) } - pub fn is_attr_macro_call(&self, item: &ast::Item) -> bool { - let file_id = self.find_file(item.syntax()).file_id; - let src = InFile::new(file_id, item); - self.with_ctx(|ctx| ctx.item_to_macro_call(src).is_some()) + pub fn is_attr_macro_call(&self, item: InFile<&ast::Item>) -> bool { + self.with_ctx(|ctx| ctx.item_to_macro_call(item).is_some()) } /// Expand the macro call with a different token tree, mapping the `token_to_map` down into the @@ -1526,8 +1522,13 @@ impl<'db> SemanticsImpl<'db> { self.analyze(field.syntax())?.resolve_record_pat_field(self.db, field) } + // FIXME: Replace this with `resolve_macro_call2` pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option { let macro_call = self.find_file(macro_call.syntax()).with_value(macro_call); + self.resolve_macro_call2(macro_call) + } + + pub fn resolve_macro_call2(&self, macro_call: InFile<&ast::MacroCall>) -> Option { self.with_ctx(|ctx| { ctx.macro_call_to_macro_call(macro_call) .and_then(|call| macro_call_to_macro_id(ctx, call)) @@ -1538,8 +1539,8 @@ impl<'db> SemanticsImpl<'db> { }) } - pub fn is_proc_macro_call(&self, macro_call: &ast::MacroCall) -> bool { - self.resolve_macro_call(macro_call) + pub fn is_proc_macro_call(&self, macro_call: InFile<&ast::MacroCall>) -> bool { + self.resolve_macro_call2(macro_call) .is_some_and(|m| matches!(m.id, MacroId::ProcMacroId(..))) } diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 1853e3a340..6c5e81ae66 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -7,7 +7,6 @@ mod escape; mod format; mod highlight; mod inject; -mod macro_; mod html; #[cfg(test)] @@ -15,14 +14,14 @@ mod tests; use std::ops::ControlFlow; -use hir::{InRealFile, Name, Semantics}; +use hir::{InFile, InRealFile, Name, Semantics}; use ide_db::{FxHashMap, Ranker, RootDatabase, SymbolKind}; use span::EditionedFileId; use syntax::{ ast::{self, IsString}, AstNode, AstToken, NodeOrToken, SyntaxKind::*, - SyntaxNode, TextRange, WalkEvent, T, + SyntaxNode, SyntaxToken, TextRange, WalkEvent, T, }; use crate::{ @@ -30,7 +29,6 @@ use crate::{ escape::{highlight_escape_byte, highlight_escape_char, highlight_escape_string}, format::highlight_format_string, highlights::Highlights, - macro_::MacroHighlighter, tags::Highlight, }, FileId, HlMod, HlOperator, HlPunct, HlTag, @@ -221,7 +219,7 @@ pub(crate) fn highlight( Some(it) => it.krate(), None => return hl.to_vec(), }; - traverse(&mut hl, &sema, config, file_id, &root, krate, range_to_highlight); + traverse(&mut hl, &sema, config, InRealFile::new(file_id, &root), krate, range_to_highlight); hl.to_vec() } @@ -229,8 +227,7 @@ fn traverse( hl: &mut Highlights, sema: &Semantics<'_, RootDatabase>, config: HighlightConfig, - file_id: EditionedFileId, - root: &SyntaxNode, + InRealFile { file_id, value: root }: InRealFile<&SyntaxNode>, krate: hir::Crate, range_to_highlight: TextRange, ) { @@ -252,8 +249,6 @@ fn traverse( let mut tt_level = 0; let mut attr_or_derive_item = None; - let mut current_macro: Option = None; - let mut macro_highlighter = MacroHighlighter::default(); // FIXME: these are not perfectly accurate, we determine them by the real file's syntax tree // an attribute nested in a macro call will not emit `inside_attribute` @@ -263,7 +258,8 @@ fn traverse( // Walk all nodes, keeping track of whether we are inside a macro or not. // If in macro, expand it first and highlight the expanded code. - for event in root.preorder_with_tokens() { + let mut preorder = root.preorder_with_tokens(); + while let Some(event) = preorder.next() { use WalkEvent::{Enter, Leave}; let range = match &event { @@ -275,16 +271,11 @@ fn traverse( continue; } - // set macro and attribute highlighting states match event.clone() { - Enter(NodeOrToken::Node(node)) - if current_macro.is_none() && ast::TokenTree::can_cast(node.kind()) => - { + Enter(NodeOrToken::Node(node)) if ast::TokenTree::can_cast(node.kind()) => { tt_level += 1; } - Leave(NodeOrToken::Node(node)) - if current_macro.is_none() && ast::TokenTree::can_cast(node.kind()) => - { + Leave(NodeOrToken::Node(node)) if ast::TokenTree::can_cast(node.kind()) => { tt_level -= 1; } Enter(NodeOrToken::Node(node)) if ast::Attr::can_cast(node.kind()) => { @@ -297,28 +288,19 @@ fn traverse( Enter(NodeOrToken::Node(node)) => { if let Some(item) = ast::Item::cast(node.clone()) { match item { - ast::Item::MacroRules(mac) => { - macro_highlighter.init(); - current_macro = Some(mac.into()); - continue; - } - ast::Item::MacroDef(mac) => { - macro_highlighter.init(); - current_macro = Some(mac.into()); - continue; - } ast::Item::Fn(_) | ast::Item::Const(_) | ast::Item::Static(_) => { bindings_shadow_count.clear() } ast::Item::MacroCall(ref macro_call) => { inside_macro_call = true; - inside_proc_macro_call = sema.is_proc_macro_call(macro_call); + inside_proc_macro_call = + sema.is_proc_macro_call(InFile::new(file_id.into(), macro_call)); } _ => (), } if attr_or_derive_item.is_none() { - if sema.is_attr_macro_call(&item) { + if sema.is_attr_macro_call(InFile::new(file_id.into(), &item)) { attr_or_derive_item = Some(AttrOrDerive::Attr(item)); } else { let adt = match item { @@ -328,7 +310,10 @@ fn traverse( _ => None, }; match adt { - Some(adt) if sema.is_derive_annotated(&adt) => { + Some(adt) + if sema + .is_derive_annotated(InFile::new(file_id.into(), &adt)) => + { attr_or_derive_item = Some(AttrOrDerive::Derive(ast::Item::from(adt))); } @@ -340,16 +325,6 @@ fn traverse( } Leave(NodeOrToken::Node(node)) if ast::Item::can_cast(node.kind()) => { match ast::Item::cast(node.clone()) { - Some(ast::Item::MacroRules(mac)) => { - assert_eq!(current_macro, Some(mac.into())); - current_macro = None; - macro_highlighter = MacroHighlighter::default(); - } - Some(ast::Item::MacroDef(mac)) => { - assert_eq!(current_macro, Some(mac.into())); - current_macro = None; - macro_highlighter = MacroHighlighter::default(); - } Some(item) if attr_or_derive_item.as_ref().is_some_and(|it| *it.item() == item) => { @@ -379,12 +354,6 @@ fn traverse( } }; - if current_macro.is_some() { - if let Some(tok) = element.as_token() { - macro_highlighter.advance(tok); - } - } - let element = match element.clone() { NodeOrToken::Node(n) => match ast::NameLike::cast(n) { Some(n) => NodeOrToken::Node(n), @@ -392,7 +361,7 @@ fn traverse( }, NodeOrToken::Token(t) => NodeOrToken::Token(t), }; - let token = element.as_token().cloned(); + let original_token = element.as_token().cloned(); // Descending tokens into macros is expensive even if no descending occurs, so make sure // that we actually are in a position where descending is possible. @@ -405,144 +374,52 @@ fn traverse( let descended_element = if in_macro { // Attempt to descend tokens into macro-calls. - let res = match element { - NodeOrToken::Token(token) if token.kind() != COMMENT => { - let ranker = Ranker::from_token(&token); - - let mut t = None; - let mut r = 0; - sema.descend_into_macros_breakable( - InRealFile::new(file_id, token.clone()), - |tok, _ctx| { - // FIXME: Consider checking ctx transparency for being opaque? - let tok = tok.value; - let my_rank = ranker.rank_token(&tok); - - if my_rank >= Ranker::MAX_RANK { - // a rank of 0b1110 means that we have found a maximally interesting - // token so stop early. - t = Some(tok); - return ControlFlow::Break(()); - } - - // r = r.max(my_rank); - // t = Some(t.take_if(|_| r < my_rank).unwrap_or(tok)); - match &mut t { - Some(prev) if r < my_rank => { - *prev = tok; - r = my_rank; - } - Some(_) => (), - None => { - r = my_rank; - t = Some(tok) - } - } - ControlFlow::Continue(()) - }, - ); - - let token = t.unwrap_or(token); - match token.parent().and_then(ast::NameLike::cast) { - // Remap the token into the wrapping single token nodes - Some(parent) => match (token.kind(), parent.syntax().kind()) { - (T![self] | T![ident], NAME | NAME_REF) => NodeOrToken::Node(parent), - (T![self] | T![super] | T![crate] | T![Self], NAME_REF) => { - NodeOrToken::Node(parent) - } - (INT_NUMBER, NAME_REF) => NodeOrToken::Node(parent), - (LIFETIME_IDENT, LIFETIME) => NodeOrToken::Node(parent), - _ => NodeOrToken::Token(token), - }, - None => NodeOrToken::Token(token), - } - } - e => e, - }; - res + match element { + NodeOrToken::Token(token) => descend_token(sema, file_id, token), + n => n, + } } else { element }; - // FIXME: do proper macro def highlighting https://github.com/rust-lang/rust-analyzer/issues/6232 - // Skip metavariables from being highlighted to prevent keyword highlighting in them - if descended_element.as_token().and_then(|t| macro_highlighter.highlight(t)).is_some() { - continue; - } - // string highlight injections, note this does not use the descended element as proc-macros // can rewrite string literals which invalidates our indices - if let (Some(token), Some(descended_token)) = (token, descended_element.as_token()) { - if ast::String::can_cast(token.kind()) && ast::String::can_cast(descended_token.kind()) - { - let string = ast::String::cast(token); - let string_to_highlight = ast::String::cast(descended_token.clone()); - if let Some((string, expanded_string)) = string.zip(string_to_highlight) { - if string.is_raw() - && inject::ra_fixture(hl, sema, config, &string, &expanded_string).is_some() - { - continue; - } - highlight_format_string( - hl, - sema, - krate, - &string, - &expanded_string, - range, - file_id.edition(), - ); - - if !string.is_raw() { - highlight_escape_string(hl, &string, range.start()); - } - } - } else if ast::ByteString::can_cast(token.kind()) - && ast::ByteString::can_cast(descended_token.kind()) - { - if let Some(byte_string) = ast::ByteString::cast(token) { - if !byte_string.is_raw() { - highlight_escape_string(hl, &byte_string, range.start()); - } - } - } else if ast::CString::can_cast(token.kind()) - && ast::CString::can_cast(descended_token.kind()) - { - if let Some(c_string) = ast::CString::cast(token) { - if !c_string.is_raw() { - highlight_escape_string(hl, &c_string, range.start()); - } - } - } else if ast::Char::can_cast(token.kind()) - && ast::Char::can_cast(descended_token.kind()) - { - let Some(char) = ast::Char::cast(token) else { - continue; - }; - - highlight_escape_char(hl, &char, range.start()) - } else if ast::Byte::can_cast(token.kind()) - && ast::Byte::can_cast(descended_token.kind()) - { - let Some(byte) = ast::Byte::cast(token) else { - continue; - }; - - highlight_escape_byte(hl, &byte, range.start()) + if let (Some(original_token), Some(descended_token)) = + (original_token, descended_element.as_token()) + { + let control_flow = string_injections( + hl, + sema, + config, + file_id, + krate, + original_token, + descended_token, + ); + if control_flow.is_break() { + continue; } } let element = match descended_element { - NodeOrToken::Node(name_like) => highlight::name_like( - sema, - krate, - &mut bindings_shadow_count, - config.syntactic_name_ref_highlighting, - name_like, - file_id.edition(), - ), + NodeOrToken::Node(name_like) => { + let hl = highlight::name_like( + sema, + krate, + &mut bindings_shadow_count, + config.syntactic_name_ref_highlighting, + name_like, + file_id.edition(), + ); + if hl.is_some() && !in_macro { + // skip highlighting the contained token of our name-like node + // as that would potentially overwrite our result + preorder.skip_subtree(); + } + hl + } NodeOrToken::Token(token) => { - highlight::token(sema, token, file_id.edition()).zip(Some(None)) + highlight::token(sema, token, file_id.edition(), tt_level > 0).zip(Some(None)) } }; if let Some((mut highlight, binding_hash)) = element { @@ -551,13 +428,6 @@ fn traverse( // let the editor do its highlighting for these tokens instead continue; } - if highlight.tag == HlTag::UnresolvedReference - && matches!(attr_or_derive_item, Some(AttrOrDerive::Derive(_)) if inside_attribute) - { - // do not emit unresolved references in derive helpers if the token mapping maps to - // something unresolvable. FIXME: There should be a way to prevent that - continue; - } // apply config filtering if !filter_by_config(&mut highlight, config) { @@ -579,6 +449,115 @@ fn traverse( } } +fn string_injections( + hl: &mut Highlights, + sema: &Semantics<'_, RootDatabase>, + config: HighlightConfig, + file_id: EditionedFileId, + krate: hir::Crate, + token: SyntaxToken, + descended_token: &SyntaxToken, +) -> ControlFlow<()> { + if ast::String::can_cast(token.kind()) && ast::String::can_cast(descended_token.kind()) { + let string = ast::String::cast(token); + let string_to_highlight = ast::String::cast(descended_token.clone()); + if let Some((string, descended_string)) = string.zip(string_to_highlight) { + if string.is_raw() + && inject::ra_fixture(hl, sema, config, &string, &descended_string).is_some() + { + return ControlFlow::Break(()); + } + highlight_format_string(hl, sema, krate, &string, &descended_string, file_id.edition()); + + if !string.is_raw() { + highlight_escape_string(hl, &string); + } + } + } else if ast::ByteString::can_cast(token.kind()) + && ast::ByteString::can_cast(descended_token.kind()) + { + if let Some(byte_string) = ast::ByteString::cast(token) { + if !byte_string.is_raw() { + highlight_escape_string(hl, &byte_string); + } + } + } else if ast::CString::can_cast(token.kind()) && ast::CString::can_cast(descended_token.kind()) + { + if let Some(c_string) = ast::CString::cast(token) { + if !c_string.is_raw() { + highlight_escape_string(hl, &c_string); + } + } + } else if ast::Char::can_cast(token.kind()) && ast::Char::can_cast(descended_token.kind()) { + let Some(char) = ast::Char::cast(token) else { + return ControlFlow::Break(()); + }; + + highlight_escape_char(hl, &char) + } else if ast::Byte::can_cast(token.kind()) && ast::Byte::can_cast(descended_token.kind()) { + let Some(byte) = ast::Byte::cast(token) else { + return ControlFlow::Break(()); + }; + + highlight_escape_byte(hl, &byte) + } + ControlFlow::Continue(()) +} + +fn descend_token( + sema: &Semantics<'_, RootDatabase>, + file_id: EditionedFileId, + token: SyntaxToken, +) -> NodeOrToken { + if token.kind() == COMMENT { + return NodeOrToken::Token(token); + } + let ranker = Ranker::from_token(&token); + + let mut t = None; + let mut r = 0; + sema.descend_into_macros_breakable(InRealFile::new(file_id, token.clone()), |tok, _ctx| { + // FIXME: Consider checking ctx transparency for being opaque? + let tok = tok.value; + let my_rank = ranker.rank_token(&tok); + + if my_rank >= Ranker::MAX_RANK { + // a rank of 0b1110 means that we have found a maximally interesting + // token so stop early. + t = Some(tok); + return ControlFlow::Break(()); + } + + // r = r.max(my_rank); + // t = Some(t.take_if(|_| r < my_rank).unwrap_or(tok)); + match &mut t { + Some(prev) if r < my_rank => { + *prev = tok; + r = my_rank; + } + Some(_) => (), + None => { + r = my_rank; + t = Some(tok) + } + } + ControlFlow::Continue(()) + }); + + let token = t.unwrap_or(token); + match token.parent().and_then(ast::NameLike::cast) { + // Remap the token into the wrapping single token nodes + Some(parent) => match (token.kind(), parent.syntax().kind()) { + (T![self] | T![ident], NAME | NAME_REF) => NodeOrToken::Node(parent), + (T![self] | T![super] | T![crate] | T![Self], NAME_REF) => NodeOrToken::Node(parent), + (INT_NUMBER, NAME_REF) => NodeOrToken::Node(parent), + (LIFETIME_IDENT, LIFETIME) => NodeOrToken::Node(parent), + _ => NodeOrToken::Token(token), + }, + None => NodeOrToken::Token(token), + } +} + fn filter_by_config(highlight: &mut Highlight, config: HighlightConfig) -> bool { match &mut highlight.tag { HlTag::StringLiteral if !config.strings => return false, diff --git a/crates/ide/src/syntax_highlighting/escape.rs b/crates/ide/src/syntax_highlighting/escape.rs index 552ce9cd8c..094f88f3a8 100644 --- a/crates/ide/src/syntax_highlighting/escape.rs +++ b/crates/ide/src/syntax_highlighting/escape.rs @@ -4,12 +4,9 @@ use crate::{HlRange, HlTag}; use syntax::ast::{Byte, Char, IsString}; use syntax::{AstToken, TextRange, TextSize}; -pub(super) fn highlight_escape_string( - stack: &mut Highlights, - string: &T, - start: TextSize, -) { +pub(super) fn highlight_escape_string(stack: &mut Highlights, string: &T) { let text = string.text(); + let start = string.syntax().text_range().start(); string.escaped_char_ranges(&mut |piece_range, char| { if text[piece_range.start().into()..].starts_with('\\') { let highlight = match char { @@ -25,7 +22,7 @@ pub(super) fn highlight_escape_string( }); } -pub(super) fn highlight_escape_char(stack: &mut Highlights, char: &Char, start: TextSize) { +pub(super) fn highlight_escape_char(stack: &mut Highlights, char: &Char) { if char.value().is_err() { // We do not emit invalid escapes highlighting here. The lexer would likely be in a bad // state and this token contains junk, since `'` is not a reliable delimiter (consider @@ -42,11 +39,14 @@ pub(super) fn highlight_escape_char(stack: &mut Highlights, char: &Char, start: return; }; - let range = TextRange::at(start + TextSize::from(1), TextSize::from(text.len() as u32)); + let range = TextRange::at( + char.syntax().text_range().start() + TextSize::from(1), + TextSize::from(text.len() as u32), + ); stack.add(HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None }) } -pub(super) fn highlight_escape_byte(stack: &mut Highlights, byte: &Byte, start: TextSize) { +pub(super) fn highlight_escape_byte(stack: &mut Highlights, byte: &Byte) { if byte.value().is_err() { // See `highlight_escape_char` for why no error highlighting here. return; @@ -61,6 +61,9 @@ pub(super) fn highlight_escape_byte(stack: &mut Highlights, byte: &Byte, start: return; }; - let range = TextRange::at(start + TextSize::from(2), TextSize::from(text.len() as u32)); + let range = TextRange::at( + byte.syntax().text_range().start() + TextSize::from(2), + TextSize::from(text.len() as u32), + ); stack.add(HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None }) } diff --git a/crates/ide/src/syntax_highlighting/format.rs b/crates/ide/src/syntax_highlighting/format.rs index 43a6bdad7e..c63043621c 100644 --- a/crates/ide/src/syntax_highlighting/format.rs +++ b/crates/ide/src/syntax_highlighting/format.rs @@ -5,7 +5,7 @@ use ide_db::{ SymbolKind, }; use span::Edition; -use syntax::{ast, TextRange}; +use syntax::{ast, AstToken}; use crate::{ syntax_highlighting::{highlight::highlight_def, highlights::Highlights}, @@ -18,15 +18,15 @@ pub(super) fn highlight_format_string( krate: hir::Crate, string: &ast::String, expanded_string: &ast::String, - range: TextRange, edition: Edition, ) { if is_format_string(expanded_string) { + let start = string.syntax().text_range().start(); // FIXME: Replace this with the HIR info we have now. lex_format_specifiers(string, &mut |piece_range, kind| { if let Some(highlight) = highlight_format_specifier(kind) { stack.add(HlRange { - range: piece_range + range.start(), + range: piece_range + start, highlight: highlight.into(), binding_hash: None, }); diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index 194fde1160..316fa5b6e9 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs @@ -23,6 +23,7 @@ pub(super) fn token( sema: &Semantics<'_, RootDatabase>, token: SyntaxToken, edition: Edition, + in_tt: bool, ) -> Option { if let Some(comment) = ast::Comment::cast(token.clone()) { let h = HlTag::Comment; @@ -40,13 +41,20 @@ pub(super) fn token( INT_NUMBER | FLOAT_NUMBER => HlTag::NumericLiteral.into(), BYTE => HlTag::ByteLiteral.into(), CHAR => HlTag::CharLiteral.into(), - IDENT if token.parent().and_then(ast::TokenTree::cast).is_some() => { + IDENT if in_tt => { // from this point on we are inside a token tree, this only happens for identifiers // that were not mapped down into macro invocations HlTag::None.into() } p if p.is_punct() => punctuation(sema, token, p), - k if k.is_keyword(edition) => keyword(sema, token, k)?, + k if k.is_keyword(edition) => { + if in_tt && token.prev_token().is_some_and(|t| t.kind() == T![$]) { + // we are likely within a macro definition where our keyword is a fragment name + HlTag::None.into() + } else { + keyword(sema, token, k)? + } + } _ => return None, }; Some(highlight) @@ -214,12 +222,6 @@ fn keyword( T![true] | T![false] => HlTag::BoolLiteral.into(), // crate is handled just as a token if it's in an `extern crate` T![crate] if parent_matches::(&token) => h, - // self, crate, super and `Self` are handled as either a Name or NameRef already, unless they - // are inside unmapped token trees - T![self] | T![crate] | T![super] | T![Self] if parent_matches::(&token) => { - return None - } - T![self] if parent_matches::(&token) => return None, T![ref] => match token.parent().and_then(ast::IdentPat::cast) { Some(ident) if sema.is_unsafe_ident_pat(&ident) => h | HlMod::Unsafe, _ => h, diff --git a/crates/ide/src/syntax_highlighting/macro_.rs b/crates/ide/src/syntax_highlighting/macro_.rs deleted file mode 100644 index b441b4cc90..0000000000 --- a/crates/ide/src/syntax_highlighting/macro_.rs +++ /dev/null @@ -1,128 +0,0 @@ -//! Syntax highlighting for macro_rules!. -use syntax::{SyntaxKind, SyntaxToken, TextRange, T}; - -use crate::{HlRange, HlTag}; - -#[derive(Default)] -pub(super) struct MacroHighlighter { - state: Option, -} - -impl MacroHighlighter { - pub(super) fn init(&mut self) { - self.state = Some(MacroMatcherParseState::default()); - } - - pub(super) fn advance(&mut self, token: &SyntaxToken) { - if let Some(state) = self.state.as_mut() { - update_macro_state(state, token); - } - } - - pub(super) fn highlight(&self, token: &SyntaxToken) -> Option { - if let Some(state) = self.state.as_ref() { - if matches!(state.rule_state, RuleState::Matcher | RuleState::Expander) { - if let Some(range) = is_metavariable(token) { - return Some(HlRange { - range, - highlight: HlTag::UnresolvedReference.into(), - binding_hash: None, - }); - } - } - } - None - } -} - -struct MacroMatcherParseState { - /// Opening and corresponding closing bracket of the matcher or expander of the current rule - paren_ty: Option<(SyntaxKind, SyntaxKind)>, - paren_level: usize, - rule_state: RuleState, - /// Whether we are inside the outer `{` `}` macro block that holds the rules - in_invoc_body: bool, -} - -impl Default for MacroMatcherParseState { - fn default() -> Self { - MacroMatcherParseState { - paren_ty: None, - paren_level: 0, - in_invoc_body: false, - rule_state: RuleState::None, - } - } -} - -#[derive(Copy, Clone, Debug, PartialEq)] -enum RuleState { - Matcher, - Expander, - Between, - None, -} - -impl RuleState { - fn transition(&mut self) { - *self = match self { - RuleState::Matcher => RuleState::Between, - RuleState::Expander => RuleState::None, - RuleState::Between => RuleState::Expander, - RuleState::None => RuleState::Matcher, - }; - } -} - -fn update_macro_state(state: &mut MacroMatcherParseState, tok: &SyntaxToken) { - if !state.in_invoc_body { - if tok.kind() == T!['{'] || tok.kind() == T!['('] { - state.in_invoc_body = true; - } - return; - } - - match state.paren_ty { - Some((open, close)) => { - if tok.kind() == open { - state.paren_level += 1; - } else if tok.kind() == close { - state.paren_level -= 1; - if state.paren_level == 0 { - state.rule_state.transition(); - state.paren_ty = None; - } - } - } - None => { - match tok.kind() { - T!['('] => { - state.paren_ty = Some((T!['('], T![')'])); - } - T!['{'] => { - state.paren_ty = Some((T!['{'], T!['}'])); - } - T!['['] => { - state.paren_ty = Some((T!['['], T![']'])); - } - _ => (), - } - if state.paren_ty.is_some() { - state.paren_level = 1; - state.rule_state.transition(); - } - } - } -} - -fn is_metavariable(token: &SyntaxToken) -> Option { - match token.kind() { - kind if kind.is_any_identifier() => { - if let Some(_dollar) = token.prev_token().filter(|t| t.kind() == T![$]) { - return Some(token.text_range()); - } - } - _ => (), - }; - None -} diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html index eb77c14c2a..5b5c51a363 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html @@ -156,7 +156,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } /// ``` -/// macro_rules! noop { ($expr:expr) => { $expr }} +/// macro_rules! noop { ($expr:expr) => { $expr }} /// noop!(1); /// ``` macro_rules! noop { diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_general.html b/crates/ide/src/syntax_highlighting/test_data/highlight_general.html index 9477d0d1b8..b5e950ffc2 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_general.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_general.html @@ -151,7 +151,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd let bar = Foo::baz; let baz = (-42,); - let baz = -baz.0; + let baz = -baz.0; let _ = !true; From 9200f770681100493c9d42759fb0486d89867ff7 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 1 Mar 2025 17:23:51 +0100 Subject: [PATCH 39/47] More precise macro modifiers for syntax highlighting --- .../hir-def/src/macro_expansion_tests/mod.rs | 10 +- crates/hir-expand/src/files.rs | 10 +- crates/hir-expand/src/lib.rs | 54 ++++---- crates/hir/src/lib.rs | 49 ++++---- crates/ide-db/src/lib.rs | 6 +- crates/ide-db/src/search.rs | 4 +- crates/ide/src/doc_links.rs | 5 +- crates/ide/src/moniker.rs | 10 +- crates/ide/src/syntax_highlighting.rs | 50 +++----- .../test_data/highlight_asm.html | 20 +-- .../test_data/highlight_attributes.html | 18 +-- .../test_data/highlight_block_mod_items.html | 4 +- .../test_data/highlight_const.html | 4 +- .../test_data/highlight_doctest.html | 6 +- .../test_data/highlight_general.html | 8 +- .../test_data/highlight_injection.html | 2 +- .../test_data/highlight_issue_18089.html | 4 +- .../test_data/highlight_keywords_2015.html | 14 +-- .../test_data/highlight_keywords_2018.html | 14 +-- .../test_data/highlight_keywords_2021.html | 14 +-- .../test_data/highlight_keywords_2024.html | 14 +-- .../test_data/highlight_macros.html | 18 +-- .../test_data/highlight_strings.html | 116 +++++++++--------- .../test_data/highlight_unsafe.html | 8 +- 24 files changed, 231 insertions(+), 231 deletions(-) diff --git a/crates/hir-def/src/macro_expansion_tests/mod.rs b/crates/hir-def/src/macro_expansion_tests/mod.rs index 408d03ff71..a2d0ba3deb 100644 --- a/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -22,7 +22,7 @@ use hir_expand::{ db::ExpandDatabase, proc_macro::{ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind}, span_map::SpanMapRef, - InFile, MacroCallKind, MacroFileId, MacroFileIdExt, + InFile, MacroCallKind, MacroFileId, MacroFileIdExt, MacroKind, }; use intern::Symbol; use itertools::Itertools; @@ -211,7 +211,11 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream if let Some(src) = src { if let Some(file_id) = src.file_id.macro_file() { - if file_id.is_attr_macro(&db) || file_id.is_custom_derive(&db) { + if let MacroKind::Derive + | MacroKind::DeriveBuiltIn + | MacroKind::Attr + | MacroKind::AttrBuiltIn = file_id.kind(&db) + { let call = file_id.call_node(&db); let mut show_spans = false; let mut show_ctxt = false; @@ -236,7 +240,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream for impl_id in def_map[local_id].scope.impls() { let src = impl_id.lookup(&db).source(&db); if let Some(macro_file) = src.file_id.macro_file() { - if macro_file.is_builtin_derive(&db) { + if let MacroKind::DeriveBuiltIn | MacroKind::Derive = macro_file.kind(&db) { let pp = pretty_print_macro_expansion( src.value.syntax().clone(), db.span_map(macro_file.into()).as_ref(), diff --git a/crates/hir-expand/src/files.rs b/crates/hir-expand/src/files.rs index 13ddb0d4ac..f3bcc77268 100644 --- a/crates/hir-expand/src/files.rs +++ b/crates/hir-expand/src/files.rs @@ -10,7 +10,7 @@ use syntax::{AstNode, AstPtr, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, use crate::{ db::{self, ExpandDatabase}, - map_node_range_up, map_node_range_up_rooted, span_for_offset, MacroFileIdExt, + map_node_range_up, map_node_range_up_rooted, span_for_offset, MacroFileIdExt, MacroKind, }; /// `InFile` stores a value of `T` inside a particular file/syntax tree. @@ -276,7 +276,11 @@ impl> InFile { HirFileIdRepr::FileId(file_id) => { return Some(InRealFile { file_id, value: self.value.borrow().clone() }) } - HirFileIdRepr::MacroFile(m) if m.is_attr_macro(db) => m, + HirFileIdRepr::MacroFile(m) + if matches!(m.kind(db), MacroKind::Attr | MacroKind::AttrBuiltIn) => + { + m + } _ => return None, }; @@ -453,7 +457,7 @@ impl InFile { } HirFileIdRepr::MacroFile(m) => m, }; - if !file_id.is_attr_macro(db) { + if !matches!(file_id.kind(db), MacroKind::Attr | MacroKind::AttrBuiltIn) { return None; } diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs index 2c664029f6..41603e3c92 100644 --- a/crates/hir-expand/src/lib.rs +++ b/crates/hir-expand/src/lib.rs @@ -416,6 +416,24 @@ impl HirFileIdExt for HirFileId { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum MacroKind { + /// `macro_rules!` or Macros 2.0 macro. + Declarative, + /// A built-in function-like macro. + DeclarativeBuiltIn, + /// A custom derive. + Derive, + /// A builtin-in derive. + DeriveBuiltIn, + /// A procedural attribute macro. + Attr, + /// A built-in attribute macro. + AttrBuiltIn, + /// A function-like procedural macro. + ProcMacro, +} + pub trait MacroFileIdExt { fn is_env_or_option_env(&self, db: &dyn ExpandDatabase) -> bool; fn is_include_like_macro(&self, db: &dyn ExpandDatabase) -> bool; @@ -427,15 +445,12 @@ pub trait MacroFileIdExt { fn expansion_info(self, db: &dyn ExpandDatabase) -> ExpansionInfo; - fn is_builtin_derive(&self, db: &dyn ExpandDatabase) -> bool; - fn is_custom_derive(&self, db: &dyn ExpandDatabase) -> bool; + fn kind(&self, db: &dyn ExpandDatabase) -> MacroKind; /// Return whether this file is an include macro fn is_include_macro(&self, db: &dyn ExpandDatabase) -> bool; fn is_eager(&self, db: &dyn ExpandDatabase) -> bool; - /// Return whether this file is an attr macro - fn is_attr_macro(&self, db: &dyn ExpandDatabase) -> bool; /// Return whether this file is the pseudo expansion of the derive attribute. /// See [`crate::builtin_attr_macro::derive_attr_expand`]. @@ -468,18 +483,18 @@ impl MacroFileIdExt for MacroFileId { ExpansionInfo::new(db, self) } - fn is_custom_derive(&self, db: &dyn ExpandDatabase) -> bool { - matches!( - db.lookup_intern_macro_call(self.macro_call_id).def.kind, - MacroDefKind::ProcMacro(_, _, ProcMacroKind::CustomDerive) - ) - } - - fn is_builtin_derive(&self, db: &dyn ExpandDatabase) -> bool { - matches!( - db.lookup_intern_macro_call(self.macro_call_id).def.kind, - MacroDefKind::BuiltInDerive(..) - ) + fn kind(&self, db: &dyn ExpandDatabase) -> MacroKind { + match db.lookup_intern_macro_call(self.macro_call_id).def.kind { + MacroDefKind::Declarative(..) => MacroKind::Declarative, + MacroDefKind::BuiltIn(..) | MacroDefKind::BuiltInEager(..) => { + MacroKind::DeclarativeBuiltIn + } + MacroDefKind::BuiltInDerive(..) => MacroKind::DeriveBuiltIn, + MacroDefKind::ProcMacro(_, _, ProcMacroKind::CustomDerive) => MacroKind::Derive, + MacroDefKind::ProcMacro(_, _, ProcMacroKind::Attr) => MacroKind::Attr, + MacroDefKind::ProcMacro(_, _, ProcMacroKind::Bang) => MacroKind::ProcMacro, + MacroDefKind::BuiltInAttr(..) => MacroKind::AttrBuiltIn, + } } fn is_include_macro(&self, db: &dyn ExpandDatabase) -> bool { @@ -507,13 +522,6 @@ impl MacroFileIdExt for MacroFileId { } } - fn is_attr_macro(&self, db: &dyn ExpandDatabase) -> bool { - matches!( - db.lookup_intern_macro_call(self.macro_call_id).def.kind, - MacroDefKind::BuiltInAttr(..) | MacroDefKind::ProcMacro(_, _, ProcMacroKind::Attr) - ) - } - fn is_derive_attr_pseudo_expansion(&self, db: &dyn ExpandDatabase) -> bool { let loc = db.lookup_intern_macro_call(self.macro_call_id); loc.def.is_attribute_derive() diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 727d31cffb..55448d4ae8 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -142,7 +142,7 @@ pub use { name::Name, prettify_macro_expansion, proc_macro::{ProcMacros, ProcMacrosBuilder}, - tt, ExpandResult, HirFileId, HirFileIdExt, MacroFileId, MacroFileIdExt, + tt, ExpandResult, HirFileId, HirFileIdExt, MacroFileId, MacroFileIdExt, MacroKind, }, hir_ty::{ consteval::ConstEvalError, @@ -699,7 +699,10 @@ impl Module { let source_map = tree_source_maps.impl_(loc.id.value).item(); let node = &tree[loc.id.value]; let file_id = loc.id.file_id(); - if file_id.macro_file().is_some_and(|it| it.is_builtin_derive(db.upcast())) { + if file_id + .macro_file() + .is_some_and(|it| it.kind(db.upcast()) == MacroKind::DeriveBuiltIn) + { // these expansion come from us, diagnosing them is a waste of resources // FIXME: Once we diagnose the inputs to builtin derives, we should at least extract those diagnostics somehow continue; @@ -3049,20 +3052,6 @@ impl BuiltinType { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum MacroKind { - /// `macro_rules!` or Macros 2.0 macro. - Declarative, - /// A built-in or custom derive. - Derive, - /// A built-in function-like macro. - BuiltIn, - /// A procedural attribute macro. - Attr, - /// A function-like procedural macro. - ProcMacro, -} - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Macro { pub(crate) id: MacroId, @@ -3093,15 +3082,19 @@ impl Macro { match self.id { MacroId::Macro2Id(it) => match it.lookup(db.upcast()).expander { MacroExpander::Declarative => MacroKind::Declarative, - MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => MacroKind::BuiltIn, - MacroExpander::BuiltInAttr(_) => MacroKind::Attr, - MacroExpander::BuiltInDerive(_) => MacroKind::Derive, + MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => { + MacroKind::DeclarativeBuiltIn + } + MacroExpander::BuiltInAttr(_) => MacroKind::AttrBuiltIn, + MacroExpander::BuiltInDerive(_) => MacroKind::DeriveBuiltIn, }, MacroId::MacroRulesId(it) => match it.lookup(db.upcast()).expander { MacroExpander::Declarative => MacroKind::Declarative, - MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => MacroKind::BuiltIn, - MacroExpander::BuiltInAttr(_) => MacroKind::Attr, - MacroExpander::BuiltInDerive(_) => MacroKind::Derive, + MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => { + MacroKind::DeclarativeBuiltIn + } + MacroExpander::BuiltInAttr(_) => MacroKind::AttrBuiltIn, + MacroExpander::BuiltInDerive(_) => MacroKind::DeriveBuiltIn, }, MacroId::ProcMacroId(it) => match it.lookup(db.upcast()).kind { ProcMacroKind::CustomDerive => MacroKind::Derive, @@ -3112,10 +3105,10 @@ impl Macro { } pub fn is_fn_like(&self, db: &dyn HirDatabase) -> bool { - match self.kind(db) { - MacroKind::Declarative | MacroKind::BuiltIn | MacroKind::ProcMacro => true, - MacroKind::Attr | MacroKind::Derive => false, - } + matches!( + self.kind(db), + MacroKind::Declarative | MacroKind::DeclarativeBuiltIn | MacroKind::ProcMacro + ) } pub fn is_builtin_derive(&self, db: &dyn HirDatabase) -> bool { @@ -3155,11 +3148,11 @@ impl Macro { } pub fn is_attr(&self, db: &dyn HirDatabase) -> bool { - matches!(self.kind(db), MacroKind::Attr) + matches!(self.kind(db), MacroKind::Attr | MacroKind::AttrBuiltIn) } pub fn is_derive(&self, db: &dyn HirDatabase) -> bool { - matches!(self.kind(db), MacroKind::Derive) + matches!(self.kind(db), MacroKind::Derive | MacroKind::DeriveBuiltIn) } } diff --git a/crates/ide-db/src/lib.rs b/crates/ide-db/src/lib.rs index 3a29232d33..96115eee6d 100644 --- a/crates/ide-db/src/lib.rs +++ b/crates/ide-db/src/lib.rs @@ -252,10 +252,10 @@ pub enum SymbolKind { impl From for SymbolKind { fn from(it: hir::MacroKind) -> Self { match it { - hir::MacroKind::Declarative | hir::MacroKind::BuiltIn => SymbolKind::Macro, + hir::MacroKind::Declarative | hir::MacroKind::DeclarativeBuiltIn => SymbolKind::Macro, hir::MacroKind::ProcMacro => SymbolKind::ProcMacro, - hir::MacroKind::Derive => SymbolKind::Derive, - hir::MacroKind::Attr => SymbolKind::Attribute, + hir::MacroKind::Derive | hir::MacroKind::DeriveBuiltIn => SymbolKind::Derive, + hir::MacroKind::Attr | hir::MacroKind::AttrBuiltIn => SymbolKind::Attribute, } } } diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs index 7963e8ae4f..02cd8b8bdf 100644 --- a/crates/ide-db/src/search.rs +++ b/crates/ide-db/src/search.rs @@ -373,7 +373,9 @@ impl Definition { SearchScope::krate(db, module.krate()) } } - hir::MacroKind::BuiltIn => SearchScope::crate_graph(db), + hir::MacroKind::AttrBuiltIn + | hir::MacroKind::DeriveBuiltIn + | hir::MacroKind::DeclarativeBuiltIn => SearchScope::crate_graph(db), hir::MacroKind::Derive | hir::MacroKind::Attr | hir::MacroKind::ProcMacro => { SearchScope::reverse_dependencies(db, module.krate()) } diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index d88f7c5033..8d2ca33bf2 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs @@ -635,12 +635,13 @@ fn filename_and_frag_for_def( } Definition::Macro(mac) => match mac.kind(db) { hir::MacroKind::Declarative - | hir::MacroKind::BuiltIn + | hir::MacroKind::AttrBuiltIn + | hir::MacroKind::DeclarativeBuiltIn | hir::MacroKind::Attr | hir::MacroKind::ProcMacro => { format!("macro.{}.html", mac.name(db).as_str()) } - hir::MacroKind::Derive => { + hir::MacroKind::Derive | hir::MacroKind::DeriveBuiltIn => { format!("derive.{}.html", mac.name(db).as_str()) } }, diff --git a/crates/ide/src/moniker.rs b/crates/ide/src/moniker.rs index 66ea49a98a..25d12a4c0b 100644 --- a/crates/ide/src/moniker.rs +++ b/crates/ide/src/moniker.rs @@ -184,11 +184,11 @@ pub(crate) fn def_to_kind(db: &RootDatabase, def: Definition) -> SymbolInformati match def { Definition::Macro(it) => match it.kind(db) { - MacroKind::Declarative => Macro, - MacroKind::Derive => Attribute, - MacroKind::BuiltIn => Macro, - MacroKind::Attr => Attribute, - MacroKind::ProcMacro => Macro, + MacroKind::Derive + | MacroKind::DeriveBuiltIn + | MacroKind::AttrBuiltIn + | MacroKind::Attr => Attribute, + MacroKind::Declarative | MacroKind::DeclarativeBuiltIn | MacroKind::ProcMacro => Macro, }, Definition::Field(..) | Definition::TupleField(..) => Field, Definition::Module(..) | Definition::Crate(..) => Module, diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 6c5e81ae66..1ce42205d5 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -14,7 +14,7 @@ mod tests; use std::ops::ControlFlow; -use hir::{InFile, InRealFile, Name, Semantics}; +use hir::{InFile, InRealFile, MacroFileIdExt, MacroKind, Name, Semantics}; use ide_db::{FxHashMap, Ranker, RootDatabase, SymbolKind}; use span::EditionedFileId; use syntax::{ @@ -253,8 +253,6 @@ fn traverse( // FIXME: these are not perfectly accurate, we determine them by the real file's syntax tree // an attribute nested in a macro call will not emit `inside_attribute` let mut inside_attribute = false; - let mut inside_macro_call = false; - let mut inside_proc_macro_call = false; // Walk all nodes, keeping track of whether we are inside a macro or not. // If in macro, expand it first and highlight the expanded code. @@ -291,11 +289,6 @@ fn traverse( ast::Item::Fn(_) | ast::Item::Const(_) | ast::Item::Static(_) => { bindings_shadow_count.clear() } - ast::Item::MacroCall(ref macro_call) => { - inside_macro_call = true; - inside_proc_macro_call = - sema.is_proc_macro_call(InFile::new(file_id.into(), macro_call)); - } _ => (), } @@ -330,10 +323,6 @@ fn traverse( { attr_or_derive_item = None; } - Some(ast::Item::MacroCall(_)) => { - inside_macro_call = false; - inside_proc_macro_call = false; - } _ => (), } } @@ -375,17 +364,17 @@ fn traverse( let descended_element = if in_macro { // Attempt to descend tokens into macro-calls. match element { - NodeOrToken::Token(token) => descend_token(sema, file_id, token), - n => n, + NodeOrToken::Token(token) => descend_token(sema, InRealFile::new(file_id, token)), + n => InFile::new(file_id.into(), n), } } else { - element + InFile::new(file_id.into(), element) }; // string highlight injections, note this does not use the descended element as proc-macros // can rewrite string literals which invalidates our indices if let (Some(original_token), Some(descended_token)) = - (original_token, descended_element.as_token()) + (original_token, descended_element.value.as_token()) { let control_flow = string_injections( hl, @@ -401,7 +390,7 @@ fn traverse( } } - let element = match descended_element { + let element = match descended_element.value { NodeOrToken::Node(name_like) => { let hl = highlight::name_like( sema, @@ -437,8 +426,9 @@ fn traverse( if inside_attribute { highlight |= HlMod::Attribute } - if inside_macro_call && tt_level > 0 { - if inside_proc_macro_call { + if let Some(m) = descended_element.file_id.macro_file() { + if let MacroKind::ProcMacro | MacroKind::Attr | MacroKind::Derive = m.kind(sema.db) + { highlight |= HlMod::ProcMacro } highlight |= HlMod::Macro @@ -506,20 +496,18 @@ fn string_injections( fn descend_token( sema: &Semantics<'_, RootDatabase>, - file_id: EditionedFileId, - token: SyntaxToken, -) -> NodeOrToken { - if token.kind() == COMMENT { - return NodeOrToken::Token(token); + token: InRealFile, +) -> InFile> { + if token.value.kind() == COMMENT { + return token.map(NodeOrToken::Token).into(); } - let ranker = Ranker::from_token(&token); + let ranker = Ranker::from_token(&token.value); let mut t = None; let mut r = 0; - sema.descend_into_macros_breakable(InRealFile::new(file_id, token.clone()), |tok, _ctx| { + sema.descend_into_macros_breakable(token.clone(), |tok, _ctx| { // FIXME: Consider checking ctx transparency for being opaque? - let tok = tok.value; - let my_rank = ranker.rank_token(&tok); + let my_rank = ranker.rank_token(&tok.value); if my_rank >= Ranker::MAX_RANK { // a rank of 0b1110 means that we have found a maximally interesting @@ -544,8 +532,8 @@ fn descend_token( ControlFlow::Continue(()) }); - let token = t.unwrap_or(token); - match token.parent().and_then(ast::NameLike::cast) { + let token = t.unwrap_or_else(|| token.into()); + token.map(|token| match token.parent().and_then(ast::NameLike::cast) { // Remap the token into the wrapping single token nodes Some(parent) => match (token.kind(), parent.syntax().kind()) { (T![self] | T![ident], NAME | NAME_REF) => NodeOrToken::Node(parent), @@ -555,7 +543,7 @@ fn descend_token( _ => NodeOrToken::Token(token), }, None => NodeOrToken::Token(token), - } + }) } fn filter_by_config(highlight: &mut Highlight, config: HighlightConfig) -> bool { diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html b/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html index 15a6386aa3..2bc22f960b 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html @@ -49,26 +49,26 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd unsafe { let foo = 1; let mut o = 0; - core::arch::asm!( + core::arch::asm!( "%input = OpLoad _ {0}", concat!("%result = ", "bar", " _ %input"), "OpStore {1} %result", in(reg) &foo, in(reg) &mut o, - ); + ); let thread_id: usize; - core::arch::asm!(" + core::arch::asm!(" mov {0}, gs:[0x30] mov {0}, [{0}+0x48] - ", out(reg) thread_id, options(pure, readonly, nostack)); + ", out(reg) thread_id, options(pure, readonly, nostack)); static UNMAP_BASE: usize; const MEM_RELEASE: usize; static VirtualFree: usize; const OffPtr: usize; const OffFn: usize; - core::arch::asm!(" + core::arch::asm!(" push {free_type} push {free_size} push {base} @@ -92,7 +92,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd base = sym UNMAP_BASE, options(noreturn), - ); + ); } } // taken from https://github.com/rust-embedded/cortex-m/blob/47921b51f8b960344fcfa1255a50a0d19efcde6d/cortex-m/src/asm.rs#L254-L274 @@ -101,19 +101,19 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd // Ensure thumb mode is set. let rv = (rv as u32) | 1; let msp = msp as u32; - core::arch::asm!( + core::arch::asm!( "mrs {tmp}, CONTROL", "bics {tmp}, {spsel}", "msr CONTROL, {tmp}", "isb", "msr MSP, {msp}", "bx {rv}", - // `out(reg) _` is not permitted in a `noreturn` asm! call, - // so instead use `in(reg) 0` and don't restore it afterwards. + // `out(reg) _` is not permitted in a `noreturn` asm! call, + // so instead use `in(reg) 0` and don't restore it afterwards. tmp = in(reg) 0, spsel = in(reg) 2, msp = in(reg) msp, rv = in(reg) rv, options(noreturn, nomem, nostack), - ); + ); } \ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html b/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html index 485d44f97e..e1d51dc0b7 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html @@ -45,20 +45,20 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } -
#[allow(dead_code)]
-#[rustfmt::skip]
+
#[allow(dead_code)]
+#[rustfmt::skip]
 #[proc_macros::identity]
-#[derive(Default)]
+#[derive(Default)]
 /// This is a doc comment
 // This is a normal comment
 /// This is a doc comment
-#[derive(Copy)]
+#[derive(Copy)]
 // This is another normal comment
 /// This is another doc comment
 // This is another normal comment
-#[derive(Copy, Unresolved)]
+#[derive(Copy, Unresolved)]
 // The reason for these being here is to test AttrIds
-enum Foo {
-    #[default]
-    Bar
-}
\ No newline at end of file +enum Foo { + #[default] + Bar +}
\ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html b/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html index c6eab90e42..af29af3f03 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html @@ -53,9 +53,9 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd }; } fn main() { - foo!(Foo); + foo!(Foo); mod module { - foo!(Bar); + foo!(Bar); fn func(_: y::Bar) { mod inner { struct Innerest<const C: usize> { field: [(); {C}] } diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_const.html b/crates/ide/src/syntax_highlighting/test_data/highlight_const.html index 96cdb532dd..6d8f6b3c6e 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_const.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_const.html @@ -57,7 +57,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd const { const || {} } - id!( + id!( CONST_ITEM; CONST_PARAM; const { @@ -65,7 +65,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd }; &raw const (); const - ); + ); ().assoc_const_method(); } trait ConstTrait { diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html index 5b5c51a363..263e4545fb 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html @@ -105,7 +105,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd /// let foo = Foo::new(); /// /// // calls bar on foo - /// assert!(foo.bar()); + /// assert!(foo.bar()); /// /// let bar = foo.bar || Foo::bar; /// @@ -157,7 +157,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd /// ``` /// macro_rules! noop { ($expr:expr) => { $expr }} -/// noop!(1); +/// noop!(1); /// ``` macro_rules! noop { ($expr:expr) => { @@ -177,7 +177,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd /// #[cfg_attr(feature = "alloc", doc = "```rust")] #[cfg_attr(not(feature = "alloc"), doc = "```ignore")] -/// let _ = example(&alloc::vec![1, 2, 3]); +/// let _ = example(&alloc::vec![1, 2, 3]); /// ``` pub fn mix_and_match() {} diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_general.html b/crates/ide/src/syntax_highlighting/test_data/highlight_general.html index b5e950ffc2..eb532a5639 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_general.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_general.html @@ -78,7 +78,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd use self::FooCopy::{self as BarCopy}; -#[derive(Copy)] +#[derive(Copy)] struct FooCopy { x: u32, } @@ -170,7 +170,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd impl<T> Option<T> { fn and<U>(self, other: Option<U>) -> Option<(T, U)> { match other { - None => unimplemented!(), + None => unimplemented!(), Nope => Nope, } } @@ -184,7 +184,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd async fn async_main() { let f1 = learn_and_sing(); let f2 = dance(); - futures::join!(f1, f2); + futures::join!(f1, f2); } fn use_foo_items() { @@ -196,7 +196,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd let control_flow = foo::identity(foo::ControlFlow::Continue); if control_flow.should_die() { - foo::die!(); + foo::die!(); } } diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html index 5fbed35192..1f9422161d 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html @@ -51,7 +51,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd fixture(r#" trait Foo { fn foo() { - println!("2 + 2 = {}", 4); + println!("2 + 2 = {}", 4); } }"# ); diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html b/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html index 06817af1b1..a846addba3 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html @@ -46,8 +46,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
fn main() {
-    template!(template);
+    template!(template);
 }
 
 #[proc_macros::issue_18089]
-fn template() {}
\ No newline at end of file +fn template() {} \ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html index 2d3407dbcd..4d4d03dba3 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html @@ -59,16 +59,16 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd struct __ where Self:; fn __(_: Self) {} -void!(Self); +void!(Self); // edition dependent -void!(try async await gen); +void!(try async await gen); // edition and context dependent -void!(dyn); +void!(dyn); // builtin custom syntax -void!(builtin offset_of format_args asm); +void!(builtin offset_of format_args asm); // contextual -void!(macro_rules, union, default, raw, auto, yeet); +void!(macro_rules, union, default, raw, auto, yeet); // reserved -void!(abstract become box do final macro override priv typeof unsized virtual yield); -void!('static 'self 'unsafe) \ No newline at end of file +void!(abstract become box do final macro override priv typeof unsized virtual yield); +void!('static 'self 'unsafe) \ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html index f8eb5d068a..a199a7ccb4 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html @@ -59,16 +59,16 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd struct __ where Self:; fn __(_: Self) {} -void!(Self); +void!(Self); // edition dependent -void!(try async await gen); +void!(try async await gen); // edition and context dependent -void!(dyn); +void!(dyn); // builtin custom syntax -void!(builtin offset_of format_args asm); +void!(builtin offset_of format_args asm); // contextual -void!(macro_rules, union, default, raw, auto, yeet); +void!(macro_rules, union, default, raw, auto, yeet); // reserved -void!(abstract become box do final macro override priv typeof unsized virtual yield); -void!('static 'self 'unsafe) \ No newline at end of file +void!(abstract become box do final macro override priv typeof unsized virtual yield); +void!('static 'self 'unsafe) \ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html index f8eb5d068a..a199a7ccb4 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html @@ -59,16 +59,16 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd struct __ where Self:; fn __(_: Self) {} -void!(Self); +void!(Self); // edition dependent -void!(try async await gen); +void!(try async await gen); // edition and context dependent -void!(dyn); +void!(dyn); // builtin custom syntax -void!(builtin offset_of format_args asm); +void!(builtin offset_of format_args asm); // contextual -void!(macro_rules, union, default, raw, auto, yeet); +void!(macro_rules, union, default, raw, auto, yeet); // reserved -void!(abstract become box do final macro override priv typeof unsized virtual yield); -void!('static 'self 'unsafe) \ No newline at end of file +void!(abstract become box do final macro override priv typeof unsized virtual yield); +void!('static 'self 'unsafe) \ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html index fca8401706..58a95f199d 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html @@ -59,16 +59,16 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd struct __ where Self:; fn __(_: Self) {} -void!(Self); +void!(Self); // edition dependent -void!(try async await gen); +void!(try async await gen); // edition and context dependent -void!(dyn); +void!(dyn); // builtin custom syntax -void!(builtin offset_of format_args asm); +void!(builtin offset_of format_args asm); // contextual -void!(macro_rules, union, default, raw, auto, yeet); +void!(macro_rules, union, default, raw, auto, yeet); // reserved -void!(abstract become box do final macro override priv typeof unsized virtual yield); -void!('static 'self 'unsafe) \ No newline at end of file +void!(abstract become box do final macro override priv typeof unsized virtual yield); +void!('static 'self 'unsafe) \ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html b/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html index f640a5e6ca..f224435e96 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html @@ -47,21 +47,21 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
use proc_macros::{mirror, identity, DeriveIdentity};
 
-mirror! {
+mirror! {
     {
         ,i32 :x pub
         ,i32 :y pub
     } Foo struct
-}
+}
 macro_rules! def_fn {
     ($($tt:tt)*) => {$($tt)*}
 }
 
-def_fn! {
+def_fn! {
     fn bar() -> u32 {
         100
     }
-}
+}
 
 macro_rules! dont_color_me_braces {
     () => {0}
@@ -100,16 +100,16 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     };
 }
 
-include!(concat!("foo/", "foo.rs"));
+include!(concat!("foo/", "foo.rs"));
 
 struct S<T>(T);
 fn main() {
     struct TestLocal;
     // regression test, TestLocal here used to not resolve
-    let _: S<id![TestLocal]>;
+    let _: S<id![TestLocal]>;
 
-    format_args!("Hello, {}!", (92,).0);
-    dont_color_me_braces!();
-    noop!(noop!(1));
+    format_args!("Hello, {}!", (92,).0);
+    dont_color_me_braces!();
+    noop!(noop!(1));
 }
 
\ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html index 1794d7dbfe..539c74f6b5 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html @@ -99,86 +99,86 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd let a = b'\xFF'; - println!("Hello {{Hello}}"); + println!("Hello {{Hello}}"); // from https://doc.rust-lang.org/std/fmt/index.html - println!("Hello"); // => "Hello" - println!("Hello, {}!", "world"); // => "Hello, world!" - println!("The number is {}", 1); // => "The number is 1" - println!("{:?}", (3, 4)); // => "(3, 4)" - println!("{value}", value=4); // => "4" - println!("{} {}", 1, 2); // => "1 2" - println!("{:04}", 42); // => "0042" with leading zerosV - println!("{1} {} {0} {}", 1, 2); // => "2 1 1 2" - println!("{argument}", argument = "test"); // => "test" - println!("{name} {}", 1, name = 2); // => "2 1" - println!("{a} {c} {b}", a="a", b='b', c=3); // => "a 3 b" - println!("{{{}}}", 2); // => "{2}" - println!("Hello {:5}!", "x"); - println!("Hello {:1$}!", "x", 5); - println!("Hello {1:0$}!", 5, "x"); - println!("Hello {:width$}!", "x", width = 5); - println!("Hello {:<5}!", "x"); - println!("Hello {:-<5}!", "x"); - println!("Hello {:^5}!", "x"); - println!("Hello {:>5}!", "x"); - println!("Hello {:+}!", 5); - println!("{:#x}!", 27); - println!("Hello {:05}!", 5); - println!("Hello {:05}!", -5); - println!("{:#010x}!", 27); - println!("Hello {0} is {1:.5}", "x", 0.01); - println!("Hello {1} is {2:.0$}", 5, "x", 0.01); - println!("Hello {0} is {2:.1$}", "x", 5, 0.01); - println!("Hello {} is {:.*}", "x", 5, 0.01); - println!("Hello {} is {2:.*}", "x", 5, 0.01); - println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01); - println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56); - println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56"); - println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56"); + println!("Hello"); // => "Hello" + println!("Hello, {}!", "world"); // => "Hello, world!" + println!("The number is {}", 1); // => "The number is 1" + println!("{:?}", (3, 4)); // => "(3, 4)" + println!("{value}", value=4); // => "4" + println!("{} {}", 1, 2); // => "1 2" + println!("{:04}", 42); // => "0042" with leading zerosV + println!("{1} {} {0} {}", 1, 2); // => "2 1 1 2" + println!("{argument}", argument = "test"); // => "test" + println!("{name} {}", 1, name = 2); // => "2 1" + println!("{a} {c} {b}", a="a", b='b', c=3); // => "a 3 b" + println!("{{{}}}", 2); // => "{2}" + println!("Hello {:5}!", "x"); + println!("Hello {:1$}!", "x", 5); + println!("Hello {1:0$}!", 5, "x"); + println!("Hello {:width$}!", "x", width = 5); + println!("Hello {:<5}!", "x"); + println!("Hello {:-<5}!", "x"); + println!("Hello {:^5}!", "x"); + println!("Hello {:>5}!", "x"); + println!("Hello {:+}!", 5); + println!("{:#x}!", 27); + println!("Hello {:05}!", 5); + println!("Hello {:05}!", -5); + println!("{:#010x}!", 27); + println!("Hello {0} is {1:.5}", "x", 0.01); + println!("Hello {1} is {2:.0$}", 5, "x", 0.01); + println!("Hello {0} is {2:.1$}", "x", 5, 0.01); + println!("Hello {} is {:.*}", "x", 5, 0.01); + println!("Hello {} is {2:.*}", "x", 5, 0.01); + println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01); + println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56); + println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56"); + println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56"); let _ = "{}" let _ = "{{}}"; - println!("Hello {{}}"); - println!("{{ Hello"); - println!("Hello }}"); - println!("{{Hello}}"); - println!("{{ Hello }}"); - println!("{{Hello }}"); - println!("{{ Hello}}"); + println!("Hello {{}}"); + println!("{{ Hello"); + println!("Hello }}"); + println!("{{Hello}}"); + println!("{{ Hello }}"); + println!("{{Hello }}"); + println!("{{ Hello}}"); - println!(r"Hello, {}!", "world"); + println!(r"Hello, {}!", "world"); // escape sequences - println!("Hello\nWorld"); - println!("\u{48}\x65\x6C\x6C\x6F World"); + println!("Hello\nWorld"); + println!("\u{48}\x65\x6C\x6C\x6F World"); let _ = "\x28\x28\x00\x63\xFF\u{FF}\n"; // invalid non-UTF8 escape sequences let _ = b"\x28\x28\x00\x63\xFF\u{FF}\n"; // valid bytes, invalid unicodes let _ = c"\u{FF}\xFF"; // valid bytes, valid unicodes let backslash = r"\\"; - println!("{\x41}", A = 92); - println!("{ничоси}", ничоси = 92); + println!("{\x41}", A = 92); + println!("{ничоси}", ничоси = 92); - println!("{:x?} {} ", thingy, n2); - panic!("{}", 0); - panic!("more {}", 1); - assert!(true, "{}", 1); - assert!(true, "{} asdasd", 1); - toho!("{}fmt", 0); + println!("{:x?} {} ", thingy, n2); + panic!("{}", 0); + panic!("more {}", 1); + assert!(true, "{}", 1); + assert!(true, "{} asdasd", 1); + toho!("{}fmt", 0); let i: u64 = 3; let o: u64; - core::arch::asm!( + core::arch::asm!( "mov {0}, {1}", "add {0}, 5", out(reg) o, in(reg) i, - ); + ); const CONSTANT: () = (): let mut m = (); - format_args!(concat!("{}"), "{}"); - format_args!("{} {} {} {} {} {} {backslash} {CONSTANT} {m}", backslash, format_args!("{}", 0), foo, "bar", toho!(), backslash); - reuse_twice!("{backslash}"); + format_args!(concat!("{}"), "{}"); + format_args!("{} {} {} {} {} {} {backslash} {CONSTANT} {m}", backslash, format_args!("{}", 0), foo, "bar", toho!(), backslash); + reuse_twice!("{backslash}"); } \ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html index d9beac3089..9a46d9f402 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html @@ -92,13 +92,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd let x = &5 as *const _ as *const usize; let u = Union { b: 0 }; - id! { + id! { unsafe { unsafe_deref!() } - }; + }; unsafe { - unsafe_deref!(); - id! { unsafe_deref!() }; + unsafe_deref!(); + id! { unsafe_deref!() }; // unsafe fn and method calls unsafe_fn(); From 8f319240b42f34d7ef88c060a9461e67506d0d5b Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 1 Mar 2025 17:44:12 +0100 Subject: [PATCH 40/47] Cleanup string handling in syntax highlighting --- crates/ide/src/syntax_highlighting.rs | 58 +++++++------------ .../ide/src/syntax_highlighting/highlight.rs | 2 +- crates/parser/src/syntax_kind/generated.rs | 19 +----- crates/syntax/rust.ungram | 6 +- 4 files changed, 27 insertions(+), 58 deletions(-) diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 1ce42205d5..519133e3ad 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -14,7 +14,7 @@ mod tests; use std::ops::ControlFlow; -use hir::{InFile, InRealFile, MacroFileIdExt, MacroKind, Name, Semantics}; +use hir::{HirFileIdExt, InFile, InRealFile, MacroFileIdExt, MacroKind, Name, Semantics}; use ide_db::{FxHashMap, Ranker, RootDatabase, SymbolKind}; use span::EditionedFileId; use syntax::{ @@ -371,8 +371,7 @@ fn traverse( InFile::new(file_id.into(), element) }; - // string highlight injections, note this does not use the descended element as proc-macros - // can rewrite string literals which invalidates our indices + // string highlight injections if let (Some(original_token), Some(descended_token)) = (original_token, descended_element.value.as_token()) { @@ -390,6 +389,7 @@ fn traverse( } } + let edition = descended_element.file_id.edition(sema.db); let element = match descended_element.value { NodeOrToken::Node(name_like) => { let hl = highlight::name_like( @@ -398,7 +398,7 @@ fn traverse( &mut bindings_shadow_count, config.syntactic_name_ref_highlighting, name_like, - file_id.edition(), + edition, ); if hl.is_some() && !in_macro { // skip highlighting the contained token of our name-like node @@ -408,7 +408,7 @@ fn traverse( hl } NodeOrToken::Token(token) => { - highlight::token(sema, token, file_id.edition(), tt_level > 0).zip(Some(None)) + highlight::token(sema, token, edition, tt_level > 0).zip(Some(None)) } }; if let Some((mut highlight, binding_hash)) = element { @@ -448,10 +448,11 @@ fn string_injections( token: SyntaxToken, descended_token: &SyntaxToken, ) -> ControlFlow<()> { - if ast::String::can_cast(token.kind()) && ast::String::can_cast(descended_token.kind()) { - let string = ast::String::cast(token); - let string_to_highlight = ast::String::cast(descended_token.clone()); - if let Some((string, descended_string)) = string.zip(string_to_highlight) { + if !matches!(token.kind(), STRING | BYTE_STRING | BYTE | CHAR | C_STRING) { + return ControlFlow::Continue(()); + } + if let Some(string) = ast::String::cast(token.clone()) { + if let Some(descended_string) = ast::String::cast(descended_token.clone()) { if string.is_raw() && inject::ra_fixture(hl, sema, config, &string, &descended_string).is_some() { @@ -463,32 +464,17 @@ fn string_injections( highlight_escape_string(hl, &string); } } - } else if ast::ByteString::can_cast(token.kind()) - && ast::ByteString::can_cast(descended_token.kind()) - { - if let Some(byte_string) = ast::ByteString::cast(token) { - if !byte_string.is_raw() { - highlight_escape_string(hl, &byte_string); - } + } else if let Some(byte_string) = ast::ByteString::cast(token.clone()) { + if !byte_string.is_raw() { + highlight_escape_string(hl, &byte_string); } - } else if ast::CString::can_cast(token.kind()) && ast::CString::can_cast(descended_token.kind()) - { - if let Some(c_string) = ast::CString::cast(token) { - if !c_string.is_raw() { - highlight_escape_string(hl, &c_string); - } + } else if let Some(c_string) = ast::CString::cast(token.clone()) { + if !c_string.is_raw() { + highlight_escape_string(hl, &c_string); } - } else if ast::Char::can_cast(token.kind()) && ast::Char::can_cast(descended_token.kind()) { - let Some(char) = ast::Char::cast(token) else { - return ControlFlow::Break(()); - }; - + } else if let Some(char) = ast::Char::cast(token.clone()) { highlight_escape_char(hl, &char) - } else if ast::Byte::can_cast(token.kind()) && ast::Byte::can_cast(descended_token.kind()) { - let Some(byte) = ast::Byte::cast(token) else { - return ControlFlow::Break(()); - }; - + } else if let Some(byte) = ast::Byte::cast(token) { highlight_escape_byte(hl, &byte) } ControlFlow::Continue(()) @@ -536,10 +522,10 @@ fn descend_token( token.map(|token| match token.parent().and_then(ast::NameLike::cast) { // Remap the token into the wrapping single token nodes Some(parent) => match (token.kind(), parent.syntax().kind()) { - (T![self] | T![ident], NAME | NAME_REF) => NodeOrToken::Node(parent), - (T![self] | T![super] | T![crate] | T![Self], NAME_REF) => NodeOrToken::Node(parent), - (INT_NUMBER, NAME_REF) => NodeOrToken::Node(parent), - (LIFETIME_IDENT, LIFETIME) => NodeOrToken::Node(parent), + (T![ident] | T![self], NAME) + | (T![ident] | T![self] | T![super] | T![crate] | T![Self], NAME_REF) + | (INT_NUMBER, NAME_REF) + | (LIFETIME_IDENT, LIFETIME) => NodeOrToken::Node(parent), _ => NodeOrToken::Token(token), }, None => NodeOrToken::Token(token), diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index 316fa5b6e9..127861a04b 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs @@ -89,7 +89,7 @@ pub(super) fn name_like( Some(IdentClass::NameRefClass(NameRefClass::Definition(def, _))) => { highlight_def(sema, krate, def, edition) } - // FIXME: Fallback for 'static and '_, as we do not resolve these yet + // FIXME: Fallback for '_, as we do not resolve these yet _ => SymbolKind::LifetimeParam.into(), }, }; diff --git a/crates/parser/src/syntax_kind/generated.rs b/crates/parser/src/syntax_kind/generated.rs index 79900425a1..e56e09eeb6 100644 --- a/crates/parser/src/syntax_kind/generated.rs +++ b/crates/parser/src/syntax_kind/generated.rs @@ -147,9 +147,6 @@ pub enum SyntaxKind { C_STRING, FLOAT_NUMBER, INT_NUMBER, - RAW_BYTE_STRING, - RAW_C_STRING, - RAW_STRING, STRING, COMMENT, ERROR, @@ -343,9 +340,6 @@ impl SyntaxKind { | C_STRING | FLOAT_NUMBER | INT_NUMBER - | RAW_BYTE_STRING - | RAW_C_STRING - | RAW_STRING | STRING | ABI | ADT @@ -898,18 +892,7 @@ impl SyntaxKind { ) } pub fn is_literal(self) -> bool { - matches!( - self, - BYTE | BYTE_STRING - | CHAR - | C_STRING - | FLOAT_NUMBER - | INT_NUMBER - | RAW_BYTE_STRING - | RAW_C_STRING - | RAW_STRING - | STRING - ) + matches!(self, BYTE | BYTE_STRING | CHAR | C_STRING | FLOAT_NUMBER | INT_NUMBER | STRING) } pub fn from_keyword(ident: &str, edition: Edition) -> Option { let kw = match ident { diff --git a/crates/syntax/rust.ungram b/crates/syntax/rust.ungram index bbb8413cbc..88d7beb897 100644 --- a/crates/syntax/rust.ungram +++ b/crates/syntax/rust.ungram @@ -438,9 +438,9 @@ MacroExpr = Literal = Attr* value:( '@int_number' | '@float_number' - | '@string' | '@raw_string' - | '@byte_string' | '@raw_byte_string' - | '@c_string' | '@raw_c_string' + | '@string' + | '@byte_string' + | '@c_string' | '@char' | '@byte' | 'true' | 'false' ) From 716e9fdb8d7b6417d69d73d3dcfd81856e5e7e06 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 1 Mar 2025 17:49:51 +0100 Subject: [PATCH 41/47] Fix `test_keyword_highlighting` test --- .../test_data/highlight_keywords_2015.html | 14 +++--- .../test_data/highlight_keywords_2018.html | 14 +++--- .../test_data/highlight_keywords_2021.html | 14 +++--- .../test_data/highlight_keywords_2024.html | 14 +++--- .../test_data/highlight_keywords_macros.html | 50 +++++++++++++++++++ crates/ide/src/syntax_highlighting/tests.rs | 27 +++++++++- crates/test-utils/src/fixture.rs | 12 ++--- 7 files changed, 107 insertions(+), 38 deletions(-) create mode 100644 crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html index 4d4d03dba3..c3377614d7 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html @@ -54,21 +54,21 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } macro_rules! void { - ($($tt:tt)*) => {} + ($($tt:tt)*) => {discard!($($tt:tt)*)} } struct __ where Self:; fn __(_: Self) {} -void!(Self); +void!(Self); // edition dependent -void!(try async await gen); +void!(try async await gen); // edition and context dependent -void!(dyn); +void!(dyn); // builtin custom syntax -void!(builtin offset_of format_args asm); +void!(builtin offset_of format_args asm); // contextual -void!(macro_rules, union, default, raw, auto, yeet); +void!(macro_rules, union, default, raw, auto, yeet); // reserved -void!(abstract become box do final macro override priv typeof unsized virtual yield); +void!(abstract become box do final macro override priv typeof unsized virtual yield); void!('static 'self 'unsafe) \ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html index a199a7ccb4..9b22500396 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html @@ -54,21 +54,21 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } macro_rules! void { - ($($tt:tt)*) => {} + ($($tt:tt)*) => {discard!($($tt:tt)*)} } struct __ where Self:; fn __(_: Self) {} -void!(Self); +void!(Self); // edition dependent -void!(try async await gen); +void!(try async await gen); // edition and context dependent -void!(dyn); +void!(dyn); // builtin custom syntax -void!(builtin offset_of format_args asm); +void!(builtin offset_of format_args asm); // contextual -void!(macro_rules, union, default, raw, auto, yeet); +void!(macro_rules, union, default, raw, auto, yeet); // reserved -void!(abstract become box do final macro override priv typeof unsized virtual yield); +void!(abstract become box do final macro override priv typeof unsized virtual yield); void!('static 'self 'unsafe) \ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html index a199a7ccb4..9b22500396 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html @@ -54,21 +54,21 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } macro_rules! void { - ($($tt:tt)*) => {} + ($($tt:tt)*) => {discard!($($tt:tt)*)} } struct __ where Self:; fn __(_: Self) {} -void!(Self); +void!(Self); // edition dependent -void!(try async await gen); +void!(try async await gen); // edition and context dependent -void!(dyn); +void!(dyn); // builtin custom syntax -void!(builtin offset_of format_args asm); +void!(builtin offset_of format_args asm); // contextual -void!(macro_rules, union, default, raw, auto, yeet); +void!(macro_rules, union, default, raw, auto, yeet); // reserved -void!(abstract become box do final macro override priv typeof unsized virtual yield); +void!(abstract become box do final macro override priv typeof unsized virtual yield); void!('static 'self 'unsafe) \ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html index 58a95f199d..ac8353120e 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html @@ -54,21 +54,21 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } macro_rules! void { - ($($tt:tt)*) => {} + ($($tt:tt)*) => {discard!($($tt:tt)*)} } struct __ where Self:; fn __(_: Self) {} -void!(Self); +void!(Self); // edition dependent -void!(try async await gen); +void!(try async await gen); // edition and context dependent -void!(dyn); +void!(dyn); // builtin custom syntax -void!(builtin offset_of format_args asm); +void!(builtin offset_of format_args asm); // contextual -void!(macro_rules, union, default, raw, auto, yeet); +void!(macro_rules, union, default, raw, auto, yeet); // reserved -void!(abstract become box do final macro override priv typeof unsized virtual yield); +void!(abstract become box do final macro override priv typeof unsized virtual yield); void!('static 'self 'unsafe) \ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html new file mode 100644 index 0000000000..694e54d2fa --- /dev/null +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html @@ -0,0 +1,50 @@ + + +
lib2015::void_2015!(try async await gen);
+lib2024::void_2024!(try async await gen);
+
\ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index 3775265f23..e48ca86c46 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs @@ -386,7 +386,7 @@ mod __ { } macro_rules! void { - ($($tt:tt)*) => {} + ($($tt:tt)*) => {discard!($($tt:tt)*)} } struct __ where Self:; @@ -411,6 +411,31 @@ void!('static 'self 'unsafe) } } +#[test] +fn test_keyword_macro_edition_highlighting() { + check_highlighting( + r#" +//- /main.rs crate:main edition:2018 deps:lib2015,lib2024 +lib2015::void_2015!(try async await gen); +lib2024::void_2024!(try async await gen); +//- /lib2015.rs crate:lib2015 edition:2015 +#[macro_export] +macro_rules! void_2015 { + ($($tt:tt)*) => {discard!($($tt:tt)*)} +} + +//- /lib2024.rs crate:lib2024 edition:2024 +#[macro_export] +macro_rules! void_2024 { + ($($tt:tt)*) => {discard!($($tt:tt)*)} +} + +"#, + expect_file![format!("./test_data/highlight_keywords_macros.html")], + false, + ); +} + #[test] fn test_string_highlighting() { // The format string detection is based on macro-expansion, diff --git a/crates/test-utils/src/fixture.rs b/crates/test-utils/src/fixture.rs index daeb56c583..7240069753 100644 --- a/crates/test-utils/src/fixture.rs +++ b/crates/test-utils/src/fixture.rs @@ -218,16 +218,11 @@ impl FixtureWithProjectMeta { ); } - if line.starts_with("//-") { + if let Some(line) = line.strip_prefix("//-") { let meta = Self::parse_meta_line(line); res.push(meta); } else { - if line.starts_with("// ") - && line.contains(':') - && !line.contains("::") - && !line.contains('.') - && line.chars().all(|it| !it.is_uppercase()) - { + if matches!(line.strip_prefix("// "), Some(l) if l.trim().starts_with('/')) { panic!("looks like invalid metadata line: {line:?}"); } @@ -242,8 +237,7 @@ impl FixtureWithProjectMeta { //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo fn parse_meta_line(meta: &str) -> Fixture { - assert!(meta.starts_with("//-")); - let meta = meta["//-".len()..].trim(); + let meta = meta.trim(); let mut components = meta.split_ascii_whitespace(); let path = components.next().expect("fixture meta must start with a path").to_owned(); From 570c6adcd37056b0d1adf344645ffd3e3fd37f65 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 28 Feb 2025 11:53:16 +0100 Subject: [PATCH 42/47] Remove syntax editing from parenthesis computation --- .../src/handlers/apply_demorgan.rs | 65 +++++++------------ .../src/handlers/inline_local_variable.rs | 20 +----- .../src/handlers/remove_parentheses.rs | 2 +- .../src/handlers/unqualify_method_call.rs | 22 +------ crates/ide/src/inlay_hints/adjustment.rs | 11 ++-- crates/syntax/src/ast/prec.rs | 17 ++++- 6 files changed, 50 insertions(+), 87 deletions(-) diff --git a/crates/ide-assists/src/handlers/apply_demorgan.rs b/crates/ide-assists/src/handlers/apply_demorgan.rs index 83c049d461..77562c588e 100644 --- a/crates/ide-assists/src/handlers/apply_demorgan.rs +++ b/crates/ide-assists/src/handlers/apply_demorgan.rs @@ -6,9 +6,16 @@ use ide_db::{ syntax_helpers::node_ext::{for_each_tail_expr, walk_expr}, }; use syntax::{ - ast::{self, syntax_factory::SyntaxFactory, AstNode, Expr::BinExpr, HasArgList}, + ast::{ + self, + prec::{precedence, ExprPrecedence}, + syntax_factory::SyntaxFactory, + AstNode, + Expr::BinExpr, + HasArgList, + }, syntax_editor::{Position, SyntaxEditor}, - SyntaxKind, SyntaxNode, T, + SyntaxKind, T, }; use crate::{utils::invert_boolean_expression, AssistContext, AssistId, AssistKind, Assists}; @@ -52,9 +59,9 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti } let op = bin_expr.op_kind()?; - let inv_token = match op { - ast::BinaryOp::LogicOp(ast::LogicOp::And) => SyntaxKind::PIPE2, - ast::BinaryOp::LogicOp(ast::LogicOp::Or) => SyntaxKind::AMP2, + let (inv_token, prec) = match op { + ast::BinaryOp::LogicOp(ast::LogicOp::And) => (SyntaxKind::PIPE2, ExprPrecedence::LOr), + ast::BinaryOp::LogicOp(ast::LogicOp::Or) => (SyntaxKind::AMP2, ExprPrecedence::LAnd), _ => return None, }; @@ -65,33 +72,33 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti editor.replace(demorganed.op_token()?, make.token(inv_token)); let mut exprs = VecDeque::from([ - (bin_expr.lhs()?, demorganed.lhs()?), - (bin_expr.rhs()?, demorganed.rhs()?), + (bin_expr.lhs()?, demorganed.lhs()?, prec), + (bin_expr.rhs()?, demorganed.rhs()?, prec), ]); - while let Some((expr, dm)) = exprs.pop_front() { + while let Some((expr, demorganed, prec)) = exprs.pop_front() { if let BinExpr(bin_expr) = &expr { - if let BinExpr(cbin_expr) = &dm { + if let BinExpr(cbin_expr) = &demorganed { if op == bin_expr.op_kind()? { editor.replace(cbin_expr.op_token()?, make.token(inv_token)); - exprs.push_back((bin_expr.lhs()?, cbin_expr.lhs()?)); - exprs.push_back((bin_expr.rhs()?, cbin_expr.rhs()?)); + exprs.push_back((bin_expr.lhs()?, cbin_expr.lhs()?, prec)); + exprs.push_back((bin_expr.rhs()?, cbin_expr.rhs()?, prec)); } else { let mut inv = invert_boolean_expression(&make, expr); - if needs_parens_in_place_of(&inv, &dm.syntax().parent()?, &dm) { + if precedence(&inv).needs_parentheses_in(prec) { inv = make.expr_paren(inv).into(); } - editor.replace(dm.syntax(), inv.syntax()); + editor.replace(demorganed.syntax(), inv.syntax()); } } else { return None; } } else { - let mut inv = invert_boolean_expression(&make, dm.clone()); - if needs_parens_in_place_of(&inv, &dm.syntax().parent()?, &dm) { + let mut inv = invert_boolean_expression(&make, demorganed.clone()); + if precedence(&inv).needs_parentheses_in(prec) { inv = make.expr_paren(inv).into(); } - editor.replace(dm.syntax(), inv.syntax()); + editor.replace(demorganed.syntax(), inv.syntax()); } } @@ -121,7 +128,7 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti let parent = neg_expr.syntax().parent(); editor = builder.make_editor(neg_expr.syntax()); - if parent.is_some_and(|parent| demorganed.needs_parens_in(parent)) { + if parent.is_some_and(|parent| demorganed.needs_parens_in(&parent)) { cov_mark::hit!(demorgan_keep_parens_for_op_precedence2); editor.replace(neg_expr.syntax(), make.expr_paren(demorganed).syntax()); } else { @@ -271,30 +278,6 @@ fn add_bang_paren(make: &SyntaxFactory, expr: ast::Expr) -> ast::Expr { make.expr_prefix(T![!], make.expr_paren(expr).into()).into() } -fn needs_parens_in_place_of( - this: &ast::Expr, - parent: &SyntaxNode, - in_place_of: &ast::Expr, -) -> bool { - assert_eq!(Some(parent), in_place_of.syntax().parent().as_ref()); - - let child_idx = parent - .children() - .enumerate() - .find_map(|(i, it)| if &it == in_place_of.syntax() { Some(i) } else { None }) - .unwrap(); - let parent = parent.clone_subtree(); - let subtree_place = parent.children().nth(child_idx).unwrap(); - - let mut editor = SyntaxEditor::new(parent); - editor.replace(subtree_place, this.syntax()); - let edit = editor.finish(); - - let replaced = edit.new_root().children().nth(child_idx).unwrap(); - let replaced = ast::Expr::cast(replaced).unwrap(); - replaced.needs_parens_in(edit.new_root().clone()) -} - #[cfg(test)] mod tests { use super::*; diff --git a/crates/ide-assists/src/handlers/inline_local_variable.rs b/crates/ide-assists/src/handlers/inline_local_variable.rs index 5d4fbfc10a..cc7bea5152 100644 --- a/crates/ide-assists/src/handlers/inline_local_variable.rs +++ b/crates/ide-assists/src/handlers/inline_local_variable.rs @@ -5,11 +5,7 @@ use ide_db::{ EditionedFileId, RootDatabase, }; use syntax::{ - ast::{ - self, - prec::{precedence, ExprPrecedence}, - AstNode, AstToken, HasName, - }, + ast::{self, AstNode, AstToken, HasName}, SyntaxElement, TextRange, }; @@ -77,22 +73,12 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>) } let usage_node = name_ref.syntax().ancestors().find(|it| ast::PathExpr::can_cast(it.kind())); - let usage_parent_option = - usage_node.and_then(|it| it.parent()).and_then(ast::Expr::cast); + let usage_parent_option = usage_node.and_then(|it| it.parent()); let usage_parent = match usage_parent_option { Some(u) => u, None => return Some((range, name_ref, false)), }; - let initializer = precedence(&initializer_expr); - let parent = precedence(&usage_parent); - Some(( - range, - name_ref, - parent != ExprPrecedence::Unambiguous - && initializer < parent - // initializer == ExprPrecedence::Prefix -> parent != ExprPrecedence::Jump - && (initializer != ExprPrecedence::Prefix || parent != ExprPrecedence::Jump), - )) + Some((range, name_ref, initializer_expr.needs_parens_in(&usage_parent))) }) .collect::>>()?; diff --git a/crates/ide-assists/src/handlers/remove_parentheses.rs b/crates/ide-assists/src/handlers/remove_parentheses.rs index 143d5e5424..e7beb23bf8 100644 --- a/crates/ide-assists/src/handlers/remove_parentheses.rs +++ b/crates/ide-assists/src/handlers/remove_parentheses.rs @@ -34,7 +34,7 @@ pub(crate) fn remove_parentheses(acc: &mut Assists, ctx: &AssistContext<'_>) -> let expr = parens.expr()?; let parent = parens.syntax().parent()?; - if expr.needs_parens_in(parent) { + if expr.needs_parens_in(&parent) { return None; } diff --git a/crates/ide-assists/src/handlers/unqualify_method_call.rs b/crates/ide-assists/src/handlers/unqualify_method_call.rs index 0876246e90..baf4ddae2f 100644 --- a/crates/ide-assists/src/handlers/unqualify_method_call.rs +++ b/crates/ide-assists/src/handlers/unqualify_method_call.rs @@ -1,6 +1,6 @@ use ide_db::imports::insert_use::ImportScope; use syntax::{ - ast::{self, make, AstNode, HasArgList}, + ast::{self, prec::ExprPrecedence, AstNode, HasArgList}, TextRange, }; @@ -55,7 +55,7 @@ pub(crate) fn unqualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) TextRange::new(path.syntax().text_range().start(), l_paren.text_range().end()); // Parens around `expr` if needed - let parens = needs_parens_as_receiver(&first_arg).then(|| { + let parens = first_arg.precedence().needs_parentheses_in(ExprPrecedence::Postfix).then(|| { let range = first_arg.syntax().text_range(); (range.start(), range.end()) }); @@ -124,24 +124,6 @@ fn add_import( } } -fn needs_parens_as_receiver(expr: &ast::Expr) -> bool { - // Make `(expr).dummy()` - let dummy_call = make::expr_method_call( - make::expr_paren(expr.clone()), - make::name_ref("dummy"), - make::arg_list([]), - ); - - // Get the `expr` clone with the right parent back - // (unreachable!s are fine since we've just constructed the expression) - let ast::Expr::MethodCallExpr(call) = &dummy_call else { unreachable!() }; - let Some(receiver) = call.receiver() else { unreachable!() }; - let ast::Expr::ParenExpr(parens) = receiver else { unreachable!() }; - let Some(expr) = parens.expr() else { unreachable!() }; - - expr.needs_parens_in(dummy_call.syntax().clone()) -} - #[cfg(test)] mod tests { use crate::tests::{check_assist, check_assist_not_applicable}; diff --git a/crates/ide/src/inlay_hints/adjustment.rs b/crates/ide/src/inlay_hints/adjustment.rs index 6b2e41f42b..8522ef0a6d 100644 --- a/crates/ide/src/inlay_hints/adjustment.rs +++ b/crates/ide/src/inlay_hints/adjustment.rs @@ -258,15 +258,12 @@ fn mode_and_needs_parens_for_adjustment_hints( fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, bool) { let prec = expr.precedence(); if postfix { - // postfix ops have higher precedence than any other operator, so we need to wrap - // any inner expression that is below - let needs_inner_parens = prec < ExprPrecedence::Postfix; + let needs_inner_parens = prec.needs_parentheses_in(ExprPrecedence::Postfix); // given we are the higher precedence, no parent expression will have stronger requirements let needs_outer_parens = false; (needs_outer_parens, needs_inner_parens) } else { - // We need to wrap all binary like things, thats everything below prefix except for jumps - let needs_inner_parens = prec < ExprPrecedence::Prefix && prec != ExprPrecedence::Jump; + let needs_inner_parens = prec.needs_parentheses_in(ExprPrecedence::Prefix); let parent = expr .syntax() .parent() @@ -278,8 +275,8 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, // if we have no parent, we don't need outer parens to disambiguate // otherwise anything with higher precedence than what we insert needs to wrap us - let needs_outer_parens = - parent.is_some_and(|parent_prec| parent_prec > ExprPrecedence::Prefix); + let needs_outer_parens = parent + .is_some_and(|parent_prec| ExprPrecedence::Prefix.needs_parentheses_in(parent_prec)); (needs_outer_parens, needs_inner_parens) } } diff --git a/crates/syntax/src/ast/prec.rs b/crates/syntax/src/ast/prec.rs index 2a47b3bea5..0c4da76299 100644 --- a/crates/syntax/src/ast/prec.rs +++ b/crates/syntax/src/ast/prec.rs @@ -41,6 +41,21 @@ pub enum ExprPrecedence { Unambiguous, } +impl ExprPrecedence { + pub fn needs_parentheses_in(self, other: ExprPrecedence) -> bool { + match other { + ExprPrecedence::Unambiguous => false, + // postfix ops have higher precedence than any other operator, so we need to wrap + // any inner expression that is below + ExprPrecedence::Postfix => self < ExprPrecedence::Postfix, + // We need to wrap all binary like things, thats everything below prefix except for + // jumps (as those are prefix operations as well) + ExprPrecedence::Prefix => ExprPrecedence::Jump < self && self < ExprPrecedence::Prefix, + parent => self <= parent, + } + } +} + #[derive(PartialEq, Debug)] pub enum Fixity { /// The operator is left-associative @@ -137,7 +152,7 @@ impl Expr { // - https://github.com/rust-lang/rust/blob/b6852428a8ea9728369b64b9964cad8e258403d3/compiler/rustc_ast/src/util/parser.rs#L296 /// Returns `true` if `self` would need to be wrapped in parentheses given that its parent is `parent`. - pub fn needs_parens_in(&self, parent: SyntaxNode) -> bool { + pub fn needs_parens_in(&self, parent: &SyntaxNode) -> bool { match_ast! { match parent { ast::Expr(e) => self.needs_parens_in_expr(&e), From f7569a4426e4d4fd3c30867c710e0a6b4d67c9e5 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 2 Mar 2025 08:03:01 +0100 Subject: [PATCH 43/47] Add flip or-pattern assist --- crates/ide-assists/src/assist_context.rs | 20 ++++- crates/ide-assists/src/handlers/flip_comma.rs | 49 +++++------- .../src/handlers/flip_or_pattern.rs | 80 +++++++++++++++++++ .../src/handlers/flip_trait_bound.rs | 9 +-- crates/ide-assists/src/lib.rs | 2 + crates/ide-assists/src/tests/generated.rs | 17 ++++ docs/book/src/assists_generated.md | 24 +++++- 7 files changed, 159 insertions(+), 42 deletions(-) create mode 100644 crates/ide-assists/src/handlers/flip_or_pattern.rs diff --git a/crates/ide-assists/src/assist_context.rs b/crates/ide-assists/src/assist_context.rs index 64e77b2d69..b1189f0d0b 100644 --- a/crates/ide-assists/src/assist_context.rs +++ b/crates/ide-assists/src/assist_context.rs @@ -52,6 +52,10 @@ pub(crate) struct AssistContext<'a> { frange: FileRange, trimmed_range: TextRange, source_file: SourceFile, + // We cache this here to speed up things slightly + token_at_offset: TokenAtOffset, + // We cache this here to speed up things slightly + covering_element: SyntaxElement, } impl<'a> AssistContext<'a> { @@ -78,8 +82,18 @@ impl<'a> AssistContext<'a> { // Selection solely consists of whitespace so just fall back to the original _ => frange.range, }; + let token_at_offset = source_file.syntax().token_at_offset(frange.range.start()); + let covering_element = source_file.syntax().covering_element(trimmed_range); - AssistContext { config, sema, frange, source_file, trimmed_range } + AssistContext { + config, + sema, + frange, + source_file, + trimmed_range, + token_at_offset, + covering_element, + } } pub(crate) fn db(&self) -> &RootDatabase { @@ -114,7 +128,7 @@ impl<'a> AssistContext<'a> { } pub(crate) fn token_at_offset(&self) -> TokenAtOffset { - self.source_file.syntax().token_at_offset(self.offset()) + self.token_at_offset.clone() } pub(crate) fn find_token_syntax_at_offset(&self, kind: SyntaxKind) -> Option { self.token_at_offset().find(|it| it.kind() == kind) @@ -136,7 +150,7 @@ impl<'a> AssistContext<'a> { } /// Returns the element covered by the selection range, this excludes trailing whitespace in the selection. pub(crate) fn covering_element(&self) -> SyntaxElement { - self.source_file.syntax().covering_element(self.selection_trimmed()) + self.covering_element.clone() } } diff --git a/crates/ide-assists/src/handlers/flip_comma.rs b/crates/ide-assists/src/handlers/flip_comma.rs index 95e035c053..dd27269b00 100644 --- a/crates/ide-assists/src/handlers/flip_comma.rs +++ b/crates/ide-assists/src/handlers/flip_comma.rs @@ -1,8 +1,8 @@ use syntax::{ algo::non_trivia_sibling, ast::{self, syntax_factory::SyntaxFactory}, - syntax_editor::{Element, SyntaxMapping}, - AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxToken, T, + syntax_editor::SyntaxMapping, + AstNode, Direction, NodeOrToken, SyntaxKind, SyntaxToken, T, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -39,37 +39,24 @@ pub(crate) fn flip_comma(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( return None; } - let prev = match prev { - SyntaxElement::Node(node) => node.syntax_element(), - _ => prev, - }; - let next = match next { - SyntaxElement::Node(node) => node.syntax_element(), - _ => next, - }; + let target = comma.text_range(); + acc.add(AssistId("flip_comma", AssistKind::RefactorRewrite), "Flip comma", target, |builder| { + let parent = comma.parent().unwrap(); + let mut editor = builder.make_editor(&parent); - acc.add( - AssistId("flip_comma", AssistKind::RefactorRewrite), - "Flip comma", - comma.text_range(), - |builder| { - let parent = comma.parent().unwrap(); - let mut editor = builder.make_editor(&parent); + if let Some(parent) = ast::TokenTree::cast(parent) { + // An attribute. It often contains a path followed by a + // token tree (e.g. `align(2)`), so we have to be smarter. + let (new_tree, mapping) = flip_tree(parent.clone(), comma); + editor.replace(parent.syntax(), new_tree.syntax()); + editor.add_mappings(mapping); + } else { + editor.replace(prev.clone(), next.clone()); + editor.replace(next.clone(), prev.clone()); + } - if let Some(parent) = ast::TokenTree::cast(parent) { - // An attribute. It often contains a path followed by a - // token tree (e.g. `align(2)`), so we have to be smarter. - let (new_tree, mapping) = flip_tree(parent.clone(), comma); - editor.replace(parent.syntax(), new_tree.syntax()); - editor.add_mappings(mapping); - } else { - editor.replace(prev.clone(), next.clone()); - editor.replace(next.clone(), prev.clone()); - } - - builder.add_file_edits(ctx.file_id(), editor); - }, - ) + builder.add_file_edits(ctx.file_id(), editor); + }) } fn flip_tree(tree: ast::TokenTree, comma: SyntaxToken) -> (ast::TokenTree, SyntaxMapping) { diff --git a/crates/ide-assists/src/handlers/flip_or_pattern.rs b/crates/ide-assists/src/handlers/flip_or_pattern.rs new file mode 100644 index 0000000000..d9fa03e719 --- /dev/null +++ b/crates/ide-assists/src/handlers/flip_or_pattern.rs @@ -0,0 +1,80 @@ +use syntax::{ + algo::non_trivia_sibling, + ast::{self, AstNode}, + Direction, T, +}; + +use crate::{AssistContext, AssistId, AssistKind, Assists}; + +// Assist: flip_or_pattern +// +// Flips two patterns in an or-pattern. +// +// ``` +// fn foo() { +// let (a |$0 b) = 1; +// } +// ``` +// -> +// ``` +// fn foo() { +// let (b | a) = 1; +// } +// ``` +pub(crate) fn flip_or_pattern(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { + // Only flip on the `|` token + let pipe = ctx.find_token_syntax_at_offset(T![|])?; + + let parent = ast::OrPat::cast(pipe.parent()?)?; + + let before = non_trivia_sibling(pipe.clone().into(), Direction::Prev)?.into_node()?; + let after = non_trivia_sibling(pipe.clone().into(), Direction::Next)?.into_node()?; + + let target = pipe.text_range(); + acc.add( + AssistId("flip_or_pattern", AssistKind::RefactorRewrite), + "Flip patterns", + target, + |builder| { + let mut editor = builder.make_editor(parent.syntax()); + editor.replace(before.clone(), after.clone()); + editor.replace(after, before); + builder.add_file_edits(ctx.file_id(), editor); + }, + ) +} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; + + #[test] + fn flip_or_pattern_assist_available() { + check_assist_target(flip_or_pattern, "fn main(a |$0 b: ()) {}", "|") + } + + #[test] + fn flip_or_pattern_not_applicable_for_leading_pipe() { + check_assist_not_applicable(flip_or_pattern, "fn main(|$0 b: ()) {}") + } + + #[test] + fn flip_or_pattern_works() { + check_assist( + flip_or_pattern, + "fn foo() { let (a | b |$0 c | d) = 1; }", + "fn foo() { let (a | c | b | d) = 1; }", + ) + } + + #[test] + fn flip_or_pattern_works_match_guard() { + check_assist( + flip_or_pattern, + "fn foo() { match() { a |$0 b if true => () }}", + "fn foo() { match() { b | a if true => () }}", + ) + } +} diff --git a/crates/ide-assists/src/handlers/flip_trait_bound.rs b/crates/ide-assists/src/handlers/flip_trait_bound.rs index 298e5bd82c..3528f5e813 100644 --- a/crates/ide-assists/src/handlers/flip_trait_bound.rs +++ b/crates/ide-assists/src/handlers/flip_trait_bound.rs @@ -18,17 +18,14 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; // fn foo() { } // ``` pub(crate) fn flip_trait_bound(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { - // We want to replicate the behavior of `flip_binexpr` by only suggesting - // the assist when the cursor is on a `+` + // Only flip on the `+` token let plus = ctx.find_token_syntax_at_offset(T![+])?; // Make sure we're in a `TypeBoundList` let parent = ast::TypeBoundList::cast(plus.parent()?)?; - let (before, after) = ( - non_trivia_sibling(plus.clone().into(), Direction::Prev)?.into_node()?, - non_trivia_sibling(plus.clone().into(), Direction::Next)?.into_node()?, - ); + let before = non_trivia_sibling(plus.clone().into(), Direction::Prev)?.into_node()?; + let after = non_trivia_sibling(plus.clone().into(), Direction::Next)?.into_node()?; let target = plus.text_range(); acc.add( diff --git a/crates/ide-assists/src/lib.rs b/crates/ide-assists/src/lib.rs index 179742f91b..448bcadb8e 100644 --- a/crates/ide-assists/src/lib.rs +++ b/crates/ide-assists/src/lib.rs @@ -149,6 +149,7 @@ mod handlers { mod fix_visibility; mod flip_binexpr; mod flip_comma; + mod flip_or_pattern; mod flip_trait_bound; mod generate_constant; mod generate_default_from_enum_variant; @@ -279,6 +280,7 @@ mod handlers { fix_visibility::fix_visibility, flip_binexpr::flip_binexpr, flip_comma::flip_comma, + flip_or_pattern::flip_or_pattern, flip_trait_bound::flip_trait_bound, generate_constant::generate_constant, generate_default_from_enum_variant::generate_default_from_enum_variant, diff --git a/crates/ide-assists/src/tests/generated.rs b/crates/ide-assists/src/tests/generated.rs index 74ae126ada..91c1a3e1bd 100644 --- a/crates/ide-assists/src/tests/generated.rs +++ b/crates/ide-assists/src/tests/generated.rs @@ -1195,6 +1195,23 @@ fn main() { ) } +#[test] +fn doctest_flip_or_pattern() { + check_doc_test( + "flip_or_pattern", + r#####" +fn foo() { + let (a |$0 b) = 1; +} +"#####, + r#####" +fn foo() { + let (b | a) = 1; +} +"#####, + ) +} + #[test] fn doctest_flip_trait_bound() { check_doc_test( diff --git a/docs/book/src/assists_generated.md b/docs/book/src/assists_generated.md index 2d233ca62a..8efc7cbabe 100644 --- a/docs/book/src/assists_generated.md +++ b/docs/book/src/assists_generated.md @@ -257,7 +257,7 @@ fn main() { ### `apply_demorgan` -**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L16) +**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L23) Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws). This transforms expressions of the form `!l || !r` into `!(l && r)`. @@ -280,7 +280,7 @@ fn main() { ### `apply_demorgan_iterator` -**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L147) +**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L154) Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws) to `Iterator::all` and `Iterator::any`. @@ -1345,6 +1345,26 @@ fn main() { ``` +### `flip_or_pattern` +**Source:** [flip_or_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/flip_or_pattern.rs#L9) + +Flips two trait bounds. + +#### Before +```rust +fn foo() { + let (a |┃ b) = 1; +} +``` + +#### After +```rust +fn foo() { + let (b | a) = 1; +} +``` + + ### `flip_trait_bound` **Source:** [flip_trait_bound.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/flip_trait_bound.rs#L9) From b1a1aa4209e069a717d94d30bcdc520e1ae23950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Sun, 2 Mar 2025 16:05:13 +0200 Subject: [PATCH 44/47] Fix transparent diagnostics --- editors/code/src/diagnostics.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/editors/code/src/diagnostics.ts b/editors/code/src/diagnostics.ts index 73621dda9c..cd0e43b212 100644 --- a/editors/code/src/diagnostics.ts +++ b/editors/code/src/diagnostics.ts @@ -207,11 +207,6 @@ export class AnsiDecorationProvider implements vscode.Disposable { } } - const themeColor = AnsiDecorationProvider._anserToThemeColor[color]; - if (themeColor) { - return new ThemeColor("terminal." + themeColor); - } - - return undefined; + return AnsiDecorationProvider._anserToThemeColor[color]; } } From c9fdc48e865f0be88b71a52ff4c3a8b5b270de37 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sun, 2 Mar 2025 09:19:25 -0500 Subject: [PATCH 45/47] Add `identifier` to pull diagnostic LSP capabilities This field in the server capabilities instructs the client to maintain the diagnostics received from a `textDocument/diagnostic` pull request as a separate set from other diagnostics: namely those sent with classic "push" diagnostics, `textDocument/publishDiagnostic`. rust-analyzer emits "native" diagnostics (computed by rust-analyzer itself) in pull diagnostics and separately emits cargo-based diagnostics with push, so push and pull diagnostics should be different sets. Setting this field instructs the client to avoid clearing push diagnostics when new pull diagnostics arrive and vice versa. --- crates/rust-analyzer/src/lsp/capabilities.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rust-analyzer/src/lsp/capabilities.rs b/crates/rust-analyzer/src/lsp/capabilities.rs index b1136dbbda..9c6b69d731 100644 --- a/crates/rust-analyzer/src/lsp/capabilities.rs +++ b/crates/rust-analyzer/src/lsp/capabilities.rs @@ -165,7 +165,7 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities { })), diagnostic_provider: Some(lsp_types::DiagnosticServerCapabilities::Options( lsp_types::DiagnosticOptions { - identifier: None, + identifier: Some("rust-analyzer".to_owned()), inter_file_dependencies: true, // FIXME workspace_diagnostics: false, From 8f3bdd1147de3140ca1678756c3bbb12afa6fc79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 3 Mar 2025 08:38:14 +0200 Subject: [PATCH 46/47] Preparing for merge from rust-lang/rust --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 6cd39fabee..e24e08d068 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -e0be1a02626abef2878cb7f4aaef7ae409477112 +daf59857d6d2b87af4b846316bf1561a6083ed51 From e015bb446cfe63fcfe25978847e047e93a452734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 3 Mar 2025 08:43:57 +0200 Subject: [PATCH 47/47] Bump rustc crates --- Cargo.lock | 28 ++++++++++++++-------------- Cargo.toml | 12 ++++++------ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 57aafcb1ec..c57953ba65 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1504,9 +1504,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_abi" -version = "0.97.0" +version = "0.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3829c3355d1681ffeaf1450ec71edcdace6820fe2e86469d8fc1ad45e2c96460" +checksum = "4b42cccfff8091a4c3397736518774dbad619e82f8def6f70d8e46dbbe396007" dependencies = [ "bitflags 2.7.0", "ra-ap-rustc_hashes", @@ -1516,18 +1516,18 @@ dependencies = [ [[package]] name = "ra-ap-rustc_hashes" -version = "0.97.0" +version = "0.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bd4d6d4c434bec08e02370a4f64a4985312097215a62e82d0f757f3a98e502e" +checksum = "46d8bd34ed6552c8cac1764106ef5adbeef3e5c7700e0ceb4c83a47a631894fe" dependencies = [ "rustc-stable-hash", ] [[package]] name = "ra-ap-rustc_index" -version = "0.97.0" +version = "0.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad6fc4bd7522e31096e2de5b0351144fe0684b608791ee26c842bf2da1b19ae" +checksum = "93799e4dccbbd47f8b66bc0aa42effc1b7077aaee09d8a40b86b8d659b80c7b7" dependencies = [ "ra-ap-rustc_index_macros", "smallvec", @@ -1535,9 +1535,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_index_macros" -version = "0.97.0" +version = "0.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfb234e1f84b92be45276c3025bee18789e9bc95bec8789bec961e78edb01c52" +checksum = "30baa5d00f94ba437a9dcaf7ae074ebe4f367bb05a4c2835e0aa2e7af3463aac" dependencies = [ "proc-macro2", "quote", @@ -1546,9 +1546,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_lexer" -version = "0.97.0" +version = "0.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a3a40bd11dc43d1cb110e730b80620cf8102f4cca8920a02b65954da0ed931f" +checksum = "3004d1d1b50afe3e1f9cdd428a282da7ffbf5f26dd8bf04af0d651d44e4873d8" dependencies = [ "memchr", "unicode-properties", @@ -1557,9 +1557,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_parse_format" -version = "0.97.0" +version = "0.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5feb877478994cb4c0c0c7a5116a352eefc0634aefc8636feb00a893fa5b7135" +checksum = "cb57e5124a64aaaf92c06130fbc1b8e1d547b5a2a96081f1f848e31c211df5d2" dependencies = [ "ra-ap-rustc_index", "ra-ap-rustc_lexer", @@ -1567,9 +1567,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_pattern_analysis" -version = "0.97.0" +version = "0.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76774d35934d464c4115908cde16f76a4f7e540fe1eea6b79336c556e37bdd3" +checksum = "e427c3d30e4bdff28abd6b0ef3e6f4dfab44acd9468a4954eeff8717d8df8819" dependencies = [ "ra-ap-rustc_index", "rustc-hash 2.0.0", diff --git a/Cargo.toml b/Cargo.toml index 19ae35142f..1132acb647 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -85,12 +85,12 @@ vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" } vfs = { path = "./crates/vfs", version = "0.0.0" } edition = { path = "./crates/edition", version = "0.0.0" } -ra-ap-rustc_hashes = { version = "0.97", default-features = false } -ra-ap-rustc_lexer = { version = "0.97", default-features = false } -ra-ap-rustc_parse_format = { version = "0.97", default-features = false } -ra-ap-rustc_index = { version = "0.97", default-features = false } -ra-ap-rustc_abi = { version = "0.97", default-features = false } -ra-ap-rustc_pattern_analysis = { version = "0.97", default-features = false } +ra-ap-rustc_hashes = { version = "0.98", default-features = false } +ra-ap-rustc_lexer = { version = "0.98", default-features = false } +ra-ap-rustc_parse_format = { version = "0.98", default-features = false } +ra-ap-rustc_index = { version = "0.98", default-features = false } +ra-ap-rustc_abi = { version = "0.98", default-features = false } +ra-ap-rustc_pattern_analysis = { version = "0.98", default-features = false } # local crates that aren't published to crates.io. These should not have versions.