Skip to content

Commit ae7c865

Browse files
fix: handle null code blocks in loops
1 parent 3fadca8 commit ae7c865

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

src/main/java/com/github/_1c_syntax/bsl/languageserver/cfg/CfgBuildingParseTreeVisitor.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.github._1c_syntax.bsl.parser.BSLParser;
2525
import com.github._1c_syntax.bsl.parser.BSLParserBaseVisitor;
2626
import com.github._1c_syntax.bsl.parser.BSLParserRuleContext;
27+
import jakarta.annotation.Nullable;
2728
import org.antlr.v4.runtime.tree.ParseTree;
2829

2930
import java.util.ArrayList;
@@ -524,7 +525,7 @@ private void makeJump(CfgVertex jumpTarget) {
524525
graph.addVertex(blocks.getCurrentBlock().end());
525526
}
526527

527-
private void buildLoopSubgraph(BSLParser.CodeBlockContext ctx, LoopVertex loopStart) {
528+
private void buildLoopSubgraph(@Nullable BSLParser.CodeBlockContext ctx, LoopVertex loopStart) {
528529
graph.addVertex(loopStart);
529530
connectGraphTail(blocks.getCurrentBlock(), loopStart);
530531

@@ -537,7 +538,9 @@ private void buildLoopSubgraph(BSLParser.CodeBlockContext ctx, LoopVertex loopSt
537538

538539
blocks.enterBlock(jumpState);
539540

540-
ctx.accept(this);
541+
if (ctx != null) {
542+
ctx.accept(this);
543+
}
541544

542545
var body = blocks.leaveBlock();
543546

src/test/java/com/github/_1c_syntax/bsl/languageserver/cfg/ControlFlowGraphBuilderTest.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,41 @@ void preprocessorIfWithElseBranching() {
451451
assertThat(walker.getCurrentNode()).isSameAs(lastStatement);
452452
}
453453

454+
@Test
455+
void testLoopWithNullCodeBlock() {
456+
var code = """
457+
Для х = 1 По 10 Цикл
458+
А = 1;
459+
КонецЦикла;""";
460+
461+
var parseTree = parse(code);
462+
463+
// Force null code block by removing the CodeBlock child
464+
var forStatement = parseTree.statement(0).compoundStatement().forStatement();
465+
var children = forStatement.children;
466+
467+
// Find and remove the CodeBlockContext child
468+
for (int i = 0; i < children.size(); i++) {
469+
if (children.get(i) instanceof BSLParser.CodeBlockContext) {
470+
children.remove(i);
471+
break;
472+
}
473+
}
474+
475+
var builder = new CfgBuildingParseTreeVisitor();
476+
var graph = builder.buildGraph(parseTree);
477+
478+
// Check if graph was built successfully
479+
assertThat(graph).isNotNull();
480+
assertThat(graph.vertexSet()).isNotEmpty();
481+
482+
// Verify basic structure - should at least have loop vertex and exit
483+
var vertices = traverseToOrderedList(graph);
484+
assertThat(vertices)
485+
.hasAtLeastOneElementOfType(ForLoopVertex.class)
486+
.hasAtLeastOneElementOfType(ExitVertex.class);
487+
}
488+
454489
@Test
455490
void preprocessorIfWithElseIfBranching() {
456491
var code = """

0 commit comments

Comments
 (0)