summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorKitson Kelly <me@kitsonkelly.com>2020-02-25 06:48:14 +1100
committerGitHub <noreply@github.com>2020-02-24 14:48:14 -0500
commit2b7e28b591a6947f76ddf9a53f49eec8f1accc0f (patch)
treecfa8f32e1e5171642fc916d77a397937e901fc48 /cli
parent5da7c7df1d8649ddb5628b4dc830aa8c23ccb488 (diff)
feat: Add Deno.formatDiagnostics (#4032)
Diffstat (limited to 'cli')
-rw-r--r--cli/diagnostics.rs17
-rw-r--r--cli/js/deno.ts1
-rw-r--r--cli/js/dispatch.ts1
-rw-r--r--cli/js/format_error.ts9
-rw-r--r--cli/js/format_error_test.ts37
-rw-r--r--cli/js/lib.deno.ns.d.ts7
-rw-r--r--cli/js/unit_tests.ts1
-rw-r--r--cli/ops/errors.rs17
8 files changed, 83 insertions, 7 deletions
diff --git a/cli/diagnostics.rs b/cli/diagnostics.rs
index 104a72c90..aaa6a1227 100644
--- a/cli/diagnostics.rs
+++ b/cli/diagnostics.rs
@@ -1,6 +1,10 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
//! This module encodes TypeScript errors (diagnostics) into Rust structs and
//! contains code for printing them to the console.
+
+// TODO(ry) This module does a lot of JSON parsing manually. It should use
+// serde_json.
+
use crate::colors;
use crate::fmt_errors::format_maybe_source_line;
use crate::fmt_errors::format_maybe_source_name;
@@ -29,7 +33,7 @@ impl Diagnostic {
let items_values = items_v.as_array().unwrap();
for item_v in items_values {
- items.push(DiagnosticItem::from_json_value(item_v));
+ items.push(DiagnosticItem::from_json_value(item_v)?);
}
}
@@ -114,14 +118,13 @@ pub struct DiagnosticItem {
}
impl DiagnosticItem {
- pub fn from_json_value(v: &serde_json::Value) -> Self {
+ pub fn from_json_value(v: &serde_json::Value) -> Option<Self> {
let obj = v.as_object().unwrap();
// required attributes
let message = obj
.get("message")
- .and_then(|v| v.as_str().map(String::from))
- .unwrap();
+ .and_then(|v| v.as_str().map(String::from))?;
let category = DiagnosticCategory::from(
obj.get("category").and_then(Value::as_i64).unwrap(),
);
@@ -154,7 +157,7 @@ impl DiagnosticItem {
for related_info_v in related_info_values {
related_information
- .push(DiagnosticItem::from_json_value(related_info_v));
+ .push(DiagnosticItem::from_json_value(related_info_v)?);
}
Some(related_information)
@@ -162,7 +165,7 @@ impl DiagnosticItem {
_ => None,
};
- Self {
+ Some(Self {
message,
message_chain,
related_information,
@@ -175,7 +178,7 @@ impl DiagnosticItem {
category,
start_column,
end_column,
- }
+ })
}
}
diff --git a/cli/js/deno.ts b/cli/js/deno.ts
index 887f60826..f5f774179 100644
--- a/cli/js/deno.ts
+++ b/cli/js/deno.ts
@@ -43,6 +43,7 @@ export {
OpenOptions,
OpenMode
} from "./files.ts";
+export { formatDiagnostics } from "./format_error.ts";
export { FsEvent, fsEvents } from "./fs_events.ts";
export {
EOF,
diff --git a/cli/js/dispatch.ts b/cli/js/dispatch.ts
index fc1c69a62..1b7e23463 100644
--- a/cli/js/dispatch.ts
+++ b/cli/js/dispatch.ts
@@ -17,6 +17,7 @@ export let OP_GET_DIR: number;
export let OP_START: number;
export let OP_APPLY_SOURCE_MAP: number;
export let OP_FORMAT_ERROR: number;
+export let OP_FORMAT_DIAGNOSTIC: number;
export let OP_CACHE: number;
export let OP_RESOLVE_MODULES: number;
export let OP_FETCH_ASSET: number;
diff --git a/cli/js/format_error.ts b/cli/js/format_error.ts
index d1d5a73f2..63250473b 100644
--- a/cli/js/format_error.ts
+++ b/cli/js/format_error.ts
@@ -1,4 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+import { DiagnosticItem } from "./diagnostics.ts";
import * as dispatch from "./dispatch.ts";
import { sendSync } from "./dispatch_json.ts";
@@ -7,3 +8,11 @@ export function formatError(errString: string): string {
const res = sendSync(dispatch.OP_FORMAT_ERROR, { error: errString });
return res.error;
}
+
+/**
+ * Format an array of diagnostic items and return them as a single string.
+ * @param items An array of diagnostic items to format
+ */
+export function formatDiagnostics(items: DiagnosticItem[]): string {
+ return sendSync(dispatch.OP_FORMAT_DIAGNOSTIC, { items });
+}
diff --git a/cli/js/format_error_test.ts b/cli/js/format_error_test.ts
new file mode 100644
index 000000000..282c2b274
--- /dev/null
+++ b/cli/js/format_error_test.ts
@@ -0,0 +1,37 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+import { assert, test } from "./test_util.ts";
+
+test(function formatDiagnosticBasic() {
+ const fixture: Deno.DiagnosticItem[] = [
+ {
+ message: "Example error",
+ category: Deno.DiagnosticCategory.Error,
+ sourceLine: "abcdefghijklmnopqrstuv",
+ lineNumber: 1000,
+ scriptResourceName: "foo.ts",
+ startColumn: 1,
+ endColumn: 2,
+ code: 4000
+ }
+ ];
+ const out = Deno.formatDiagnostics(fixture);
+ assert(out.includes("Example error"));
+ assert(out.includes("foo.ts"));
+});
+
+test(function formatDiagnosticError() {
+ let thrown = false;
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const bad = ([{ hello: 123 }] as any) as Deno.DiagnosticItem[];
+ try {
+ Deno.formatDiagnostics(bad);
+ } catch (e) {
+ assert(e instanceof TypeError);
+ thrown = true;
+ }
+ assert(thrown);
+});
+
+if (import.meta.main) {
+ Deno.runTests();
+}
diff --git a/cli/js/lib.deno.ns.d.ts b/cli/js/lib.deno.ns.d.ts
index 0c9430869..4d7822c90 100644
--- a/cli/js/lib.deno.ns.d.ts
+++ b/cli/js/lib.deno.ns.d.ts
@@ -1903,6 +1903,13 @@ declare namespace Deno {
/** UNSTABLE: new API, yet to be vetted.
*
+ * Format an array of diagnostic items and return them as a single string.
+ * @param items An array of diagnostic items to format
+ */
+ export function formatDiagnostics(items: DiagnosticItem[]): string;
+
+ /** UNSTABLE: new API, yet to be vetted.
+ *
* A specific subset TypeScript compiler options that can be supported by
* the Deno TypeScript compiler.
*/
diff --git a/cli/js/unit_tests.ts b/cli/js/unit_tests.ts
index ec4505c21..1c8237466 100644
--- a/cli/js/unit_tests.ts
+++ b/cli/js/unit_tests.ts
@@ -23,6 +23,7 @@ import "./fetch_test.ts";
import "./file_test.ts";
import "./files_test.ts";
import "./form_data_test.ts";
+import "./format_error_test.ts";
import "./fs_events_test.ts";
import "./get_random_values_test.ts";
import "./globals_test.ts";
diff --git a/cli/ops/errors.rs b/cli/ops/errors.rs
index 4dd4f1ca1..b5cc75f7a 100644
--- a/cli/ops/errors.rs
+++ b/cli/ops/errors.rs
@@ -1,5 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{Deserialize, JsonOp, Value};
+use crate::diagnostics::Diagnostic;
use crate::fmt_errors::JSError;
use crate::op_error::OpError;
use crate::ops::json_op;
@@ -18,6 +19,10 @@ pub fn init(i: &mut Isolate, s: &State) {
"format_error",
s.core_op(json_op(s.stateful_op(op_format_error))),
);
+ i.register_op(
+ "format_diagnostic",
+ s.core_op(json_op(s.stateful_op(op_format_diagnostic))),
+ );
}
#[derive(Deserialize)]
@@ -68,3 +73,15 @@ fn op_apply_source_map(
"column": orig_column as u32,
})))
}
+
+fn op_format_diagnostic(
+ _state: &State,
+ args: Value,
+ _zero_copy: Option<ZeroCopyBuf>,
+) -> Result<JsonOp, OpError> {
+ if let Some(diagnostic) = Diagnostic::from_json_value(&args) {
+ Ok(JsonOp::Sync(json!(diagnostic.to_string())))
+ } else {
+ Err(OpError::type_error("bad diagnostic".to_string()))
+ }
+}