Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ NekoJS 生成的类型声明(`.neko_probe/`)已经把 `ServerEvents`、`Bloc
* 拼写错误(如把 `event.recipes` 写成 `event.rec`)会立即被标红,无需 `import` 任何类型 —— 全局事件对象的签名会自动推断 `event` 的类型。
* 运行时(游戏内)同样会拦截这类错误:事件回调里访问不存在的成员、或使用未定义的变量,会被记录到错误面板,用 `/nekojs view_all_errors` 查看。

> 注意:NekoJS 内置的是 erasable TypeScript 前端(类型标注会在运行前擦除),暂不支持 `enum` / `namespace` / `module` 等 TS 语法;这类语法会在加载时报错,请在脚本中避免
> 注意:NekoJS 内置的 TypeScript 前端支持「可擦除」语法(类型标注、`type`/`interface`、泛型、`as`/`satisfies`、`import type`/`export type`、`declare`、参数属性 `constructor(public x)`、`enum`/`const enum`、`namespace`/`module`、类成员修饰符、`?.`/`!`、函数重载签名等)——这些会在运行前擦除或降级为运行时 IIFE/赋值。**不支持** 装饰器(`@Decorator`)—— NekoJS 是脚本引擎非 TS 框架,遇到装饰器会清晰报错,请改用普通函数包装

---

Expand All @@ -169,7 +169,7 @@ NekoJS 的脚本运行在受限 GraalJS 环境中,但它不是“不可信代

### 语言前端

NekoJS 核心主打轻量与稳定,内置 `.ts` 的 erasable TypeScript 支持:类型标注、`type` / `interface`、`import type` / `export type` 等会在 Java 前端中擦除,之后继续走 NekoJS 自有 ESM/CJS pipeline。NekoJS 也内置轻量 `.jsx/.tsx` classic runtime lowering,会把 JSX 元素降到 `globalThis.__nekoJsxFactory(...)` / `globalThis.__nekoJsxFragment(...)`。
NekoJS 核心主打轻量与稳定,内置 `.ts` 的 TypeScript 支持:类型标注、`type` / `interface`、`import type` / `export type`、泛型(含泛型箭头 `<T>(x: T) => T`)、`as` / `satisfies`、内联 `import { x, type T }`、参数属性、`enum` / `namespace`、类成员修饰符等会在 Java 前端中擦除或降级,之后继续走 NekoJS 自有 ESM/CJS pipeline。NekoJS 也内置 `.jsx/.tsx` lowering:默认 classic runtime(`globalThis.__nekoJsxFactory(...)` / `globalThis.__nekoJsxFragment(...)`),支持 HTML 实体解码、命名空间标签(`<svg:rect/>`)、泛型组件(`<Foo<T>/>`);在 `nekojs/config/engine.toml` 里设 `jsxAutomaticRuntime = true` 可切换到标准 automatic runtime:从 `nekojs/jsx-runtime` 导入 `jsx`、`jsxs` 和 `Fragment`,子节点放在 `props.children`。在 `nekojs/` 工作区内,请将 runtime 模块放在裸模块路径 `node_modules/nekojs/jsx-runtime.js`。

后续方向是继续增强 NekoJS 本体语言前端,而不是依赖外部 NekoSWC 模组来承担高级 TS/TSX/JSX 转换。脚本语言插件 registry 仍保留给第三方语言扩展使用,但 NekoJS 自身的 TypeScript、JSX、sourcemap chain 和 diagnostics 会优先在本体实现。

Expand Down
8 changes: 8 additions & 0 deletions common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ java.toolchain.languageVersion = JavaLanguageVersion.of(21)
dependencies {
testImplementation platform('org.junit:junit-bom:6.0.0')
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'com.google.code.gson:gson:2.11.0'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
// 25.1.3.6; exported so every platform receives the same remapper SPI.
api("curse.maven:graal-1504336:8456810")
Expand All @@ -50,6 +51,13 @@ dependencies {
compileOnly 'org.projectlombok:lombok:1.18.44'
annotationProcessor 'org.projectlombok:lombok:1.18.44'

// 测试运行时 stub:compiler/probe 链上的类引用 gson/log4j 等,游戏内由 MC/NeoForge 提供,
// 但 common 独立测试时需要在 testRuntimeOnly 提供这些实现,否则 NoClassDefFoundError。
testRuntimeOnly 'org.slf4j:slf4j-api:2.0.13'
testRuntimeOnly 'org.apache.logging.log4j:log4j-api:2.20.0'
testRuntimeOnly 'org.apache.logging.log4j:log4j-core:2.20.0'
testRuntimeOnly 'com.ibm.icu:icu4j:77.1'

}

test {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,16 @@
public final class NekoCompilationPipeline {

public NekoCompileOutput compile(Path file, String source, String extension, NekoLanguagePlugin language) throws Exception {
return compile(file, source, extension, language, false);
}

public NekoCompileOutput compile(Path file, String source, String extension, NekoLanguagePlugin language,
boolean jsxAutomaticRuntime) throws Exception {
NekoSourceFile sourceFile = new NekoSourceFile(file, source, extension);
NekoTokenStream tokens = language.lexer().tokenize(sourceFile);
NekoLexer lexer = language.lexer();
NekoTokenStream tokens = lexer instanceof NekoJsxLexer jsxLexer
? jsxLexer.tokenize(sourceFile, jsxAutomaticRuntime)
: lexer.tokenize(sourceFile);
NekoSourceAst ast = language.parser().parse(tokens);
NekoIRProgram program = language.lowering().lower(ast);
NekoEsmModuleAst esmAst = ast instanceof NekoEsmSourceAst esm ? esm.esmAst() : null;
Expand Down
Loading
Loading