feat: 新增全局常量表支持跨模块常量管理

- 添加 GlobalConstTable 类,用于编译期间跨模块常量查询和折叠
- 提供注册常量、查询常量和获取所有常量的功能
- 保证线程安全,支持并发操作- 常量的 key采用“模块名.常量名”的格式,确保唯一性
This commit is contained in:
Luke 2025-08-26 11:35:08 +08:00
parent 1a0c3a38cb
commit 1e2b0e4e0d

View File

@ -0,0 +1,70 @@
package org.jcnc.snow.compiler.ir.common;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 全局常量表用于跨模块编译期常量查询和折叠
*
* <p>
* 主要功能
* <ul>
* <li> IRProgramBuilder 预扫描阶段将所有模块级 <code>const</code> 常量
* ModuleA.a注册到全局常量表支持跨模块访问</li>
* <li>后续任何阶段均可通过 {@link #get(String)} 查询已注册常量实现编译期常量折叠</li>
* <li>保证线程安全支持并发注册和访问</li>
* </ul>
* <p>
* 常量的 key 格式为模块名.常量名 "ModuleA.a"以便唯一标识
*
* <p>
* 典型用法
* <pre>
* GlobalConstTable.register("ModuleA.a", 10); // 注册常量
* Object val = GlobalConstTable.get("ModuleA.a"); // 查询常量
* </pre>
*/
public final class GlobalConstTable {
/** 存储全局常量: “ModuleName.constName” → 常量值。线程安全。 */
private static final Map<String, Object> CONSTS = new ConcurrentHashMap<>();
/**
* 工具类构造器防止实例化
*/
private GlobalConstTable() { /* utility class */ }
/**
* 注册一个全局常量到表中只在首次注册时生效避免被覆盖
*
* @param qualifiedName 常量的全限定名 "ModuleA.a"
* @param value 常量的字面值 10字符串布尔等
* @throws IllegalArgumentException 名称为 null 或空串时抛出
*/
public static void register(String qualifiedName, Object value) {
if (qualifiedName == null || qualifiedName.isBlank()) {
throw new IllegalArgumentException("常量名不能为空");
}
CONSTS.putIfAbsent(qualifiedName, value);
}
/**
* 获取指定全局常量的值
*
* @param qualifiedName 常量的全限定名 "ModuleA.a"
* @return 查到的常量值如果未注册则返回 null
*/
public static Object get(String qualifiedName) {
return CONSTS.get(qualifiedName);
}
/**
* 返回全部已注册常量的不可变视图快照
* <p>注意只读不可修改</p>
*
* @return key=常量名value=常量值的不可变 Map
*/
public static Map<String, Object> all() {
return Map.copyOf(CONSTS);
}
}