parser: do not allow calling private functions

pull/4951/head^2
Alexander Medvednikov 2020-05-18 22:54:08 +02:00
parent 2a62f1a312
commit 03525843a0
9 changed files with 49 additions and 40 deletions

View File

@ -31,7 +31,7 @@ fn C.backtrace_symbols(a &voidptr, size int) &charptr
fn C.backtrace_symbols_fd(a &voidptr, size int, fd int)
// <libproc.h>
fn proc_pidpath(int, voidptr, int) int
pub fn proc_pidpath(int, voidptr, int) int
fn C.realpath(byteptr, byteptr) &char

View File

@ -836,7 +836,7 @@ pub fn on_segfault(f voidptr) {
fn C.getpid() int
fn C.proc_pidpath(int, byteptr, int) int
//fn C.proc_pidpath(int, byteptr, int) int
fn C.readlink() int

View File

@ -12,7 +12,7 @@ const (
max_u64 = u64(C.UINT64_MAX)// as u64 // use this until we add support
)
fn byte_to_lower(c byte) byte {
pub fn byte_to_lower(c byte) byte {
return c | (`x` - `X`)
}

View File

@ -29,7 +29,7 @@ struct C.timespec {
// the first arg is defined in include/bits/types.h as `__S32_TYPE`, which is `int`
fn C.clock_gettime(int, &C.timespec)
fn sys_mono_now() u64 {
pub fn sys_mono_now() u64 {
$if macos {
return sys_mono_now_darwin()
} $else {

View File

@ -41,7 +41,7 @@ fn init_win_time_start() u64 {
return s
}
fn sys_mono_now() u64 {
pub fn sys_mono_now() u64 {
tm := u64(0)
C.QueryPerformanceCounter(&tm) // XP or later never fail
return (tm - start_time) * 1_000_000_000 / freq_time

View File

@ -878,6 +878,10 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
call_expr.pos)
}
}
if !f.is_pub && !f.is_c && !c.is_builtin_mod && !c.pref.is_test && f.mod != c.mod && f.name !=
'' && f.mod != '' {
c.warn('function `$f.name` is private. curmod=$c.mod fmod=$f.mod', call_expr.pos)
}
call_expr.return_type = f.return_type
if f.return_type == table.void_type && f.ctdefine.len > 0 && f.ctdefine !in c.pref.compile_defines {
call_expr.should_be_skipped = true
@ -1483,35 +1487,7 @@ fn (mut c Checker) stmt(node ast.Stmt) {
c.check_expr_opt_call(it.expr, etype, false)
}
ast.FnDecl {
if !it.is_c && !it.is_js && !c.is_builtin_mod {
c.check_valid_snake_case(it.name, 'function name', it.pos)
}
if it.is_method {
sym := c.table.get_type_symbol(it.receiver.typ)
if sym.kind == .interface_ {
c.error('interfaces cannot be used as method receiver', it.receiver_pos)
}
// if sym.has_method(it.name) {
// c.warn('duplicate method `$it.name`', it.pos)
// }
}
if !it.is_c {
// Make sure all types are valid
for arg in it.args {
sym := c.table.get_type_symbol(arg.typ)
if sym.kind == .placeholder {
c.error('unknown type `$sym.name`', it.pos)
}
}
}
c.expected_type = table.void_type
c.fn_return_type = it.return_type
c.stmts(it.stmts)
if !it.is_c && !it.is_js && !it.no_body && it.return_type != table.void_type &&
!c.returns && it.name !in ['panic', 'exit'] {
c.error('missing return at end of function `$it.name`', it.pos)
}
c.returns = false
c.fn_decl(it)
}
ast.ForCStmt {
c.in_for_count++
@ -2312,3 +2288,35 @@ fn (mut c Checker) warn_or_error(message string, pos token.Position, warn bool)
fn (c &Checker) fileis(s string) bool {
return c.file.path.contains(s)
}
fn (mut c Checker) fn_decl(it ast.FnDecl) {
if !it.is_c && !it.is_js && !c.is_builtin_mod {
c.check_valid_snake_case(it.name, 'function name', it.pos)
}
if it.is_method {
sym := c.table.get_type_symbol(it.receiver.typ)
if sym.kind == .interface_ {
c.error('interfaces cannot be used as method receiver', it.receiver_pos)
}
// if sym.has_method(it.name) {
// c.warn('duplicate method `$it.name`', it.pos)
// }
}
if !it.is_c {
// Make sure all types are valid
for arg in it.args {
sym := c.table.get_type_symbol(arg.typ)
if sym.kind == .placeholder {
c.error('unknown type `$sym.name`', it.pos)
}
}
}
c.expected_type = table.void_type
c.fn_return_type = it.return_type
c.stmts(it.stmts)
if !it.is_c && !it.is_js && !it.no_body && it.return_type != table.void_type && !c.returns &&
it.name !in ['panic', 'exit'] {
c.error('missing return at end of function `$it.name`', it.pos)
}
c.returns = false
}

View File

@ -255,6 +255,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
is_generic: is_generic
is_pub: is_pub
ctdefine: ctdefine
mod: p.mod
})
}
// Body

View File

@ -3,21 +3,21 @@ module util
import os
[inline]
fn is_name_char(c byte) bool {
pub fn is_name_char(c byte) bool {
return (c >= `a` && c <= `z`) || (c >= `A` && c <= `Z`) || c == `_`
}
[inline]
fn is_func_char(c byte) bool {
pub fn is_func_char(c byte) bool {
return (c >= `a` && c <= `z`) || (c >= `A` && c <= `Z`) || c == `_` || c.is_digit()
}
[inline]
fn is_nl(c byte) bool {
pub fn is_nl(c byte) bool {
return c == `\r` || c == `\n`
}
fn contains_capital(s string) bool {
pub fn contains_capital(s string) bool {
for c in s {
if c >= `A` && c <= `Z` {
return true
@ -28,7 +28,7 @@ fn contains_capital(s string) bool {
// HTTPRequest bad
// HttpRequest good
fn good_type_name(s string) bool {
pub fn good_type_name(s string) bool {
if s.len < 4 {
return true
}

View File

@ -222,7 +222,7 @@ fn imax(a, b int) int {
}
}
fn replace_op(s string) string {
pub fn replace_op(s string) string {
last_char := s[s.len - 1]
suffix := match last_char {
`+` { '_plus' }