summaryrefslogtreecommitdiff
path: root/cli/tools/registry/diagnostics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/tools/registry/diagnostics.rs')
-rw-r--r--cli/tools/registry/diagnostics.rs152
1 files changed, 152 insertions, 0 deletions
diff --git a/cli/tools/registry/diagnostics.rs b/cli/tools/registry/diagnostics.rs
new file mode 100644
index 000000000..f6d81f5a8
--- /dev/null
+++ b/cli/tools/registry/diagnostics.rs
@@ -0,0 +1,152 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+
+use std::borrow::Cow;
+use std::fmt::Display;
+use std::sync::Arc;
+use std::sync::Mutex;
+
+use deno_ast::swc::common::util::take::Take;
+use deno_core::anyhow::anyhow;
+use deno_core::error::AnyError;
+use deno_graph::FastCheckDiagnostic;
+use deno_graph::ParsedSourceStore;
+
+use crate::diagnostics::Diagnostic;
+use crate::diagnostics::DiagnosticLevel;
+use crate::diagnostics::DiagnosticLocation;
+use crate::diagnostics::DiagnosticSnippet;
+use crate::diagnostics::DiagnosticSnippetHighlight;
+use crate::diagnostics::DiagnosticSnippetHighlightStyle;
+use crate::diagnostics::DiagnosticSnippetSource;
+use crate::diagnostics::DiagnosticSourcePos;
+use crate::diagnostics::DiagnosticSourceRange;
+use crate::diagnostics::SourceTextParsedSourceStore;
+
+#[derive(Clone, Default)]
+pub struct PublishDiagnosticsCollector {
+ diagnostics: Arc<Mutex<Vec<PublishDiagnostic>>>,
+}
+
+impl PublishDiagnosticsCollector {
+ pub fn print_and_error(
+ &self,
+ sources: &dyn ParsedSourceStore,
+ ) -> Result<(), AnyError> {
+ let mut errors = 0;
+ let diagnostics = self.diagnostics.lock().unwrap().take();
+ let sources = SourceTextParsedSourceStore(sources);
+ for diagnostic in diagnostics {
+ eprintln!("{}", diagnostic.display(&sources));
+ if matches!(diagnostic.level(), DiagnosticLevel::Error) {
+ errors += 1;
+ }
+ }
+ if errors > 0 {
+ Err(anyhow!(
+ "Found {} problem{}",
+ errors,
+ if errors == 1 { "" } else { "s" }
+ ))
+ } else {
+ Ok(())
+ }
+ }
+
+ pub fn push(&self, diagnostic: PublishDiagnostic) {
+ self.diagnostics.lock().unwrap().push(diagnostic);
+ }
+}
+
+pub enum PublishDiagnostic {
+ FastCheck { diagnostic: FastCheckDiagnostic },
+}
+
+impl Diagnostic for PublishDiagnostic {
+ fn level(&self) -> DiagnosticLevel {
+ match self {
+ PublishDiagnostic::FastCheck {
+ diagnostic: FastCheckDiagnostic::UnsupportedJavaScriptEntrypoint { .. },
+ } => DiagnosticLevel::Warning,
+ PublishDiagnostic::FastCheck { .. } => DiagnosticLevel::Error,
+ }
+ }
+
+ fn code(&self) -> impl Display + '_ {
+ match &self {
+ PublishDiagnostic::FastCheck { diagnostic, .. } => diagnostic.code(),
+ }
+ }
+
+ fn message(&self) -> impl Display + '_ {
+ match &self {
+ PublishDiagnostic::FastCheck { diagnostic, .. } => diagnostic.to_string(), // todo
+ }
+ }
+
+ fn location(&self) -> DiagnosticLocation {
+ match &self {
+ PublishDiagnostic::FastCheck { diagnostic } => match diagnostic.range() {
+ Some(range) => DiagnosticLocation::PositionInFile {
+ specifier: Cow::Borrowed(diagnostic.specifier()),
+ source_pos: DiagnosticSourcePos::SourcePos(range.range.start),
+ },
+ None => DiagnosticLocation::File {
+ specifier: Cow::Borrowed(diagnostic.specifier()),
+ },
+ },
+ }
+ }
+
+ fn snippet(&self) -> Option<DiagnosticSnippet<'_>> {
+ match &self {
+ PublishDiagnostic::FastCheck { diagnostic } => {
+ diagnostic.range().map(|range| DiagnosticSnippet {
+ source: DiagnosticSnippetSource::Specifier(Cow::Borrowed(
+ diagnostic.specifier(),
+ )),
+ highlight: DiagnosticSnippetHighlight {
+ style: DiagnosticSnippetHighlightStyle::Error,
+ range: DiagnosticSourceRange {
+ start: DiagnosticSourcePos::SourcePos(range.range.start),
+ end: DiagnosticSourcePos::SourcePos(range.range.end),
+ },
+ description: diagnostic.range_description().map(Cow::Borrowed),
+ },
+ })
+ }
+ }
+ }
+
+ fn hint(&self) -> Option<impl Display + '_> {
+ match &self {
+ PublishDiagnostic::FastCheck { diagnostic } => {
+ Some(diagnostic.fix_hint())
+ }
+ }
+ }
+
+ fn snippet_fixed(&self) -> Option<DiagnosticSnippet<'_>> {
+ None
+ }
+
+ fn info(&self) -> Cow<'_, [Cow<'_, str>]> {
+ match &self {
+ PublishDiagnostic::FastCheck { diagnostic } => {
+ let infos = diagnostic
+ .additional_info()
+ .iter()
+ .map(|s| Cow::Borrowed(*s))
+ .collect();
+ Cow::Owned(infos)
+ }
+ }
+ }
+
+ fn docs_url(&self) -> Option<impl Display + '_> {
+ match &self {
+ PublishDiagnostic::FastCheck { diagnostic } => {
+ Some(format!("https://jsr.io/go/{}", diagnostic.code()))
+ }
+ }
+ }
+}