Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,12 @@ public ParseTree visitIfStatement(BSLParser.IfStatementContext ctx) {

// тело true
blocks.enterBlock();
if (ctx.ifBranch().codeBlock() != null) {
if (ctx.ifBranch().codeBlock() != null && !Trees.nodeContainsErrors(ctx.ifBranch())) {
ctx.ifBranch().codeBlock().accept(this);
}
var truePart = blocks.leaveBlock();

graph.addVertex(truePart.begin());
graph.addEdge(conditionStatement, truePart.begin(), CfgEdgeType.TRUE_BRANCH);
currentLevelBlock.getBuildParts().push(truePart.end());
currentLevelBlock.getBuildParts().push(conditionStatement);
Expand Down Expand Up @@ -198,9 +199,12 @@ public ParseTree visitElsifBranch(BSLParser.ElsifBranchContext ctx) {

// тело true
blocks.enterBlock();
ctx.codeBlock().accept(this);
if (ctx.codeBlock() != null && !Trees.nodeContainsErrors(ctx)) {
ctx.codeBlock().accept(this);
}
var truePart = blocks.leaveBlock();

graph.addVertex(truePart.begin());
graph.addEdge(condition, truePart.begin(), CfgEdgeType.TRUE_BRANCH);
blocks.getCurrentBlock().getBuildParts().push(truePart.end());
blocks.getCurrentBlock().getBuildParts().push(condition);
Expand All @@ -218,11 +222,14 @@ public ParseTree visitCodeBlock(BSLParser.CodeBlockContext ctx) {
@Override
public ParseTree visitElseBranch(BSLParser.ElseBranchContext ctx) {
blocks.enterBlock();
ctx.codeBlock().accept(this);
if (ctx.codeBlock() != null && !Trees.nodeContainsErrors(ctx)) {
ctx.codeBlock().accept(this);
}
var block = blocks.leaveBlock();

// на стеке находится условие
var condition = blocks.getCurrentBlock().getBuildParts().pop();
graph.addVertex(block.begin());
graph.addEdge(condition, block.begin(), CfgEdgeType.FALSE_BRANCH);
blocks.getCurrentBlock().getBuildParts().push(block.end());

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package com.github._1c_syntax.bsl.languageserver.cfg;

import com.github._1c_syntax.bsl.languageserver.util.TestUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest
class CfgEmptyStringDotTest {

@Test
void testEmptyStringWithDotShouldNotCrash() {
var code = """
Процедура РаспределитьНаТовары(Команда)

Если Товар.ТаможеннаяСтоимость = "". Тогда

КонецЕсли;

КонецПроцедуры
""";

var dContext = TestUtils.getDocumentContext(code);
var parseTree = dContext.getAst().subs().sub(0).procedure().subCodeBlock().codeBlock();

var builder = new CfgBuildingParseTreeVisitor();
builder.producePreprocessorConditions(true);
builder.produceLoopIterations(false);
builder.determineAdjacentDeadCode(false);

// This should not crash
var graph = builder.buildGraph(parseTree);

// Basic validation that the graph was created
assertThat(graph).isNotNull();
assertThat(graph.getEntryPoint()).isNotNull();
assertThat(graph.getExitPoint()).isNotNull();
}

@Test
void testEmptyElsifBranchShouldNotCrash() {
var code = """
Процедура Тест()

Если Условие1 Тогда
Действие1();
ИначеЕсли Условие2 = "". Тогда

КонецЕсли;

КонецПроцедуры
""";

var dContext = TestUtils.getDocumentContext(code);
var parseTree = dContext.getAst().subs().sub(0).procedure().subCodeBlock().codeBlock();

var builder = new CfgBuildingParseTreeVisitor();
builder.producePreprocessorConditions(true);
builder.produceLoopIterations(false);
builder.determineAdjacentDeadCode(false);

// This should not crash
var graph = builder.buildGraph(parseTree);

// Basic validation that the graph was created
assertThat(graph).isNotNull();
assertThat(graph.getEntryPoint()).isNotNull();
assertThat(graph.getExitPoint()).isNotNull();
}

@Test
void testEmptyElseBranchShouldNotCrash() {
var code = """
Процедура Тест()

Если Условие1 Тогда
Действие1();
Иначе

КонецЕсли;

КонецПроцедуры
""";

var dContext = TestUtils.getDocumentContext(code);
var parseTree = dContext.getAst().subs().sub(0).procedure().subCodeBlock().codeBlock();

var builder = new CfgBuildingParseTreeVisitor();
builder.producePreprocessorConditions(true);
builder.produceLoopIterations(false);
builder.determineAdjacentDeadCode(false);

// This should not crash
var graph = builder.buildGraph(parseTree);

// Basic validation that the graph was created
assertThat(graph).isNotNull();
assertThat(graph.getEntryPoint()).isNotNull();
assertThat(graph.getExitPoint()).isNotNull();
}

@Test
void testOriginalIssueCase() {
// This is the exact code from the issue report
var code = """
Процедура Тест()

Если Товар.ТаможеннаяСтоимость = "". Тогда

КонецЕсли;

КонецПроцедуры
""";

var dContext = TestUtils.getDocumentContext(code);
var parseTree = dContext.getAst().subs().sub(0).procedure().subCodeBlock().codeBlock();

var builder = new CfgBuildingParseTreeVisitor();
builder.producePreprocessorConditions(true);
builder.produceLoopIterations(false);
builder.determineAdjacentDeadCode(false);

// This should not crash (was crashing before the fix)
var graph = builder.buildGraph(parseTree);

// Basic validation that the graph was created
assertThat(graph).isNotNull();
assertThat(graph.getEntryPoint()).isNotNull();
assertThat(graph.getExitPoint()).isNotNull();
}
}