ffi 2.3 green: static body items in #jni_class

`JniMethodDecl` gains `is_static: bool = false`. parseJniClassDecl's
body loop now recognises a `static` identifier prefix (context-sensitive
— `static` stays a plain identifier elsewhere) and consumes it before
the method name, setting `is_static` on the resulting decl. Dispatch
to `GetStaticMethodID` / `CallStatic*Method` arrives in Phase 2.12.

122/122 examples green.
This commit is contained in:
agra
2026-05-20 09:35:09 +03:00
parent 082ef430a3
commit ecce8cdca3
4 changed files with 17 additions and 4 deletions

View File

@@ -538,6 +538,7 @@ pub const JniMethodDecl = struct {
params: []const *Node, // type_expr nodes — first is `*Self` for instance methods
param_names: []const []const u8,
return_type: ?*Node, // null = void
is_static: bool = false, // true for `static name :: ...`
};
pub const JniClassDecl = struct {

View File

@@ -1043,8 +1043,19 @@ pub const Parser = struct {
var methods = std.ArrayList(ast.JniMethodDecl).empty;
while (self.current.tag != .r_brace and self.current.tag != .eof) {
// Instance method: name :: (self: *Self, args...) -> Ret;
// (`static`, fields, #extends, #implements land in later steps.)
// Optional `static` prefix → class method (no implicit `self`).
// Context-sensitive — `static` is a plain identifier elsewhere.
var is_static = false;
if (self.current.tag == .identifier and
std.mem.eql(u8, self.tokenSlice(self.current), "static") and
self.peekNext() == .identifier)
{
is_static = true;
self.advance(); // consume `static`
}
// Method: name :: (args...) -> Ret;
// (Fields, #extends, #implements land in later steps.)
if (self.current.tag != .identifier) {
return self.fail("expected method name in '#jni_class' body");
}
@@ -1085,6 +1096,7 @@ pub const Parser = struct {
.params = try param_types.toOwnedSlice(self.allocator),
.param_names = try param_names.toOwnedSlice(self.allocator),
.return_type = return_type,
.is_static = is_static,
});
}
try self.expect(.r_brace);