refactor(ffi-linkage)!: Phase 9.0 — delete the hash_foreign token (src is foreign-free)
Per user directive (total purge): remove the hash_foreign token entirely rather than keep it for a friendly deprecation message. Deleted: the token enum (token.zig), the lexer keyword entry + directive-list mention + lex test (lexer.zig), the 4 parser rejection sites + 2 lookahead clauses + the runtime-class prefix #foreign peek arm (parser.zig), and the lsp completion arm (server.zig). '#foreign' now lexes as an invalid '#' token → a generic 'expected ;' parse error (no migration hint — the accepted UX cost of zero-foreign). Deleted examples/1176-diagnostics-foreign-removed (its purpose, the friendly rejection, no longer exists). src/ now contains ZERO 'foreign' (case-insensitive). Suite green (645 corpus / 443 unit, 0 failed). Remaining for the 9.4 gate: issues/*.md prose + example filenames.
This commit is contained in:
@@ -257,16 +257,7 @@ pub const Parser = struct {
|
||||
// Define-by-default: bare `#jni_class("...")` declares a new class (sx-defined).
|
||||
// Postfix `extern` flips that to "reference an existing class on the runtime
|
||||
// side". `#jni_main` flags the class as the launchable entry (Android Activity).
|
||||
const prefix_loc = self.current.loc;
|
||||
if (self.tryParseRuntimeClassPrefix()) |prefix| {
|
||||
// Phase 8 cutover: the removed prefix linkage directive on a
|
||||
// runtime-class directive — reference an existing class via the
|
||||
// postfix `extern` modifier (`X :: #objc_class("…") extern { … }`)
|
||||
// instead. `prefix_loc` pins the diagnostic to the removed-directive
|
||||
// token (already consumed by the lookahead).
|
||||
if (prefix.is_extern) {
|
||||
return self.failAt(prefix_loc, "`#foreign` has been removed; use the postfix `extern` (import) / `export` (define) linkage keyword instead");
|
||||
}
|
||||
return self.parseRuntimeClassDecl(name, start_pos, prefix.runtime, prefix.is_extern, prefix.is_main, name_is_raw);
|
||||
}
|
||||
|
||||
@@ -321,13 +312,6 @@ pub const Parser = struct {
|
||||
return try self.createNode(start_pos, .{ .const_decl = .{ .name = name, .type_annotation = value, .value = bi, .name_span = name_span, .is_raw = name_is_raw } });
|
||||
}
|
||||
|
||||
// Phase 8 cutover: the removed prefix linkage directive on a
|
||||
// const-with-type decl — reject it with a migration message (the
|
||||
// postfix form is `name :: type extern [lib] ["c_name"];`).
|
||||
if (self.current.tag == .hash_foreign) {
|
||||
return self.fail("`#foreign` has been removed; use the postfix `extern` (import) / `export` (define) linkage keyword instead");
|
||||
}
|
||||
|
||||
try self.expect(.semicolon);
|
||||
return try self.createNode(start_pos, .{ .const_decl = .{ .name = name, .type_annotation = null, .value = value, .name_span = name_span, .is_raw = name_is_raw } });
|
||||
}
|
||||
@@ -412,16 +396,9 @@ pub const Parser = struct {
|
||||
return try self.createNode(start_pos, .{ .var_decl = .{ .name = name, .name_span = name_span, .type_annotation = type_node, .value = null, .is_raw = name_is_raw } });
|
||||
}
|
||||
|
||||
// Phase 8 cutover: the removed prefix linkage directive on a data
|
||||
// global — reject it (the postfix form `name : type extern [lib]
|
||||
// ["c_name"];` is handled by the `kw_extern` arm below).
|
||||
if (self.current.tag == .hash_foreign) {
|
||||
return self.fail("`#foreign` has been removed; use the postfix `extern` (import) / `export` (define) linkage keyword instead");
|
||||
}
|
||||
|
||||
if (self.current.tag == .kw_extern) {
|
||||
// name : type extern [LIB] ["csym"]; (extern data global — the
|
||||
// extern-named counterpart of `extern`; resolved at link time)
|
||||
// name : type extern [LIB] ["csym"]; (extern data global, resolved
|
||||
// at link time)
|
||||
self.advance();
|
||||
var ext_lib: ?[]const u8 = null;
|
||||
if (self.current.tag == .identifier) {
|
||||
@@ -1307,17 +1284,16 @@ pub const Parser = struct {
|
||||
/// only when a runtime directive follows; otherwise leaves the parser
|
||||
/// state untouched.
|
||||
fn tryParseRuntimeClassPrefix(self: *Parser) ?RuntimeClassPrefix {
|
||||
// Peek ahead through modifier tokens to confirm a directive follows.
|
||||
// Peek ahead through the optional `#jni_main` modifier to confirm a
|
||||
// runtime-class directive follows. (`is_extern` — reference vs define —
|
||||
// is decided by the POSTFIX `extern`/`export` keyword in parseRuntimeClassDecl,
|
||||
// never a prefix; it stays false here.)
|
||||
var lookahead_idx: usize = 0;
|
||||
var is_extern = false;
|
||||
const is_extern = false;
|
||||
var is_main = false;
|
||||
while (true) {
|
||||
const tag = self.peekTag(lookahead_idx);
|
||||
switch (tag) {
|
||||
.hash_foreign => {
|
||||
is_extern = true;
|
||||
lookahead_idx += 1;
|
||||
},
|
||||
.hash_jni_main => {
|
||||
is_main = true;
|
||||
lookahead_idx += 1;
|
||||
@@ -2017,11 +1993,6 @@ pub const Parser = struct {
|
||||
const ci_start = self.current.loc.start;
|
||||
self.advance();
|
||||
break :blk try self.createNode(ci_start, .{ .compiler_expr = {} });
|
||||
} else if (self.current.tag == .hash_foreign) {
|
||||
// Phase 8 cutover: the removed fn-body linkage marker — reject it.
|
||||
// The import form is now the postfix `extern` keyword handled above
|
||||
// (`f :: (…) -> R extern [LIB] ["csym"];`).
|
||||
return self.fail("`#foreign` has been removed; use the postfix `extern` (import) / `export` (define) linkage keyword instead");
|
||||
} else if (self.current.tag == .fat_arrow) blk: {
|
||||
is_arrow = true;
|
||||
self.advance();
|
||||
@@ -3647,7 +3618,7 @@ pub const Parser = struct {
|
||||
if (tag == .arrow) return self.hasFnBodyAfterArrow();
|
||||
// `kw_extern`/`kw_export`: a postfix linkage modifier (e.g. `f :: () extern;`
|
||||
// with no return type) marks a fn decl just like `callconv`.
|
||||
return tag == .l_brace or tag == .hash_builtin or tag == .hash_compiler or tag == .hash_foreign or tag == .fat_arrow or tag == .kw_callconv or tag == .kw_extern or tag == .kw_export;
|
||||
return tag == .l_brace or tag == .hash_builtin or tag == .hash_compiler or tag == .fat_arrow or tag == .kw_callconv or tag == .kw_extern or tag == .kw_export;
|
||||
}
|
||||
|
||||
fn hasFnBodyAfterArrow(self: *Parser) bool {
|
||||
@@ -3673,7 +3644,7 @@ pub const Parser = struct {
|
||||
while (self.current.tag != .eof) {
|
||||
if (self.current.tag == .fat_arrow) return true;
|
||||
if (self.current.tag == .l_brace) return true;
|
||||
if (self.current.tag == .hash_builtin or self.current.tag == .hash_compiler or self.current.tag == .hash_foreign) return true;
|
||||
if (self.current.tag == .hash_builtin or self.current.tag == .hash_compiler) return true;
|
||||
if (self.current.tag == .kw_callconv) return true;
|
||||
// Postfix linkage modifier after the return type: `-> R extern;` /
|
||||
// `-> R export { … }` (and `-> R callconv(.c) extern`). Marks a fn def.
|
||||
|
||||
Reference in New Issue
Block a user