diff --git a/src/dreamchecker/lib.rs b/src/dreamchecker/lib.rs index fd6a3a2e..27029815 100644 --- a/src/dreamchecker/lib.rs +++ b/src/dreamchecker/lib.rs @@ -1213,7 +1213,6 @@ impl<'o, 's> AnalyzeProc<'o, 's> { // TODO: factor in the previous return type if there was one let return_type = self.visit_expression(location, expr, None, local_vars); local_vars.get_mut(".").unwrap().analysis = return_type; - // TODO: break out of the analysis for this branch? return ControlFlow { returns: true, continues: false, breaks: false, fuzzy: false } }, Statement::Return(None) => { return ControlFlow { returns: true, continues: false, breaks: false, fuzzy: false } }, @@ -1270,9 +1269,10 @@ impl<'o, 's> AnalyzeProc<'o, 's> { } if let Some(else_arm) = else_arm { if alwaystrue { - // TODO: fix location for else blocks - error(location,"unreachable else block, preceeding if/elseif condition(s) are always true") - .register(self.context); + if let Some(else_expr) = else_arm.first() { + error(else_expr.location ,"unreachable else block, preceeding if/elseif condition(s) are always true") + .register(self.context); + } } let state = self.visit_block(else_arm, &mut local_vars.clone()); allterm.merge_false(state); @@ -1370,14 +1370,14 @@ impl<'o, 's> AnalyzeProc<'o, 's> { let mut allterm = ControlFlow::alltrue(); self.visit_control_condition(location, input); self.visit_expression(location, input, None, local_vars); - for &(ref case, ref block) in cases.iter() { + for (case, ref block) in cases.iter() { let mut scoped_locals = local_vars.clone(); - for case_part in case.iter() { + for case_part in case.elem.iter() { match case_part { - dm::ast::Case::Exact(expr) => { self.visit_expression(location, expr, None, &mut scoped_locals); }, + dm::ast::Case::Exact(expr) => { self.visit_expression(case.location, expr, None, &mut scoped_locals); }, dm::ast::Case::Range(start, end) => { - self.visit_expression(location, start, None, &mut scoped_locals); - self.visit_expression(location, end, None, &mut scoped_locals); + self.visit_expression(case.location, start, None, &mut scoped_locals); + self.visit_expression(case.location, end, None, &mut scoped_locals); } } } diff --git a/src/dreamchecker/tests/branch_eval_tests.rs b/src/dreamchecker/tests/branch_eval_tests.rs index 4b12cb4a..3f382715 100644 --- a/src/dreamchecker/tests/branch_eval_tests.rs +++ b/src/dreamchecker/tests/branch_eval_tests.rs @@ -41,7 +41,7 @@ pub const IF_ARMS_ERRORS: &[(u32, u16, &str)] = &[ (2, 7, "if condition is always true"), (4, 12, "unreachable if block, preceeding if/elseif condition(s) are always true"), // TODO: fix location reporting on this - (2, 5, "unreachable else block, preceeding if/elseif condition(s) are always true"), + (7, 9, "unreachable else block, preceeding if/elseif condition(s) are always true"), ]; #[test] diff --git a/src/dreammaker/ast.rs b/src/dreammaker/ast.rs index 5f0e8630..a98e0185 100644 --- a/src/dreammaker/ast.rs +++ b/src/dreammaker/ast.rs @@ -990,7 +990,7 @@ pub enum Statement { }, Switch { input: Expression, - cases: Vec<(Vec, Block)>, + cases: Vec<(Spanned>, Block)>, default: Option, }, TryCatch { diff --git a/src/dreammaker/parser.rs b/src/dreammaker/parser.rs index 705edf7f..916f1ebf 100644 --- a/src/dreammaker/parser.rs +++ b/src/dreammaker/parser.rs @@ -1310,7 +1310,7 @@ impl<'ctx, 'an, 'inp> Parser<'ctx, 'an, 'inp> { self.context.register_error(self.error("switch case cannot be empty")); } let block = require!(self.block(loop_ctx)); - cases.push((what, block)); + cases.push((Spanned::new(self.location(), what), block)); } let default = if let Some(()) = self.exact_ident("else")? { Some(require!(self.block(loop_ctx))) diff --git a/src/langserver/find_references.rs b/src/langserver/find_references.rs index 7b872c49..33409259 100644 --- a/src/langserver/find_references.rs +++ b/src/langserver/find_references.rs @@ -283,13 +283,13 @@ impl<'o> WalkProc<'o> { }, Statement::Switch { input, cases, default } => { self.visit_expression(location, input, None); - for &(ref case, ref block) in cases.iter() { - for case_part in case.iter() { + for (case, ref block) in cases.iter() { + for case_part in case.elem.iter() { match case_part { - dm::ast::Case::Exact(expr) => { self.visit_expression(location, expr, None); }, + dm::ast::Case::Exact(expr) => { self.visit_expression(case.location, expr, None); }, dm::ast::Case::Range(start, end) => { - self.visit_expression(location, start, None); - self.visit_expression(location, end, None); + self.visit_expression(case.location, start, None); + self.visit_expression(case.location, end, None); } } }