!64 feature: 实现私有函数(下划线开头仅限本模块访问)语义检查

Merge pull request !64 from Luke/feature/add-function-access-control
This commit is contained in:
Luke 2025-08-26 10:12:30 +00:00 committed by Gitee
commit 16ba11c391
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
4 changed files with 64 additions and 7 deletions

10
.run/Demo25.run.xml Normal file
View File

@ -0,0 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Demo25" type="Application" factoryName="Application" folderName="Demo">
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo/Demo25 -o target/Demo25" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

View File

@ -0,0 +1,23 @@
module: Main
import: os,ModuleA
globals:
declare c: int = 10
function: main
returns: void
body:
c = ModuleA.getA()
os.print(c)
end body
end function
end module
module: ModuleA
globals:
declare a: int = 2
function: getA
returns: int
body:
return a
end body
end function
end module

View File

@ -0,0 +1,11 @@
module: os
import: os
function: print
params:
declare i1: int
returns: void
body:
syscall("PRINT",i1)
end body
end function
end module

View File

@ -25,6 +25,7 @@ import java.util.List;
* <li>支持数值参数的宽化转换 int double</li> * <li>支持数值参数的宽化转换 int double</li>
* <li>支持数值到字符串的隐式转换自动视为调用 {@code to_string}</li> * <li>支持数值到字符串的隐式转换自动视为调用 {@code to_string}</li>
* <li>在发生类型不匹配未导入模块或函数未定义等情况下记录语义错误</li> * <li>在发生类型不匹配未导入模块或函数未定义等情况下记录语义错误</li>
* <li>新增"_"开头的函数名只允许在本模块访问禁止跨模块访问</li>
* </ul> * </ul>
*/ */
public class CallExpressionAnalyzer implements ExpressionAnalyzer<CallExpressionNode> { public class CallExpressionAnalyzer implements ExpressionAnalyzer<CallExpressionNode> {
@ -64,20 +65,32 @@ public class CallExpressionAnalyzer implements ExpressionAnalyzer<CallExpression
} }
target = ctx.getModules().get(mod); target = ctx.getModules().get(mod);
functionName = member; functionName = member;
}
// 简单函数名形式: func(...) // 简单函数名形式: func(...)
} else if (callee instanceof IdentifierNode(String name, NodeContext _)) { else if (callee instanceof IdentifierNode(String name, NodeContext _)) {
functionName = name; functionName = name;
}
// 不支持的 callee 形式 // 不支持的 callee 形式
} else { else {
ctx.getErrors().add(new SemanticError(callee, ctx.getErrors().add(new SemanticError(callee,
"不支持的调用方式: " + callee)); "不支持的调用方式: " + callee));
ctx.log("错误: 不支持的调用方式 " + callee); ctx.log("错误: 不支持的调用方式 " + callee);
return BuiltinType.INT; return BuiltinType.INT;
} }
// 查找目标函数签名先在当前模块/显式模块查找 // -------------------------
// 私有函数访问控制
// -------------------------
// 如果函数名以"_"开头且不是在本模块调用则报错
if (functionName.startsWith("_") && !target.getName().equals(mi.getName())) {
ctx.getErrors().add(new SemanticError(callee,
"无法访问模块私有函数: " + target.getName() + "." + functionName
+ "(下划线开头的函数只允许在定义模块内访问)"));
ctx.log("错误: 试图跨模块访问私有函数 " + target.getName() + "." + functionName);
return BuiltinType.INT;
}
// 查找目标函数签名先在当前模块/指定模块查找
FunctionType ft = target.getFunctions().get(functionName); FunctionType ft = target.getFunctions().get(functionName);
// 未找到则报错 // 未找到则报错