refactor(ffi-linkage): Phase 9.3-src — purge 'foreign' from src/ comments + a user-facing diagnostic
Reword every 'foreign' comment to the extern/runtime-class vocabulary matching the renamed identifiers (foreign call→extern call, foreign class→runtime class, foreign path→runtime path, the #foreign-literal comment mentions → extern, etc.). Also fixes two USER-FACING issues: the 'expected … #foreign … after type annotation' parse error no longer advertises the removed keyword, and the Android 'no #jni_main' help diagnostic now shows '#jni_class(…) extern' instead of the rejected '#foreign #jni_class'. Removed the now-dead prefix-#foreign-vs-postfix conflict branch in parseRuntimeClassDecl (the caller rejects #foreign before it runs). src/ now contains 'foreign' ONLY in the hash_foreign token machinery + its 4 rejection messages — the deprecation mechanism (kept per the 9.0 recommendation; the message MUST name #foreign to guide migration). Snapshot-neutral; suite green (646 corpus / 444 unit, 0 failed).
This commit is contained in:
@@ -214,7 +214,7 @@ pub fn checkRequiredEntryPoints(self: *Lowering) void {
|
||||
diags.addFmt(.err, null, "target is Android but no `#jni_main` Activity declared. " ++
|
||||
"The OS launches a Java-side Activity that delegates lifecycle " ++
|
||||
"callbacks into sx — declare one like:\n\n" ++
|
||||
" Bundle :: #foreign #jni_class(\"android/os/Bundle\") {{ }}\n\n" ++
|
||||
" Bundle :: #jni_class(\"android/os/Bundle\") extern {{ }}\n\n" ++
|
||||
" MyApp :: #jni_main #jni_class(\"co/example/MyApp\") {{\n" ++
|
||||
" onCreate :: (self: *Self, b: *Bundle) {{ /* ... */ }}\n" ++
|
||||
" }}", .{});
|
||||
@@ -375,7 +375,7 @@ pub fn detectContextDecl(decls: []const *const Node) bool {
|
||||
}
|
||||
|
||||
/// Returns true if a sx function declaration should receive the
|
||||
/// implicit `__sx_ctx` parameter. False for foreign-libc bindings,
|
||||
/// implicit `__sx_ctx` parameter. False for extern-libc bindings,
|
||||
/// #builtin / #compiler bodies, and C-conv functions (which keep
|
||||
/// their literal C ABI). Also false for OS-called entry points
|
||||
/// (`isExportedEntryName`): main and JNI hooks are invoked by the
|
||||
@@ -1101,7 +1101,7 @@ pub fn registerTopLevelGlobal(self: *Lowering, vd: *const ast.VarDecl) void {
|
||||
// Use self.resolveType so type aliases like `Handle :: u32;` resolve
|
||||
// to their target type (not a synthetic empty struct). When the
|
||||
// user omitted the annotation, infer from the initializer
|
||||
// expression; foreign globals with no annotation are diagnosed
|
||||
// expression; extern globals with no annotation are diagnosed
|
||||
// because their type can't be inferred without an initializer.
|
||||
const var_ty: TypeId = if (vd.type_annotation) |ta|
|
||||
self.resolveType(ta)
|
||||
@@ -1113,7 +1113,7 @@ pub fn registerTopLevelGlobal(self: *Lowering, vd: *const ast.VarDecl) void {
|
||||
break :blk .void;
|
||||
};
|
||||
// Foreign / extern globals reference a symbol defined in libSystem etc.
|
||||
// (`_NSConcreteStackBlock : *void #foreign;` or `… : *void extern;`). The C
|
||||
// (`_NSConcreteStackBlock : *void extern;` or `… : *void extern;`). The C
|
||||
// symbol name is the optional override (`extern_name`) or the sx name itself.
|
||||
const sym_name = vd.extern_name orelse vd.name;
|
||||
const name_id = self.module.types.internString(sym_name);
|
||||
@@ -1397,7 +1397,7 @@ pub fn lowerRetainedSameNameAuthors(self: *Lowering) void {
|
||||
if (winner == fd) continue;
|
||||
|
||||
// Only plain free functions get an out-of-line slot; generic /
|
||||
// foreign / builtin / #compiler authors keep their existing
|
||||
// extern / builtin / #compiler authors keep their existing
|
||||
// dispatch (mirrors lazyLowerFunction / declareFunction guards).
|
||||
if (!isPlainFreeFn(fd)) continue;
|
||||
|
||||
@@ -1452,7 +1452,7 @@ pub const TypeHeadResolution = union(enum) {
|
||||
pending,
|
||||
/// A flat-visible author DOES declare `name` as a type, but its TypeId
|
||||
/// slot is not registered yet — a forward / self / mutual reference
|
||||
/// resolved mid-registration (`next: *ArenaChunk`), or a foreign /
|
||||
/// resolved mid-registration (`next: *ArenaChunk`), or an extern /
|
||||
/// lazily-registered author with no `findByName` slot. `resolveNominalLeaf`
|
||||
/// keeps the empty-struct stub, which `internNamedTypeDecl` ADOPTS (key-
|
||||
/// stable `updatePreservingKey`) when the type registers — so the forward
|
||||
@@ -1513,7 +1513,7 @@ pub const TypeHeadResolution = union(enum) {
|
||||
/// same module is one author): `≥2 distinct` → `.ambiguous`; exactly one
|
||||
/// that DIFFERS from the winner → select it; otherwise `.none`.
|
||||
///
|
||||
/// Generic / comptime / foreign / builtin authors are never rerouted — the
|
||||
/// Generic / comptime / extern / builtin authors are never rerouted — the
|
||||
/// existing dispatch owns those shapes; `isPlainFreeFn` filters them out
|
||||
/// BEFORE the count gate (so a same-name collision of non-plain authors is
|
||||
/// NOT ambiguous), and the selector returns `.none`. No eager
|
||||
@@ -1540,7 +1540,7 @@ pub fn selectPlainCallableAuthor(self: *Lowering, name: []const u8, caller_file:
|
||||
|
||||
// Caller does not author `name` as a fn → its flat-reachable authors.
|
||||
// Filter to plain free functions BEFORE counting: a same-name collision
|
||||
// of non-plain authors (e.g. two flat-imported modules each `#foreign`ing
|
||||
// of non-plain authors (e.g. two flat-imported modules each `extern`ing
|
||||
// the same symbol) is NOT counted as ambiguous — it falls through to
|
||||
// `.none` and the existing first-wins path.
|
||||
var the_one: ?*const ast.FnDecl = null;
|
||||
@@ -1597,7 +1597,7 @@ pub fn selectNominalLeaf(self: *Lowering, name: []const u8, from: []const u8, ra
|
||||
}
|
||||
// Bare nominal name. A bare TYPE name is visible iff a flat-import-
|
||||
// reachable module authors it AS A TYPE — and a TYPE author is EITHER a
|
||||
// named type (struct/enum/union/error-set/protocol/foreign class) OR a
|
||||
// named type (struct/enum/union/error-set/protocol/runtime class) OR a
|
||||
// type ALIAS (`Name :: <type>`, a `const_decl` whose value resolved to a
|
||||
// type, recorded in E0's `type_aliases_by_source`). Both kinds are gated
|
||||
// identically: `moduleTypeAuthor` is the SINGLE source of truth, so a
|
||||
@@ -1741,7 +1741,7 @@ pub fn selectNominalLeaf(self: *Lowering, name: []const u8, from: []const u8, ra
|
||||
}
|
||||
|
||||
/// TRUE iff `raw` declares a NAMED TYPE — struct / enum / union / error-set /
|
||||
/// protocol / foreign class. A `fn_decl`, a value-or-alias `const_decl`, and a
|
||||
/// protocol / runtime class. A `fn_decl`, a value-or-alias `const_decl`, and a
|
||||
/// `namespace_decl` are NOT named types. A type ALIAS is a `const_decl`;
|
||||
/// it is recognised via `type_aliases_by_source` separately from named types.
|
||||
pub fn isNamedTypeKind(raw: resolver_mod.RawDeclRef) bool {
|
||||
@@ -1766,7 +1766,7 @@ pub fn isNamedTypeKind(raw: resolver_mod.RawDeclRef) bool {
|
||||
/// through `internNamedTypeDecl` (`registerEnumDecl` / `registerUnionDecl`),
|
||||
/// keyed by the raw-facts decl pointer, with the `findByName` fallback for a
|
||||
/// single author registered before its slot lands. error-set / protocol /
|
||||
/// foreign-class keep the legacy `findByName` resolution (their same-name
|
||||
/// runtime-class keep the legacy `findByName` resolution (their same-name
|
||||
/// shadows are later E6 sub-steps — E6b/E6c/E6d).
|
||||
pub fn namedRefTid(self: *Lowering, ref: resolver_mod.RawDeclRef, name: []const u8) ?TypeId {
|
||||
const table = &self.module.types;
|
||||
@@ -1831,7 +1831,7 @@ pub fn localTypeInAnySource(self: *Lowering, name: []const u8) bool {
|
||||
/// Resolve the bare TYPE leaf to a `TypeId` for `resolveTypeWithBindings`.
|
||||
/// Routes through the source-aware `selectNominalLeaf`. `.pending` (forward
|
||||
/// alias) and `.forward` (a real author not interned yet — self / forward /
|
||||
/// foreign reference) keep the empty-struct stub, which the type ADOPTS on
|
||||
/// extern reference) keep the empty-struct stub, which the type ADOPTS on
|
||||
/// registration (`internNamedTypeDecl`). `.undeclared` (NO author anywhere)
|
||||
/// is genuinely-undeclared: in a NON-main module — which the
|
||||
/// `UnknownTypeChecker` trusts and never walks — the leaf is the only guard,
|
||||
@@ -2298,14 +2298,14 @@ pub fn lazyLowerFunction(self: *Lowering, name: []const u8) void {
|
||||
if (self.lookupObjcDefinedClassForMethod(name)) |fcd| {
|
||||
self.current_runtime_class = fcd;
|
||||
}
|
||||
// No AST? (builtins, foreign functions, or imported functions not in this file)
|
||||
// No AST? (builtins, extern functions, or imported functions not in this file)
|
||||
const fd = self.program_index.fn_ast_map.get(name) orelse return;
|
||||
// Foreign declarations stay as extern stubs but need to be REGISTERED
|
||||
// in the current module so callers get a real FuncId. Without this,
|
||||
// a comptime-lowered function (e.g. `concat` from std.sx pulled into
|
||||
// a fresh ct_module via `evalComptimeString`) emits `.call` against a
|
||||
// FuncId that doesn't exist locally; the interp can't find the
|
||||
// foreign target and silently no-ops instead of dispatching to libc.
|
||||
// extern target and silently no-ops instead of dispatching to libc.
|
||||
if (fd.extern_export == .extern_) {
|
||||
if (self.resolveFuncByName(name) == null) {
|
||||
self.declareFunction(fd, name);
|
||||
@@ -2511,10 +2511,10 @@ pub fn lowerFunction(self: *Lowering, fd: *const ast.FnDecl, name: []const u8, i
|
||||
}) catch unreachable;
|
||||
}
|
||||
|
||||
// Check if the function body is a builtin or foreign declaration (no body
|
||||
// Check if the function body is a builtin or extern declaration (no body
|
||||
// needed). `extern` imports are declare-only too (empty placeholder body).
|
||||
if (fd.body.data == .builtin_expr or fd.body.data == .compiler_expr or fd.extern_export == .extern_) {
|
||||
// Already declared by scanDecls/declareFunction (which handles #foreign renames)
|
||||
// Already declared by scanDecls/declareFunction (which handles #extern renames)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user