!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="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" /> <option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" /> <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"> <extension name="coverage">
<pattern> <pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" /> <option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager"> <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="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" /> <option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" /> <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"> <extension name="coverage">
<pattern> <pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" /> <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"> <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="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" /> <option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" /> <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"> <extension name="coverage">
<pattern> <pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" /> <option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager"> <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="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" /> <option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" /> <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"> <extension name="coverage">
<pattern> <pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" /> <option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager"> <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="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" /> <option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" /> <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"> <extension name="coverage">
<pattern> <pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" /> <option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager"> <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="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" /> <option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" /> <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"> <extension name="coverage">
<pattern> <pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" /> <option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager"> <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="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" /> <option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" /> <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"> <extension name="coverage">
<pattern> <pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" /> <option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager"> <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="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" /> <option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" /> <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"> <extension name="coverage">
<pattern> <pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" /> <option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager"> <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="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" /> <option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" /> <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"> <extension name="coverage">
<pattern> <pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" /> <option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,9 +1,9 @@
<component name="ProjectRunConfigurationManager"> <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="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" /> <option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" /> <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"> <extension name="coverage">
<pattern> <pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" /> <option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />

View File

@ -1,17 +1,21 @@
module: Main module: Main
function: main function: main
parameter:
return_type: int return_type: int
body: body:
declare n1: int =1 foo()
declare n2: int =2
declare n3: int =1 return 0
if n1 ==1 then end body
if n2 ==2 then end function
n3 =3
end if function: foo
end if return_type: int
return n3 body:
if false then
return 1
end if
return 0
end body end body
end function end function
end module 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.FunctionNode;
import org.jcnc.snow.compiler.parser.ast.ModuleNode; 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.analyzers.base.StatementAnalyzer;
import org.jcnc.snow.compiler.semantic.error.SemanticError; import org.jcnc.snow.compiler.semantic.error.SemanticError;
import org.jcnc.snow.compiler.semantic.symbol.Symbol; import org.jcnc.snow.compiler.semantic.symbol.Symbol;
import org.jcnc.snow.compiler.semantic.symbol.SymbolKind; import org.jcnc.snow.compiler.semantic.symbol.SymbolKind;
import org.jcnc.snow.compiler.semantic.symbol.SymbolTable; import org.jcnc.snow.compiler.semantic.symbol.SymbolTable;
import org.jcnc.snow.compiler.semantic.type.BuiltinType;
/** /**
* {@code FunctionChecker} 是语义分析阶段中用于检查函数体语句合法性的调度器 * {@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 语句"
));
}
}
} }
} }
} }