mirror of
https://github.com/denoland/deno.git
synced 2025-02-12 16:59:32 -05:00
first diagnostic from a plugin!
This commit is contained in:
parent
bc00517f9e
commit
7f45875211
3 changed files with 116 additions and 44 deletions
|
@ -1,4 +1,4 @@
|
||||||
import { op_lint_get_rule } from "ext:core/ops";
|
import { op_lint_get_rule, op_lint_report } from "ext:core/ops";
|
||||||
|
|
||||||
export class Context {
|
export class Context {
|
||||||
id;
|
id;
|
||||||
|
@ -10,8 +10,8 @@ export class Context {
|
||||||
this.fileName = fileName;
|
this.fileName = fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
report() {
|
report(data) {
|
||||||
console.log("Not implemented report");
|
op_lint_report(this.id, this.fileName, data.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -380,39 +380,45 @@ impl WorkspaceLinter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let r = linter.lint_file(
|
let mut r = linter.lint_file(
|
||||||
&file_path,
|
&file_path,
|
||||||
file_text,
|
file_text,
|
||||||
cli_options.ext_flag().as_deref(),
|
cli_options.ext_flag().as_deref(),
|
||||||
);
|
);
|
||||||
if let Ok((file_source, file_diagnostics)) = &r {
|
let r = match r {
|
||||||
let file_source_ = file_source.clone();
|
Ok((file_source, mut file_diagnostics)) => {
|
||||||
tokio_util::create_and_run_current_thread(
|
let file_source_ = file_source.clone();
|
||||||
async move {
|
let plugin_diagnostics =
|
||||||
let plugin_runner = linter.get_plugin_runner().unwrap();
|
tokio_util::create_and_run_current_thread(
|
||||||
let mut plugin_runner = plugin_runner.lock();
|
async move {
|
||||||
let serialized_ast =
|
let plugin_runner = linter.get_plugin_runner().unwrap();
|
||||||
plugins::get_estree_from_parsed_source(file_source_)?;
|
let mut plugin_runner = plugin_runner.lock();
|
||||||
plugins::run_rules_for_ast(
|
let serialized_ast =
|
||||||
&mut *plugin_runner,
|
plugins::get_estree_from_parsed_source(file_source_)?;
|
||||||
serialized_ast,
|
plugins::run_rules_for_ast(
|
||||||
)
|
&mut *plugin_runner,
|
||||||
.await
|
serialized_ast,
|
||||||
}
|
)
|
||||||
.boxed_local(),
|
.await
|
||||||
)?;
|
}
|
||||||
|
.boxed_local(),
|
||||||
|
)?;
|
||||||
|
|
||||||
if let Some(incremental_cache) = &maybe_incremental_cache {
|
file_diagnostics.extend_from_slice(&plugin_diagnostics);
|
||||||
if file_diagnostics.is_empty() {
|
if let Some(incremental_cache) = &maybe_incremental_cache {
|
||||||
// update the incremental cache if there were no diagnostics
|
if file_diagnostics.is_empty() {
|
||||||
incremental_cache.update_file(
|
// update the incremental cache if there were no diagnostics
|
||||||
&file_path,
|
incremental_cache.update_file(
|
||||||
// ensure the returned text is used here as it may have been modified via --fix
|
&file_path,
|
||||||
file_source.text(),
|
// ensure the returned text is used here as it may have been modified via --fix
|
||||||
)
|
file_source.text(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Ok((file_source, file_diagnostics))
|
||||||
}
|
}
|
||||||
}
|
Err(err) => Err(err),
|
||||||
|
};
|
||||||
|
|
||||||
let success = handle_lint_result(
|
let success = handle_lint_result(
|
||||||
&file_path.to_string_lossy(),
|
&file_path.to_string_lossy(),
|
||||||
|
|
|
@ -15,6 +15,8 @@ use deno_core::JsRuntime;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
use deno_core::PollEventLoopOptions;
|
use deno_core::PollEventLoopOptions;
|
||||||
use deno_core::RuntimeOptions;
|
use deno_core::RuntimeOptions;
|
||||||
|
use deno_lint::diagnostic::LintDiagnostic;
|
||||||
|
use deno_lint::diagnostic::LintDiagnosticDetails;
|
||||||
use deno_runtime::tokio_util;
|
use deno_runtime::tokio_util;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -31,11 +33,18 @@ pub enum PluginRunnerRequest {
|
||||||
Run(String),
|
Run(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum PluginRunnerResponse {
|
pub enum PluginRunnerResponse {
|
||||||
LoadPlugin(Result<(), AnyError>),
|
LoadPlugin(Result<(), AnyError>),
|
||||||
// TODO: should return diagnostics
|
Run(Result<Vec<LintDiagnostic>, AnyError>),
|
||||||
Run(Result<(), AnyError>),
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for PluginRunnerResponse {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::LoadPlugin(_arg0) => f.debug_tuple("LoadPlugin").finish(),
|
||||||
|
Self::Run(_arg0) => f.debug_tuple("Run").finish(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -57,17 +66,24 @@ impl PluginRunner {
|
||||||
let (tx_req, rx_req) = channel(10);
|
let (tx_req, rx_req) = channel(10);
|
||||||
let (tx_res, rx_res) = channel(10);
|
let (tx_res, rx_res) = channel(10);
|
||||||
|
|
||||||
|
eprintln!("spawning thread");
|
||||||
let join_handle = std::thread::spawn(move || {
|
let join_handle = std::thread::spawn(move || {
|
||||||
|
eprintln!("thread spawned");
|
||||||
let mut runtime = JsRuntime::new(RuntimeOptions {
|
let mut runtime = JsRuntime::new(RuntimeOptions {
|
||||||
extensions: vec![deno_lint_ext::init_ops()],
|
extensions: vec![deno_lint_ext::init_ops()],
|
||||||
module_loader: Some(Rc::new(deno_core::FsModuleLoader)),
|
module_loader: Some(Rc::new(deno_core::FsModuleLoader)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
let obj = runtime.lazy_load_es_module_with_code(
|
eprintln!("before loaded");
|
||||||
|
|
||||||
|
let obj_result = runtime.lazy_load_es_module_with_code(
|
||||||
"ext:cli/lint.js",
|
"ext:cli/lint.js",
|
||||||
deno_core::ascii_str_include!(concat!("lint.js")),
|
deno_core::ascii_str_include!(concat!("lint.js")),
|
||||||
)?;
|
);
|
||||||
|
|
||||||
|
eprintln!("after loaded {}", obj_result.is_err());
|
||||||
|
let obj = obj_result?;
|
||||||
|
|
||||||
let run_plugin_rule_fn = {
|
let run_plugin_rule_fn = {
|
||||||
let scope = &mut runtime.handle_scope();
|
let scope = &mut runtime.handle_scope();
|
||||||
|
@ -85,10 +101,13 @@ impl PluginRunner {
|
||||||
tx: tx_res,
|
tx: tx_res,
|
||||||
rx: rx_req,
|
rx: rx_req,
|
||||||
};
|
};
|
||||||
|
// TODO(bartlomieju): send "host ready" message to the proxy
|
||||||
runner.run_loop()
|
eprintln!("running host loop");
|
||||||
|
runner.run_loop()?;
|
||||||
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
|
eprintln!("is thread finished {}", join_handle.is_finished());
|
||||||
let proxy = PluginRunnerProxy {
|
let proxy = PluginRunnerProxy {
|
||||||
tx: tx_req,
|
tx: tx_req,
|
||||||
rx: Arc::new(tokio::sync::Mutex::new(rx_res)),
|
rx: Arc::new(tokio::sync::Mutex::new(rx_res)),
|
||||||
|
@ -100,7 +119,9 @@ impl PluginRunner {
|
||||||
|
|
||||||
fn run_loop(mut self) -> Result<(), AnyError> {
|
fn run_loop(mut self) -> Result<(), AnyError> {
|
||||||
let fut = async move {
|
let fut = async move {
|
||||||
|
eprintln!("waiting for message");
|
||||||
while let Some(req) = self.rx.recv().await {
|
while let Some(req) = self.rx.recv().await {
|
||||||
|
eprintln!("received message");
|
||||||
match req {
|
match req {
|
||||||
PluginRunnerRequest::LoadPlugins(specifiers) => {
|
PluginRunnerRequest::LoadPlugins(specifiers) => {
|
||||||
let r = self.load_plugins(specifiers).await;
|
let r = self.load_plugins(specifiers).await;
|
||||||
|
@ -117,17 +138,28 @@ impl PluginRunner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let r = self.run_rules(rules_to_run, serialized_ast).await;
|
let r = match self.run_rules(rules_to_run, serialized_ast).await {
|
||||||
|
Ok(()) => Ok(self.take_diagnostics()),
|
||||||
|
Err(err) => Err(err),
|
||||||
|
};
|
||||||
let _ = self.tx.send(PluginRunnerResponse::Run(r)).await;
|
let _ = self.tx.send(PluginRunnerResponse::Run(r)).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
eprintln!("breaking loop");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed_local();
|
.boxed_local();
|
||||||
tokio_util::create_and_run_current_thread(fut)
|
tokio_util::create_and_run_current_thread(fut)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn take_diagnostics(&mut self) -> Vec<LintDiagnostic> {
|
||||||
|
let op_state = self.runtime.op_state();
|
||||||
|
let mut state = op_state.borrow_mut();
|
||||||
|
let mut container = state.borrow_mut::<LintPluginContainer>();
|
||||||
|
std::mem::take(&mut container.diagnostics)
|
||||||
|
}
|
||||||
|
|
||||||
fn get_rules_to_run(&mut self) -> IndexMap<String, Vec<String>> {
|
fn get_rules_to_run(&mut self) -> IndexMap<String, Vec<String>> {
|
||||||
let op_state = self.runtime.op_state();
|
let op_state = self.runtime.op_state();
|
||||||
let state = op_state.borrow();
|
let state = op_state.borrow();
|
||||||
|
@ -227,6 +259,7 @@ impl PluginRunnerProxy {
|
||||||
.send(PluginRunnerRequest::LoadPlugins(plugin_specifiers))
|
.send(PluginRunnerRequest::LoadPlugins(plugin_specifiers))
|
||||||
.await?;
|
.await?;
|
||||||
let mut rx = self.rx.lock().await;
|
let mut rx = self.rx.lock().await;
|
||||||
|
eprintln!("receiving load plugins");
|
||||||
if let Some(_val) = rx.recv().await {
|
if let Some(_val) = rx.recv().await {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -236,14 +269,16 @@ impl PluginRunnerProxy {
|
||||||
pub async fn run_rules(
|
pub async fn run_rules(
|
||||||
&self,
|
&self,
|
||||||
serialized_ast: String,
|
serialized_ast: String,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<Vec<LintDiagnostic>, AnyError> {
|
||||||
self
|
self
|
||||||
.tx
|
.tx
|
||||||
.send(PluginRunnerRequest::Run(serialized_ast))
|
.send(PluginRunnerRequest::Run(serialized_ast))
|
||||||
.await?;
|
.await?;
|
||||||
let mut rx = self.rx.lock().await;
|
let mut rx = self.rx.lock().await;
|
||||||
if let Some(_val) = rx.recv().await {
|
eprintln!("receiving diagnostics");
|
||||||
return Ok(());
|
if let Some(PluginRunnerResponse::Run(diagnostics_result)) = rx.recv().await
|
||||||
|
{
|
||||||
|
return diagnostics_result;
|
||||||
}
|
}
|
||||||
Err(custom_error("AlreadyClosed", "Plugin host has closed"))
|
Err(custom_error("AlreadyClosed", "Plugin host has closed"))
|
||||||
}
|
}
|
||||||
|
@ -260,9 +295,9 @@ pub async fn create_runner_and_load_plugins(
|
||||||
pub async fn run_rules_for_ast(
|
pub async fn run_rules_for_ast(
|
||||||
runner_proxy: &mut PluginRunnerProxy,
|
runner_proxy: &mut PluginRunnerProxy,
|
||||||
serialized_ast: String,
|
serialized_ast: String,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<Vec<LintDiagnostic>, AnyError> {
|
||||||
runner_proxy.run_rules(serialized_ast).await?;
|
let d = runner_proxy.run_rules(serialized_ast).await?;
|
||||||
Ok(())
|
Ok(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_estree_from_parsed_source(
|
pub fn get_estree_from_parsed_source(
|
||||||
|
@ -299,6 +334,7 @@ struct LintPluginDesc {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct LintPluginContainer {
|
struct LintPluginContainer {
|
||||||
plugins: IndexMap<String, LintPluginDesc>,
|
plugins: IndexMap<String, LintPluginDesc>,
|
||||||
|
diagnostics: Vec<LintDiagnostic>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LintPluginContainer {
|
impl LintPluginContainer {
|
||||||
|
@ -317,6 +353,24 @@ impl LintPluginContainer {
|
||||||
self.plugins.insert(name, desc);
|
self.plugins.insert(name, desc);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn report(&mut self, id: String, specifier: String, message: String) {
|
||||||
|
let lint_diagnostic = LintDiagnostic {
|
||||||
|
// TODO: fix
|
||||||
|
specifier: ModuleSpecifier::parse(&format!("file:///{}", specifier))
|
||||||
|
.unwrap(),
|
||||||
|
range: None,
|
||||||
|
details: LintDiagnosticDetails {
|
||||||
|
message,
|
||||||
|
code: id,
|
||||||
|
hint: None,
|
||||||
|
fixes: vec![],
|
||||||
|
custom_docs_url: None,
|
||||||
|
info: vec![],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
self.diagnostics.push(lint_diagnostic);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deno_core::extension!(
|
deno_core::extension!(
|
||||||
|
@ -324,7 +378,8 @@ deno_core::extension!(
|
||||||
ops = [
|
ops = [
|
||||||
op_lint_register_lint_plugin,
|
op_lint_register_lint_plugin,
|
||||||
op_lint_register_lint_plugin_rule,
|
op_lint_register_lint_plugin_rule,
|
||||||
op_lint_get_rule
|
op_lint_get_rule,
|
||||||
|
op_lint_report,
|
||||||
],
|
],
|
||||||
state = |state| {
|
state = |state| {
|
||||||
state.put(LintPluginContainer::default());
|
state.put(LintPluginContainer::default());
|
||||||
|
@ -385,3 +440,14 @@ fn op_lint_get_rule(
|
||||||
};
|
};
|
||||||
Ok(rule.clone())
|
Ok(rule.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[op2(fast)]
|
||||||
|
fn op_lint_report(
|
||||||
|
state: &mut OpState,
|
||||||
|
#[string] id: String,
|
||||||
|
#[string] specifier: String,
|
||||||
|
#[string] message: String,
|
||||||
|
) {
|
||||||
|
let mut container = state.borrow_mut::<LintPluginContainer>();
|
||||||
|
container.report(id, specifier, message);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue