From eb6cee36907257fd3967652339e2fc4fb4970f61 Mon Sep 17 00:00:00 2001 From: Danny McGee Date: Tue, 21 May 2024 20:01:47 -0400 Subject: [PATCH 1/5] =?UTF-8?q?Basically=20zero=20actual=20progress=20made?= =?UTF-8?q?,=20very=20cool=20=F0=9F=91=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 158 +++++++++++++++++++++ Cargo.toml | 7 + package-lock.json | 8 +- package.json | 2 +- packages/client/src/app/client.ts | 30 ++++ packages/client/src/app/context.ts | 54 +++++++- packages/client/src/app/main.ts | 2 - packages/log/Cargo.toml | 20 +++ packages/log/project.json | 36 +++++ packages/log/src/lib.rs | 169 +++++++++++++++++++++++ packages/server/Cargo.toml | 15 +- packages/server/src/config.rs | 6 +- packages/server/src/declarations/find.rs | 28 ++-- packages/server/src/declarations/mod.rs | 4 +- packages/server/src/documents/mod.rs | 9 +- packages/server/src/ipc/mod.rs | 12 +- packages/server/src/ipc/notify.rs | 23 ++- packages/server/src/ipc/request.rs | 12 +- packages/server/src/main.rs | 6 + packages/server/src/pre/mod.rs | 10 +- packages/server/src/pre/pruner.rs | 6 +- packages/server/src/references.rs | 2 +- packages/server/src/testing.rs | 2 +- packages/server/src/utils.rs | 2 +- packages/server/src/validation/conv.rs | 2 +- 25 files changed, 560 insertions(+), 65 deletions(-) create mode 100644 packages/log/Cargo.toml create mode 100644 packages/log/project.json create mode 100644 packages/log/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 53854582..2d62aee0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -472,6 +472,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "downcast-rs" version = "1.2.1" @@ -756,6 +765,15 @@ dependencies = [ "url", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "memchr" version = "2.7.2" @@ -787,6 +805,22 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "610a5acd306ec67f907abe5567859a3c693fb9886eb1f012ab8f2a47bef3db51" +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-traits" version = "0.2.18" @@ -796,6 +830,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -808,6 +851,12 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking" version = "2.2.0" @@ -887,6 +936,12 @@ dependencies = [ "plotters-backend", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "proc-macro2" version = "1.0.81" @@ -1090,9 +1145,19 @@ dependencies = [ "serde", "serde_json", "snapshot", + "wgsl-lsp-log", "wgsl-parser", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "similar" version = "2.5.0" @@ -1212,6 +1277,39 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -1271,6 +1369,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "time", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -1338,6 +1477,12 @@ dependencies = [ "serde", ] +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "version_check" version = "0.9.4" @@ -1446,6 +1591,19 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "wgsl-lsp-log" +version = "0.1.0" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_utils", + "time", + "tracing-error", + "tracing-log", + "tracing-subscriber", +] + [[package]] name = "wgsl-parser" version = "0.3.0" diff --git a/Cargo.toml b/Cargo.toml index 4d794ea3..ee844d80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver = "2" members = [ + "packages/log", "packages/parser", "packages/server", "packages/utils", @@ -9,6 +10,12 @@ members = [ [workspace.dependencies] anyhow = "1.0" +bevy_app = "0.13.2" +bevy_core = "0.13.2" +bevy_derive = "0.13.2" +bevy_log = "0.13.2" +bevy_ecs = "0.13.2" +bevy_utils = "0.13.2" bitflags = "2.5" gramatika = { version = "0.6.0", features = ["substr-source"] } parking_lot = "0.12" diff --git a/package-lock.json b/package-lock.json index 9d3b2554..41610cec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "@swc/helpers": "~0.5.2", "@types/jest": "29.4.4", "@types/node": "18.16.9", - "@types/vscode": "^1.61.0", + "@types/vscode": "^1.75.0", "@typescript-eslint/eslint-plugin": "7.3.0", "@typescript-eslint/parser": "7.3.0", "@vscode-devkit/grammar": "0.0.1", @@ -3905,9 +3905,9 @@ "dev": true }, "node_modules/@types/vscode": { - "version": "1.62.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.62.0.tgz", - "integrity": "sha512-iGlQJ1w5e3qPUryroO6v4lxg3ql1ztdTCwQW3xEwFawdyPLoeUSv48SYfMwc7kQA7h6ThUqflZIjgKAykeF9oA==", + "version": "1.89.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.89.0.tgz", + "integrity": "sha512-TMfGKLSVxfGfoO8JfIE/neZqv7QLwS4nwPwL/NwMvxtAY2230H2I4Z5xx6836pmJvMAzqooRQ4pmLm7RUicP3A==", "dev": true }, "node_modules/@types/yargs": { diff --git a/package.json b/package.json index 939a1dfe..bfccd388 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "@swc/helpers": "~0.5.2", "@types/jest": "29.4.4", "@types/node": "18.16.9", - "@types/vscode": "^1.61.0", + "@types/vscode": "^1.75.0", "@typescript-eslint/eslint-plugin": "7.3.0", "@typescript-eslint/parser": "7.3.0", "@vscode-devkit/grammar": "0.0.1", diff --git a/packages/client/src/app/client.ts b/packages/client/src/app/client.ts index 9ca5643b..f8775027 100644 --- a/packages/client/src/app/client.ts +++ b/packages/client/src/app/client.ts @@ -1,4 +1,6 @@ +import * as cp from "child_process"; import * as path from "path"; +import { regex } from "@vscode-devkit/grammar"; import { Uri, workspace } from "vscode"; import { DidChangeConfigurationNotification, @@ -9,6 +11,7 @@ import { import { Configuration } from "./configuration"; import ctx from "./context"; import ext from "./extensions"; +import { StringDecoder } from "string_decoder"; namespace client { export function create() { @@ -28,6 +31,33 @@ namespace client { }); client.start().then(() => { + const server = client["_serverProcess"] as cp.ChildProcess; + + const dateStamp = /[0-9]{4}-[0-9]{2}-[0-9]{2}/; + const timeStamp = /[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}/; + const logPattern = regex`/^${dateStamp} ${timeStamp} +([A-Z]+) (.+)/`; + + const decoder = new StringDecoder("utf-8"); + + server.stderr.on("data", (chunk: Buffer) => { + let line = decoder.write(chunk); + + let match = line.match(logPattern); + if (match) { + let [, level, message] = match; + switch (level) { + case "TRACE": ctx.get()?.trace(message); break; + case "DEBUG": ctx.get()?.debug(message); break; + case "INFO": ctx.get()?.info(message); break; + case "WARN": ctx.get()?.warn(message); break; + case "ERROR": ctx.get()?.error(message); break; + default: ctx.get()?.info(message); + } + } else { + ctx.get()?.info(line); + } + }); + client.onNotification(ext.UNREAD_DEPENDENCY, async params => { let dependency = Uri.parse(params.dependency); // TODO: report error if path is invalid diff --git a/packages/client/src/app/context.ts b/packages/client/src/app/context.ts index 9daf2ea3..ed08a288 100644 --- a/packages/client/src/app/context.ts +++ b/packages/client/src/app/context.ts @@ -1,4 +1,4 @@ -import { ExtensionContext, OutputChannel, window } from "vscode"; +import { ExtensionContext, LogOutputChannel, window } from "vscode"; import { LanguageClient } from "vscode-languageclient/node"; // prettier-ignore @@ -8,12 +8,12 @@ class Context implements ExtensionContext { inner: ExtensionContext; client: LanguageClient; - private _channel: OutputChannel; + private _channel: LogOutputChannel; constructor(ctx: ExtensionContext, client: LanguageClient) { this.inner = ctx; this.client = client; - this._channel = window.createOutputChannel("WGSL Language Client"); + this._channel = window.createOutputChannel("WGSL Language Client", { log: true }); Context.instance = this; } @@ -39,8 +39,32 @@ class Context implements ExtensionContext { get asAbsolutePath() { return this.inner.asAbsolutePath } - log(message: string): void { - this._channel.appendLine(message); + append(value: string): void { + this._channel.append(value); + } + + appendLine(value: string): void { + this._channel.appendLine(value); + } + + trace(message: string, ...args: any[]): void { + this._channel.trace(message, ...args); + } + + debug(message: string, ...args: any[]): void { + this._channel.debug(message, ...args); + } + + info(message: string, ...args: any[]): void { + this._channel.info(message, ...args); + } + + warn(message: string, ...args: any[]): void { + this._channel.warn(message, ...args); + } + + error(error: string | Error, ...args: any[]): void { + this._channel.error(error, ...args); } } @@ -52,6 +76,26 @@ namespace ctx { export function get() { return Context.instance; } + + export function trace(message: string, ...args: any[]): void { + get()?.trace(message, ...args); + } + + export function debug(message: string, ...args: any[]): void { + get()?.debug(message, ...args); + } + + export function info(message: string, ...args: any[]): void { + get()?.info(message, ...args); + } + + export function warn(message: string, ...args: any[]): void { + get()?.warn(message, ...args); + } + + export function error(error: string | Error, ...args: any[]): void { + get()?.error(error, ...args); + } } export default ctx; diff --git a/packages/client/src/app/main.ts b/packages/client/src/app/main.ts index 91e255af..148b39d1 100644 --- a/packages/client/src/app/main.ts +++ b/packages/client/src/app/main.ts @@ -10,8 +10,6 @@ import contentProviders, { // prettier-ignore export function activate(context: ExtensionContext) { - console.log("WGSL Language Support activated"); - ctx.bootstrap(context, client.create()); contentProviders.register("wgsl-ast", DebugAstProvider); diff --git a/packages/log/Cargo.toml b/packages/log/Cargo.toml new file mode 100644 index 00000000..4642e602 --- /dev/null +++ b/packages/log/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "wgsl-lsp-log" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" + +[dependencies] +bevy_app = { workspace = true } +bevy_ecs = { workspace = true } +bevy_utils = { workspace = true } +time = { version = "0.3.36", features = ["formatting", "local-offset"]} +tracing-error = "0.2.0" +tracing-log = "0.2.0" +tracing-subscriber = { version = "0.3.1", features = [ + "env-filter", + "fmt", + "registry", + "std", + "time", +]} diff --git a/packages/log/project.json b/packages/log/project.json new file mode 100644 index 00000000..759d9aa0 --- /dev/null +++ b/packages/log/project.json @@ -0,0 +1,36 @@ +{ + "name": "log", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "projectType": "library", + "sourceRoot": "packages/log/src", + "targets": { + "build": { + "executor": "@nxrs/cargo:build", + "options": { + "package": "wgsl-lsp-log", + "profile": "dev" + }, + "configurations": { + "production": { + "profile": "release" + } + } + }, + "test": { + "executor": "@nxrs/cargo:test", + "options": { + "package": "wgsl-lsp-log" + } + }, + "lint": { + "executor": "@nxrs/cargo:clippy", + "options": { + "package": "wgsl-lsp-log", + "fix": false, + "failOnWarnings": true, + "noDeps": true + } + } + }, + "tags": [] +} diff --git a/packages/log/src/lib.rs b/packages/log/src/lib.rs new file mode 100644 index 00000000..267c81f3 --- /dev/null +++ b/packages/log/src/lib.rs @@ -0,0 +1,169 @@ +use bevy_app::{App, Plugin}; +use bevy_utils::tracing::{subscriber as bevy_subscriber, Event, Level, Subscriber}; +pub use bevy_utils::{ + debug_once, error_once, info_once, once, trace_once, + tracing::{ + debug, debug_span, error, error_span, info, info_span, trace, trace_span, warn, warn_span, + }, + warn_once, +}; +use time::format_description::{BorrowedFormatItem, FormatItem}; +use tracing_error::ErrorLayer; +use tracing_log::{LogTracer, NormalizeEvent}; +use tracing_subscriber::{ + fmt::{ + format::{Format, Full, Writer}, + time::{FormatTime, OffsetTime, SystemTime}, + FmtContext, FormatEvent, FormatFields, + }, + prelude::*, + registry::{LookupSpan, Registry}, + EnvFilter, FmtSubscriber, +}; + +pub struct LogPlugin { + /// Filters logs using the [`EnvFilter`] format + pub filter: String, + + /// Filters out logs that are "less than" the given level. + /// This can be further filtered using the `filter` setting. + pub level: Level, +} + +impl Default for LogPlugin { + fn default() -> Self { + Self { + filter: String::new(), + level: Level::INFO, + } + } +} + +impl Plugin for LogPlugin { + fn build(&self, _: &mut App) { + let old_handler = std::panic::take_hook(); + std::panic::set_hook(Box::new(move |infos| { + eprintln!("{}", tracing_error::SpanTrace::capture()); + old_handler(infos); + })); + + let default_filter = format!("{},{}", self.level, self.filter); + let filter_layer = EnvFilter::try_from_default_env() + .or_else(|_| EnvFilter::try_new(&default_filter)) + .unwrap(); + + let subscriber = Registry::default() + .with(filter_layer) + .with(ErrorLayer::default()) + .with( + tracing_subscriber::fmt::layer() + .with_ansi(false) + .with_timer(fmt_time()) + .with_writer(std::io::stderr), + ); + let subscriber = Box::new(subscriber); + + let logger_already_set = LogTracer::init().is_err(); + let subscriber_already_set = bevy_subscriber::set_global_default(subscriber).is_err(); + + match (logger_already_set, subscriber_already_set) { + (true, true) => error!( + "Could not set global logger and tracing subscriber as they are already set. \ + Consider disabling LogPlugin." + ), + (true, false) => error!( + "Could not set global logger as it is already set. \ + Consider disabling LogPlugin." + ), + (false, true) => error!( + "Could not set global tracing subscriber as it is already set. \ + Consider disabling LogPlugin." + ), + (false, false) => (), + } + } +} + +// struct CustomFormat(Format>>>); +// struct CustomFormat { +// timer: OffsetTime>>, +// } + +fn fmt_time() -> impl FormatTime { + let timer = time::format_description::parse( + "[year]-[month padding:zero]-[day padding:zero] \ + [hour repr:24]:[minute padding:zero]:[second padding:zero].[subsecond digits:3]", + ) + .expect("Failed to parse date-time format"); + + let time_offset = time::UtcOffset::current_local_offset().unwrap_or(time::UtcOffset::UTC); + tracing_subscriber::fmt::time::OffsetTime::new(time_offset, timer) +} + +// impl Default for CustomFormat { +// fn default() -> Self { +// let timer = time::format_description::parse( +// "[year]-[month padding:zero]-[day padding:zero] \ +// [hour repr:24]:[minute padding:zero]:[second padding:zero].[subsecond digits:3]", +// ) +// .expect("Failed to parse date-time format"); + +// let time_offset = time::UtcOffset::current_local_offset().unwrap_or(time::UtcOffset::UTC); +// let timer = tracing_subscriber::fmt::time::OffsetTime::new(time_offset, timer); + +// Self { timer } +// } +// } + +// impl FormatEvent for CustomFormat +// where +// S: Subscriber + for<'a> LookupSpan<'a>, +// N: for<'a> FormatFields<'a> + 'static, +// { +// fn format_event( +// &self, +// ctx: &FmtContext<'_, S, N>, +// mut writer: Writer<'_>, +// event: &Event<'_>, +// ) -> std::fmt::Result { +// let meta = event.normalized_metadata(); +// let meta = meta.as_ref().unwrap_or_else(|| event.metadata()); + +// self.timer.format_time(&mut writer)?; +// writer.write_char(' ')?; + +// write!(writer, "{} ", FmtLevel(*meta.level()))?; + +// ctx.format_fields(writer.by_ref(), event)?; + +// writeln!(writer) +// } +// } + +// struct FmtLevel(Level); + +// impl std::fmt::Display for FmtLevel { +// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +// match self.0 { +// Level::TRACE => f.pad("[trace]"), +// Level::DEBUG => f.pad("[debug]"), +// Level::INFO => f.pad("[info]"), +// Level::WARN => f.pad("[warn]"), +// Level::ERROR => f.pad("[error]"), +// } +// } +// } + +// fn format() -> Format>>> { +// let timer = time::format_description::parse( +// "[year]-[month padding:zero]-[day padding:zero] \ +// [hour repr:24]:[minute padding:zero]:[second padding:zero].[subsecond digits:3]", +// ) +// .expect("Failed to parse date-time format"); + +// let time_offset = time::UtcOffset::current_local_offset().unwrap_or(time::UtcOffset::UTC); +// let timer = tracing_subscriber::fmt::time::OffsetTime::new(time_offset, timer); + +// let result = Format::default().with_ansi(false).with_timer(timer); +// result +// } diff --git a/packages/server/Cargo.toml b/packages/server/Cargo.toml index 4c779d67..82a50fa3 100644 --- a/packages/server/Cargo.toml +++ b/packages/server/Cargo.toml @@ -6,11 +6,12 @@ license = "MIT OR Apache-2.0" [dependencies] anyhow = { workspace = true } -bevy_app = "0.13.2" -bevy_core = "0.13.2" -bevy_derive = "0.13.2" -bevy_ecs = "0.13.2" -bevy_utils = "0.13.2" +bevy_app = { workspace = true } +bevy_core = { workspace = true } +bevy_derive = { workspace = true } +bevy_ecs = { workspace = true } +# bevy_log = { workspace = true } +bevy_utils = { workspace = true } bitflags = { workspace = true } crossbeam = "0.8" gramatika = { workspace = true } @@ -23,6 +24,10 @@ ropey = "1.5" serde = { version = "1", features = ["derive"] } serde_json = "1" +[dependencies.log] +package = "wgsl-lsp-log" +path = "../log" + [dependencies.parser] package = "wgsl-parser" path = "../parser" diff --git a/packages/server/src/config.rs b/packages/server/src/config.rs index f8cafd06..fcfbca64 100644 --- a/packages/server/src/config.rs +++ b/packages/server/src/config.rs @@ -94,7 +94,7 @@ fn update_config( mut er_config_change: EventReader, ) -> anyhow::Result<()> { if er_config_change.len() > 1 { - eprintln!("WARNING: Multiple configuration changes are not yet handled correctly!"); + log::warn!("Multiple configuration changes are not yet handled correctly!"); } if let Some(event) = er_config_change.read().last() { @@ -121,8 +121,8 @@ impl TryFrom<&serde_json::Value> for Config { bail!("Cannot deserialize configuration from an empty array"); } if configs.len() > 1 { - eprintln!("WARNING: Multiple configurations not yet handled correctly!"); - eprintln!(" Configurations: {configs:?}"); + log::warn!("WARNING: Multiple configurations not yet handled correctly!"); + log::warn!(" Configurations: {configs:?}"); serde_json::from_value(configs.iter().last().unwrap().clone())? } diff --git a/packages/server/src/declarations/find.rs b/packages/server/src/declarations/find.rs index 4cb68b53..41a9afe6 100644 --- a/packages/server/src/declarations/find.rs +++ b/packages/server/src/declarations/find.rs @@ -34,12 +34,12 @@ pub(super) fn find_decl( let parent_expr = parser::utils::find_parent::(tree, needle.span()); if parent_expr.is_none() && needle.kind() != TokenKind::Struct { if debug { - eprintln!("Failed to find parent expression for needle"); + log::debug!("Failed to find parent expression for needle"); } if let Some(qualified_path) = imports?.get(&needle.lexeme()) { if debug { - eprintln!("Found import: {qualified_path:?}"); + log::debug!("Found import: {qualified_path:?}"); } return find_directly_imported( needle, @@ -61,12 +61,12 @@ pub(super) fn find_decl( let ident = if let Some(parent_expr) = parent_expr.as_ref() { if debug { - eprintln!("Parent expression: {parent_expr:#?}"); + log::debug!("Parent expression: {parent_expr:#?}"); } find_ident_expr_in_parent_expr(needle, parent_expr, debug)? } else if let Some(parent_decl) = parent_decl.as_ref() { if debug { - eprintln!("Parent declaration: {parent_decl:#?}"); + log::debug!("Parent declaration: {parent_decl:#?}"); } find_ident_expr_in_parent_decl(needle, parent_decl, debug)? } else { @@ -87,9 +87,9 @@ pub(super) fn find_decl( let (namespace_tokens, leaf) = decompose_ident_expr(ident); if debug { - eprintln!("Decomposed..."); - eprintln!(" namespace: {namespace_tokens:?}"); - eprintln!(" leaf: {leaf:?}"); + log::debug!("Decomposed..."); + log::debug!(" namespace: {namespace_tokens:?}"); + log::debug!(" leaf: {leaf:?}"); } if let Some(result) = find_for_imported_namespace( @@ -124,7 +124,7 @@ fn find_directly_imported( debug: bool, ) -> Option<(Token, Url)> { if debug { - eprintln!("find_directly_imported {needle:?}"); + log::debug!("find_directly_imported {needle:?}"); } let mut end = qualified_path.len(); @@ -324,7 +324,7 @@ fn find_for_imported_namespace( debug: bool, ) -> Option<(Token, Url)> { if debug { - eprintln!("find_symbol_for_imported_namespace {needle:?}"); + log::debug!("find_symbol_for_imported_namespace {needle:?}"); } let [namespace] = &namespace_tokens else { @@ -332,12 +332,12 @@ fn find_for_imported_namespace( }; let qualified_path = imports.get(&namespace.lexeme())?; if debug { - eprintln!("import: {qualified_path:?}"); + log::debug!("import: {qualified_path:?}"); } let module_uri = module_paths.get(qualified_path)?; if debug { - eprintln!("Module URI: {module_uri}"); + log::debug!("Module URI: {module_uri}"); } let &entity = documents.get(module_uri)?; @@ -420,7 +420,7 @@ fn find_ident_expr_in_parent_expr<'a>( debug: bool, ) -> Option<&'a IdentExpr> { if debug { - eprintln!("find_ident_expr {expr:#?}"); + log::debug!("find_ident_expr {expr:#?}"); } match expr { @@ -444,7 +444,7 @@ fn find_ident_expr_in_parent_decl<'a>( debug: bool, ) -> Option<&'a IdentExpr> { if debug { - eprintln!("find_ident_expr_in_parent_decl: {decl:#?}"); + log::debug!("find_ident_expr_in_parent_decl: {decl:#?}"); } match decl { Decl::Param(ParamDecl { ty, .. }) @@ -468,7 +468,7 @@ fn find_ident_expr_in_type_decl<'a>( debug: bool, ) -> Option<&'a IdentExpr> { if debug { - eprintln!("find_ident_expr_in_type_decl: {ty:#?}"); + log::debug!("find_ident_expr_in_type_decl: {ty:#?}"); } if ty.name.span().contains(needle.span()) { Some(&ty.name) diff --git a/packages/server/src/declarations/mod.rs b/packages/server/src/declarations/mod.rs index 8e142608..f928a1e5 100644 --- a/packages/server/src/declarations/mod.rs +++ b/packages/server/src/declarations/mod.rs @@ -227,7 +227,9 @@ fn map_token_references( )]); } } else { - eprintln!("Failed to find TokenReferences for document: {entity:?} {decl_uri}"); + log::error!( + "Failed to find TokenReferences for document: {entity:?} {decl_uri}" + ); } } diff --git a/packages/server/src/documents/mod.rs b/packages/server/src/documents/mod.rs index 5fdfcd55..d733965d 100644 --- a/packages/server/src/documents/mod.rs +++ b/packages/server/src/documents/mod.rs @@ -104,6 +104,7 @@ fn read_new_documents( for event in e_doc_reads.drain() { let source = event.0.text_document.text; let uri = event.0.text_document.uri; + log::info!(" reading document \"{uri}\""); let canon_uri = uri.clone().into_canonical(); if r_pending_reads.contains(&canon_uri) { @@ -122,6 +123,8 @@ fn update_existing_documents( ) -> anyhow::Result<()> { for event in e_doc_changes.drain() { let uri = event.0.text_document.uri; + log::info!(" updating document \"{uri}\""); + let Some(&entity) = r_documents.get(&uri) else { bail!(" Failed to find document entity for URI: {uri}"); }; @@ -153,6 +156,8 @@ fn handle_config_changes( mut r_pending_docs: ResMut, q_docs: Query<(&DocumentUri, &WgslSource)>, ) { + log::info!(" Handling configuration change"); + for (uri, source) in q_docs.iter() { if !r_pending_docs.contains_key(&**uri) { r_pending_docs.insert(uri.0.clone(), source.0.clone()); @@ -168,6 +173,8 @@ fn process_pending_documents( r_config: Res, ) { for (uri, source) in r_pending_docs.drain() { + log::info!(" Processing document \"{uri}\""); + let entity = if let Some(&entity) = r_documents.get(&uri) { entity } else { @@ -321,7 +328,7 @@ fn register_module_path(map: &mut ModulePathsMap, import_path_decl: &ImportPathD map.insert(module_path, uri.clone()); - eprintln!( + log::info!( " Module paths updated: `{}` -> {}", import_path_decl.qualified_name(), uri diff --git a/packages/server/src/ipc/mod.rs b/packages/server/src/ipc/mod.rs index 3537851f..f3289e37 100644 --- a/packages/server/src/ipc/mod.rs +++ b/packages/server/src/ipc/mod.rs @@ -94,7 +94,7 @@ fn start_event_loop( match msg { Message::Request(request) => { if let Err(err) = request::dispatch(&mut app.world, request) { - eprintln!("{err}"); + log::error!("{err}"); } } Message::Response(response) => { @@ -103,14 +103,14 @@ fn start_event_loop( (Some(result), None) => Ok(result), (None, Some(err)) => Err(err), (Some(result), Some(err)) => { - eprintln!("WARNING: Response from client has a result and an error."); - eprintln!(" Ignoring the error: {err:?}"); + log::warn!("Response from client has a result and an error."); + log::warn!(" Ignoring the error: {err:?}"); Ok(result) } (None, None) => { - eprintln!("WARNING: Response from client has no result and no error."); - eprintln!(" Ignoring response for request ID: {id}"); + log::warn!("Response from client has no result and no error."); + log::warn!(" Ignoring response for request ID: {id}"); app.update(); continue; @@ -121,7 +121,7 @@ fn start_event_loop( } Message::Notification(notification) => { if let Err(err) = notify::dispatch(&mut app.world, notification) { - eprintln!("{err}"); + log::error!("{err}"); } } } diff --git a/packages/server/src/ipc/notify.rs b/packages/server/src/ipc/notify.rs index 9b10dc7d..ead085f7 100644 --- a/packages/server/src/ipc/notify.rs +++ b/packages/server/src/ipc/notify.rs @@ -17,7 +17,8 @@ pub fn register_events(app: &mut App) { app.add_event::() .add_event::() .add_event::() - .add_event::(); + .add_event::() + .add_event::(); } #[derive(Event, Clone, Debug, Deref, DerefMut)] @@ -40,18 +41,28 @@ pub(super) fn dispatch(world: &mut World, n: Notification) -> anyhow::Result<()> // TODO: Figure out how to do proper logging with filters and such // if let Some(uri) = n.params.uri() { - // eprintln!("[Notification] {} : {uri}", n.method); + // eprintln!("[Notification] {} : \"{uri}\"", n.method); // } else { // eprintln!("[Notification] {}", n.method); // } match &n.method[..] { DidOpenTextDocument::METHOD => { - let params = n.extract(DidOpenTextDocument::METHOD)?; + let params: DidOpenTextDocumentParams = n.extract(DidOpenTextDocument::METHOD)?; + log::info!( + "[Notification] {} : \"{}\"", + DidOpenTextDocument::METHOD, + ¶ms.text_document.uri + ); world.send_event(DocumentOpen(params)); } DidChangeTextDocument::METHOD => { - let params = n.extract(DidChangeTextDocument::METHOD)?; + let params: DidChangeTextDocumentParams = n.extract(DidChangeTextDocument::METHOD)?; + log::info!( + "[Notification] {} : \"{}\"", + DidChangeTextDocument::METHOD, + ¶ms.text_document.uri + ); world.send_event(DocumentChange(params)); } DidCloseTextDocument::METHOD => { @@ -59,7 +70,8 @@ pub(super) fn dispatch(world: &mut World, n: Notification) -> anyhow::Result<()> world.send_event(DocumentClose(params)); } DidChangeConfiguration::METHOD => { - let params = n.extract(DidChangeConfiguration::METHOD)?; + let params: DidChangeConfigurationParams = n.extract(DidChangeConfiguration::METHOD)?; + log::info!("[Notification] {}", DidChangeConfiguration::METHOD); world.send_event(ConfigChange(params)); } Cancel::METHOD => { @@ -68,6 +80,7 @@ pub(super) fn dispatch(world: &mut World, n: Notification) -> anyhow::Result<()> NumberOrString::Number(n) => n.into(), NumberOrString::String(s) => s.into(), }; + log::info!("[Notification] {} : [{id}]", Cancel::METHOD); // TODO: Consider instead using the `&mut World` to try and find the // event with matching ID and remove it from the `Events` // resource if found. Tbh, it's probably not worth the CPU cycles diff --git a/packages/server/src/ipc/request.rs b/packages/server/src/ipc/request.rs index 17ebe0e1..60fd3a8f 100644 --- a/packages/server/src/ipc/request.rs +++ b/packages/server/src/ipc/request.rs @@ -7,7 +7,7 @@ use lsp_types::{ SemanticTokensDeltaParams, SemanticTokensParams, SemanticTokensRangeParams, }; -// use super::GetUri; +use super::GetUri; use crate::lsp_extensions::{DebugAstRequest, DebugDocumentParams, DebugTokensRequest}; pub fn register_events(app: &mut App) { @@ -69,11 +69,11 @@ pub(super) fn dispatch(world: &mut World, r: lsp_server::Request) -> anyhow::Res use SemanticTokens::*; // TODO: Figure out how to do proper logging with filters and such - // if let Some(uri) = r.params.uri() { - // eprintln!("[Request] {} : {uri}", r.method); - // } else { - // eprintln!("[Request] {}", r.method); - // } + if let Some(uri) = r.params.uri() { + log::info!("[Request] {} [{}] : \"{uri}\"", r.method, r.id); + } else { + log::info!("[Request] {} [{}]", r.method, r.id); + } match &r.method[..] { LspHoverRequest::METHOD => { diff --git a/packages/server/src/main.rs b/packages/server/src/main.rs index a1dddff4..8f8fee5c 100644 --- a/packages/server/src/main.rs +++ b/packages/server/src/main.rs @@ -1,8 +1,10 @@ use bevy_app::App; use bevy_core::{TaskPoolPlugin, TypeRegistrationPlugin}; +use bevy_utils::tracing::Level; use config::ConfigPlugin; use declarations::DeclarationsPlugin; use dependencies::DependenciesPlugin; +use log::LogPlugin; use lsp_server::Connection; use crate::{ @@ -49,6 +51,10 @@ fn start() -> App { app.add_plugins(( TaskPoolPlugin::default(), TypeRegistrationPlugin, + LogPlugin { + filter: "trace,lsp_server::msg=warn,lsp_server::stdio=warn".into(), + ..Default::default() + }, ConfigPlugin, DocumentsPlugin, DeclarationsPlugin, diff --git a/packages/server/src/pre/mod.rs b/packages/server/src/pre/mod.rs index 75e5a8f2..4835ee97 100644 --- a/packages/server/src/pre/mod.rs +++ b/packages/server/src/pre/mod.rs @@ -26,7 +26,7 @@ pub struct PruneResult { } pub fn prune(uri: &Url, source: Substr, defs: HashMap) -> PruneResult { - eprintln!(" Preprocessing {uri}"); + log::info!(" Preprocessing \"{uri}\""); let (parsed, source, _pre_parse_errors) = pre::parse(source); @@ -35,13 +35,13 @@ pub fn prune(uri: &Url, source: Substr, defs: HashMap) -> PruneR let (pruned, source_map, replacements, replacement_errors) = pruner.write_output(); - eprintln!("Pruned source for {uri}:"); + log::debug!("Pruned source for {uri}:"); for (idx, line) in pruned.lines().enumerate() { - eprintln!(" {:>4} | {line}", idx + 1); + log::debug!(" {:>4} | {line}", idx + 1); } - eprintln!("Source map for {uri}:"); - eprintln!("{source_map:#?}"); + log::debug!("Source map for {uri}:"); + log::debug!("{source_map:#?}"); PruneResult { original: pruner.source, diff --git a/packages/server/src/pre/pruner.rs b/packages/server/src/pre/pruner.rs index dafab449..50213e35 100644 --- a/packages/server/src/pre/pruner.rs +++ b/packages/server/src/pre/pruner.rs @@ -255,14 +255,14 @@ impl Visitor for Pruner { rem }; - eprintln!("Defining `{def}` = `{value}`"); + // eprintln!("Defining `{def}` = `{value}`"); self.defs.insert(def.into(), value.into()); } else { - eprintln!("Defining `{def}`"); + // eprintln!("Defining `{def}`"); self.defs.insert(def.into(), String::new()); } } else { - eprintln!("Defining `{rem}`"); + // eprintln!("Defining `{rem}`"); self.defs.insert(rem.into(), String::new()); } } diff --git a/packages/server/src/references.rs b/packages/server/src/references.rs index 755c9a07..de03ece3 100644 --- a/packages/server/src/references.rs +++ b/packages/server/src/references.rs @@ -80,7 +80,7 @@ fn handle_requests( let include_decl = request.context.include_declaration; let Some(&entity) = r_docs.get(uri) else { - eprintln!("Failed to find document entity for URI: {uri}"); + log::error!("Failed to find document entity for URI: {uri}"); // TODO: Try again next update r_ipc.send(Message::Response(Response { diff --git a/packages/server/src/testing.rs b/packages/server/src/testing.rs index e82078b6..1192826d 100644 --- a/packages/server/src/testing.rs +++ b/packages/server/src/testing.rs @@ -153,7 +153,7 @@ fn handle_server_requests( ew_responses.send(ipc::Response(id, Ok(response))); } other => { - eprintln!("WARNING: Unhandled server request: {other}"); + log::warn!("Unhandled server request: {other}"); } } } diff --git a/packages/server/src/utils.rs b/packages/server/src/utils.rs index eaf6cfe6..f758da3d 100644 --- a/packages/server/src/utils.rs +++ b/packages/server/src/utils.rs @@ -6,7 +6,7 @@ use parser::{utils::ToRange, Span, Spanned}; pub fn log_error(result: Result<(), E>) { if let Err(err) = result { - eprintln!("{err}"); + log::error!("{err}"); } } diff --git a/packages/server/src/validation/conv.rs b/packages/server/src/validation/conv.rs index c57bc9ad..f666d01f 100644 --- a/packages/server/src/validation/conv.rs +++ b/packages/server/src/validation/conv.rs @@ -45,7 +45,7 @@ impl<'a> IntoDiagnostics<'a> for WithSpan { fn into_diagnostics(self, kind: ErrorKind, data: &'a Self::Data) -> Vec { use NagaValidationError::*; - eprintln!("Converting naga validation error: {self:#?}"); + log::debug!("Converting naga validation error: {self:#?}"); let (module, src, tokens, ast, scopes) = data; From 6a1c089f7199f9e788128f44ee2f686ec1d061dd Mon Sep 17 00:00:00 2001 From: Danny McGee Date: Thu, 23 May 2024 19:49:48 -0400 Subject: [PATCH 2/5] Fix soft-lock --- packages/log/Cargo.toml | 2 +- packages/log/src/lib.rs | 126 +++++++------------------ packages/parser/src/comment.rs | 4 +- packages/parser/src/common.rs | 2 +- packages/parser/src/decl/import.rs | 2 +- packages/parser/src/decl/mod.rs | 2 +- packages/parser/src/parser.rs | 2 +- packages/parser/src/stmt.rs | 6 +- packages/server/src/documents/mod.rs | 13 +++ packages/server/src/ipc/notify.rs | 25 ++--- packages/server/src/ipc/request.rs | 4 +- packages/server/src/main.rs | 4 +- packages/server/src/pre/mod.rs | 7 +- packages/server/src/validation/conv.rs | 6 +- 14 files changed, 78 insertions(+), 127 deletions(-) diff --git a/packages/log/Cargo.toml b/packages/log/Cargo.toml index 4642e602..c593edd9 100644 --- a/packages/log/Cargo.toml +++ b/packages/log/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" bevy_app = { workspace = true } bevy_ecs = { workspace = true } bevy_utils = { workspace = true } -time = { version = "0.3.36", features = ["formatting", "local-offset"]} +time = { version = "0.3.36", features = ["formatting", "local-offset", "macros"]} tracing-error = "0.2.0" tracing-log = "0.2.0" tracing-subscriber = { version = "0.3.1", features = [ diff --git a/packages/log/src/lib.rs b/packages/log/src/lib.rs index 267c81f3..449c900a 100644 --- a/packages/log/src/lib.rs +++ b/packages/log/src/lib.rs @@ -1,5 +1,5 @@ use bevy_app::{App, Plugin}; -use bevy_utils::tracing::{subscriber as bevy_subscriber, Event, Level, Subscriber}; +use bevy_utils::tracing::{subscriber as bevy_subscriber, Level}; pub use bevy_utils::{ debug_once, error_once, info_once, once, trace_once, tracing::{ @@ -7,19 +7,9 @@ pub use bevy_utils::{ }, warn_once, }; -use time::format_description::{BorrowedFormatItem, FormatItem}; use tracing_error::ErrorLayer; -use tracing_log::{LogTracer, NormalizeEvent}; -use tracing_subscriber::{ - fmt::{ - format::{Format, Full, Writer}, - time::{FormatTime, OffsetTime, SystemTime}, - FmtContext, FormatEvent, FormatFields, - }, - prelude::*, - registry::{LookupSpan, Registry}, - EnvFilter, FmtSubscriber, -}; +use tracing_log::LogTracer; +use tracing_subscriber::{fmt::time::FormatTime, prelude::*, registry::Registry, EnvFilter}; pub struct LogPlugin { /// Filters logs using the [`EnvFilter`] format @@ -61,6 +51,34 @@ impl Plugin for LogPlugin { .with_timer(fmt_time()) .with_writer(std::io::stderr), ); + + #[cfg(r#false)] + let subscriber = { + let log_file_timestamp = time::OffsetDateTime::now_local() + .unwrap() + .format(time::macros::format_description!( + "[year]-[month padding:zero]-[day padding:zero]_\ + [hour repr:24]-[minute padding:zero]-[second padding:zero]" + )) + .unwrap(); + + let log_path = format!("D:/.vscode-wgsl/{log_file_timestamp}.log"); + let log_file = std::fs::OpenOptions::new() + .append(false) + .write(true) + .truncate(true) + .create(true) + .open(log_path) + .unwrap(); + + subscriber.with( + tracing_subscriber::fmt::layer() + .with_ansi(false) + .with_timer(fmt_time()) + .with_writer(log_file), + ) + }; + let subscriber = Box::new(subscriber); let logger_already_set = LogTracer::init().is_err(); @@ -84,86 +102,12 @@ impl Plugin for LogPlugin { } } -// struct CustomFormat(Format>>>); -// struct CustomFormat { -// timer: OffsetTime>>, -// } - fn fmt_time() -> impl FormatTime { - let timer = time::format_description::parse( + let timer = time::macros::format_description!( "[year]-[month padding:zero]-[day padding:zero] \ - [hour repr:24]:[minute padding:zero]:[second padding:zero].[subsecond digits:3]", - ) - .expect("Failed to parse date-time format"); - + [hour repr:24]:[minute padding:zero]:[second padding:zero].[subsecond digits:3]" + ); let time_offset = time::UtcOffset::current_local_offset().unwrap_or(time::UtcOffset::UTC); + tracing_subscriber::fmt::time::OffsetTime::new(time_offset, timer) } - -// impl Default for CustomFormat { -// fn default() -> Self { -// let timer = time::format_description::parse( -// "[year]-[month padding:zero]-[day padding:zero] \ -// [hour repr:24]:[minute padding:zero]:[second padding:zero].[subsecond digits:3]", -// ) -// .expect("Failed to parse date-time format"); - -// let time_offset = time::UtcOffset::current_local_offset().unwrap_or(time::UtcOffset::UTC); -// let timer = tracing_subscriber::fmt::time::OffsetTime::new(time_offset, timer); - -// Self { timer } -// } -// } - -// impl FormatEvent for CustomFormat -// where -// S: Subscriber + for<'a> LookupSpan<'a>, -// N: for<'a> FormatFields<'a> + 'static, -// { -// fn format_event( -// &self, -// ctx: &FmtContext<'_, S, N>, -// mut writer: Writer<'_>, -// event: &Event<'_>, -// ) -> std::fmt::Result { -// let meta = event.normalized_metadata(); -// let meta = meta.as_ref().unwrap_or_else(|| event.metadata()); - -// self.timer.format_time(&mut writer)?; -// writer.write_char(' ')?; - -// write!(writer, "{} ", FmtLevel(*meta.level()))?; - -// ctx.format_fields(writer.by_ref(), event)?; - -// writeln!(writer) -// } -// } - -// struct FmtLevel(Level); - -// impl std::fmt::Display for FmtLevel { -// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { -// match self.0 { -// Level::TRACE => f.pad("[trace]"), -// Level::DEBUG => f.pad("[debug]"), -// Level::INFO => f.pad("[info]"), -// Level::WARN => f.pad("[warn]"), -// Level::ERROR => f.pad("[error]"), -// } -// } -// } - -// fn format() -> Format>>> { -// let timer = time::format_description::parse( -// "[year]-[month padding:zero]-[day padding:zero] \ -// [hour repr:24]:[minute padding:zero]:[second padding:zero].[subsecond digits:3]", -// ) -// .expect("Failed to parse date-time format"); - -// let time_offset = time::UtcOffset::current_local_offset().unwrap_or(time::UtcOffset::UTC); -// let timer = tracing_subscriber::fmt::time::OffsetTime::new(time_offset, timer); - -// let result = Format::default().with_ansi(false).with_timer(timer); -// result -// } diff --git a/packages/parser/src/comment.rs b/packages/parser/src/comment.rs index 8573cab2..360780e9 100644 --- a/packages/parser/src/comment.rs +++ b/packages/parser/src/comment.rs @@ -46,7 +46,7 @@ impl Parse for Comment { None => Err(SpannedError { message: "Unexpected end of input".into(), source: input.source(), - span: None, + span: input.prev().map(|token| token.span()), }), } } @@ -120,7 +120,7 @@ impl Parse for BlockComment { return Err(SpannedError { message: "Unexpected end of input".into(), source: input.source(), - span: None, + span: input.prev().map(|token| token.span()), }); } } diff --git a/packages/parser/src/common.rs b/packages/parser/src/common.rs index 19caed50..610573ab 100644 --- a/packages/parser/src/common.rs +++ b/packages/parser/src/common.rs @@ -243,7 +243,7 @@ impl Parse for TypeDecl { return Err(SpannedError { message: "Unexpected end of input".into(), source: input.source(), - span: None, + span: input.prev().map(|token| token.span()), }) } } diff --git a/packages/parser/src/decl/import.rs b/packages/parser/src/decl/import.rs index ddaa4892..e524bb88 100644 --- a/packages/parser/src/decl/import.rs +++ b/packages/parser/src/decl/import.rs @@ -212,7 +212,7 @@ impl Parse for ImportPath { None => Err(SpannedError { message: "Unexpected end of input".into(), source: input.source(), - span: None, + span: input.prev().map(|token| token.span()), }), } } diff --git a/packages/parser/src/decl/mod.rs b/packages/parser/src/decl/mod.rs index bf78c192..bf61bd45 100644 --- a/packages/parser/src/decl/mod.rs +++ b/packages/parser/src/decl/mod.rs @@ -132,7 +132,7 @@ impl Parse for Decl { None => Err(SpannedError { message: "Unexpected end of input".into(), source: input.source(), - span: None, + span: input.prev().map(|token| token.span()), }), } } diff --git a/packages/parser/src/parser.rs b/packages/parser/src/parser.rs index 5870deb3..2e54af89 100644 --- a/packages/parser/src/parser.rs +++ b/packages/parser/src/parser.rs @@ -59,7 +59,7 @@ pub(crate) trait ErrorRecoveringParseStream: ParseStreamer { let mut results = vec![]; let mut recovering = false; - while loop_condition(self) { + while !self.is_empty() && loop_condition(self) { match self.parse::

() { Ok(parsed) => { if recovering { diff --git a/packages/parser/src/stmt.rs b/packages/parser/src/stmt.rs index 96197cad..5a256a36 100644 --- a/packages/parser/src/stmt.rs +++ b/packages/parser/src/stmt.rs @@ -328,7 +328,7 @@ impl Parse for SwitchBody { return Err(SpannedError { message: "Unexpected end of input".into(), source: input.source(), - span: None, + span: input.prev().map(|token| token.span()), }) } }; @@ -371,7 +371,7 @@ impl Parse for CaseStmt { return Err(SpannedError { message: "Unexpected end of input".into(), source: input.source(), - span: None, + span: input.prev().map(|token| token.span()), }); } }; @@ -480,7 +480,7 @@ impl Parse for ForStmt { return Err(SpannedError { message: "Unexpected end of input".into(), source: input.source(), - span: None, + span: input.prev().map(|token| token.span()), }) } }; diff --git a/packages/server/src/documents/mod.rs b/packages/server/src/documents/mod.rs index d733965d..3ea32cdd 100644 --- a/packages/server/src/documents/mod.rs +++ b/packages/server/src/documents/mod.rs @@ -176,8 +176,10 @@ fn process_pending_documents( log::info!(" Processing document \"{uri}\""); let entity = if let Some(&entity) = r_documents.get(&uri) { + log::trace!(" Found entity in DocumentsMap"); entity } else { + log::trace!(" Spawning new entity"); let entity = cmd .spawn(( DocumentUri(uri.clone()), @@ -190,12 +192,18 @@ fn process_pending_documents( entity }; + log::trace!(" Document entity: {entity:?}"); let mut parser = ParseStream::from(source); let tree = parser.parse::().unwrap(); + log::trace!(" Parsed syntax tree"); let import_path_decl = find_import_path_decl(&tree); if let Some(import_path_decl) = import_path_decl { + log::trace!( + " Found import path declaration: {}", + import_path_decl.qualified_name() + ); register_module_path(&mut r_module_paths, import_path_decl, &uri); } @@ -205,11 +213,16 @@ fn process_pending_documents( comments, errors, } = parser.into_inner(); + log::trace!(" Extracted ParseResult with:"); + log::trace!(" {} tokens", tokens.len()); + log::trace!(" {} comments", comments.len()); + log::trace!(" {} errors", errors.len()); let needs_preprocessing = !errors.is_empty() && tokens .iter() .any(|token| matches!(token.kind(), TokenKind::Pragma)); + log::trace!(" Document needs preprocessing: {needs_preprocessing}"); if !needs_preprocessing { if let Some(imported_symbols) = collect_imported_symbols(&tree) { diff --git a/packages/server/src/ipc/notify.rs b/packages/server/src/ipc/notify.rs index ead085f7..3ac9c9a2 100644 --- a/packages/server/src/ipc/notify.rs +++ b/packages/server/src/ipc/notify.rs @@ -11,7 +11,7 @@ use lsp_types::{ DidCloseTextDocumentParams, DidOpenTextDocumentParams, NumberOrString, }; -// use super::GetUri; +use crate::ipc::GetUri; pub fn register_events(app: &mut App) { app.add_event::() @@ -39,30 +39,19 @@ pub struct CancelRequest(pub RequestId); pub(super) fn dispatch(world: &mut World, n: Notification) -> anyhow::Result<()> { use lsp_types::notification::Notification as _; - // TODO: Figure out how to do proper logging with filters and such - // if let Some(uri) = n.params.uri() { - // eprintln!("[Notification] {} : \"{uri}\"", n.method); - // } else { - // eprintln!("[Notification] {}", n.method); - // } + if let Some(uri) = n.params.uri() { + log::trace!("[Notification] {} : \"{uri}\"", n.method); + } else { + log::trace!("[Notification] {}", n.method); + } match &n.method[..] { DidOpenTextDocument::METHOD => { let params: DidOpenTextDocumentParams = n.extract(DidOpenTextDocument::METHOD)?; - log::info!( - "[Notification] {} : \"{}\"", - DidOpenTextDocument::METHOD, - ¶ms.text_document.uri - ); world.send_event(DocumentOpen(params)); } DidChangeTextDocument::METHOD => { let params: DidChangeTextDocumentParams = n.extract(DidChangeTextDocument::METHOD)?; - log::info!( - "[Notification] {} : \"{}\"", - DidChangeTextDocument::METHOD, - ¶ms.text_document.uri - ); world.send_event(DocumentChange(params)); } DidCloseTextDocument::METHOD => { @@ -71,7 +60,6 @@ pub(super) fn dispatch(world: &mut World, n: Notification) -> anyhow::Result<()> } DidChangeConfiguration::METHOD => { let params: DidChangeConfigurationParams = n.extract(DidChangeConfiguration::METHOD)?; - log::info!("[Notification] {}", DidChangeConfiguration::METHOD); world.send_event(ConfigChange(params)); } Cancel::METHOD => { @@ -80,7 +68,6 @@ pub(super) fn dispatch(world: &mut World, n: Notification) -> anyhow::Result<()> NumberOrString::Number(n) => n.into(), NumberOrString::String(s) => s.into(), }; - log::info!("[Notification] {} : [{id}]", Cancel::METHOD); // TODO: Consider instead using the `&mut World` to try and find the // event with matching ID and remove it from the `Events` // resource if found. Tbh, it's probably not worth the CPU cycles diff --git a/packages/server/src/ipc/request.rs b/packages/server/src/ipc/request.rs index 60fd3a8f..ffa4c932 100644 --- a/packages/server/src/ipc/request.rs +++ b/packages/server/src/ipc/request.rs @@ -70,9 +70,9 @@ pub(super) fn dispatch(world: &mut World, r: lsp_server::Request) -> anyhow::Res // TODO: Figure out how to do proper logging with filters and such if let Some(uri) = r.params.uri() { - log::info!("[Request] {} [{}] : \"{uri}\"", r.method, r.id); + log::trace!("[Request] {} [{}] : \"{uri}\"", r.method, r.id); } else { - log::info!("[Request] {} [{}]", r.method, r.id); + log::trace!("[Request] {} [{}]", r.method, r.id); } match &r.method[..] { diff --git a/packages/server/src/main.rs b/packages/server/src/main.rs index 8f8fee5c..ab1f5c7e 100644 --- a/packages/server/src/main.rs +++ b/packages/server/src/main.rs @@ -52,8 +52,8 @@ fn start() -> App { TaskPoolPlugin::default(), TypeRegistrationPlugin, LogPlugin { - filter: "trace,lsp_server::msg=warn,lsp_server::stdio=warn".into(), - ..Default::default() + level: Level::WARN, + filter: "warn,server=trace".into(), }, ConfigPlugin, DocumentsPlugin, diff --git a/packages/server/src/pre/mod.rs b/packages/server/src/pre/mod.rs index 4835ee97..6ead0eec 100644 --- a/packages/server/src/pre/mod.rs +++ b/packages/server/src/pre/mod.rs @@ -40,8 +40,11 @@ pub fn prune(uri: &Url, source: Substr, defs: HashMap) -> PruneR log::debug!(" {:>4} | {line}", idx + 1); } - log::debug!("Source map for {uri}:"); - log::debug!("{source_map:#?}"); + log::debug!("Source map for \"{uri}\":"); + let source_map_dbg = format!("{source_map:#?}"); + for line in source_map_dbg.lines() { + log::debug!("{line}"); + } PruneResult { original: pruner.source, diff --git a/packages/server/src/validation/conv.rs b/packages/server/src/validation/conv.rs index f666d01f..1796e0d9 100644 --- a/packages/server/src/validation/conv.rs +++ b/packages/server/src/validation/conv.rs @@ -45,7 +45,11 @@ impl<'a> IntoDiagnostics<'a> for WithSpan { fn into_diagnostics(self, kind: ErrorKind, data: &'a Self::Data) -> Vec { use NagaValidationError::*; - log::debug!("Converting naga validation error: {self:#?}"); + log::debug!("Converting naga validation error:"); + let self_dbg = format!("{self:#?}"); + for line in self_dbg.lines() { + log::debug!("{}", line.replace(" ", " ")); + } let (module, src, tokens, ast, scopes) = data; From fef86507c00d16eebf511f92b6ecbe16ab5f3899 Mon Sep 17 00:00:00 2001 From: Danny McGee Date: Thu, 23 May 2024 19:51:17 -0400 Subject: [PATCH 3/5] Revert bad server-output-passtrhough attempt --- packages/client/src/app/client.ts | 30 ------------------------------ packages/client/src/app/context.ts | 20 -------------------- 2 files changed, 50 deletions(-) diff --git a/packages/client/src/app/client.ts b/packages/client/src/app/client.ts index f8775027..9ca5643b 100644 --- a/packages/client/src/app/client.ts +++ b/packages/client/src/app/client.ts @@ -1,6 +1,4 @@ -import * as cp from "child_process"; import * as path from "path"; -import { regex } from "@vscode-devkit/grammar"; import { Uri, workspace } from "vscode"; import { DidChangeConfigurationNotification, @@ -11,7 +9,6 @@ import { import { Configuration } from "./configuration"; import ctx from "./context"; import ext from "./extensions"; -import { StringDecoder } from "string_decoder"; namespace client { export function create() { @@ -31,33 +28,6 @@ namespace client { }); client.start().then(() => { - const server = client["_serverProcess"] as cp.ChildProcess; - - const dateStamp = /[0-9]{4}-[0-9]{2}-[0-9]{2}/; - const timeStamp = /[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}/; - const logPattern = regex`/^${dateStamp} ${timeStamp} +([A-Z]+) (.+)/`; - - const decoder = new StringDecoder("utf-8"); - - server.stderr.on("data", (chunk: Buffer) => { - let line = decoder.write(chunk); - - let match = line.match(logPattern); - if (match) { - let [, level, message] = match; - switch (level) { - case "TRACE": ctx.get()?.trace(message); break; - case "DEBUG": ctx.get()?.debug(message); break; - case "INFO": ctx.get()?.info(message); break; - case "WARN": ctx.get()?.warn(message); break; - case "ERROR": ctx.get()?.error(message); break; - default: ctx.get()?.info(message); - } - } else { - ctx.get()?.info(line); - } - }); - client.onNotification(ext.UNREAD_DEPENDENCY, async params => { let dependency = Uri.parse(params.dependency); // TODO: report error if path is invalid diff --git a/packages/client/src/app/context.ts b/packages/client/src/app/context.ts index ed08a288..0f4bfbe1 100644 --- a/packages/client/src/app/context.ts +++ b/packages/client/src/app/context.ts @@ -76,26 +76,6 @@ namespace ctx { export function get() { return Context.instance; } - - export function trace(message: string, ...args: any[]): void { - get()?.trace(message, ...args); - } - - export function debug(message: string, ...args: any[]): void { - get()?.debug(message, ...args); - } - - export function info(message: string, ...args: any[]): void { - get()?.info(message, ...args); - } - - export function warn(message: string, ...args: any[]): void { - get()?.warn(message, ...args); - } - - export function error(error: string | Error, ...args: any[]): void { - get()?.error(error, ...args); - } } export default ctx; From 8fc6224932febc51bdbef445e903287234b99219 Mon Sep 17 00:00:00 2001 From: Danny McGee Date: Thu, 23 May 2024 19:55:19 -0400 Subject: [PATCH 4/5] Cleanup --- packages/server/src/ipc/notify.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/server/src/ipc/notify.rs b/packages/server/src/ipc/notify.rs index 3ac9c9a2..a1dc58dd 100644 --- a/packages/server/src/ipc/notify.rs +++ b/packages/server/src/ipc/notify.rs @@ -11,7 +11,7 @@ use lsp_types::{ DidCloseTextDocumentParams, DidOpenTextDocumentParams, NumberOrString, }; -use crate::ipc::GetUri; +use super::GetUri; pub fn register_events(app: &mut App) { app.add_event::() @@ -47,11 +47,11 @@ pub(super) fn dispatch(world: &mut World, n: Notification) -> anyhow::Result<()> match &n.method[..] { DidOpenTextDocument::METHOD => { - let params: DidOpenTextDocumentParams = n.extract(DidOpenTextDocument::METHOD)?; + let params = n.extract(DidOpenTextDocument::METHOD)?; world.send_event(DocumentOpen(params)); } DidChangeTextDocument::METHOD => { - let params: DidChangeTextDocumentParams = n.extract(DidChangeTextDocument::METHOD)?; + let params = n.extract(DidChangeTextDocument::METHOD)?; world.send_event(DocumentChange(params)); } DidCloseTextDocument::METHOD => { @@ -59,7 +59,7 @@ pub(super) fn dispatch(world: &mut World, n: Notification) -> anyhow::Result<()> world.send_event(DocumentClose(params)); } DidChangeConfiguration::METHOD => { - let params: DidChangeConfigurationParams = n.extract(DidChangeConfiguration::METHOD)?; + let params = n.extract(DidChangeConfiguration::METHOD)?; world.send_event(ConfigChange(params)); } Cancel::METHOD => { From 2074d3b3e77858ce25136c362b8379ee7e9b1bdb Mon Sep 17 00:00:00 2001 From: Danny McGee Date: Thu, 23 May 2024 20:00:39 -0400 Subject: [PATCH 5/5] Remove resolved `TODO` comment --- packages/server/src/ipc/request.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/server/src/ipc/request.rs b/packages/server/src/ipc/request.rs index ffa4c932..f2aa2c53 100644 --- a/packages/server/src/ipc/request.rs +++ b/packages/server/src/ipc/request.rs @@ -68,7 +68,6 @@ pub(super) fn dispatch(world: &mut World, r: lsp_server::Request) -> anyhow::Res }; use SemanticTokens::*; - // TODO: Figure out how to do proper logging with filters and such if let Some(uri) = r.params.uri() { log::trace!("[Request] {} [{}] : \"{uri}\"", r.method, r.id); } else {