Skip to content

Commit

Permalink
Report any statements after return statements as unreachable
Browse files Browse the repository at this point in the history
  • Loading branch information
kindlich committed Sep 14, 2024
1 parent eeb4ebb commit 78dc709
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -571,4 +571,8 @@ public static CompileError invalidPropertyPair(TypeID type, String name) {
public static CompileError invalidLambdaHeader(FunctionHeader header) {
return new CompileError(CompileExceptionCode.LAMBDA_HEADER_INVALID, "Invalid lambda header " + header);
}

public static CompileError unreachableStatement() {
return new CompileError(CompileExceptionCode.UNREACHABLE_STATEMENT, "Unreachable statement");
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#disabled: Not part of the refactor
#error: 10:UNREACHABLE_STATEMENT

function test(check: bool): string {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@
import org.openzen.zenscript.codemodel.type.TypeID;
import org.openzen.zenscript.validator.Validator;

import java.util.Arrays;

public class ReturnStatementValidator implements StatementVisitor<ReturnStatementValidator.ReturnKind> {

private final Validator validator;

public ReturnStatementValidator(Validator validator) {
this.validator = validator;
}

/**
* Validates whether a given statement appropriately returns a value as required by its return type.
*
Expand All @@ -24,7 +28,7 @@ public static void validate(TypeID returnType, Statement statement, Validator va
return;
}

ReturnStatementValidator.ReturnKind returnKind = statement.accept(new ReturnStatementValidator());
ReturnStatementValidator.ReturnKind returnKind = statement.accept(new ReturnStatementValidator(validator));
switch (returnKind) {
case ALWAYS_RETURNS:
return;
Expand Down Expand Up @@ -129,7 +133,17 @@ public ReturnKind visitWhile(WhileStatement statement) {
}

private ReturnKind mergeInsideBlock(Statement[] statements) {
return Arrays.stream(statements).map(it -> it.accept(this)).reduce(ReturnKind.NEVER_RETURNS, ReturnKind::max);
ReturnKind result = ReturnKind.NEVER_RETURNS;
for (Statement statement : statements) {
if (result == ReturnKind.ALWAYS_RETURNS) {
validator.logError(statement.position, CompileErrors.unreachableStatement());
break;
}

result = ReturnKind.max(result, statement.accept(this));
}

return result;
}

public enum ReturnKind {
Expand Down

0 comments on commit 78dc709

Please sign in to comment.