From d9a4137d45affa1f03b97fb0525201b9a8f2a175 Mon Sep 17 00:00:00 2001 From: StunxFS Date: Sun, 3 Dec 2023 10:12:55 -0400 Subject: [PATCH 1/2] change --- lib/c/src/{errno.ri => errno.c.ri} | 0 .../src/{TestRunner.ri => TestRunner.c.ri} | 0 lib/core/src/{string_to.c.ri => string_to.ri} | 0 lib/rivet/src/ast/SourceFile.ri | 14 ++++++++++ lib/rivet/src/ast/Sym.ri | 9 +++++++ lib/rivet/src/ast/mod.ri | 8 ------ lib/rivet/src/checker/mod.ri | 10 +++++++ lib/rivet/src/lib.ri | 2 +- lib/rivet/src/parser/mod.ri | 3 ++- lib/rivet/src/prefs/mod.ri | 2 +- lib/rivet/src/resolver/Register.ri | 2 +- lib/rivet/src/resolver/exprs.ri | 18 +++++++++++++ lib/rivet/src/resolver/mod.ri | 26 ++++++++++++------- 13 files changed, 73 insertions(+), 21 deletions(-) rename lib/c/src/{errno.ri => errno.c.ri} (100%) rename lib/core/src/{TestRunner.ri => TestRunner.c.ri} (100%) rename lib/core/src/{string_to.c.ri => string_to.ri} (100%) create mode 100644 lib/rivet/src/ast/SourceFile.ri diff --git a/lib/c/src/errno.ri b/lib/c/src/errno.c.ri similarity index 100% rename from lib/c/src/errno.ri rename to lib/c/src/errno.c.ri diff --git a/lib/core/src/TestRunner.ri b/lib/core/src/TestRunner.c.ri similarity index 100% rename from lib/core/src/TestRunner.ri rename to lib/core/src/TestRunner.c.ri diff --git a/lib/core/src/string_to.c.ri b/lib/core/src/string_to.ri similarity index 100% rename from lib/core/src/string_to.c.ri rename to lib/core/src/string_to.ri diff --git a/lib/rivet/src/ast/SourceFile.ri b/lib/rivet/src/ast/SourceFile.ri new file mode 100644 index 000000000..aaeed8f07 --- /dev/null +++ b/lib/rivet/src/ast/SourceFile.ri @@ -0,0 +1,14 @@ +// Copyright (C) 2023 The Rivet Developers. All rights reserved. +// Use of this source code is governed by an MIT license that can +// be found in the LICENSE file. + +import ../token; + +#[boxed] +pub struct SourceFile { + pub path: string; + pub decls: []Decl; + pub mut mod: Module; + pub mut imported_symbols: ImportedSymbols; + pub mut pos: token.Pos; +} diff --git a/lib/rivet/src/ast/Sym.ri b/lib/rivet/src/ast/Sym.ri index 9e306335b..040d40f73 100644 --- a/lib/rivet/src/ast/Sym.ri +++ b/lib/rivet/src/ast/Sym.ri @@ -37,6 +37,15 @@ pub enum ABI as uint8 < traits.Stringable { }; } + // TODO: remove, use `.to_lower()` instead + #[inline] + pub func lower(&self) -> string { + return match self.* { + .C -> "c", + .Rivet -> "rivet" + }; + } + #[inline] pub func to_string(&self) -> string { return match self.* { diff --git a/lib/rivet/src/ast/mod.ri b/lib/rivet/src/ast/mod.ri index c3b207011..4e0d018a4 100644 --- a/lib/rivet/src/ast/mod.ri +++ b/lib/rivet/src/ast/mod.ri @@ -10,14 +10,6 @@ pub enum Node { Expr: Expr } -#[boxed] -pub struct SourceFile { - pub file: string; - pub decls: []Decl; - pub mut mod: Module; - pub mut imported_symbols: ImportedSymbols; -} - #[boxed] pub struct ImportedSymbol { pub name: string; diff --git a/lib/rivet/src/checker/mod.ri b/lib/rivet/src/checker/mod.ri index 0d9b6364f..a32065f9a 100644 --- a/lib/rivet/src/checker/mod.ri +++ b/lib/rivet/src/checker/mod.ri @@ -46,6 +46,16 @@ pub struct Checker { self.source_file = source_file; self.expected_type = .Void(); self.check_decls(source_file.decls); + // check unused imports + for imported_sym in source_file.imported_symbols.syms { + if !imported_sym.is_used and imported_sym.name != "_" { + report.warn( + "{} `{}` is imported but never used".fmt( + imported_sym.sym.type_of(), imported_sym.sym.name + ), imported_sym.pos + ); + } + } } // check global mutable variables for sym in self.table.universe.scope.syms { diff --git a/lib/rivet/src/lib.ri b/lib/rivet/src/lib.ri index 56971627e..ea2d5a252 100644 --- a/lib/rivet/src/lib.ri +++ b/lib/rivet/src/lib.ri @@ -128,7 +128,7 @@ pub struct Compiler { continue; } import_decl.info = self.load_module( - import_decl.path, import_decl.alias_name, sf.file, + import_decl.path, import_decl.alias_name, sf.path, import_decl.path_pos )!; import_decl.alias_name = import_decl.info.alias_name; diff --git a/lib/rivet/src/parser/mod.ri b/lib/rivet/src/parser/mod.ri index 29d00d707..8934dab10 100644 --- a/lib/rivet/src/parser/mod.ri +++ b/lib/rivet/src/parser/mod.ri @@ -54,7 +54,8 @@ pub struct Parser { return ast.SourceFile(file, [], self.mod_sym); } self.advance(2); - return ast.SourceFile(file, self.parse_decls(), self.mod_sym); + pos := self.tok.pos; + return ast.SourceFile(file, self.parse_decls(), self.mod_sym, pos: pos + self.prev_tok.pos); } func next(mut self) { diff --git a/lib/rivet/src/prefs/mod.ri b/lib/rivet/src/prefs/mod.ri index f03be017d..413f919d2 100644 --- a/lib/rivet/src/prefs/mod.ri +++ b/lib/rivet/src/prefs/mod.ri @@ -71,7 +71,7 @@ pub struct Prefs { pub mut all_warns_are_errors: bool; pub mut hide_all_warns: bool; pub mut is_verbose: bool; - pub mut is_fmt: bool; + pub mut is_fmt: bool; // Output info pub mut output_mode: OutputMode; diff --git a/lib/rivet/src/resolver/Register.ri b/lib/rivet/src/resolver/Register.ri index 0c3a74e47..7cd3d4ec7 100644 --- a/lib/rivet/src/resolver/Register.ri +++ b/lib/rivet/src/resolver/Register.ri @@ -239,7 +239,7 @@ pub struct Register { }, .Func as func_decl -> func_decl.sym = self.add_sym(ast.Func( parent: self.sym, - abi: self.abi, + abi: func_decl.abi, is_public: func_decl.is_public, is_extern: func_decl.is_extern, is_unsafe: func_decl.is_unsafe, diff --git a/lib/rivet/src/resolver/exprs.ri b/lib/rivet/src/resolver/exprs.ri index e88bc707f..7e8dda371 100644 --- a/lib/rivet/src/resolver/exprs.ri +++ b/lib/rivet/src/resolver/exprs.ri @@ -263,6 +263,7 @@ extend Resolver { if ident.is_sym and ident.sym is ast.SymRef as mut sym_ref { ident.sym = self.clean_symbol_reference(sym_ref); } + self.check_symbol_abi(ident.sym, ident.pos); } else { report.error("cannot find `{}` in this scope".fmt(ident.name), ident.pos); } @@ -297,6 +298,7 @@ extend Resolver { ) { selector.found = true; selector.sym = sym; + self.check_symbol_abi(sym, selector.pos); } } } @@ -353,4 +355,20 @@ extend Resolver { } return sym_ref.ref; } + + func check_symbol_abi(mut self, sym: ast.Sym, pos: token.Pos) { + if sym.abi != .Rivet { + if self.source_file_abi != sym.abi { + mut warn := report.warn_builder( + "using a symbol whose ABI is different from that of the current file", pos + ); + warn.add_note("`{}` is declared as `extern ({})`", sym.name, sym.abi); + warn.add_help( + "consider adding `.{}.` extension to current filename", sym.abi.lower() + ); + warn.emit(); + } + self.different_abi_usage_count += 1; + } + } } diff --git a/lib/rivet/src/resolver/mod.ri b/lib/rivet/src/resolver/mod.ri index df654374c..6e3981b5f 100644 --- a/lib/rivet/src/resolver/mod.ri +++ b/lib/rivet/src/resolver/mod.ri @@ -6,6 +6,8 @@ import ../ast; import ../prefs; import ../token; import ../report; +import std/console; +import { Path } from std/fs; struct Prelude { name: string; @@ -24,6 +26,8 @@ pub struct Resolver { mut self_sym_is_set: bool; mut source_file: ast.SourceFile; + mut source_file_abi: ast.ABI := .Rivet; + mut different_abi_usage_count: uint; pub func resolve_files(mut self, source_files: []ast.SourceFile) { Register(self.table, self.prefs).walk_files(source_files); @@ -34,22 +38,26 @@ pub struct Resolver { Prelude("Throwable", self.table.throwable_sym) ]; for sf in source_files { + self.source_file_abi = .Rivet; self.sym = sf.mod; self.source_file = sf; + self.detect_source_file_abi(); self.resolve_decls(self.source_file.decls); - // check unused imports - for imported_sym in sf.imported_symbols.syms { - if !imported_sym.is_used and imported_sym.name != "_" { - report.warn( - "{} `{}` is imported but never used".fmt( - imported_sym.sym.type_of(), imported_sym.sym.name - ), imported_sym.pos - ); - } + if self.source_file_abi == .Rivet and self.different_abi_usage_count > 0 { + report.warn("filename requires ABI specification", sf.pos); + } else if self.source_file_abi != .Rivet and self.different_abi_usage_count == 0 { + report.warn("filename does not require ABI specification", sf.pos); } } } + func detect_source_file_abi(mut self) { + filename := Path.file_name(self.source_file.path); + if filename.contains(".c.") { + self.source_file_abi = .C; + } + } + func check_vis(self, sym: ast.Sym, pos: token.Pos) { if !sym.is_public and !self.source_file.mod.has_access_to(sym) { report.error("{} `{}` is private".fmt(sym.type_of(), sym.name), pos); From 05ee4735906887e4501b9adafeec6a681b3117dc Mon Sep 17 00:00:00 2001 From: StunxFS Date: Sun, 3 Dec 2023 15:25:42 -0400 Subject: [PATCH 2/2] fix(rivet/resolver): fix file abi checking --- lib/core/src/{TestRunner.c.ri => TestRunner.ri} | 0 lib/core/src/{Vector.c.ri => Vector.ri} | 0 lib/core/src/errors.c.ri | 12 ------------ lib/core/src/errors.ri | 10 +++++++++- lib/core/src/{ptr.c.ri => ptr.ri} | 0 lib/core/src/{rune.c.ri => rune.ri} | 0 lib/core/src/{utils.c.ri => utils.ri} | 0 lib/rivet/src/resolver/exprs.ri | 7 ++++--- lib/rivet/src/resolver/mod.ri | 8 +++++--- 9 files changed, 18 insertions(+), 19 deletions(-) rename lib/core/src/{TestRunner.c.ri => TestRunner.ri} (100%) rename lib/core/src/{Vector.c.ri => Vector.ri} (100%) delete mode 100644 lib/core/src/errors.c.ri rename lib/core/src/{ptr.c.ri => ptr.ri} (100%) rename lib/core/src/{rune.c.ri => rune.ri} (100%) rename lib/core/src/{utils.c.ri => utils.ri} (100%) diff --git a/lib/core/src/TestRunner.c.ri b/lib/core/src/TestRunner.ri similarity index 100% rename from lib/core/src/TestRunner.c.ri rename to lib/core/src/TestRunner.ri diff --git a/lib/core/src/Vector.c.ri b/lib/core/src/Vector.ri similarity index 100% rename from lib/core/src/Vector.c.ri rename to lib/core/src/Vector.ri diff --git a/lib/core/src/errors.c.ri b/lib/core/src/errors.c.ri deleted file mode 100644 index 0e1c77fcc..000000000 --- a/lib/core/src/errors.c.ri +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (C) 2023 The Rivet Developers. All rights reserved. -// Use of this source code is governed by an MIT license that can -// be found in the LICENSE file. - -import c; - -pub alias ErrnoError := c.ErrnoError; - -// FIXME: pub alias last_errno_error := c.last_errno_error; -pub func last_errno_error() -> c.ErrnoError { - return c.last_errno_error(); -} diff --git a/lib/core/src/errors.ri b/lib/core/src/errors.ri index f38579bc6..5e156ad8b 100644 --- a/lib/core/src/errors.ri +++ b/lib/core/src/errors.ri @@ -2,6 +2,15 @@ // Use of this source code is governed by an MIT license that can // be found in the LICENSE file. +import c; + +pub alias ErrnoError := c.ErrnoError; + +// FIXME: pub alias last_errno_error := c.last_errno_error; +pub func last_errno_error() -> c.ErrnoError { + return c.last_errno_error(); +} + var returnTrace := ReturnTrace(); /// This trait is used for errors throwed with result types (!T). @@ -117,4 +126,3 @@ pub struct ValueOutOfRangeError < Throwable { return self.msg; } } - diff --git a/lib/core/src/ptr.c.ri b/lib/core/src/ptr.ri similarity index 100% rename from lib/core/src/ptr.c.ri rename to lib/core/src/ptr.ri diff --git a/lib/core/src/rune.c.ri b/lib/core/src/rune.ri similarity index 100% rename from lib/core/src/rune.c.ri rename to lib/core/src/rune.ri diff --git a/lib/core/src/utils.c.ri b/lib/core/src/utils.ri similarity index 100% rename from lib/core/src/utils.c.ri rename to lib/core/src/utils.ri diff --git a/lib/rivet/src/resolver/exprs.ri b/lib/rivet/src/resolver/exprs.ri index 7e8dda371..3c484c04b 100644 --- a/lib/rivet/src/resolver/exprs.ri +++ b/lib/rivet/src/resolver/exprs.ri @@ -358,17 +358,18 @@ extend Resolver { func check_symbol_abi(mut self, sym: ast.Sym, pos: token.Pos) { if sym.abi != .Rivet { - if self.source_file_abi != sym.abi { + if self.source_file_abi == sym.abi { + self.different_abi_usage_count += 1; + } else { mut warn := report.warn_builder( "using a symbol whose ABI is different from that of the current file", pos ); warn.add_note("`{}` is declared as `extern ({})`", sym.name, sym.abi); warn.add_help( - "consider adding `.{}.` extension to current filename", sym.abi.lower() + "consider adding `.{}.ri` extension to current filename", sym.abi.lower() ); warn.emit(); } - self.different_abi_usage_count += 1; } } } diff --git a/lib/rivet/src/resolver/mod.ri b/lib/rivet/src/resolver/mod.ri index 6e3981b5f..ea37bd2c6 100644 --- a/lib/rivet/src/resolver/mod.ri +++ b/lib/rivet/src/resolver/mod.ri @@ -26,7 +26,7 @@ pub struct Resolver { mut self_sym_is_set: bool; mut source_file: ast.SourceFile; - mut source_file_abi: ast.ABI := .Rivet; + mut source_file_abi: ast.ABI; mut different_abi_usage_count: uint; pub func resolve_files(mut self, source_files: []ast.SourceFile) { @@ -38,10 +38,10 @@ pub struct Resolver { Prelude("Throwable", self.table.throwable_sym) ]; for sf in source_files { - self.source_file_abi = .Rivet; self.sym = sf.mod; self.source_file = sf; self.detect_source_file_abi(); + self.different_abi_usage_count = 0; self.resolve_decls(self.source_file.decls); if self.source_file_abi == .Rivet and self.different_abi_usage_count > 0 { report.warn("filename requires ABI specification", sf.pos); @@ -53,8 +53,10 @@ pub struct Resolver { func detect_source_file_abi(mut self) { filename := Path.file_name(self.source_file.path); - if filename.contains(".c.") { + if filename.ends_with(".c.ri") { self.source_file_abi = .C; + } else { + self.source_file_abi = .Rivet; } }