diff --git a/src/main/java/org/jcnc/snow/pkg/lifecycle/LifecycleManager.java b/src/main/java/org/jcnc/snow/pkg/lifecycle/LifecycleManager.java
index 60f5ebc..6c1b5db 100644
--- a/src/main/java/org/jcnc/snow/pkg/lifecycle/LifecycleManager.java
+++ b/src/main/java/org/jcnc/snow/pkg/lifecycle/LifecycleManager.java
@@ -6,9 +6,10 @@ import java.util.EnumMap;
import java.util.Map;
/**
- * 管理不同生命周期阶段与其对应任务的工具类。
+ * 生命周期任务管理器。
+ * 用于管理不同生命周期阶段与其对应 {@link Task},并支持顺序执行所有已注册任务。
*
- * 可为每个 {@link LifecyclePhase} 注册对应的 {@link Task},并按阶段顺序执行所有任务。 + * 可为每个 {@link LifecyclePhase} 注册对应的 {@link Task},并在构建/部署流程中自动执行。 *
* *
@@ -20,9 +21,7 @@ import java.util.Map;
*/
public final class LifecycleManager {
- /**
- * 存储生命周期阶段与对应任务的映射关系。
- */
+ /** 生命周期阶段与对应任务的映射关系 */
private final Map tasks = new EnumMap<>(LifecyclePhase.class);
/**
@@ -45,11 +44,13 @@ public final class LifecycleManager {
/**
* 按 {@link LifecyclePhase} 声明顺序依次执行所有已注册任务。
- *
- * 未注册任务的阶段将被跳过。任务执行前会打印阶段名。
- *
+ *
+ * - 未注册任务的阶段会被自动跳过
+ * - 每个任务执行前会输出当前阶段名
+ * - 执行中遇到异常将立即抛出并终止后续执行
+ *
*
- * @throws Exception 若某个任务执行时抛出异常,将直接抛出并终止后续任务执行
+ * @throws Exception 若某个任务执行时抛出异常,将直接抛出
*/
public void executeAll() throws Exception {
for (LifecyclePhase phase : LifecyclePhase.values()) {
diff --git a/src/main/java/org/jcnc/snow/pkg/lifecycle/LifecyclePhase.java b/src/main/java/org/jcnc/snow/pkg/lifecycle/LifecyclePhase.java
index aaa464c..39d9759 100644
--- a/src/main/java/org/jcnc/snow/pkg/lifecycle/LifecyclePhase.java
+++ b/src/main/java/org/jcnc/snow/pkg/lifecycle/LifecyclePhase.java
@@ -1,7 +1,10 @@
package org.jcnc.snow.pkg.lifecycle;
/**
- * 定义了典型软件包生命周期的各个阶段。
+ * 定义典型软件包生命周期的各个阶段枚举。
+ *
+ * 用于区分构建、依赖、发布等不同阶段的任务调度与管理。
+ *
*/
public enum LifecyclePhase {
/** 初始化阶段 */
diff --git a/src/main/java/org/jcnc/snow/pkg/model/BuildConfiguration.java b/src/main/java/org/jcnc/snow/pkg/model/BuildConfiguration.java
index c0f0075..de4b64c 100644
--- a/src/main/java/org/jcnc/snow/pkg/model/BuildConfiguration.java
+++ b/src/main/java/org/jcnc/snow/pkg/model/BuildConfiguration.java
@@ -6,16 +6,16 @@ import java.util.HashMap;
/**
* 构建配置对象,封装构建过程中的所有选项。
*
- * 支持基于模板变量(形如{@code @{key}})的选项值替换。
+ * 支持模板变量(形如 @{key})的值自动替换。
*
*/
public final class BuildConfiguration {
- /** 存储配置项的键值对 */
+ /** 存储所有配置项 */
private final Map options;
/**
- * 私有构造函数,用于初始化配置项。
+ * 私有构造函数,仅供工厂方法调用。
*
* @param options 配置项键值对
*/
@@ -24,14 +24,15 @@ public final class BuildConfiguration {
}
/**
- * 基于原始配置项和变量属性创建配置对象。
- *
- * 会将原始配置中的所有值中的{@code @{key}}模板,替换为属性props中对应的值。
- *
+ * 基于原始配置项和属性集创建配置对象。
+ *
+ * - 会将所有值中的
@{key} 模板变量,替换为 props 中对应的值
+ * - 属性未匹配到时保留原模板
+ *
*
- * @param flat 原始的配置项,值中可包含模板变量(如@{name})
- * @param props 用于替换模板变量的属性集
- * @return 构建完成的配置对象
+ * @param flat 原始配置项,值中可包含模板变量
+ * @param props 变量替换用的属性集
+ * @return 处理后生成的配置对象
*/
public static BuildConfiguration fromFlatMap(Map flat, Map props) {
Map resolved = new HashMap<>();
@@ -46,11 +47,11 @@ public final class BuildConfiguration {
}
/**
- * 获取指定key对应的配置值。
+ * 获取指定配置项的值。
*
* @param key 配置项名称
- * @param def 默认值(若未找到key则返回此值)
- * @return 配置项对应值,若不存在则返回默认值
+ * @param def 默认值(未找到时返回)
+ * @return 配置项值,若不存在则返回默认值
*/
public String get(String key, String def) {
return options.getOrDefault(key, def);
diff --git a/src/main/java/org/jcnc/snow/pkg/model/Dependency.java b/src/main/java/org/jcnc/snow/pkg/model/Dependency.java
index 6385de1..481682e 100644
--- a/src/main/java/org/jcnc/snow/pkg/model/Dependency.java
+++ b/src/main/java/org/jcnc/snow/pkg/model/Dependency.java
@@ -5,18 +5,23 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
- * group:artifact:version 依赖坐标。
+ * group:artifact:version 依赖坐标对象。
*
- * 支持通过占位符和属性映射进行动态变量替换,可用于构建工具或依赖管理场景。
+ * 支持占位符和属性映射进行动态变量替换,适用于 Snow 语言包管理和源码依赖场景。
*
*
*
- * 示例:
+ * 示例用法:
* Dependency dep = Dependency.fromString(
* "core", "com.example:core:@{version}",
* Map.of("version", "1.2.3")
* );
*
+ *
+ * @param id 依赖唯一标识
+ * @param group 组织/分组名
+ * @param artifact 构件名
+ * @param version 版本号
*/
public record Dependency(
String id,
@@ -25,25 +30,23 @@ public record Dependency(
String version
) {
- /**
- * 用于匹配 group:artifact:version 格式的正则表达式。
- */
+ /** 匹配 group:artifact:version 格式的正则表达式。 */
private static final Pattern GAV = Pattern.compile("([^:]+):([^:]+):(.+)");
/**
* 根据字符串坐标和属性映射创建依赖对象。
*
- * 坐标中的占位符如 {@code @{key}} 会用 props 中对应的值替换。
+ * 坐标中的占位符(如 @{key})会用 props 中对应的值替换。
*
*
* @param id 依赖唯一标识
- * @param coordinate 依赖坐标字符串,格式为 group:artifact:version,支持变量占位符
- * @param props 占位符替换的属性映射
+ * @param coordinate 坐标字符串,格式为 group:artifact:version,支持占位符
+ * @param props 占位符替换属性映射
* @return 解析后的 Dependency 实例
- * @throws IllegalArgumentException 如果坐标格式非法
+ * @throws IllegalArgumentException 坐标格式非法时抛出
*/
public static Dependency fromString(String id, String coordinate, Map props) {
- // 替换 @{prop} 占位符
+ // 替换占位符
String resolved = coordinate;
for (Map.Entry p : props.entrySet()) {
resolved = resolved.replace("@{" + p.getKey() + "}", p.getValue());
@@ -57,23 +60,23 @@ public record Dependency(
}
/**
- * 生成依赖对应的标准仓库 jar 路径。
+ * 生成依赖对应的源码文件路径。
*
- * 路径格式通常为:groupId/artifactId/version/artifactId-version.jar
- * 例如:com/example/core/1.2.3/core-1.2.3.jar
+ * 路径格式:groupId/artifactId/version/artifactId.snow
+ * 例如:com/example/core/1.2.3/core.snow
*
*
- * @return 仓库 jar 文件的相对路径
+ * @return 仓库源码文件的相对路径
*/
public String toPath() {
String groupPath = group.replace('.', '/');
- return groupPath + "/" + artifact + "/" + version + "/" + artifact + "-" + version + ".jar";
+ return groupPath + "/" + artifact + "/" + version + "/" + artifact + ".snow";
}
/**
* 返回该依赖的 group:artifact:version 字符串表示。
*
- * @return Maven 坐标字符串
+ * @return 坐标字符串
*/
@Override
public String toString() {
diff --git a/src/main/java/org/jcnc/snow/pkg/model/Project.java b/src/main/java/org/jcnc/snow/pkg/model/Project.java
index 2b09cdb..efedc97 100644
--- a/src/main/java/org/jcnc/snow/pkg/model/Project.java
+++ b/src/main/java/org/jcnc/snow/pkg/model/Project.java
@@ -8,42 +8,41 @@ import java.util.Map;
/**
* 表示一个软件包/模块的项目信息,包括元数据、属性、仓库、依赖和构建配置等。
*
- * 本类为不可变对象,仅提供getter,无setter。
- * 支持通过 {@link #fromFlatMap(Map)} 静态工厂方法从扁平Map快速创建。
+ * 本类为不可变对象,仅提供 getter 方法,无 setter。
+ * 支持通过 {@link #fromFlatMap(Map)} 静态工厂方法,从扁平 Map 快速创建实例。
*
*
*
- * Map<String,String> map = ...;
+ * Map<String, String> map = ...;
* Project project = Project.fromFlatMap(map);
*
*/
public final class Project {
- /** 组织/分组名(如com.example) */
+ /** 组织/分组名(如 com.example) */
private final String group;
- /** 构件/模块名(如app-core) */
+ /** 构件/模块名(如 app-core) */
private final String artifact;
/** 项目展示名称 */
private final String name;
- /** 版本号(如1.0.0) */
+ /** 版本号(如 1.0.0) */
private final String version;
/** 项目描述 */
private final String description;
/** 许可证标识 */
private final String license;
- /** 项目主页URL */
+ /** 项目主页 URL */
private final String homepage;
/** 额外属性(不影响主字段,可用于模板/占位符) */
private final Map properties;
- /** 仓库列表(仓库ID -> 仓库对象) */
+ /** 仓库列表(仓库 ID -> 仓库对象) */
private final Map repositories;
/** 依赖列表 */
private final List dependencies;
/** 构建配置 */
private final BuildConfiguration build;
-
/**
* 构造函数(私有),请使用 {@link #fromFlatMap(Map)} 创建实例。
*/
@@ -74,7 +73,7 @@ public final class Project {
}
/**
- * 通过扁平Map创建 Project 实例。约定key格式如下:
+ * 通过扁平 Map 创建 Project 实例。key 格式约定如下:
*
* - project.* —— 项目元数据
* - properties.* —— 额外属性
@@ -83,12 +82,11 @@ public final class Project {
* - build.* —— 构建配置
*
*
- * @param map 扁平的配置map
+ * @param map 扁平的配置 map
* @return Project 实例
*/
public static Project fromFlatMap(Map map) {
-
- // 1. simple project metadata
+ // 1. 基本元数据
String group = map.getOrDefault("project.group", "unknown");
String artifact = map.getOrDefault("project.artifact", "unknown");
String name = map.getOrDefault("project.name", artifact);
@@ -123,14 +121,13 @@ public final class Project {
}
});
- // 5. build.* simply hand the subtree map
+ // 5. build.*
Map buildMap = new LinkedHashMap<>();
map.forEach((k, v) -> {
if (k.startsWith("build.")) {
buildMap.put(k.substring("build.".length()), v);
}
});
-
BuildConfiguration buildCfg = BuildConfiguration.fromFlatMap(buildMap, props);
return new Project(group, artifact, name, version, description, license, homepage, props, repos, deps, buildCfg);
@@ -161,12 +158,12 @@ public final class Project {
return description;
}
- /** @return 许可证 */
+ /** @return 许可证标识 */
public String getLicense() {
return license;
}
- /** @return 项目主页URL */
+ /** @return 项目主页 URL */
public String getHomepage() {
return homepage;
}
diff --git a/src/main/java/org/jcnc/snow/pkg/model/Repository.java b/src/main/java/org/jcnc/snow/pkg/model/Repository.java
index 3e839f9..73d97b2 100644
--- a/src/main/java/org/jcnc/snow/pkg/model/Repository.java
+++ b/src/main/java/org/jcnc/snow/pkg/model/Repository.java
@@ -3,16 +3,16 @@ package org.jcnc.snow.pkg.model;
/**
* 表示一个远程仓库的基本信息,通常用于依赖解析和发布。
*
- * 每个仓库由唯一的ID和对应的URL确定。
+ * 每个仓库由唯一的 ID 和对应的 URL 标识。
*
*
*
- * 示例:
+ * 示例用法:
* Repository repo = new Repository("central", "https://");
*
*
* @param id 仓库唯一标识
- * @param url 仓库地址(一般为HTTP(S)链接)
+ * @param url 仓库地址(通常为 HTTP(S) 链接)
*/
public record Repository(String id, String url) {
}
diff --git a/src/main/java/org/jcnc/snow/pkg/tasks/CleanTask.java b/src/main/java/org/jcnc/snow/pkg/tasks/CleanTask.java
index 0b5c1c5..80700d6 100644
--- a/src/main/java/org/jcnc/snow/pkg/tasks/CleanTask.java
+++ b/src/main/java/org/jcnc/snow/pkg/tasks/CleanTask.java
@@ -6,17 +6,27 @@ import java.nio.file.Path;
import java.util.Comparator;
/**
- * 清理构建输出目录(如 build 和 dist)的任务实现。
+ * 用于清理构建输出目录(如 {@code build} 和 {@code dist})的任务实现类。
*
- * 实现 {@link Task} 接口,通常用于构建流程中的清理阶段。
+ * 实现 {@link Task} 接口,常用于自动化构建流程的清理阶段,负责递归删除指定的构建产物目录。
*
+ *
+ * 本类为无状态实现,线程安全。
+ *
+ *
+ * 示例用法:
+ * {@code
+ * Task clean = new CleanTask();
+ * clean.run();
+ * }
*/
public final class CleanTask implements Task {
/**
- * 执行清理任务,删除 "build" 和 "dist" 目录及其所有内容。
+ * 执行清理任务,递归删除当前目录下的 {@code build} 和 {@code dist} 目录及其所有内容。
+ * 如果目标目录不存在,则跳过不处理。
*
- * @throws IOException 删除目录过程中出现 IO 错误时抛出
+ * @throws IOException 删除目录或文件过程中发生 IO 错误时抛出
*/
@Override
public void run() throws IOException {
@@ -27,10 +37,15 @@ public final class CleanTask implements Task {
/**
* 递归删除指定目录及其所有子文件和子目录。
- * 使用 try-with-resources 自动关闭文件流,避免资源泄漏。
+ *
+ * 若目录不存在,则直接返回。
+ *
+ *
+ * 内部使用 try-with-resources 保证文件流自动关闭,避免资源泄漏。
+ *
*
* @param dir 需要删除的目录路径
- * @throws IOException 删除过程中出现 IO 错误时抛出
+ * @throws IOException 删除目录或文件过程中发生 IO 错误时抛出
*/
private void deleteDir(Path dir) throws IOException {
if (Files.notExists(dir)) return;
diff --git a/src/main/java/org/jcnc/snow/pkg/tasks/CompileTask.java b/src/main/java/org/jcnc/snow/pkg/tasks/CompileTask.java
index ae39157..04519d7 100644
--- a/src/main/java/org/jcnc/snow/pkg/tasks/CompileTask.java
+++ b/src/main/java/org/jcnc/snow/pkg/tasks/CompileTask.java
@@ -25,17 +25,16 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
-
/**
- * CLI 命令:将 .snow 源文件编译为 VM 字节码(.water 文件)。
+ * CLI 任务:编译 .snow 源文件为 VM 字节码(.water 文件)。
*
- * 支持递归目录、多文件编译,可选编译后立即运行。
- * 命令参数支持 run、-o、-d 等。
+ * 支持单文件、多文件和目录递归编译,并可在编译后立即运行虚拟机。
+ * 命令行参数支持 run、-o、-d 及直接指定源文件。
*
*
*
* 用法示例:
- * $ snow compile [run] [-o <name>] [-d <srcDir>] [file1.snow file2.snow …]
+ * $ snow compile [run] [-o <name>] [-d <srcDir>] [file1.snow file2.snow ...]
*
*/
public final class CompileTask implements Task {
@@ -44,26 +43,49 @@ public final class CompileTask implements Task {
/** 原始命令行参数 */
private final String[] args;
+ /**
+ * 创建一个编译任务。
+ *
+ * @param project 项目信息对象
+ * @param args 命令行参数数组
+ */
public CompileTask(Project project, String[] args) {
this.project = project;
this.args = args;
}
+ /**
+ * 创建一个不带参数的编译任务。
+ *
+ * @param project 项目信息对象
+ */
public CompileTask(Project project) {
this(project, new String[0]);
}
+ /**
+ * 执行编译任务。该方法会解析参数并调用 {@link #execute(String[])} 进行实际编译流程。
+ *
+ * @throws Exception 执行过程中出现任意异常时抛出
+ */
@Override
public void run() throws Exception {
- // 将任务委托给原始 execute 实现
execute(this.args);
}
- /* --------------------------------------------------------------------- */
- /* 执行 compile 子命令 */
- /* --------------------------------------------------------------------- */
+ /**
+ * 编译 .snow 源文件为 VM 字节码,并可选择立即运行。
+ *
+ * - 支持参数 run(编译后运行)、-o(输出文件名)、-d(递归目录)、直接指定多个源文件。
+ * - 输出源代码、AST、IR、最终 VM code,并写出 .water 文件。
+ *
+ *
+ * @param args 命令行参数数组
+ * @return 0 表示成功,非 0 表示失败
+ * @throws Exception 编译或写入过程中出现异常时抛出
+ */
public int execute(String[] args) throws Exception {
- /* ---------------- 解析命令行参数 ---------------- */
+ // ---------------- 解析命令行参数 ----------------
boolean runAfterCompile = false;
String outputName = null;
Path dir = null;
@@ -101,7 +123,7 @@ public final class CompileTask implements Task {
}
}
- /* --------- 如果指定了目录则递归收集所有 *.snow --------- */
+ // --------- 如果指定了目录则递归收集所有 *.snow ---------
if (dir != null) {
if (!Files.isDirectory(dir)) {
System.err.println("Not a directory: " + dir);
@@ -119,19 +141,17 @@ public final class CompileTask implements Task {
return 1;
}
- /* 多文件但未指定 -o 且非目录编译 —— 提示必须指定输出名 */
+ // 多文件但未指定 -o 且非目录编译 —— 提示必须指定输出名
if (sources.size() > 1 && outputName == null && dir == null) {
System.err.println("Please specify output name using -o ");
return 1;
}
- /* ----------------------------------------------------------------- */
- /* 1. 词法 + 语法分析;同时打印源代码 */
- /* ----------------------------------------------------------------- */
+ // ---------------- 1. 词法/语法分析,并打印源代码 ----------------
List allAst = new ArrayList<>();
System.out.println("## 编译器输出");
- System.out.println("### Snow 源代码"); // ========== 新增:二级标题 ==========
+ System.out.println("### Snow 源代码");
for (Path p : sources) {
if (!Files.exists(p)) {
@@ -141,38 +161,31 @@ public final class CompileTask implements Task {
String code = Files.readString(p, StandardCharsets.UTF_8);
- // ------- 打印每个文件的源码 -------
+ // 打印源码
System.out.println("#### " + p.getFileName());
System.out.println(code);
- // --------------------------------------------------------
- /* 词法 + 语法 */
+ // 词法、语法分析
LexerEngine lexer = new LexerEngine(code, p.toString());
ParserContext ctx = new ParserContext(lexer.getAllTokens(), p.toString());
allAst.addAll(new ParserEngine(ctx).parse());
}
- /* ----------------------------------------------------------------- */
- /* 2. 语义分析 */
- /* ----------------------------------------------------------------- */
+ // ---------------- 2. 语义分析 ----------------
SemanticAnalyzerRunner.runSemanticAnalysis(allAst, false);
- /* ----------------------------------------------------------------- */
- /* 3. AST → IR,并把 main 函数调到首位 */
- /* ----------------------------------------------------------------- */
+ // ---------------- 3. AST → IR,并将 main 函数移动至首位 ----------------
IRProgram program = new IRProgramBuilder().buildProgram(allAst);
program = reorderForEntry(program);
- /* ---------------- 打印 AST / IR ---------------- */
+ // 打印 AST 和 IR
System.out.println("### AST");
ASTPrinter.printJson(allAst);
System.out.println("### IR");
System.out.println(program);
- /* ----------------------------------------------------------------- */
- /* 4. IR → VM 指令 */
- /* ----------------------------------------------------------------- */
+ // ---------------- 4. IR → VM 指令 ----------------
VMProgramBuilder builder = new VMProgramBuilder();
List> generators =
InstructionGeneratorProvider.defaultGenerators();
@@ -187,16 +200,12 @@ public final class CompileTask implements Task {
System.out.println("### VM code");
finalCode.forEach(System.out::println);
- /* ----------------------------------------------------------------- */
- /* 5. 写出 .water 文件 */
- /* ----------------------------------------------------------------- */
+ // ---------------- 5. 写出 .water 文件 ----------------
Path outputFile = deriveOutputPath(sources, outputName, dir);
Files.write(outputFile, finalCode, StandardCharsets.UTF_8);
System.out.println("Written to " + outputFile.toAbsolutePath());
- /* ----------------------------------------------------------------- */
- /* 6. 可选:立即运行 VM */
- /* ----------------------------------------------------------------- */
+ // ---------------- 6. 可选:立即运行 VM ----------------
if (runAfterCompile) {
System.out.println("\n=== Launching VM ===");
VMLauncher.main(new String[]{outputFile.toString()});
@@ -205,18 +214,19 @@ public final class CompileTask implements Task {
return 0;
}
- /* --------------------------------------------------------------------- */
- /* 辅助方法 */
- /* --------------------------------------------------------------------- */
-
/**
- * 根据输入情况推断 .water 输出文件名:
+ * 推断 .water 输出文件名。
*
- * - 若指定 -o,则直接使用
- * - 目录编译:取目录名
- * - 单文件编译:取文件名去掉 .snow
- * - 其他情况兜底为 "program"
+ * - 如果指定 -o,直接使用该名称。
+ * - 目录编译时,取目录名。
+ * - 单文件编译时,取文件名去掉 .snow 后缀。
+ * - 否则默认 "program"。
*
+ *
+ * @param sources 源文件路径列表
+ * @param outName 输出文件名(如有指定,否则为 null)
+ * @param dir 源码目录(如有指定,否则为 null)
+ * @return 推断出的输出文件路径(.water 文件)
*/
private static Path deriveOutputPath(List sources, String outName, Path dir) {
String base;
@@ -234,7 +244,10 @@ public final class CompileTask implements Task {
}
/**
- * 把 main 函数交换到程序函数列表首位,确保 PC=0 即入口。
+ * 将 main 函数调整至函数列表首位,确保程序入口为 PC=0。
+ *
+ * @param in 原始 IRProgram
+ * @return 调整入口后的 IRProgram
*/
private static IRProgram reorderForEntry(IRProgram in) {
List ordered = new ArrayList<>(in.functions());
diff --git a/src/main/java/org/jcnc/snow/pkg/tasks/GenerateTask.java b/src/main/java/org/jcnc/snow/pkg/tasks/GenerateTask.java
index 589dc43..b7c50e3 100644
--- a/src/main/java/org/jcnc/snow/pkg/tasks/GenerateTask.java
+++ b/src/main/java/org/jcnc/snow/pkg/tasks/GenerateTask.java
@@ -10,9 +10,10 @@ import java.nio.file.Paths;
import java.util.List;
/**
- * 任务:依据 {@link Project} 元数据创建标准项目目录。
+ * 项目脚手架生成任务。
+ * 根据 {@link Project} 元数据自动创建标准项目目录结构,并生成示例入口文件 src/main.snow。
*
- * 生成内容:
+ * 生成内容包括:
*
* - src/ —— 源码目录
* - test/ —— 测试源码目录
@@ -20,27 +21,44 @@ import java.util.List;
* - dist/ —— 打包输出目录
* - src/main.snow —— “Hello, Snow!” 示例入口
*
+ * 如目录或入口文件已存在,则自动跳过,不会覆盖。
+ *
*/
public final class GenerateTask implements Task {
+ /** 项目信息元数据 */
private final Project project;
+ /**
+ * 创建项目生成任务。
+ *
+ * @param project 项目信息元数据对象
+ */
public GenerateTask(Project project) {
this.project = project;
}
+ /**
+ * 执行脚手架生成流程,创建标准目录和入口示例文件。
+ *
+ * - 若相关目录不存在则创建
+ * - 若
src/main.snow 不存在则写入模板
+ * - 生成过程输出进度信息
+ *
+ *
+ * @throws IOException 创建目录或写入文件时发生 IO 错误时抛出
+ */
@Override
public void run() throws IOException {
Path root = Paths.get(".").toAbsolutePath();
- /* -------- 创建目录 -------- */
+ // 创建标准目录
List dirs = List.of(
root.resolve("src"),
root.resolve("test"),
root.resolve("build"),
root.resolve("dist")
);
-
for (Path dir : dirs) {
if (Files.notExists(dir)) {
Files.createDirectories(dir);
@@ -48,7 +66,7 @@ public final class GenerateTask implements Task {
}
}
- /* -------- 创建示例入口文件 -------- */
+ // 创建 src/main.snow 示例入口文件
Path mainSnow = root.resolve("src").resolve("main.snow");
if (Files.notExists(mainSnow)) {
Files.writeString(mainSnow, SnowExampleTemplate.getMainModule());
diff --git a/src/main/java/org/jcnc/snow/pkg/tasks/PackageTask.java b/src/main/java/org/jcnc/snow/pkg/tasks/PackageTask.java
index 7524f73..a04dcf0 100644
--- a/src/main/java/org/jcnc/snow/pkg/tasks/PackageTask.java
+++ b/src/main/java/org/jcnc/snow/pkg/tasks/PackageTask.java
@@ -9,29 +9,38 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
- * 项目打包任务,将编译输出目录(如 build/classes)打包为 .ice 文件。
+ * 项目打包任务,将编译输出目录(如 build/classes)打包为 .ice 文件。
*
- * 实现 {@link Task} 接口,通常用于构建流程中的打包阶段。
+ * 实现 {@link Task} 接口,通常用于构建流程的打包阶段。
+ * 只会打包 build/classes 目录下所有文件,不含其他目录。
+ *
+ *
+ * 输出文件位于 dist 目录,命名为 artifact-version.ice。
*
*/
public final class PackageTask implements Task {
- /** 目标项目 */
+ /** 目标项目元数据 */
private final Project project;
/**
- * 创建 PackageTask 实例。
+ * 创建打包任务。
*
- * @param project 目标项目
+ * @param project 目标项目元数据
*/
public PackageTask(Project project) {
this.project = project;
}
/**
- * 执行打包任务,将编译输出目录压缩为 artifact-version.ice 文件。
+ * 执行打包任务,将 build/classes 目录下所有文件压缩为 dist/artifact-version.ice。
+ *
+ * - 若输出目录 dist 不存在会自动创建
+ * - 只打包 build/classes 下所有普通文件(保持相对目录结构)
+ * - 如无 build/classes 则不会生成包
+ *
*
- * @throws Exception 打包过程中出现 IO 或其他异常时抛出
+ * @throws Exception 打包过程中发生 IO 或其他异常时抛出
*/
@Override
public void run() throws Exception {
@@ -43,15 +52,15 @@ public final class PackageTask implements Task {
Path packageFile = distDir.resolve(fileName);
try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(packageFile))) {
- // 仅将编译输出目录打包
+ // 仅将 build/classes 目录打包
Path classesDir = Path.of("build/classes");
if (Files.exists(classesDir)) {
- // 使用 try-with-resources 正确关闭 Stream
+ // 遍历所有文件并写入 zip
try (Stream stream = Files.walk(classesDir)) {
stream.filter(Files::isRegularFile)
.forEach(p -> {
try {
- // 将文件以相对路径加入压缩包
+ // 以 classesDir 为根的相对路径存入 zip
zos.putNextEntry(new ZipEntry(classesDir.relativize(p).toString()));
Files.copy(p, zos);
zos.closeEntry();
diff --git a/src/main/java/org/jcnc/snow/pkg/tasks/PublishTask.java b/src/main/java/org/jcnc/snow/pkg/tasks/PublishTask.java
index d67b0e1..310b8fa 100644
--- a/src/main/java/org/jcnc/snow/pkg/tasks/PublishTask.java
+++ b/src/main/java/org/jcnc/snow/pkg/tasks/PublishTask.java
@@ -5,25 +5,26 @@ import org.jcnc.snow.pkg.model.Project;
/**
* 发布项目构件到远程仓库的任务实现。
*
- * 实现 {@link Task} 接口,通常用于构建流程中的发布阶段。目前仅为演示,尚未实现实际上传。
+ * 实现 {@link Task} 接口,通常用于构建流程中的发布阶段。
+ * 当前仅输出发布提示,尚未实现实际上传功能。
*
*/
public final class PublishTask implements Task {
- /** 目标项目 */
+ /** 目标项目元数据 */
private final Project project;
/**
- * 创建 PublishTask 实例。
+ * 创建发布任务。
*
- * @param project 目标项目
+ * @param project 目标项目元数据
*/
public PublishTask(Project project) {
this.project = project;
}
/**
- * 执行发布任务。当前仅打印发布提示,未实现实际上传逻辑。
+ * 执行发布任务。目前仅打印发布提示信息,未实现实际上传逻辑。
*
* @throws Exception 预留,未来实现上传逻辑时可能抛出异常
*/
diff --git a/src/main/java/org/jcnc/snow/pkg/tasks/RunTask.java b/src/main/java/org/jcnc/snow/pkg/tasks/RunTask.java
index 1eb871a..ce83966 100644
--- a/src/main/java/org/jcnc/snow/pkg/tasks/RunTask.java
+++ b/src/main/java/org/jcnc/snow/pkg/tasks/RunTask.java
@@ -1,4 +1,3 @@
-
package org.jcnc.snow.pkg.tasks;
import org.jcnc.snow.vm.VMLauncher;
@@ -6,26 +5,32 @@ import org.jcnc.snow.vm.VMLauncher;
/**
* 任务:执行已编译的 VM 字节码文件(.water)。
*
- * 作为 CLI、IDE 插件或其他宿主环境启动虚拟机的统一入口,
- * 将调用 {@link VMLauncher#main(String[])} 执行。
+ * 作为 CLI、IDE 插件或其他宿主环境启动虚拟机的统一入口,
+ * 通过调用 {@link VMLauncher#main(String[])} 启动 VM 并执行指定程序。
*
*/
public final class RunTask implements Task {
- /** 传递给 VM 的完整参数列表(第一个应为 .water 文件路径) */
+ /**
+ * 传递给虚拟机的完整参数列表(第一个应为 .water 文件路径)
+ */
private final String[] args;
/**
* 创建运行任务。
*
- * @param args VM 参数数组(第一个为程序路径,其后为可选参数)
+ * @param args VM 参数数组(第一个为 .water 程序路径,其后为可选参数)
*/
public RunTask(String... args) {
this.args = args;
}
/**
- * 执行运行任务,内部委托 {@link VMLauncher#main(String[])}。
+ * 执行运行任务。内部委托 {@link VMLauncher#main(String[])} 启动 VM。
+ *
+ * - 如果参数为空则抛出 {@link IllegalArgumentException}
+ * - 异常由虚拟机本身抛出,直接透出
+ *
*
* @throws Exception 虚拟机启动或运行期间抛出的异常
*/
diff --git a/src/main/java/org/jcnc/snow/pkg/tasks/Task.java b/src/main/java/org/jcnc/snow/pkg/tasks/Task.java
index 755adc2..071fdbc 100644
--- a/src/main/java/org/jcnc/snow/pkg/tasks/Task.java
+++ b/src/main/java/org/jcnc/snow/pkg/tasks/Task.java
@@ -1,9 +1,9 @@
package org.jcnc.snow.pkg.tasks;
/**
- * 构建任务的通用接口,所有具体任务都应实现该接口。
+ * 构建任务的通用接口,所有具体任务(如编译、打包、清理等)都应实现该接口。
*
- * 用于统一生命周期内的任务行为,例如编译、打包、清理等。
+ * 用于统一不同阶段任务的生命周期与执行行为。
*
*/
public interface Task {
@@ -11,7 +11,7 @@ public interface Task {
/**
* 执行具体任务的入口方法。
*
- * @throws Exception 任务执行过程中出现的异常
+ * @throws Exception 任务执行过程中出现的任意异常
*/
void run() throws Exception;
}
diff --git a/src/main/java/org/jcnc/snow/pkg/utils/SnowExampleTemplate.java b/src/main/java/org/jcnc/snow/pkg/utils/SnowExampleTemplate.java
index e55fd4d..722fd91 100644
--- a/src/main/java/org/jcnc/snow/pkg/utils/SnowExampleTemplate.java
+++ b/src/main/java/org/jcnc/snow/pkg/utils/SnowExampleTemplate.java
@@ -1,52 +1,58 @@
package org.jcnc.snow.pkg.utils;
/**
- * 提供示例 .snow 模块代码模板。
+ * 示例模块模板工具类,提供 main.snow 的标准示例代码字符串。
+ *
+ * 用于项目脚手架生成或帮助用户快速上手 .snow 语言。
+ *
*/
public final class SnowExampleTemplate {
+ /**
+ * 工具类构造方法,禁止实例化。
+ */
private SnowExampleTemplate() {
// 工具类不允许实例化
}
/**
- * 返回 main.snow 示例模块内容。
+ * 获取 main.snow 示例模块的内容字符串。
*
- * @return 示例模块代码字符串
+ * @return main.snow 示例模块的完整代码
*/
public static String getMainModule() {
return """
- module: Math
- function: main
- parameter:
- return_type: int
- body:
- Math.factorial(6)
- return 0
- end body
- end function
-
- function: factorial
- parameter:
- declare n:int
- return_type: int
- body:
- declare num1:int = 1
- loop:
- initializer:
- declare counter:int = 1
- condition:
- counter <= n
- update:
- counter = counter + 1
- body:
- num1 = num1 * counter
- end body
- end loop
- return num1
- end body
- end function
- end module
- """;
+ module: Math
+ function: main
+ parameter:
+ return_type: int
+ body:
+ Math.factorial(6)
+ return 0
+ end body
+ end function
+
+ function: factorial
+ parameter:
+ declare n:int
+ return_type: int
+ body:
+ declare num1:int = 1
+ loop:
+ initializer:
+ declare counter:int = 1
+ condition:
+ counter <= n
+ update:
+ counter = counter + 1
+ body:
+ num1 = num1 * counter
+ end body
+ end loop
+ return num1
+ end body
+ end function
+ end module
+ """;
}
}