From 2254dfe9fa9a30a1e5f1dadd04fdb17fd904f08e Mon Sep 17 00:00:00 2001 From: Kaz Wesley Date: Thu, 11 Apr 2024 00:27:19 -0400 Subject: [PATCH] Reduce parser dependencies (#9671) * Reduce parser dependencies - `enso-parser-syntax-tree-visitor` is now only used when building tests and debug tools. - Remove `enso-logging` crate and its macros. - The main bin for `enso-parser` has been moved to a `check_syntax` tool in `enso-parser-debug`. --- Cargo.lock | 19 - Cargo.toml | 3 - lib/rust/logging/Cargo.toml | 24 - lib/rust/logging/macros/Cargo.toml | 17 - lib/rust/logging/macros/build.rs | 28 - lib/rust/logging/macros/src/lib.rs | 580 ------------------ lib/rust/logging/src/lib.rs | 10 - lib/rust/parser/Cargo.toml | 5 +- lib/rust/parser/debug/Cargo.toml | 2 +- .../main.rs => debug/src/bin/check_syntax.rs} | 6 +- lib/rust/parser/debug/tests/parse.rs | 2 +- lib/rust/parser/doc-parser/Cargo.toml | 1 + lib/rust/parser/doc-parser/src/lib.rs | 4 +- lib/rust/parser/doc-parser/src/main.rs | 2 +- lib/rust/parser/jni/src/lib.rs | 2 +- lib/rust/parser/src/macros/resolver.rs | 4 - lib/rust/parser/src/syntax/tree.rs | 183 +++--- lib/rust/parser/src/syntax/tree/block.rs | 9 +- .../parser/src/syntax/tree/visitor/src/lib.rs | 24 +- lib/rust/prelude/Cargo.toml | 1 - lib/rust/prelude/src/lib.rs | 18 - 21 files changed, 91 insertions(+), 853 deletions(-) delete mode 100644 lib/rust/logging/Cargo.toml delete mode 100644 lib/rust/logging/macros/Cargo.toml delete mode 100644 lib/rust/logging/macros/build.rs delete mode 100644 lib/rust/logging/macros/src/lib.rs delete mode 100644 lib/rust/logging/src/lib.rs rename lib/rust/parser/{src/main.rs => debug/src/bin/check_syntax.rs} (90%) diff --git a/Cargo.lock b/Cargo.lock index 1490e9687f..43f9d89efc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1468,24 +1468,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "enso-logging" -version = "0.3.1" -dependencies = [ - "enso-logging-macros", - "web-sys", -] - -[[package]] -name = "enso-logging-macros" -version = "0.1.0" -dependencies = [ - "Inflector", - "proc-macro2", - "quote", - "syn 2.0.53", -] - [[package]] name = "enso-macro-utils" version = "0.2.0" @@ -1610,7 +1592,6 @@ dependencies = [ "boolinator", "derivative", "derive_more", - "enso-logging", "enso-macros", "enso-reflect", "enso-zst", diff --git a/Cargo.toml b/Cargo.toml index 6658bce616..a0f8e93279 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -115,8 +115,6 @@ futures = { version = "0.3" } itertools = { version = "0.12.1" } lazy_static = { version = "1.4" } serde_json = { version = "1.0", features = ["raw_value"] } -smallvec = { version = "1.0.0" } -js-sys = { version = "0.3" } owned_ttf_parser = { version = "0.15.1" } convert_case = { version = "0.6.0" } rustybuzz = { version = "0.5.1" } @@ -149,4 +147,3 @@ syn_1 = { package = "syn", version = "1.0", features = [ quote = { version = "1.0.23" } semver = { version = "1.0.0", features = ["serde"] } strum = { version = "0.26.2", features = ["derive"] } -thiserror = "1.0.40" diff --git a/lib/rust/logging/Cargo.toml b/lib/rust/logging/Cargo.toml deleted file mode 100644 index 94f5db8b3d..0000000000 --- a/lib/rust/logging/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "enso-logging" -version = "0.3.1" -authors = ["Enso Team "] -edition = "2021" -description = "An efficient logger for writing applications in Rust." -readme = "README.md" -homepage = "https://github.com/enso-org/enso/lib/rust/logging" -repository = "https://github.com/enso-org/enso" -license-file = "../../LICENSE" -keywords = ["logging"] -categories = ["development-tools::debugging"] - -[lib] - -[features] -default = [] - -[dependencies] -enso-logging-macros = { path = "macros" } -web-sys = { version = "0.3.4", features = ["console"] } - -[lints] -workspace = true diff --git a/lib/rust/logging/macros/Cargo.toml b/lib/rust/logging/macros/Cargo.toml deleted file mode 100644 index b538b926d3..0000000000 --- a/lib/rust/logging/macros/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "enso-logging-macros" -version = "0.1.0" -edition = "2021" -authors = ["Enso Team "] - -[lib] -proc-macro = true - -[dependencies] -proc-macro2 = { workspace = true } -quote = { workspace = true } -syn = { workspace = true } -Inflector = "0.11" - -[lints] -workspace = true diff --git a/lib/rust/logging/macros/build.rs b/lib/rust/logging/macros/build.rs deleted file mode 100644 index 67031e82e5..0000000000 --- a/lib/rust/logging/macros/build.rs +++ /dev/null @@ -1,28 +0,0 @@ -//! Build script for [`enso_logging_macros`]. This is needed to make cargo aware that -//! the crate depends on the values of environment variables at compile time, and changes to those -//! variables should result in recompiling this crate and its dependents. - -// === Non-Standard Linter Configuration === -#![warn(missing_copy_implementations)] -#![warn(missing_debug_implementations)] -#![warn(missing_docs)] -#![warn(trivial_casts)] -#![warn(trivial_numeric_casts)] -#![warn(unsafe_code)] -#![warn(unused_import_braces)] -#![warn(unused_qualifications)] - - - -fn main() { - declare_env_dependence("ENSO_MAX_LOG_LEVEL"); - declare_env_dependence("ENSO_UNCOLLAPSED_LOG_LEVEL"); -} - -/// Make cargo aware that the result of compiling this crate depends on an environment variable. -fn declare_env_dependence(env: &str) { - println!("cargo:rerun-if-env-changed={env}"); - // This is a no-op assignment, except it makes cargo aware that the output depends on the env. - let value = std::env::var(env).unwrap_or_default(); - println!("cargo:rustc-env={env}={value}"); -} diff --git a/lib/rust/logging/macros/src/lib.rs b/lib/rust/logging/macros/src/lib.rs deleted file mode 100644 index ec6564c0da..0000000000 --- a/lib/rust/logging/macros/src/lib.rs +++ /dev/null @@ -1,580 +0,0 @@ -//! Proc macros supporting the implementation of the `enso_logging` library. - -// === Features === -#![feature(anonymous_lifetime_in_impl_trait)] -#![feature(proc_macro_span)] -#![feature(let_chains)] -// === Non-Standard Linter Configuration === -#![deny(unconditional_recursion)] -#![warn(missing_docs)] -#![warn(trivial_casts)] - -use inflector::Inflector; -use quote::quote; - - - -/// The log levels defined in the Console Web API. -/// See: https://console.spec.whatwg.org/#loglevel-severity -const WEB_LOG_LEVELS: &[&str] = &["error", "warn", "info", "debug"]; - - - -// ================================== -// === Compile-time configuration === -// ================================== - -const LEVEL_CONFIGURATION_ENV_VARS: LevelConfiguration<&str> = LevelConfiguration { - max_enabled: "ENSO_MAX_LOG_LEVEL", - max_uncollapsed: "ENSO_MAX_UNCOLLAPSED_LOG_LEVEL", -}; - - - -// ===================== -// === Helper macros === -// ===================== - -macro_rules! map_fns { - ($Ty:tt, [$($covariant:tt),*]) => { map_fns!($Ty, [$($covariant),*], []); }; - ($Ty:ident, [$($covariant:ident),*], [$($invariant:ident),*]) => { - impl $Ty { - #[allow(unused)] - fn map(self, f: F) -> $Ty where F: Fn(T) -> U { - let Self { - $($covariant,)* - $($invariant,)* - } = self; - $Ty { - $($covariant: f($covariant),)* - $($invariant,)* - } - } - - #[allow(unused)] - fn for_each(self, mut f: F) where F: FnMut(T) { - $(f(self.$covariant);)* - } - - #[allow(unused)] - fn as_ref(&self) -> $Ty<&T> { - let Self { - $($covariant,)* - $($invariant,)* - } = self; - $Ty { - $($covariant,)* - $($invariant: $invariant.clone(),)* - } - } - } - }; -} - - - -// ================= -// === Interface === -// ================= - -/// Implement a logging API for the spcecified log levels. -#[proc_macro] -pub fn define_log_levels(ts: proc_macro::TokenStream) -> proc_macro::TokenStream { - use syn::parse::Parser; - let parser = syn::punctuated::Punctuated::::parse_terminated; - let args = parser.parse(ts).unwrap(); - let names: Vec<_> = args.into_iter().map(|ident| ident.to_string().to_snake_case()).collect(); - let position_in_args = |name| { - names.iter().position(|arg| &name == arg).unwrap_or_else(|| { - let error = "Environment variable value must correspond to a defined log level"; - panic!("{error}. Found: {name:?}, expected one of: {names:?}.") - }) - }; - let level_configuration = LEVEL_CONFIGURATION_ENV_VARS - .map(|var| std::env::var(var).ok().map(position_in_args).unwrap_or_default()); - logging_api(names, level_configuration) -} - -struct LevelConfiguration { - max_enabled: T, - max_uncollapsed: T, -} -map_fns!(LevelConfiguration, [max_enabled, max_uncollapsed]); - - - -// ===================== -// === Top-level API === -// ===================== - -fn logging_api( - level_names: impl IntoIterator, - config: LevelConfiguration, -) -> proc_macro::TokenStream { - let global_logger_ident = ident("GlobalLogger"); - let global_logger_path = ident_to_path(global_logger_ident.clone()); - let levels = levels(level_names, &config, global_logger_path); - let api: Api = [ - span_trait(), - logger_trait(&levels), - span_api(&levels), - event_api(&levels), - global_logger(global_logger_ident, &levels), - ] - .into_iter() - .collect(); - api.into_library().into() -} - - -// === Information used to construct level-specific interfaces === - -struct Level { - // Intrinsic properties of a level: - name: String, - enabled: bool, - uncollapsed: bool, - // Identifiers for API cross-references: - trait_methods: LoggerMethods, - global_logger_methods: LoggerMethods, -} - -impl Level { - fn new(name: String, enabled: bool, uncollapsed: bool, global_logger_path: &syn::Path) -> Self { - let trait_methods = trait_methods(&name); - let global_logger_methods = - trait_methods.clone().map(|x| qualified(global_logger_path.clone(), x)); - Level { global_logger_methods, trait_methods, enabled, uncollapsed, name } - } -} - -fn levels( - names: impl IntoIterator, - config: &LevelConfiguration, - global_logger_path: syn::Path, -) -> Vec { - let enabled = |i| config.max_enabled >= i; - let uncollapsed = |i| config.max_uncollapsed >= i; - let level = |(i, name)| Level::new(name, enabled(i), uncollapsed(i), &global_logger_path); - names.into_iter().enumerate().map(level).collect() -} - - - -// ============================== -// === Representation of APIs === -// ============================== - -#[derive(Default)] -struct Api { - implementation: proc_macro2::TokenStream, - exports: Vec, -} - -impl Api { - fn extend(&mut self, mut other: Self) { - self.implementation.extend(other.implementation); - self.exports.append(&mut other.exports); - } - fn into_library(self) -> proc_macro2::TokenStream { - let reexport = |name: &syn::Ident| { - quote! { pub use crate::internal::#name; } - }; - let prelude: proc_macro2::TokenStream = - self.exports.iter().filter(|&e| e.prelude).map(|e| reexport(&e.ident)).collect(); - let exports: proc_macro2::TokenStream = - self.exports.iter().map(|e| reexport(&e.ident)).collect(); - let implementation = self.implementation; - quote! { - /// Exports, intended to be used by glob-import. - pub mod prelude { - #prelude - } - #exports - /// Low-level interface, used by macro implementations. - pub mod internal { - #implementation - } - } - } -} - -impl FromIterator for Api { - fn from_iter>(iter: T) -> Self { - let mut collected: Api = Default::default(); - iter.into_iter().for_each(|api| collected.extend(api)); - collected - } -} - -impl From for Api { - fn from(implementation: proc_macro2::TokenStream) -> Self { - Self { implementation, ..Default::default() } - } -} - -struct Export { - ident: syn::Ident, - prelude: bool, -} - -impl Export { - fn prelude(ident: syn::Ident) -> Self { - Self { ident, prelude: true } - } -} - - - -// ===================== -// === LogSpan trait === -// ===================== - -fn span_trait() -> Api { - let trait_name = ident("LogSpan"); - let implementation = quote! { - /// Identifies a location in the source that may be traced in the logs. - pub trait #trait_name { - /// Log entry into the span, run the given closure, and log exit. - #[inline(always)] - fn in_scope(self, f: F) -> T where Self: Sized, F: FnOnce() -> T { - let _scope = self.entered(); - f() - } - /// Log entry into the span, and log exit when the returned value is dropped. - #[inline(always)] - fn entered(self) -> Entered where Self: Sized { - Entered::new(self) - } - #[allow(missing_docs)] - fn _enter(&self); - #[allow(missing_docs)] - fn _exit(&self); - } - /// RAII guard that enters a span when created and exits when dropped. - pub struct Entered(S); - impl Entered { - #[allow(missing_docs)] - pub fn new(span: S) -> Self { - span._enter(); - Self(span) - } - } - impl Drop for Entered { - fn drop(&mut self) { - self.0._exit(); - } - } - }; - let exports = vec![Export::prelude(trait_name)]; - Api { implementation, exports } -} - - - -// ==================== -// === Logger trait === -// ==================== - -fn logger_trait(levels: impl IntoIterator) -> Api { - let mut methods = proc_macro2::TokenStream::new(); - for level in levels { - level.trait_methods.signatures().for_each(|x| methods.extend(x)) - } - (quote! { - /// A type that serves as a destination for logging. - pub trait Logger { - #methods - } - }) - .into() -} - -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] -struct LoggerMethods { - emit_fn: T, - enter_fn: T, - exit_fn: T, -} -map_fns!(LoggerMethods, [emit_fn, enter_fn, exit_fn]); - -impl LoggerMethods { - fn signatures(&self) -> LoggerMethods { - let LoggerMethods { emit_fn, enter_fn, exit_fn } = self; - LoggerMethods { - emit_fn: quote! { #[allow(missing_docs)] fn #emit_fn(span: &str); }, - enter_fn: quote! { #[allow(missing_docs)] fn #enter_fn(span: &str); }, - exit_fn: quote! { #[allow(missing_docs)] fn #exit_fn(); }, - } - } - - fn with_bodies( - &self, - bodies: &LoggerMethods, - ) -> LoggerMethods { - let LoggerMethods { emit_fn, enter_fn, exit_fn } = self; - let LoggerMethods { emit_fn: emit_body, enter_fn: enter_body, exit_fn: exit_body } = bodies; - LoggerMethods { - emit_fn: quote! { #[inline] fn #emit_fn(span: &str) { #emit_body } }, - enter_fn: quote! { #[inline] fn #enter_fn(span: &str) { #enter_body } }, - exit_fn: quote! { #[inline] fn #exit_fn() { #exit_body } }, - } - } -} - -fn trait_methods(level: &str) -> LoggerMethods { - (LoggerMethods { - emit_fn: format!("emit_{level}"), - enter_fn: format!("enter_{level}"), - exit_fn: format!("exit_{level}"), - }) - .as_ref() - .map(ident) -} - - - -// ================= -// === Event API === -// ================= - -fn event_api(levels: impl IntoIterator) -> Api { - levels - .into_iter() - .map(|level| event_api_for_level(&level.name, &level.global_logger_methods, level.enabled)) - .collect() -} - -fn event_api_for_level(level: &str, methods: &LoggerMethods, enabled: bool) -> Api { - let event_macro = ident(level); - let emit_fn = &methods.emit_fn; - let level_tag = level.to_screaming_snake_case(); - let body = if enabled { - quote! { - use $crate::internal::Logger; - $crate::internal::#emit_fn( - &format!( - "[{}] {}:{} {}", - #level_tag, - file!(), - line!(), - format_args!($($args)*) - )); - } - } else { - quote! { - let _unused_at_this_log_level = format_args!($($args)*); - } - }; - let implementation = quote! { - /// Emit a log message, if the log-level is enabled. - #[macro_export] - macro_rules! #event_macro { - ($($args:tt)*) => {{ #body }}; - } - }; - Api { implementation, ..Default::default() } -} - - - -// ================ -// === Span API === -// ================ - -fn span_api(levels: impl IntoIterator) -> Api { - levels - .into_iter() - .map(|level| span_api_for_level(&level.name, &level.global_logger_methods, level.enabled)) - .collect() -} - -fn span_api_for_level(level: &str, methods: &LoggerMethods, enabled: bool) -> Api { - let object_name = ident(level.to_pascal_case()); - let macro_name = ident(format!("{level}_span")); - let object_contents = enabled.then_some(quote! { pub String }).unwrap_or_default(); - let enter_fn = &methods.enter_fn; - let exit_fn = &methods.exit_fn; - let enter_impl = enabled - .then_some(quote! { - #enter_fn(&self.0); - }) - .unwrap_or_default(); - let exit_impl = enabled - .then_some(quote! { - #exit_fn(); - }) - .unwrap_or_default(); - let level_tag = level.to_screaming_snake_case(); - let creation_body = if enabled { - quote! { - $crate::internal::#object_name( - format!( - "[{}] {}:{} {}", - #level_tag, - file!(), - line!(), - format_args!($($args)*) - ) - ) - } - } else { - quote! { - let _unused_at_this_log_level = format_args!($($args)*); - $crate::internal::#object_name() - } - }; - let implementation = quote! { - /// Refers to a region in the source code that may have associated logging. - #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] - pub struct #object_name(#object_contents); - impl LogSpan for #object_name { - #[inline(always)] - fn _enter(&self) { - #enter_impl - } - #[inline(always)] - fn _exit(&self) { - #exit_impl - } - } - /// Create an object that identifies a location in the source code for logging purposes. - #[macro_export] - macro_rules! #macro_name { - ($($args:tt)*) => {{ - #creation_body - }} - } - }; - implementation.into() -} - - - -// ========================= -// === Global Logger API === -// ========================= - -fn global_logger(logger: syn::Ident, levels: impl IntoIterator) -> Api { - let console_logger = ident("NativeConsole"); - let web_logger = ident("WebConsole"); - let mut web_logger_methods = proc_macro2::TokenStream::new(); - let mut console_logger_methods = proc_macro2::TokenStream::new(); - let mut web_level = WEB_LOG_LEVELS.iter().copied().fuse(); - let mut web = web_level.next().unwrap(); - for level in levels { - level - .trait_methods - .with_bodies(&level.enabled.then(console_logger_impl).unwrap_or_default()) - .for_each(|x| console_logger_methods.extend(x)); - level - .trait_methods - .with_bodies(&level.enabled.then_some(web_logger_impl(web, level)).unwrap_or_default()) - .for_each(|x| web_logger_methods.extend(x)); - web = web_level.next().unwrap_or(web); - } - (quote! { - #[cfg(target_arch = "wasm32")] - /// The currently-enabled global logger. - pub type #logger = web::#web_logger; - #[cfg(not(target_arch = "wasm32"))] - /// The currently-enabled global logger. - pub type #logger = native::#console_logger; - /// Logging support for wasm environments. - #[cfg(target_arch = "wasm32")] - pub mod web { - use super::*; - /// A [`Logger`] that emits messages to the Console Web API. - pub struct #web_logger; - impl Logger for #web_logger { - #web_logger_methods - } - } - /// Logging support for non-wasm environments. - #[cfg(not(target_arch = "wasm32"))] - pub mod native { - use super::*; - /// A [`Logger`] that emits messages to the native console. - pub struct #console_logger; - thread_local! { - static CONSOLE_INDENT: core::cell::Cell = core::cell::Cell::new(0); - } - impl Logger for #console_logger { - #console_logger_methods - } - } - }) - .into() -} - - - -// ============================= -// === Native console logger === -// ============================= - -fn console_logger_impl() -> LoggerMethods { - LoggerMethods { - emit_fn: quote! { - let indent = CONSOLE_INDENT.get(); - println!("{:indent$}{}", "", span, indent=indent*4); - }, - enter_fn: quote! { - let indent = CONSOLE_INDENT.get(); - println!("{:indent$}{}", "", span, indent=indent*4); - CONSOLE_INDENT.set(indent + 1); - }, - exit_fn: quote! { - let indent = CONSOLE_INDENT.get(); - CONSOLE_INDENT.set(indent - 1); - }, - } -} - - - -// ====================== -// === Web API logger === -// ====================== - -fn web_logger_impl(web_level: &str, level: &Level) -> LoggerMethods { - let event_fn = ident(format!("{web_level}_1")); - let group_fn = ident(if level.uncollapsed { "group_1" } else { "group_collapsed_1" }); - LoggerMethods { - emit_fn: quote! { - web_sys::console::#event_fn(&span.into()); - }, - enter_fn: quote! { - web_sys::console::#group_fn(&span.into()); - }, - exit_fn: quote! { - web_sys::console::group_end(); - }, - } -} - - - -// ============================ -// === Syn-building helpers === -// ============================ - -fn qualified(mut path: syn::Path, name: syn::Ident) -> syn::Path { - path.segments.push(path_segment(name)); - path -} - -fn path_segment(ident: syn::Ident) -> syn::PathSegment { - syn::PathSegment { ident, arguments: Default::default() } -} - -fn ident(name: impl AsRef) -> syn::Ident { - syn::Ident::new(name.as_ref(), proc_macro2::Span::call_site()) -} - -fn ident_to_path(segment: syn::Ident) -> syn::Path { - syn::Path { - leading_colon: Default::default(), - segments: std::iter::once(path_segment(segment)).collect(), - } -} diff --git a/lib/rust/logging/src/lib.rs b/lib/rust/logging/src/lib.rs deleted file mode 100644 index 84b1317fee..0000000000 --- a/lib/rust/logging/src/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! High-performance logging library. - -// === Non-Standard Linter Configuration === -#![deny(unconditional_recursion)] -#![warn(missing_docs)] -#![warn(trivial_casts)] - - - -enso_logging_macros::define_log_levels![Error, Warn, Info, Debug, Trace]; diff --git a/lib/rust/parser/Cargo.toml b/lib/rust/parser/Cargo.toml index 1c69716c15..3e94a4726a 100644 --- a/lib/rust/parser/Cargo.toml +++ b/lib/rust/parser/Cargo.toml @@ -9,11 +9,14 @@ homepage = "https://github.com/enso-org/enso" repository = "https://github.com/enso-org/enso" license-file = "../../LICENSE" +[features] +debug = ["dep:enso-parser-syntax-tree-visitor"] + [dependencies] enso-prelude = { path = "../prelude" } enso-reflect = { path = "../reflect" } enso-data-structures = { path = "../data-structures" } -enso-parser-syntax-tree-visitor = { path = "src/syntax/tree/visitor" } +enso-parser-syntax-tree-visitor = { path = "src/syntax/tree/visitor", optional = true } paste = { version = "1.0" } serde = { workspace = true } serde_json = { workspace = true } diff --git a/lib/rust/parser/debug/Cargo.toml b/lib/rust/parser/debug/Cargo.toml index 89ca2c71b2..8974de608c 100644 --- a/lib/rust/parser/debug/Cargo.toml +++ b/lib/rust/parser/debug/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/enso-org/enso" license-file = "../../LICENSE" [dependencies] -enso-parser = { path = "../" } +enso-parser = { path = "../", features = ["debug"] } enso-metamodel = { path = "../../metamodel", features = ["rust"] } enso-metamodel-lexpr = { path = "../../metamodel/lexpr" } enso-reflect = { path = "../../reflect" } diff --git a/lib/rust/parser/src/main.rs b/lib/rust/parser/debug/src/bin/check_syntax.rs similarity index 90% rename from lib/rust/parser/src/main.rs rename to lib/rust/parser/debug/src/bin/check_syntax.rs index 47c828df02..ef0928c84f 100644 --- a/lib/rust/parser/src/main.rs +++ b/lib/rust/parser/debug/src/bin/check_syntax.rs @@ -1,4 +1,6 @@ -//! Tests for [`enso_parser`]. +//! Parses Enso sources and reports any syntax errors, while performing internal consistency checks. +//! Source files may be specified as command line arguments; if none a provided, source code will be +//! read from standard input. // === Non-Standard Linter Configuration === #![allow(clippy::option_map_unit_fn)] @@ -38,7 +40,7 @@ fn check_file(path: &str, mut code: &str, parser: &mut enso_parser::Parser) { } let ast = parser.run(code); let errors = RefCell::new(vec![]); - ast.map(|tree| { + ast.visit_trees(|tree| { if let enso_parser::syntax::tree::Variant::Invalid(err) = &*tree.variant { let error = format!("{}: {}", err.error.message, tree.code()); errors.borrow_mut().push((error, tree.span.clone())); diff --git a/lib/rust/parser/debug/tests/parse.rs b/lib/rust/parser/debug/tests/parse.rs index 70407570d4..bafd6c8c1a 100644 --- a/lib/rust/parser/debug/tests/parse.rs +++ b/lib/rust/parser/debug/tests/parse.rs @@ -1702,7 +1702,7 @@ impl Errors { let ast = parse(code); expect_tree_representing_code(code, &ast); let errors = core::cell::Cell::new(Errors::default()); - ast.map(|tree| match &*tree.variant { + ast.visit_trees(|tree| match &*tree.variant { enso_parser::syntax::tree::Variant::Invalid(_) => { errors.update(|e| Self { invalid_node: true, ..e }); } diff --git a/lib/rust/parser/doc-parser/Cargo.toml b/lib/rust/parser/doc-parser/Cargo.toml index feb49bd3af..62b263669d 100644 --- a/lib/rust/parser/doc-parser/Cargo.toml +++ b/lib/rust/parser/doc-parser/Cargo.toml @@ -18,6 +18,7 @@ serde = { workspace = true } [dev-dependencies] enso-metamodel = { path = "../../metamodel", features = ["rust"] } enso-metamodel-lexpr = { path = "../../metamodel/lexpr" } +enso-parser = { path = "..", features = ["debug"] } lexpr = "0.2.6" pretty_assertions = "1.4" diff --git a/lib/rust/parser/doc-parser/src/lib.rs b/lib/rust/parser/doc-parser/src/lib.rs index c245f2060d..6f08cfd986 100644 --- a/lib/rust/parser/doc-parser/src/lib.rs +++ b/lib/rust/parser/doc-parser/src/lib.rs @@ -246,9 +246,7 @@ impl<'a, L: Location> Span<'a, L> { } Some(_) => break, None => { - let unexpected_condition = "Internal error: Expected greater indent level."; - self.warn(unexpected_condition); - warn!("{unexpected_condition}"); + self.warn("Internal error: Expected greater indent level."); break; } } diff --git a/lib/rust/parser/doc-parser/src/main.rs b/lib/rust/parser/doc-parser/src/main.rs index d9f2c547ad..055450874b 100644 --- a/lib/rust/parser/doc-parser/src/main.rs +++ b/lib/rust/parser/doc-parser/src/main.rs @@ -48,7 +48,7 @@ fn extract_docs(_filename: &str, mut code: &str) -> Vec { } let ast = enso_parser::Parser::new().run(code); let docs = RefCell::new(vec![]); - ast.map(|tree| match &*tree.variant { + ast.visit_trees(|tree| match &*tree.variant { enso_parser::syntax::tree::Variant::Documented(doc) => { docs.borrow_mut().push(doc.documentation.clone()); } diff --git a/lib/rust/parser/jni/src/lib.rs b/lib/rust/parser/jni/src/lib.rs index 33746f1ca9..5eb7d01bd9 100644 --- a/lib/rust/parser/jni/src/lib.rs +++ b/lib/rust/parser/jni/src/lib.rs @@ -52,7 +52,7 @@ pub extern "system" fn Java_org_enso_syntax2_Parser_parseInput( if let Some((meta_, code_)) = enso_parser::metadata::parse(input) { match meta_ { Ok(meta_) => meta = Some(meta_), - Err(e) => error!("Ignoring invalid metadata: {e}."), + Err(e) => eprintln!("Ignoring invalid metadata: {e}."), } code = code_; } diff --git a/lib/rust/parser/src/macros/resolver.rs b/lib/rust/parser/src/macros/resolver.rs index b74a73f40f..c93cae864a 100644 --- a/lib/rust/parser/src/macros/resolver.rs +++ b/lib/rust/parser/src/macros/resolver.rs @@ -302,19 +302,16 @@ impl<'s> Resolver<'s> { if self.macros.len() > self.macro_scope_start() { let current_macro = self.macros.last_mut().unwrap(); if let Some(subsegments) = current_macro.possible_next_segments.get(repr) { - trace!("Entering next segment of the current macro."); let mut new_match_tree = Self::move_to_next_segment(&mut current_macro.matched_macro_def, subsegments); mem::swap(&mut new_match_tree, &mut current_macro.possible_next_segments); return Step::StartSegment(token); } else if let Some(popped) = self.pop_macro_stack_if_reserved(repr) { - trace!("Next token reserved by parent macro. Resolving current macro."); self.resolve(popped); return Step::MacroStackPop(token.into()); } } if let Some(segments) = root_macro_map.get(repr, context) { - trace!("Starting a new nested macro resolution."); let mut matched_macro_def = default(); let segments_start = self.segments.len(); let new_macro = PartiallyMatchedMacro { @@ -328,7 +325,6 @@ impl<'s> Resolver<'s> { self.macros.push(new_macro); Step::StartSegment(token) } else { - trace!("Consuming token as current segment body."); Step::NormalToken(token.into()) } } diff --git a/lib/rust/parser/src/syntax/tree.rs b/lib/rust/parser/src/syntax/tree.rs index 2e2e6c7479..205054903c 100644 --- a/lib/rust/parser/src/syntax/tree.rs +++ b/lib/rust/parser/src/syntax/tree.rs @@ -6,6 +6,7 @@ use crate::syntax::*; use crate::span_builder; +#[cfg(feature = "debug")] use enso_parser_syntax_tree_visitor::Visitor; @@ -61,7 +62,8 @@ impl<'s> Default for Tree<'s> { macro_rules! with_ast_definition { ($f:ident ($($args:tt)*)) => { $f! { $($args)* /// [`Tree`] variants definition. See its docs to learn more. #[tagged_enum] - #[derive(Clone, Eq, PartialEq, Visitor, Serialize, Reflect, Deserialize)] + #[cfg_attr(feature = "debug", derive(Visitor))] + #[derive(Clone, Eq, PartialEq, Serialize, Reflect, Deserialize)] #[allow(clippy::large_enum_variant)] // Inefficient. Will be fixed in #182878443. #[tagged_enum(apply_attributes_to = "variants")] #[reflect(inline)] @@ -383,7 +385,8 @@ with_ast_definition!(generate_ast_definition()); // === Invalid === /// Error of parsing attached to an [`Tree`] node. -#[derive(Clone, Debug, Eq, PartialEq, Visitor, Serialize, Reflect, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Reflect, Deserialize)] #[allow(missing_docs)] #[reflect(transparent)] #[serde(from = "crate::serialization::Error")] @@ -417,7 +420,8 @@ impl<'s> span::Builder<'s> for Error { // === Argument blocks === /// An argument specification on its own line. -#[derive(Clone, Debug, Eq, PartialEq, Visitor, Serialize, Reflect, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Reflect, Deserialize)] pub struct ArgumentDefinitionLine<'s> { /// The token beginning the line. pub newline: token::Newline<'s>, @@ -435,7 +439,8 @@ impl<'s> span::Builder<'s> for ArgumentDefinitionLine<'s> { // === Text literals === /// A component of a text literal, within the quotation marks. -#[derive(Clone, Debug, Eq, PartialEq, Visitor, Serialize, Reflect, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Reflect, Deserialize)] pub enum TextElement<'s> { /// The text content of the literal. If it is multiline, the offset information may contain /// part of the content, after trimming appropriately. @@ -481,7 +486,8 @@ impl<'s> span::Builder<'s> for TextElement<'s> { // === Documentation === /// A documentation comment. -#[derive(Debug, Clone, Eq, PartialEq, Visitor, Serialize, Reflect, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Debug, Clone, Eq, PartialEq, Serialize, Reflect, Deserialize)] pub struct DocComment<'s> { /// The comment-initiating token. pub open: token::TextStart<'s>, @@ -522,7 +528,8 @@ impl<'s> span::Builder<'s> for DocComment<'s> { // === Number literals === -#[derive(Clone, Debug, Eq, PartialEq, Visitor, Serialize, Reflect, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Reflect, Deserialize)] #[allow(missing_docs)] pub struct FractionalDigits<'s> { /// The dot operator. @@ -541,7 +548,8 @@ impl<'s> span::Builder<'s> for FractionalDigits<'s> { // === Functions === /// A function argument definition. -#[derive(Clone, Debug, Eq, PartialEq, Visitor, Serialize, Reflect, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Reflect, Deserialize)] pub struct ArgumentDefinition<'s> { /// Opening parenthesis (outer). pub open: Option>, @@ -576,7 +584,8 @@ impl<'s> span::Builder<'s> for ArgumentDefinition<'s> { } /// A default value specification in a function argument definition. -#[derive(Clone, Debug, Eq, PartialEq, Visitor, Serialize, Reflect, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Reflect, Deserialize)] pub struct ArgumentDefault<'s> { /// The `=` token. pub equals: token::Operator<'s>, @@ -591,7 +600,8 @@ impl<'s> span::Builder<'s> for ArgumentDefault<'s> { } /// A type ascribed to an argument definition. -#[derive(Clone, Debug, Eq, PartialEq, Visitor, Serialize, Reflect, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Reflect, Deserialize)] pub struct ArgumentType<'s> { /// The `:` token. pub operator: token::Operator<'s>, @@ -607,7 +617,8 @@ impl<'s> span::Builder<'s> for ArgumentType<'s> { } /// A function return type specification. -#[derive(Clone, Debug, Eq, PartialEq, Visitor, Serialize, Reflect, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Reflect, Deserialize)] pub struct ReturnSpecification<'s> { /// The `->` operator. pub arrow: token::Operator<'s>, @@ -626,7 +637,8 @@ impl<'s> span::Builder<'s> for ReturnSpecification<'s> { // === CaseOf === /// A line that may contain a case-expression in a case-of expression. -#[derive(Clone, Debug, Default, Eq, PartialEq, Visitor, Serialize, Reflect, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Reflect, Deserialize)] pub struct CaseLine<'s> { /// The token beginning the line. This will always be present, unless the first case-expression /// is on the same line as the initial case-of. @@ -653,7 +665,8 @@ impl<'s> span::Builder<'s> for CaseLine<'s> { } /// A case-expression in a case-of expression. -#[derive(Clone, Debug, Default, Eq, PartialEq, Visitor, Serialize, Reflect, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Reflect, Deserialize)] pub struct Case<'s> { /// Documentation, if present. pub documentation: Option>, @@ -692,7 +705,8 @@ impl<'s> span::Builder<'s> for Case<'s> { pub type OperatorOrError<'s> = Result, MultipleOperatorError<'s>>; /// Error indicating multiple operators found next to each other, like `a + * b`. -#[derive(Clone, Debug, Eq, PartialEq, Visitor, Serialize, Reflect, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Reflect, Deserialize)] #[allow(missing_docs)] pub struct MultipleOperatorError<'s> { pub operators: NonEmptyVec>, @@ -731,7 +745,8 @@ impl<'s> NonEmptyOperatorSequence<'s> for OperatorOrError<'s> { // === MultiSegmentApp === /// A segment of [`MultiSegmentApp`], like `if cond` in the `if cond then ok else fail` expression. -#[derive(Clone, Debug, Eq, PartialEq, Visitor, Serialize, Reflect, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Reflect, Deserialize)] #[allow(missing_docs)] pub struct MultiSegmentAppSegment<'s> { pub header: Token<'s>, @@ -748,7 +763,8 @@ impl<'s> span::Builder<'s> for MultiSegmentAppSegment<'s> { // === Array and Tuple === /// A node following an operator. -#[derive(Clone, Debug, Eq, PartialEq, Visitor, Serialize, Reflect, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Reflect, Deserialize)] pub struct OperatorDelimitedTree<'s> { /// The delimiting operator. pub operator: token::Operator<'s>, @@ -1098,25 +1114,12 @@ impl<'s> From> for Tree<'s> { /// could move to it as soon as this error gets resolved: /// https://github.com/rust-lang/rust/issues/96634. #[allow(missing_docs)] -pub trait Visitor { - fn before_visiting_children(&mut self) {} - fn after_visiting_children(&mut self) {} -} - -/// The visitor trait allowing for [`Tree`] nodes traversal. -#[allow(missing_docs)] -pub trait TreeVisitor<'s, 'a>: Visitor { - fn visit(&mut self, ast: &'a Tree<'s>) -> bool; -} - -/// The visitor trait allowing for [`Span`] traversal. -#[allow(missing_docs)] -pub trait SpanVisitor<'s, 'a>: Visitor { - fn visit(&mut self, ast: span::Ref<'s, 'a>) -> bool; -} +#[cfg(feature = "debug")] +pub trait Visitor {} /// The visitor trait allowing for [`Item`] traversal. #[allow(missing_docs)] +#[cfg(feature = "debug")] pub trait ItemVisitor<'s, 'a>: Visitor { fn visit_item(&mut self, ast: item::Ref<'s, 'a>) -> bool; } @@ -1129,11 +1132,13 @@ macro_rules! define_visitor { $visitable:ident ) => { /// The visitable trait. See documentation of [`define_visitor`] to learn more. + #[cfg(feature = "debug")] #[allow(missing_docs)] pub trait $visitable<'s, 'a> { fn $visit>(&'a self, _visitor: &mut V) {} } + #[cfg(feature = "debug")] impl<'s, 'a, T: $visitable<'s, 'a>> $visitable<'s, 'a> for Option { fn $visit>(&'a self, visitor: &mut V) { if let Some(elem) = self { @@ -1142,6 +1147,7 @@ macro_rules! define_visitor { } } + #[cfg(feature = "debug")] impl<'s, 'a, T: $visitable<'s, 'a>, E: $visitable<'s, 'a>> $visitable<'s, 'a> for Result { @@ -1153,12 +1159,14 @@ macro_rules! define_visitor { } } + #[cfg(feature = "debug")] impl<'s, 'a, T: $visitable<'s, 'a>> $visitable<'s, 'a> for Vec { fn $visit>(&'a self, visitor: &mut V) { self.iter().map(|t| $visitable::$visit(t, visitor)).for_each(drop); } } + #[cfg(feature = "debug")] impl<'s, 'a, T: $visitable<'s, 'a>> $visitable<'s, 'a> for NonEmptyVec { fn $visit>(&'a self, visitor: &mut V) { self.iter().map(|t| $visitable::$visit(t, visitor)).for_each(drop); @@ -1167,33 +1175,14 @@ macro_rules! define_visitor { }; } -macro_rules! define_visitor_for_tokens { - ( - $(#$kind_meta:tt)* - pub enum $kind:ident { - $( - $(#$variant_meta:tt)* - $variant:ident $({$($args:tt)*})? - ),* $(,)? - } - ) => { - impl<'s, 'a> TreeVisitable<'s, 'a> for token::$kind {} - }; -} - -define_visitor!(Tree, visit, TreeVisitor, TreeVisitable); -define_visitor!(Span, visit_span, SpanVisitor, SpanVisitable); define_visitor!(Item, visit_item, ItemVisitor, ItemVisitable); -crate::with_token_definition!(define_visitor_for_tokens()); - // === Trait Implementations for Simple Leaf Types === macro_rules! spanless_leaf_impls { ($ty:ty) => { - impl<'s, 'a> TreeVisitable<'s, 'a> for $ty {} - impl<'a, 's> SpanVisitable<'s, 'a> for $ty {} + #[cfg(feature = "debug")] impl<'a, 's> ItemVisitable<'s, 'a> for $ty {} impl<'s> span::Builder<'s> for $ty { fn add_to_span(&mut self, span: Span<'s>) -> Span<'s> { @@ -1209,45 +1198,10 @@ spanless_leaf_impls!(VisibleOffset); spanless_leaf_impls!(Cow<'static, str>); -// === TreeVisitable special cases === - -impl<'s, 'a> TreeVisitable<'s, 'a> for Tree<'s> { - fn visit>(&'a self, visitor: &mut V) { - if visitor.visit(self) { - self.variant.visit(visitor) - } - } -} - - -impl<'s, 'a, T> TreeVisitable<'s, 'a> for Token<'s, T> {} - - -// === SpanVisitable special cases === - -impl<'s, 'a> SpanVisitable<'s, 'a> for Tree<'s> { - fn visit_span>(&'a self, visitor: &mut V) { - if visitor.visit(span::Ref { - left_offset: &self.span.left_offset, - code_length: self.span.code_length, - }) { - self.variant.visit_span(visitor) - } - } -} - - -impl<'a, 's, T> SpanVisitable<'s, 'a> for Token<'s, T> { - fn visit_span>(&'a self, visitor: &mut V) { - let code_length = self.code.length(); - visitor.visit(span::Ref { left_offset: &self.left_offset, code_length }); - } -} - - // === ItemVisitable special cases === +#[cfg(feature = "debug")] impl<'s, 'a> ItemVisitable<'s, 'a> for Tree<'s> { fn visit_item>(&'a self, visitor: &mut V) { if visitor.visit_item(item::Ref::Tree(self)) { @@ -1256,6 +1210,7 @@ impl<'s, 'a> ItemVisitable<'s, 'a> for Tree<'s> { } } +#[cfg(feature = "debug")] impl<'s: 'a, 'a, T: 'a> ItemVisitable<'s, 'a> for Token<'s, T> where &'a Token<'s, T>: Into> { @@ -1271,13 +1226,16 @@ where &'a Token<'s, T>: Into> // ========================== /// A visitor collecting code representation of AST nodes. +#[cfg(feature = "debug")] #[derive(Debug, Default)] #[allow(missing_docs)] struct CodePrinterVisitor { pub code: String, } +#[cfg(feature = "debug")] impl Visitor for CodePrinterVisitor {} +#[cfg(feature = "debug")] impl<'s, 'a> ItemVisitor<'s, 'a> for CodePrinterVisitor { fn visit_item(&mut self, item: item::Ref<'s, 'a>) -> bool { match item { @@ -1291,6 +1249,7 @@ impl<'s, 'a> ItemVisitor<'s, 'a> for CodePrinterVisitor { } } +#[cfg(feature = "debug")] impl<'s> Tree<'s> { /// Code generator of this AST. pub fn code(&self) -> String { @@ -1309,35 +1268,11 @@ impl<'s> Tree<'s> { -// ================= -// === FnVisitor === -// ================= - -/// A visitor allowing running a function on every [`Tree`] node. -#[derive(Debug, Default)] -#[allow(missing_docs)] -pub struct FnVisitor(pub F); - -impl Visitor for FnVisitor {} -impl<'s: 'a, 'a, T, F: Fn(&'a Tree<'s>) -> T> TreeVisitor<'s, 'a> for FnVisitor { - fn visit(&mut self, ast: &'a Tree<'s>) -> bool { - (self.0)(ast); - true - } -} - - -impl<'s> Tree<'s> { - /// Map the provided function over each [`Tree`] node. The function results will be discarded. - pub fn map(&self, f: impl Fn(&Tree<'s>) -> T) { - let mut visitor = FnVisitor(f); - self.visit(&mut visitor); - } -} - - +// ===================== // === ItemFnVisitor === +// ===================== +#[cfg(feature = "debug")] impl<'s> Tree<'s> { /// Apply the provided function to each [`Token`] or [`Tree`] that is a child of the node. pub fn visit_items(&self, f: F) @@ -1356,4 +1291,24 @@ impl<'s> Tree<'s> { } self.variant.visit_item(&mut ItemFnVisitor { f }); } + + /// Apply the provided function recursively to each [`Tree`] that is a descendant of the node. + pub fn visit_trees(&self, f: F) + where F: for<'a> FnMut(&'a Tree<'s>) { + struct ItemFnVisitor { + f: F, + } + impl Visitor for ItemFnVisitor {} + impl<'a, 's: 'a, F> ItemVisitor<'s, 'a> for ItemFnVisitor + where F: FnMut(&'a Tree<'s>) + { + fn visit_item(&mut self, item: item::Ref<'s, 'a>) -> bool { + if let item::Ref::Tree(tree) = item { + (self.f)(tree); + } + true + } + } + self.variant.visit_item(&mut ItemFnVisitor { f }); + } } diff --git a/lib/rust/parser/src/syntax/tree/block.rs b/lib/rust/parser/src/syntax/tree/block.rs index bbc519303a..5158642771 100644 --- a/lib/rust/parser/src/syntax/tree/block.rs +++ b/lib/rust/parser/src/syntax/tree/block.rs @@ -9,7 +9,8 @@ use crate::syntax::tree::*; // ============= /// A line of code. -#[derive(Debug, Clone, PartialEq, Eq, Visitor, Reflect, Serialize, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Debug, Clone, PartialEq, Eq, Reflect, Serialize, Deserialize)] pub struct Line<'s> { /// Token ending the previous line, if any. pub newline: token::Newline<'s>, @@ -196,7 +197,8 @@ impl<'s> From> for Tree<'s> { // ====================== /// The content of a line in an operator block. -#[derive(Debug, Clone, PartialEq, Eq, Visitor, Reflect, Serialize, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Debug, Clone, PartialEq, Eq, Reflect, Serialize, Deserialize)] pub struct OperatorBlockExpression<'s> { /// The operator at the beginning of the line. pub operator: OperatorOrError<'s>, @@ -234,7 +236,8 @@ impl<'s> span::Builder<'s> for OperatorBlockExpression<'s> { // === Operator block lines ==== /// A line in an operator block. -#[derive(Debug, Clone, PartialEq, Eq, Visitor, Reflect, Serialize, Deserialize)] +#[cfg_attr(feature = "debug", derive(Visitor))] +#[derive(Debug, Clone, PartialEq, Eq, Reflect, Serialize, Deserialize)] pub struct OperatorLine<'s> { /// Token ending the previous line, if any. pub newline: token::Newline<'s>, diff --git a/lib/rust/parser/src/syntax/tree/visitor/src/lib.rs b/lib/rust/parser/src/syntax/tree/visitor/src/lib.rs index 79e4f93717..059fb99a97 100644 --- a/lib/rust/parser/src/syntax/tree/visitor/src/lib.rs +++ b/lib/rust/parser/src/syntax/tree/visitor/src/lib.rs @@ -32,8 +32,8 @@ use syn::Variant; /// ====================== use quote::ToTokens; -/// Implements [`TreeVisitable`], [`TreeVisitableMut`], [`SpanVisitable`], and [`SpanVisitableMut`]. -/// These traits are defined in the [`crate::ast`] module. Macros in this module hardcode the names +/// Implements [`ItemVisitable`]. +/// This trait is defined in the [`crate::ast`] module. Macros in this module hardcode the names /// of the traits and are not implemented in a generic way because the current Rust implementation /// does not understand generic definition. See the [`crate::ast`] module to learn more about the /// design and the Rust compiler issue. @@ -42,8 +42,6 @@ pub fn derive_visitor(input: proc_macro::TokenStream) -> proc_macro::TokenStream let decl = syn::parse_macro_input!(input as DeriveInput); let ident = &decl.ident; let (impl_generics, ty_generics, _inherent_where_clause_opt) = &decl.generics.split_for_impl(); - let body = gen_body(quote!(TreeVisitable::visit), &decl.data, false); - let body_span = gen_body(quote!(SpanVisitable::visit_span), &decl.data, false); let body_item = gen_body(quote!(ItemVisitable::visit_item), &decl.data, false); let impl_generics_vec: Vec<_> = impl_generics.to_token_stream().into_iter().collect(); @@ -61,27 +59,9 @@ pub fn derive_visitor(input: proc_macro::TokenStream) -> proc_macro::TokenStream let impl_generics = quote!(<#impl_generics 'a>); let output = quote! { - impl #impl_generics TreeVisitable #impl_generics for #ident #ty_generics { - fn visit(&'a self, visitor:&mut T) { - visitor.before_visiting_children(); - #body - visitor.after_visiting_children(); - } - } - - impl #impl_generics SpanVisitable #impl_generics for #ident #ty_generics { - fn visit_span(&'a self, visitor:&mut T) { - visitor.before_visiting_children(); - #body_span - visitor.after_visiting_children(); - } - } - impl #impl_generics ItemVisitable #impl_generics for #ident #ty_generics { fn visit_item(&'a self, visitor:&mut T) { - visitor.before_visiting_children(); #body_item - visitor.after_visiting_children(); } } }; diff --git a/lib/rust/prelude/Cargo.toml b/lib/rust/prelude/Cargo.toml index 208f743c49..6c9ec7b51f 100644 --- a/lib/rust/prelude/Cargo.toml +++ b/lib/rust/prelude/Cargo.toml @@ -16,7 +16,6 @@ publish = true crate-type = ["rlib"] [dependencies] -enso-logging = { path = "../logging" } enso-reflect = { path = "../reflect" } enso-zst = { path = "../zst" } boolinator = { workspace = true } diff --git a/lib/rust/prelude/src/lib.rs b/lib/rust/prelude/src/lib.rs index 4aa0fc9636..ded1cc9a33 100644 --- a/lib/rust/prelude/src/lib.rs +++ b/lib/rust/prelude/src/lib.rs @@ -22,21 +22,3 @@ pub use derive_more::*; pub use enso_reflect::prelude::*; pub use serde::Deserialize; pub use serde::Serialize; - - - -// =============== -// === Logging === -// =============== - -pub use enso_logging::debug; -pub use enso_logging::debug_span; -pub use enso_logging::error; -pub use enso_logging::error_span; -pub use enso_logging::info; -pub use enso_logging::info_span; -pub use enso_logging::prelude::*; -pub use enso_logging::trace; -pub use enso_logging::trace_span; -pub use enso_logging::warn; -pub use enso_logging::warn_span;