Skip to content

Commit 35cca53

Browse files
committed
support luajit conitnue and const stat
1 parent 81a64da commit 35cca53

20 files changed

Lines changed: 221 additions & 185 deletions

File tree

crates/emmylua_code_analysis/src/compilation/analyzer/decl/stats.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ use super::{DeclAnalyzer, members::find_index_owner};
1616
pub fn analyze_local_stat(analyzer: &mut DeclAnalyzer, stat: LuaLocalStat) -> Option<()> {
1717
let local_name_list = stat.get_local_name_list().collect::<Vec<_>>();
1818
let value_expr_list = stat.get_value_exprs().collect::<Vec<_>>();
19+
let is_const = if stat.is_const() {
20+
Some(LocalAttribute::Const)
21+
} else {
22+
None
23+
};
1924

2025
for (index, local_name) in local_name_list.iter().enumerate() {
2126
let name = if let Some(name_token) = local_name.get_name_token() {
@@ -29,10 +34,10 @@ pub fn analyze_local_stat(analyzer: &mut DeclAnalyzer, stat: LuaLocalStat) -> Op
2934
} else if attrib.is_close() {
3035
Some(LocalAttribute::Close)
3136
} else {
32-
None
37+
is_const.clone()
3338
}
3439
} else {
35-
None
40+
is_const.clone()
3641
};
3742

3843
let file_id = analyzer.get_file_id();

crates/emmylua_code_analysis/src/compilation/analyzer/flow/bind_analyze/exprs/mod.rs

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ mod bind_binary_expr;
22

33
use emmylua_parser::{
44
LuaAst, LuaAstNode, LuaCallExpr, LuaClosureExpr, LuaExpr, LuaIndexExpr, LuaNameExpr,
5-
LuaNilCoalescingExpr, LuaTableExpr, LuaTernaryExpr, LuaUnaryExpr,
5+
LuaTableExpr, LuaTernaryExpr, LuaUnaryExpr,
66
};
77

88
use crate::{
@@ -57,9 +57,6 @@ pub fn bind_expr(binder: &mut FlowBinder, expr: LuaExpr, current: FlowId) -> Flo
5757
LuaExpr::BinaryExpr(binary_expr) => bind_binary_expr(binder, binary_expr, current),
5858
LuaExpr::UnaryExpr(unary_expr) => bind_unary_expr(binder, unary_expr, current),
5959
LuaExpr::TernaryExpr(ternary_expr) => bind_ternary_expr(binder, ternary_expr, current),
60-
LuaExpr::NilCoalescingExpr(nil_coalescing_expr) => {
61-
bind_nil_coalescing_expr(binder, nil_coalescing_expr, current)
62-
}
6360
};
6461

6562
current
@@ -160,24 +157,3 @@ fn bind_ternary_expr(
160157

161158
Some(())
162159
}
163-
164-
fn bind_nil_coalescing_expr(
165-
binder: &mut FlowBinder,
166-
nil_coalescing_expr: LuaNilCoalescingExpr,
167-
current: FlowId,
168-
) -> Option<()> {
169-
let (left, right) = nil_coalescing_expr.get_left_right_exprs()?;
170-
171-
let pre_right = binder.create_branch_label();
172-
bind_condition_expr(binder, left, current, binder.true_target, pre_right);
173-
let current = finish_flow_label(binder, pre_right, current);
174-
bind_condition_expr(
175-
binder,
176-
right,
177-
current,
178-
binder.true_target,
179-
binder.false_target,
180-
);
181-
182-
Some(())
183-
}

crates/emmylua_code_analysis/src/compilation/analyzer/flow/bind_analyze/mod.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ use crate::{
1212
comment::bind_comment,
1313
exprs::bind_expr,
1414
stats::{
15-
bind_assign_stat, bind_break_stat, bind_call_expr_stat, bind_do_stat,
16-
bind_for_range_stat, bind_for_stat, bind_func_stat, bind_goto_stat, bind_if_stat,
17-
bind_label_stat, bind_local_func_stat, bind_local_stat, bind_repeat_stat,
18-
bind_return_stat, bind_while_stat,
15+
bind_assign_stat, bind_break_stat, bind_call_expr_stat, bind_continue_stat,
16+
bind_do_stat, bind_for_range_stat, bind_for_stat, bind_func_stat, bind_goto_stat,
17+
bind_if_stat, bind_label_stat, bind_local_func_stat, bind_local_stat,
18+
bind_repeat_stat, bind_return_stat, bind_while_stat,
1919
},
2020
},
2121
binder::FlowBinder,
@@ -41,7 +41,7 @@ fn bind_block(binder: &mut FlowBinder, block: LuaBlock, current: FlowId) -> Flow
4141

4242
if let Some(flow_node) = binder.get_flow(return_flow_id) {
4343
match &flow_node.kind {
44-
FlowNodeKind::Return | FlowNodeKind::Break => {
44+
FlowNodeKind::Return | FlowNodeKind::Break | FlowNodeKind::Continue => {
4545
return_flow_id = binder.unreachable;
4646
can_change_flow = false;
4747
}
@@ -72,6 +72,9 @@ fn bind_node(binder: &mut FlowBinder, node: LuaAst, current: FlowId) -> FlowId {
7272
}
7373
LuaAst::LuaLabelStat(label_stat) => bind_label_stat(binder, label_stat, current),
7474
LuaAst::LuaBreakStat(break_stat) => bind_break_stat(binder, break_stat, current),
75+
LuaAst::LuaContinueStat(continue_stat) => {
76+
bind_continue_stat(binder, continue_stat, current)
77+
}
7578
LuaAst::LuaGotoStat(goto_stat) => bind_goto_stat(binder, goto_stat, current),
7679
LuaAst::LuaReturnStat(return_stat) => bind_return_stat(binder, return_stat, current),
7780
LuaAst::LuaDoStat(do_stat) => bind_do_stat(binder, do_stat, current),

crates/emmylua_code_analysis/src/compilation/analyzer/flow/bind_analyze/stats.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use emmylua_parser::{
22
BinaryOperator, LuaAssignStat, LuaAst, LuaAstNode, LuaBlock, LuaBreakStat, LuaCallArgList,
3-
LuaCallExprStat, LuaDoStat, LuaExpr, LuaForRangeStat, LuaForStat, LuaFuncStat, LuaGotoStat,
4-
LuaIfStat, LuaLabelStat, LuaLocalName, LuaLocalStat, LuaRepeatStat, LuaReturnStat, LuaVarExpr,
5-
LuaWhileStat,
3+
LuaCallExprStat, LuaContinueStat, LuaDoStat, LuaExpr, LuaForRangeStat, LuaForStat, LuaFuncStat,
4+
LuaGotoStat, LuaIfStat, LuaLabelStat, LuaLocalName, LuaLocalStat, LuaRepeatStat, LuaReturnStat,
5+
LuaVarExpr, LuaWhileStat,
66
};
77

88
use crate::{
@@ -255,6 +255,29 @@ pub fn bind_break_stat(
255255
break_flow_id
256256
}
257257

258+
pub fn bind_continue_stat(
259+
binder: &mut FlowBinder,
260+
continue_stat: LuaContinueStat,
261+
current: FlowId,
262+
) -> FlowId {
263+
let continue_flow_id = binder.create_continue();
264+
if let Some(loop_flow) = binder.get_flow(binder.loop_label)
265+
&& loop_flow.kind.is_unreachable()
266+
{
267+
// report a error if we are trying to continue outside a loop
268+
binder.report_error(AnalyzeError::new(
269+
DiagnosticCode::SyntaxError,
270+
&t!("Continue outside loop"),
271+
continue_stat.get_range(),
272+
));
273+
return current;
274+
}
275+
276+
binder.add_antecedent(continue_flow_id, current);
277+
binder.add_antecedent(binder.loop_label, continue_flow_id);
278+
continue_flow_id
279+
}
280+
258281
pub fn bind_goto_stat(binder: &mut FlowBinder, goto_stat: LuaGotoStat, current: FlowId) -> FlowId {
259282
// Goto statements are handled separately in the flow analysis
260283
// They will be processed when we analyze the labels

crates/emmylua_code_analysis/src/compilation/analyzer/flow/binder.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ impl<'a> FlowBinder<'a> {
108108
self.create_node(FlowNodeKind::Break)
109109
}
110110

111+
pub fn create_continue(&mut self) -> FlowId {
112+
self.create_node(FlowNodeKind::Continue)
113+
}
114+
111115
pub fn create_return(&mut self) -> FlowId {
112116
self.create_node(FlowNodeKind::Return)
113117
}

crates/emmylua_code_analysis/src/db_index/flow/flow_node.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ pub enum FlowNodeKind {
5656
TagCast(LuaAstPtr<LuaDocTagCast>),
5757
/// Break statement
5858
Break,
59+
/// Continue statement
60+
Continue,
5961
/// Return statement
6062
Return,
6163
}
@@ -75,7 +77,10 @@ impl FlowNodeKind {
7577
}
7678

7779
pub fn is_change_flow(&self) -> bool {
78-
matches!(self, FlowNodeKind::Break | FlowNodeKind::Return)
80+
matches!(
81+
self,
82+
FlowNodeKind::Break | FlowNodeKind::Return | FlowNodeKind::Continue
83+
)
7984
}
8085

8186
pub fn is_assignment(&self) -> bool {

crates/emmylua_code_analysis/src/semantic/infer/infer_index/mod.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
mod infer_array;
22

33
use emmylua_parser::{
4-
LuaExpr, LuaIndexExpr, LuaIndexKey, LuaIndexMemberExpr, LuaNilCoalescingExpr, LuaTernaryExpr,
5-
NumberResult, PathTrait,
4+
LuaExpr, LuaIndexExpr, LuaIndexKey, LuaIndexMemberExpr, LuaTernaryExpr, NumberResult, PathTrait,
65
};
76
use hashbrown::HashSet;
87
use internment::ArcIntern;
@@ -108,19 +107,6 @@ pub fn infer_ternary_expr(
108107
Ok(TypeOps::Union.apply(db, &true_type, &false_type))
109108
}
110109

111-
pub fn infer_nil_coalescing_expr(
112-
db: &DbIndex,
113-
cache: &mut LuaInferCache,
114-
nil_coalescing_expr: LuaNilCoalescingExpr,
115-
) -> InferResult {
116-
let Some((left_expr, right_expr)) = nil_coalescing_expr.get_left_right_exprs() else {
117-
return Err(InferFailReason::None);
118-
};
119-
let left_type = infer_expr(db, cache, left_expr)?;
120-
let right_type = infer_expr(db, cache, right_expr)?;
121-
Ok(TypeOps::Union.apply(db, &left_type, &right_type))
122-
}
123-
124110
fn infer_member_type_pass_flow(
125111
db: &DbIndex,
126112
cache: &mut LuaInferCache,

crates/emmylua_code_analysis/src/semantic/infer/mod.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use smol_str::SmolStr;
3636
use crate::{
3737
InFiled, InferGuard, LuaMemberKey, VariadicType,
3838
db_index::{DbIndex, LuaOperator, LuaOperatorMetaMethod, LuaSignatureId, LuaType},
39-
semantic::infer::infer_index::{infer_nil_coalescing_expr, infer_ternary_expr},
39+
semantic::infer::infer_index::infer_ternary_expr,
4040
};
4141

4242
use super::{CacheEntry, LuaInferCache, member::infer_raw_member_type};
@@ -134,9 +134,6 @@ pub fn infer_expr(db: &DbIndex, cache: &mut LuaInferCache, expr: LuaExpr) -> Inf
134134
LuaExpr::NameExpr(name_expr) => infer_name_expr(db, cache, name_expr),
135135
LuaExpr::IndexExpr(index_expr) => infer_index_expr(db, cache, index_expr, !no_flow),
136136
LuaExpr::TernaryExpr(ternary_expr) => infer_ternary_expr(db, cache, ternary_expr),
137-
LuaExpr::NilCoalescingExpr(nil_coalescing_expr) => {
138-
infer_nil_coalescing_expr(db, cache, nil_coalescing_expr)
139-
}
140137
};
141138

142139
match &result_type {

crates/emmylua_code_analysis/src/semantic/infer/narrow/get_type_at_flow.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,6 +1353,7 @@ impl<'a> FlowTypeEngine<'a> {
13531353
}
13541354
FlowNodeKind::LoopLabel
13551355
| FlowNodeKind::Break
1356+
| FlowNodeKind::Continue
13561357
| FlowNodeKind::Return
13571358
| FlowNodeKind::ForIStat(_) => {
13581359
walk.antecedent_flow_id = get_single_antecedent(flow_node)?;

crates/emmylua_formatter/src/formatter/expr.rs

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use emmylua_parser::{
22
BinaryOperator, LuaAssignStat, LuaAstNode, LuaAstToken, LuaBinaryExpr, LuaCallArgList,
33
LuaCallExpr, LuaClosureExpr, LuaComment, LuaExpr, LuaIndexExpr, LuaIndexKey, LuaKind,
4-
LuaLiteralExpr, LuaLiteralToken, LuaLocalStat, LuaNameExpr, LuaNilCoalescingExpr, LuaParamList,
5-
LuaParenExpr, LuaSingleArgExpr, LuaStat, LuaSyntaxId, LuaSyntaxKind, LuaSyntaxNode,
6-
LuaSyntaxToken, LuaTableExpr, LuaTableField, LuaTernaryExpr, LuaTokenKind, LuaUnaryExpr,
4+
LuaLiteralExpr, LuaLiteralToken, LuaLocalStat, LuaNameExpr, LuaParamList, LuaParenExpr,
5+
LuaSingleArgExpr, LuaStat, LuaSyntaxId, LuaSyntaxKind, LuaSyntaxNode, LuaSyntaxToken,
6+
LuaTableExpr, LuaTableField, LuaTernaryExpr, LuaTokenKind, LuaUnaryExpr,
77
};
88
use rowan::TextRange;
99

@@ -61,7 +61,6 @@ pub fn format_expr_with_options(
6161
LuaExpr::TableExpr(expr) => format_table_expr(ctx, plan, expr),
6262
LuaExpr::ClosureExpr(expr) => format_closure_expr(ctx, plan, expr),
6363
LuaExpr::TernaryExpr(expr) => format_ternary_expr(ctx, plan, expr),
64-
LuaExpr::NilCoalescingExpr(expr) => format_nil_coalescing_expr(ctx, plan, expr),
6564
}
6665
}
6766

@@ -2366,22 +2365,6 @@ fn format_ternary_expr(
23662365
docs
23672366
}
23682367

2369-
fn format_nil_coalescing_expr(
2370-
ctx: &FormatContext,
2371-
plan: &FormatPlan,
2372-
expr: &LuaNilCoalescingExpr,
2373-
) -> Vec<DocIR> {
2374-
let Some((left_expr, right_expr)) = expr.get_left_right_exprs() else {
2375-
return vec![ir::source_node(expr.syntax().clone())];
2376-
};
2377-
let mut docs = format_expr(ctx, plan, &left_expr);
2378-
docs.push(ir::space());
2379-
docs.push(ir::syntax_token(LuaTokenKind::TkNilCoalescing));
2380-
docs.push(ir::space());
2381-
docs.extend(format_expr(ctx, plan, &right_expr));
2382-
docs
2383-
}
2384-
23852368
fn try_format_simple_inline_closure_expr(
23862369
ctx: &FormatContext,
23872370
plan: &FormatPlan,

0 commit comments

Comments
 (0)