aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2024-08-26 22:38:13 +0100
committerGitHub <noreply@github.com>2024-08-26 22:38:13 +0100
commitade4e312fe271030a71baf1291e87728f75cc559 (patch)
treef1cc79d447110e9b491ba005c475e67ba55563f5
parent12bd07d2df1e823687ad967e146c22141c651f5d (diff)
parentdd86a8f01398a2da08f8eb4495049f081901332c (diff)
Merge pull request #4154 from avanspector/master
Delay lexical checking for foreign blocks that are in file scope
-rw-r--r--src/checker.cpp26
-rw-r--r--src/parser.cpp2
-rw-r--r--src/parser.hpp1
3 files changed, 25 insertions, 4 deletions
diff --git a/src/checker.cpp b/src/checker.cpp
index 637659582..fdc1ce840 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -3174,7 +3174,7 @@ gb_internal DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
return true;
} else if (name == "link_prefix") {
if (ev.kind == ExactValue_String) {
- String link_prefix = ev.value_string;
+ String link_prefix = string_trim_whitespace(ev.value_string);
if (link_prefix.len != 0 && !is_foreign_name_valid(link_prefix)) {
error(elem, "Invalid link prefix: '%.*s'", LIT(link_prefix));
} else {
@@ -3186,7 +3186,7 @@ gb_internal DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
return true;
} else if (name == "link_suffix") {
if (ev.kind == ExactValue_String) {
- String link_suffix = ev.value_string;
+ String link_suffix = string_trim_whitespace(ev.value_string);
if (link_suffix.len != 0 && !is_foreign_name_valid(link_suffix)) {
error(elem, "Invalid link suffix: '%.*s'", LIT(link_suffix));
} else {
@@ -4532,7 +4532,9 @@ gb_internal void check_collect_entities(CheckerContext *c, Slice<Ast *> const &n
case_end;
case_ast_node(fb, ForeignBlockDecl, decl);
- check_add_foreign_block_decl(c, decl);
+ if (curr_file != nullptr) {
+ array_add(&curr_file->delayed_decls_queues[AstDelayQueue_ForeignBlock], decl);
+ }
case_end;
default:
@@ -4548,6 +4550,14 @@ gb_internal void check_collect_entities(CheckerContext *c, Slice<Ast *> const &n
// NOTE(bill): 'when' stmts need to be handled after the other as the condition may refer to something
// declared after this stmt in source
if (curr_file == nullptr) {
+ // For 'foreign' block statements that are not in file scope.
+ for_array(decl_index, nodes) {
+ Ast *decl = nodes[decl_index];
+ if (decl->kind == Ast_ForeignBlockDecl) {
+ check_add_foreign_block_decl(c, decl);
+ }
+ }
+
for_array(decl_index, nodes) {
Ast *decl = nodes[decl_index];
if (decl->kind == Ast_WhenStmt) {
@@ -5512,6 +5522,16 @@ gb_internal void check_import_entities(Checker *c) {
AstFile *f = pkg->files[i];
reset_checker_context(&ctx, f, &untyped);
+ for (Ast *decl : f->delayed_decls_queues[AstDelayQueue_ForeignBlock]) {
+ check_add_foreign_block_decl(&ctx, decl);
+ }
+ array_clear(&f->delayed_decls_queues[AstDelayQueue_ForeignBlock]);
+ }
+
+ for_array(i, pkg->files) {
+ AstFile *f = pkg->files[i];
+ reset_checker_context(&ctx, f, &untyped);
+
for (Ast *expr : f->delayed_decls_queues[AstDelayQueue_Expr]) {
Operand o = {};
check_expr(&ctx, &o, expr);
diff --git a/src/parser.cpp b/src/parser.cpp
index b250a3163..e3143dd33 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -6446,7 +6446,7 @@ gb_internal bool parse_file(Parser *p, AstFile *f) {
}
f->total_file_decl_count += calc_decl_count(stmt);
- if (stmt->kind == Ast_WhenStmt || stmt->kind == Ast_ExprStmt || stmt->kind == Ast_ImportDecl) {
+ if (stmt->kind == Ast_WhenStmt || stmt->kind == Ast_ExprStmt || stmt->kind == Ast_ImportDecl || stmt->kind == Ast_ForeignBlockDecl) {
f->delayed_decl_count += 1;
}
}
diff --git a/src/parser.hpp b/src/parser.hpp
index f1794f79a..d5117a31e 100644
--- a/src/parser.hpp
+++ b/src/parser.hpp
@@ -82,6 +82,7 @@ enum AstFileFlag : u32 {
enum AstDelayQueueKind {
AstDelayQueue_Import,
AstDelayQueue_Expr,
+ AstDelayQueue_ForeignBlock,
AstDelayQueue_COUNT,
};