replace leading _ for private symbols with keyword hide

This commit is contained in:
2026-07-14 20:19:01 +02:00
parent 5157cf3bcc
commit 267947e79d
31 changed files with 125220 additions and 122709 deletions
+2 -2
View File
@@ -966,7 +966,7 @@ configure_io_main :: proc(checker: ^Checker) {
return
}
provider_name := symbol.intern(checker.symbols, "_system")
provider_name := symbol.intern(checker.symbols, "system")
provider := ast.INVALID_FUNCTION
for function, function_id in checker.ast_module.functions {
if function.pkg != io_package || function.name != provider_name {
@@ -986,7 +986,7 @@ configure_io_main :: proc(checker: ^Checker) {
checker.template_diagnostics[main_template] = source.add(
checker.diagnostics,
main.span,
"@std/io does not provide the required '_system func() Io' startup implementation",
"@std/io does not provide the required 'hide system func() Io' startup implementation",
)
return
}
+1
View File
@@ -24,6 +24,7 @@ keyword_kind :: proc(text: string) -> token.Kind {
case "distinct": return .Keyword_Distinct
case "alias": return .Keyword_Alias
case "import": return .Keyword_Import
case "hide": return .Keyword_Hide
case "return": return .Keyword_Return
case "try": return .Keyword_Try
case "catch": return .Keyword_Catch
+65 -28
View File
@@ -26,6 +26,7 @@ Parser :: struct {
// struct literal. Nested `(`/`[`/call-arg contexts (delimiter_depth > 0) still
// allow struct literals.
no_struct_literal: bool,
hidden_names: [dynamic]symbol.Id,
}
MAX_EXPRESSION_NESTING :: 256
@@ -37,9 +38,31 @@ token_text :: proc(parser: ^Parser, tok: token.Token) -> string {
return parser.source_file.text[int(tok.span.start):int(tok.span.end)]
}
file_hidden_name :: proc(parser: ^Parser, tok: token.Token) -> bool {
name := token_text(parser, tok)
return len(name) > 1 && name[0] == '_'
file_hidden_name :: proc(parser: ^Parser, name: symbol.Id) -> bool {
for hidden in parser.hidden_names {
if hidden == name {
return true
}
}
return false
}
collect_hidden_names :: proc(parser: ^Parser) {
depth := 0
for item, index in parser.tokens.items {
#partial switch item.kind {
case .Left_Brace:
depth += 1
case .Right_Brace:
depth = max(depth-1, 0)
case .Keyword_Hide:
if depth == 0 && index+1 < len(parser.tokens.items) &&
parser.tokens.items[index+1].kind == .Identifier {
append(&parser.hidden_names, parser.tokens.items[index+1].symbol)
}
case:
}
}
}
span_from :: proc(first, last: source.Span) -> source.Span {
@@ -396,7 +419,7 @@ parse_type_atom :: proc(parser: ^Parser) -> ast.Type_Syntax {
u32(name.symbol),
u32(qualifier),
u32(parser.file),
!symbol.is_valid(qualifier) && file_hidden_name(parser, name),
!symbol.is_valid(qualifier) && file_hidden_name(parser, name.symbol),
)
if current(parser).kind == .Left_Paren {
call := parse_call(parser, qualifier, first, name, 0, false)
@@ -2192,7 +2215,7 @@ parse_while :: proc(parser: ^Parser) -> ast.Stmt_Id {
return id
}
parse_function :: proc(parser: ^Parser, name: token.Token, c_abi: bool) {
parse_function :: proc(parser: ^Parser, name: token.Token, c_abi, file_hidden: bool) {
advance(parser)
if _, ok := allow(parser, .Left_Paren); !ok {
source.add(parser.diagnostics, current(parser).span, "expected '(' after 'func'")
@@ -2223,7 +2246,7 @@ parse_function :: proc(parser: ^Parser, name: token.Token, c_abi: bool) {
pkg=parser.pkg,
file=parser.file,
c_abi=c_abi,
file_hidden=!c_abi && file_hidden_name(parser, name),
file_hidden=file_hidden,
has_body=false,
variadic=variadic,
params=params,
@@ -2242,7 +2265,7 @@ parse_function :: proc(parser: ^Parser, name: token.Token, c_abi: bool) {
pkg=parser.pkg,
file=parser.file,
c_abi=c_abi,
file_hidden=!c_abi && file_hidden_name(parser, name),
file_hidden=file_hidden,
has_body=true,
variadic=variadic,
params=params,
@@ -2388,9 +2411,9 @@ parse_inline_union_type :: proc(parser: ^Parser) -> types.Type {
return types.union_anonymous(&parser.module.type_store, fields[:], tag)
}
parse_struct :: proc(parser: ^Parser, name: token.Token, c_layout: bool, is_union := false) {
parse_struct :: proc(parser: ^Parser, name: token.Token, c_layout, file_hidden: bool, is_union := false) {
start := advance(parser)
id := types.named(&parser.module.type_store, u32(parser.pkg), u32(name.symbol), file=u32(parser.file), file_hidden=!c_layout && file_hidden_name(parser, name))
id := types.named(&parser.module.type_store, u32(parser.pkg), u32(name.symbol), file=u32(parser.file), file_hidden=file_hidden)
// A tagged union spells its discriminant in parens: `union(Enum)` reuses an existing
// enum; `union(enum)` synthesizes one from the variant names after the body is parsed.
tag := types.INVALID
@@ -2452,9 +2475,9 @@ parse_struct :: proc(parser: ^Parser, name: token.Token, c_layout: bool, is_unio
_ = finish_statement(parser)
}
parse_opaque :: proc(parser: ^Parser, name: token.Token) {
parse_opaque :: proc(parser: ^Parser, name: token.Token, file_hidden: bool) {
start := advance(parser)
id := types.named(&parser.module.type_store, u32(parser.pkg), u32(name.symbol), file=u32(parser.file), file_hidden=file_hidden_name(parser, name))
id := types.named(&parser.module.type_store, u32(parser.pkg), u32(name.symbol), file=u32(parser.file), file_hidden=file_hidden)
if !types.define_record(&parser.module.type_store, id, nil, false, true, false) {
source.addf(parser.diagnostics, name.span, "duplicate type declaration '%s'", token_text(parser, name))
}
@@ -2480,10 +2503,10 @@ synthesize_union_tag :: proc(parser: ^Parser, fields: []types.Field) -> types.Ty
return types.enum_anonymous(&parser.module.type_store, members, types.U16)
}
parse_distinct :: proc(parser: ^Parser, name: token.Token) {
parse_distinct :: proc(parser: ^Parser, name: token.Token, file_hidden: bool) {
start := advance(parser)
child := parse_type(parser)
id := types.named(&parser.module.type_store, u32(parser.pkg), u32(name.symbol), file=u32(parser.file), file_hidden=file_hidden_name(parser, name))
id := types.named(&parser.module.type_store, u32(parser.pkg), u32(name.symbol), file=u32(parser.file), file_hidden=file_hidden)
if !types.define_distinct(&parser.module.type_store, id, child) {
source.addf(parser.diagnostics, name.span, "duplicate type declaration '%s'", token_text(parser, name))
}
@@ -2493,7 +2516,7 @@ parse_distinct :: proc(parser: ^Parser, name: token.Token) {
_ = finish_statement(parser)
}
parse_alias :: proc(parser: ^Parser, name: token.Token) {
parse_alias :: proc(parser: ^Parser, name: token.Token, file_hidden: bool) {
start := advance(parser)
saved := parser.cursor
if current(parser).kind == .Identifier && peek(parser).kind == .Dot {
@@ -2510,7 +2533,7 @@ parse_alias :: proc(parser: ^Parser, name: token.Token) {
pkg=parser.pkg,
file=parser.file,
target_pkg=ast.INVALID_PACKAGE,
file_hidden=file_hidden_name(parser, name),
file_hidden=file_hidden,
valid=true,
diagnostic=source.INVALID_DIAGNOSTIC,
})
@@ -2521,7 +2544,7 @@ parse_alias :: proc(parser: ^Parser, name: token.Token) {
}
parser.cursor = saved
child := parse_type(parser)
id := types.named(&parser.module.type_store, u32(parser.pkg), u32(name.symbol), file=u32(parser.file), file_hidden=file_hidden_name(parser, name))
id := types.named(&parser.module.type_store, u32(parser.pkg), u32(name.symbol), file=u32(parser.file), file_hidden=file_hidden)
if !types.define_alias(&parser.module.type_store, id, child) {
source.addf(parser.diagnostics, name.span, "duplicate type declaration '%s'", token_text(parser, name))
}
@@ -2650,7 +2673,7 @@ parse_inline_enum_type :: proc(parser: ^Parser) -> types.Type {
return types.enum_anonymous(&parser.module.type_store, members[:], backing)
}
parse_enum :: proc(parser: ^Parser, name: token.Token) {
parse_enum :: proc(parser: ^Parser, name: token.Token, file_hidden: bool) {
start := advance(parser)
explicit_backing := false
backing := types.INVALID
@@ -2668,7 +2691,7 @@ parse_enum :: proc(parser: ^Parser, name: token.Token) {
_ = finish_statement(parser)
return
}
id := types.named(&parser.module.type_store, u32(parser.pkg), u32(name.symbol), file=u32(parser.file), file_hidden=file_hidden_name(parser, name))
id := types.named(&parser.module.type_store, u32(parser.pkg), u32(name.symbol), file=u32(parser.file), file_hidden=file_hidden)
if !types.define_enum(&parser.module.type_store, id, backing, members[:], explicit_backing) {
source.addf(parser.diagnostics, name.span, "duplicate type declaration '%s'", token_text(parser, name))
}
@@ -2764,13 +2787,18 @@ parse_import :: proc(parser: ^Parser, alias: token.Token, start: token.Token) {
}
parse_top_level :: proc(parser: ^Parser) {
hide_token, file_hidden := allow(parser, .Keyword_Hide)
if current(parser).kind == .Keyword_Import {
if file_hidden {
source.add(parser.diagnostics, hide_token.span, "imports are already file-local and cannot use 'hide'")
}
start := advance(parser)
parse_import(parser, token.Token{}, start)
return
}
if current(parser).kind != .Identifier {
source.add(parser.diagnostics, current(parser).span, "expected a top-level declaration")
message := "expected a declaration name after 'hide'" if file_hidden else "expected a top-level declaration"
source.add(parser.diagnostics, current(parser).span, message)
for current(parser).kind != .Newline && current(parser).kind != .Eof {
advance(parser)
}
@@ -2783,6 +2811,9 @@ parse_top_level :: proc(parser: ^Parser) {
advance(parser)
skip_newlines(parser)
if current(parser).kind == .Keyword_Import {
if file_hidden {
source.add(parser.diagnostics, hide_token.span, "imports are already file-local and cannot use 'hide'")
}
start := advance(parser)
parse_import(parser, name, start)
return
@@ -2791,7 +2822,7 @@ parse_top_level :: proc(parser: ^Parser) {
}
if current(parser).kind == .Keyword_Func || current(parser).kind == .Keyword_C_Func {
c_abi := current(parser).kind == .Keyword_C_Func
parse_function(parser, name, c_abi)
parse_function(parser, name, c_abi, file_hidden)
return
}
type_syntax := types.INVALID
@@ -2812,32 +2843,32 @@ parse_top_level :: proc(parser: ^Parser) {
source.add(parser.diagnostics, span_from(name.span, current(parser).span),
"function declarations do not use '::'; write 'name func(...)' or 'name c_func(...)'")
c_abi := current(parser).kind == .Keyword_C_Func
parse_function(parser, name, c_abi)
parse_function(parser, name, c_abi, file_hidden)
return
}
if operator.kind == .Colon_Colon &&
(current(parser).kind == .Keyword_Struct || current(parser).kind == .Keyword_C_Struct) {
parse_struct(parser, name, current(parser).kind == .Keyword_C_Struct)
parse_struct(parser, name, current(parser).kind == .Keyword_C_Struct, file_hidden)
return
}
if operator.kind == .Colon_Colon && current(parser).kind == .Keyword_Opaque {
parse_opaque(parser, name)
parse_opaque(parser, name, file_hidden)
return
}
if operator.kind == .Colon_Colon && current(parser).kind == .Keyword_Union {
parse_struct(parser, name, false, is_union=true)
parse_struct(parser, name, false, file_hidden, is_union=true)
return
}
if operator.kind == .Colon_Colon && current(parser).kind == .Keyword_Enum {
parse_enum(parser, name)
parse_enum(parser, name, file_hidden)
return
}
if operator.kind == .Colon_Colon && current(parser).kind == .Keyword_Distinct {
parse_distinct(parser, name)
parse_distinct(parser, name, file_hidden)
return
}
if operator.kind == .Colon_Colon && current(parser).kind == .Keyword_Alias {
parse_alias(parser, name)
parse_alias(parser, name, file_hidden)
return
}
@@ -2848,7 +2879,7 @@ parse_top_level :: proc(parser: ^Parser) {
name=name.symbol,
pkg=parser.pkg,
file=parser.file,
file_hidden=file_hidden_name(parser, name),
file_hidden=file_hidden,
type=type_syntax,
immutable=operator.kind == .Colon_Colon,
expr=expr,
@@ -2869,6 +2900,9 @@ parse :: proc(
diagnostics=diagnostics,
module=ast.init_module(allocator),
}
parser.hidden_names.allocator = allocator
defer delete(parser.hidden_names)
collect_hidden_names(&parser)
skip_newlines(&parser)
for current(&parser).kind != .Eof {
parse_top_level(&parser)
@@ -2893,6 +2927,9 @@ parse_into :: proc(
pkg=pkg,
file=file,
}
parser.hidden_names.allocator = module.allocator
defer delete(parser.hidden_names)
collect_hidden_names(&parser)
skip_newlines(&parser)
for current(&parser).kind != .Eof {
parse_top_level(&parser)
+1
View File
@@ -60,6 +60,7 @@ Kind :: enum u8 {
Keyword_Distinct,
Keyword_Alias,
Keyword_Import,
Keyword_Hide,
Keyword_Return,
Keyword_Try,
Keyword_Catch,