Skip to content

Commit c6986b0

Browse files
authored
Merge pull request #3723 from 1c-syntax/copilot/fix-nullpointerexception-bsl-parser
Fix NullPointerException in incomplete ternary operator parsing
2 parents a11189a + f8eaffe commit c6986b0

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ public int getPriority() {
6666
* @param ctx AST выражения
6767
* @return дерево вычисления выражения
6868
*/
69-
public static @Nullable BslExpression buildExpressionTree(BSLParser.ExpressionContext ctx) {
69+
public static @Nullable BslExpression buildExpressionTree(BSLParser.@Nullable ExpressionContext ctx) {
70+
if (ctx == null) {
71+
return null;
72+
}
7073
var instance = new ExpressionTreeBuildingVisitor();
7174
instance.visitExpression(ctx);
7275
return instance.getExpressionTree();
@@ -419,11 +422,19 @@ public ParseTree visitAccessCall(BSLParser.AccessCallContext ctx) {
419422

420423
@Override
421424
public ParseTree visitTernaryOperator(BSLParser.TernaryOperatorContext ctx) {
422-
var ternary = TernaryOperatorNode.create(
423-
Objects.requireNonNull(makeSubexpression(ctx.expression(0))),
424-
Objects.requireNonNull(makeSubexpression(ctx.expression(1))),
425-
Objects.requireNonNull(makeSubexpression(ctx.expression(2)))
426-
);
425+
var condition = makeSubexpression(ctx.expression(0));
426+
var truePart = makeSubexpression(ctx.expression(1));
427+
var falsePart = makeSubexpression(ctx.expression(2));
428+
429+
// If any expression is null (which happens when the parser encounters syntax errors
430+
// in incomplete ternary operators like "?" or "Возврат ?"), create an error node
431+
// instead of attempting to create a TernaryOperatorNode to avoid NullPointerException
432+
if (condition == null || truePart == null || falsePart == null) {
433+
operands.push(new ErrorExpressionNode(ctx));
434+
return ctx;
435+
}
436+
437+
var ternary = TernaryOperatorNode.create(condition, truePart, falsePart);
427438

428439
ternary.setRepresentingAst(ctx);
429440
operands.push(ternary);

src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitorTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ static Stream<Arguments> errorHandlingTestCases() {
8888
createIfStatementTestCase("New expression", "Новый"),
8989
createIfStatementTestCase("New expression with parenthes", "Новый ("),
9090
createIfStatementTestCase("New expression with two parantheses", "Новый ()"),
91-
createIfStatementTestCase("New expression with NOT", "Новый Структура(\"\", Не)", ConstructorCallNode.class)
91+
createIfStatementTestCase("New expression with NOT", "Новый Структура(\"\", Не)", ConstructorCallNode.class),
92+
createIfStatementTestCase("Incomplete ternary operator - only question mark", "?")
9293
);
9394
}
9495

0 commit comments

Comments
 (0)