ffi 2.1: parser accepts Foo :: #jni_class("path") { } opaque form
New `hash_jni_class` token + lexer entry, `JniClassDecl` AST node
(alias + java path; body deferred to 2.2+), `parseJniClassDecl`
consuming `("...") { }` and rejecting non-empty bodies for now.
Sema registers the alias as a type_alias symbol; LSP classifies
the directive as a keyword. The 2.0 xfail snapshot flips to
`parse-only ok`, exit 0.
120/120 examples green; zig test clean.
This commit is contained in:
@@ -209,6 +209,11 @@ pub const Parser = struct {
|
||||
return self.parseProtocolDecl(name, start_pos);
|
||||
}
|
||||
|
||||
// JNI class binding: name :: #jni_class("java/path/Foo") { ...body... }
|
||||
if (self.current.tag == .hash_jni_class) {
|
||||
return self.parseJniClassDecl(name, start_pos);
|
||||
}
|
||||
|
||||
// C-style union declaration
|
||||
if (self.current.tag == .kw_union) {
|
||||
return self.parseUnionDecl(name, start_pos);
|
||||
@@ -1022,6 +1027,32 @@ pub const Parser = struct {
|
||||
} });
|
||||
}
|
||||
|
||||
fn parseJniClassDecl(self: *Parser, name: []const u8, start_pos: u32) anyerror!*Node {
|
||||
self.advance(); // skip '#jni_class'
|
||||
|
||||
try self.expect(.l_paren);
|
||||
if (self.current.tag != .string_literal) {
|
||||
return self.fail("expected string literal Java class path after '#jni_class('");
|
||||
}
|
||||
const raw = self.tokenSlice(self.current);
|
||||
const java_path = raw[1 .. raw.len - 1];
|
||||
self.advance();
|
||||
try self.expect(.r_paren);
|
||||
|
||||
try self.expect(.l_brace);
|
||||
// Body items (methods, fields, #extends, #implements, ...) land in steps
|
||||
// 2.2 onward. Step 2.1 accepts only the empty body (opaque forward decl).
|
||||
if (self.current.tag != .r_brace) {
|
||||
return self.fail("non-empty `#jni_class` body not yet supported (Phase 2.1 accepts only the empty/opaque form)");
|
||||
}
|
||||
try self.expect(.r_brace);
|
||||
|
||||
return try self.createNode(start_pos, .{ .jni_class_decl = .{
|
||||
.name = name,
|
||||
.java_path = java_path,
|
||||
} });
|
||||
}
|
||||
|
||||
fn parseImplBlock(self: *Parser, start_pos: u32) anyerror!*Node {
|
||||
self.advance(); // skip 'impl'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user