!33 fix: 在非 void 函数中强制使用 return 语句

Merge pull request !33 from Luke/bugfix/missing-return-check
This commit is contained in:
Luke 2025-07-10 04:19:39 +00:00 committed by Gitee
commit d9b3593e9b
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
26 changed files with 86 additions and 29 deletions

View File

@ -3,7 +3,7 @@
<option name="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo1 -o target/Demo1" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo/Demo1 -o target/Demo1" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Demo10" type="Application" factoryName="Application" folderName="Demo" activateToolWindowBeforeRun="false">
<configuration default="false" name="Demo10" type="Application" factoryName="Application" folderName="Demo">
<option name="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo10 -o target/Demo10" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo/Demo10 -o target/Demo10" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

17
.run/Demo12.run.xml Normal file
View File

@ -0,0 +1,17 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Demo12" type="Application" factoryName="Application" folderName="Demo">
<option name="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo/Demo12 -o target/Demo12" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Demo2" type="Application" factoryName="Application" folderName="Demo" activateToolWindowBeforeRun="false">
<configuration default="false" name="Demo2" type="Application" factoryName="Application" folderName="Demo">
<option name="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo2 -o target/Demo2" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo/Demo2 -o target/Demo2" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Demo3" type="Application" factoryName="Application" folderName="Demo" activateToolWindowBeforeRun="false">
<configuration default="false" name="Demo3" type="Application" factoryName="Application" folderName="Demo">
<option name="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo3 -o target/Demo3" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo/Demo3 -o target/Demo3" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Demo4" type="Application" factoryName="Application" folderName="Demo" activateToolWindowBeforeRun="false">
<configuration default="false" name="Demo4" type="Application" factoryName="Application" folderName="Demo">
<option name="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo4 -o target/Demo4" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo/Demo4 -o target/Demo4" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Demo5" type="Application" factoryName="Application" folderName="Demo" activateToolWindowBeforeRun="false">
<configuration default="false" name="Demo5" type="Application" factoryName="Application" folderName="Demo">
<option name="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo5 -o target/Demo5" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo/Demo5 -o target/Demo5" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Demo6" type="Application" factoryName="Application" folderName="Demo" activateToolWindowBeforeRun="false">
<configuration default="false" name="Demo6" type="Application" factoryName="Application" folderName="Demo">
<option name="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo6 -o target/Demo6" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo/Demo6 -o target/Demo6" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Demo7" type="Application" factoryName="Application" folderName="Demo" activateToolWindowBeforeRun="false">
<configuration default="false" name="Demo7" type="Application" factoryName="Application" folderName="Demo">
<option name="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo7 -o target/Demo7" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo/Demo7 -o target/Demo7" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Demo8" type="Application" factoryName="Application" folderName="Demo" activateToolWindowBeforeRun="false">
<configuration default="false" name="Demo8" type="Application" factoryName="Application" folderName="Demo">
<option name="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo8 -o target/Demo8" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo/Demo8 -o target/Demo8" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Demo9" type="Application" factoryName="Application" folderName="Demo" activateToolWindowBeforeRun="false">
<configuration default="false" name="Demo9" type="Application" factoryName="Application" folderName="Demo">
<option name="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo9 -o target/Demo9" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo/Demo9 -o target/Demo9" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,17 +1,21 @@
module: Main
function: main
parameter:
return_type: int
body:
declare n1: int =1
declare n2: int =2
declare n3: int =1
if n1 ==1 then
if n2 ==2 then
n3 =3
end if
end if
return n3
foo()
return 0
end body
end function
function: foo
return_type: int
body:
if false then
return 1
end if
return 0
end body
end function
end module

View File

@ -0,0 +1,21 @@
module: Main
function: main
return_type: int
body:
foo()
return 0
end body
end function
function: foo
return_type: int
body:
if false then
return 1
end if
return 0
end body
end function
end module

View File

@ -2,11 +2,13 @@ package org.jcnc.snow.compiler.semantic.core;
import org.jcnc.snow.compiler.parser.ast.FunctionNode;
import org.jcnc.snow.compiler.parser.ast.ModuleNode;
import org.jcnc.snow.compiler.parser.ast.ReturnNode;
import org.jcnc.snow.compiler.semantic.analyzers.base.StatementAnalyzer;
import org.jcnc.snow.compiler.semantic.error.SemanticError;
import org.jcnc.snow.compiler.semantic.symbol.Symbol;
import org.jcnc.snow.compiler.semantic.symbol.SymbolKind;
import org.jcnc.snow.compiler.semantic.symbol.SymbolTable;
import org.jcnc.snow.compiler.semantic.type.BuiltinType;
/**
* {@code FunctionChecker} 是语义分析阶段中用于检查函数体语句合法性的调度器
@ -79,6 +81,19 @@ public record FunctionChecker(Context ctx) {
));
}
}
// 检查非 void 函数是否至少包含一条 return 语句
var returnType = ctx.parseType(fn.returnType());
if (returnType != BuiltinType.VOID) {
boolean hasReturn = fn.body().stream()
.anyMatch(stmtNode -> stmtNode instanceof ReturnNode);
if (!hasReturn) {
ctx.errors().add(new SemanticError(
fn,
"非 void 函数必须包含至少一条 return 语句"
));
}
}
}
}
}