mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-08-03 17:58:17 +00:00
fix: value used by exprs are not warned (#1664)
This commit is contained in:
parent
4d13734fed
commit
14f0a20ed6
9 changed files with 94 additions and 10 deletions
|
@ -112,6 +112,7 @@ impl<'w> Linter<'w> {
|
|||
linter: self,
|
||||
func_info,
|
||||
return_block_info: None,
|
||||
expr_context: ExprContext::Block,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -393,6 +394,7 @@ struct LateFuncLinter<'a, 'b> {
|
|||
linter: &'a mut Linter<'b>,
|
||||
func_info: FuncInfo,
|
||||
return_block_info: Option<ReturnBlockInfo>,
|
||||
expr_context: ExprContext,
|
||||
}
|
||||
|
||||
impl LateFuncLinter<'_, '_> {
|
||||
|
@ -410,6 +412,16 @@ impl LateFuncLinter<'_, '_> {
|
|||
self.expr(expr.body())
|
||||
}
|
||||
|
||||
fn expr_ctx<F>(&mut self, ctx: ExprContext, f: F) -> Option<()>
|
||||
where
|
||||
F: FnOnce(&mut Self) -> Option<()>,
|
||||
{
|
||||
let old = std::mem::replace(&mut self.expr_context, ctx);
|
||||
f(self);
|
||||
self.expr_context = old;
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn join(&mut self, parent: Option<ReturnBlockInfo>) {
|
||||
if let Some(parent) = parent {
|
||||
match &mut self.return_block_info {
|
||||
|
@ -438,7 +450,7 @@ impl DataFlowVisitor for LateFuncLinter<'_, '_> {
|
|||
}
|
||||
|
||||
fn block<'a>(&mut self, exprs: impl DoubleEndedIterator<Item = ast::Expr<'a>>) -> Option<()> {
|
||||
self.exprs(exprs)
|
||||
self.expr_ctx(ExprContext::Block, |this| this.exprs(exprs))
|
||||
}
|
||||
|
||||
fn loop_break(&mut self, _expr: ast::LoopBreak<'_>) -> Option<()> {
|
||||
|
@ -490,6 +502,20 @@ impl DataFlowVisitor for LateFuncLinter<'_, '_> {
|
|||
Some(())
|
||||
}
|
||||
|
||||
fn field_access(&mut self, _expr: ast::FieldAccess<'_>) -> Option<()> {
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn unary(&mut self, expr: ast::Unary<'_>) -> Option<()> {
|
||||
self.expr_ctx(ExprContext::Expr, |this| this.expr(expr.expr()))
|
||||
}
|
||||
|
||||
fn binary(&mut self, expr: ast::Binary<'_>) -> Option<()> {
|
||||
self.expr_ctx(ExprContext::Expr, |this| {
|
||||
this.exprs([expr.lhs(), expr.rhs()].into_iter())
|
||||
})
|
||||
}
|
||||
|
||||
fn equation(&mut self, expr: ast::Equation<'_>) -> Option<()> {
|
||||
self.value(ast::Expr::Equation(expr));
|
||||
Some(())
|
||||
|
@ -505,6 +531,11 @@ impl DataFlowVisitor for LateFuncLinter<'_, '_> {
|
|||
Some(())
|
||||
}
|
||||
|
||||
fn include(&mut self, expr: ast::ModuleInclude<'_>) -> Option<()> {
|
||||
self.value(ast::Expr::Include(expr));
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn func_call(&mut self, _expr: ast::FuncCall<'_>) -> Option<()> {
|
||||
Some(())
|
||||
}
|
||||
|
@ -532,6 +563,11 @@ impl DataFlowVisitor for LateFuncLinter<'_, '_> {
|
|||
}
|
||||
|
||||
fn value(&mut self, expr: ast::Expr) -> Option<()> {
|
||||
match self.expr_context {
|
||||
ExprContext::Block => {}
|
||||
ExprContext::Expr => return None,
|
||||
}
|
||||
|
||||
let ri = self.return_block_info.as_mut()?;
|
||||
if ri.warned {
|
||||
return None;
|
||||
|
@ -573,10 +609,6 @@ impl DataFlowVisitor for LateFuncLinter<'_, '_> {
|
|||
Some(())
|
||||
}
|
||||
|
||||
fn field_access(&mut self, _expr: ast::FieldAccess<'_>) -> Option<()> {
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn show(&mut self, expr: ast::ShowRule<'_>) -> Option<()> {
|
||||
self.value(ast::Expr::Show(expr));
|
||||
Some(())
|
||||
|
@ -594,11 +626,6 @@ impl DataFlowVisitor for LateFuncLinter<'_, '_> {
|
|||
fn while_loop(&mut self, expr: ast::WhileLoop<'_>) -> Option<()> {
|
||||
self.expr(expr.body())
|
||||
}
|
||||
|
||||
fn include(&mut self, expr: ast::ModuleInclude<'_>) -> Option<()> {
|
||||
self.value(ast::Expr::Include(expr));
|
||||
Some(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
|
@ -974,6 +1001,11 @@ impl BuggyBlockLoc<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
enum ExprContext {
|
||||
Block,
|
||||
Expr,
|
||||
}
|
||||
|
||||
fn is_show_set(it: ast::Expr) -> bool {
|
||||
matches!(it, ast::Expr::Set(..) | ast::Expr::Show(..))
|
||||
}
|
||||
|
|
7
crates/tinymist-query/src/fixtures/lint/assign_ok.typ
Normal file
7
crates/tinymist-query/src/fixtures/lint/assign_ok.typ
Normal file
|
@ -0,0 +1,7 @@
|
|||
|
||||
#let f() = {
|
||||
let x
|
||||
x = (1,)
|
||||
return
|
||||
}
|
||||
|
4
crates/tinymist-query/src/fixtures/lint/binary.typ
Normal file
4
crates/tinymist-query/src/fixtures/lint/binary.typ
Normal file
|
@ -0,0 +1,4 @@
|
|||
#let f() = {
|
||||
1 + (1,)
|
||||
return 0
|
||||
}
|
10
crates/tinymist-query/src/fixtures/lint/return_partial.typ
Normal file
10
crates/tinymist-query/src/fixtures/lint/return_partial.typ
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
#let f() = {
|
||||
let x
|
||||
x = (1,)
|
||||
if x.len() == 0 {
|
||||
return
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#let as-padding-dict(padding) = {
|
||||
if padding == none {
|
||||
padding = 0
|
||||
}
|
||||
|
||||
return padding
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/analysis.rs
|
||||
expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||
input_file: crates/tinymist-query/src/fixtures/lint/assign_ok.typ
|
||||
---
|
||||
{}
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/analysis.rs
|
||||
expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||
input_file: crates/tinymist-query/src/fixtures/lint/binary.typ
|
||||
---
|
||||
{}
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/analysis.rs
|
||||
expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||
input_file: crates/tinymist-query/src/fixtures/lint/return_partial.typ
|
||||
---
|
||||
{}
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/analysis.rs
|
||||
expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||
input_file: crates/tinymist-query/src/fixtures/lint/return_partial2.typ
|
||||
---
|
||||
{}
|
Loading…
Add table
Add a link
Reference in a new issue