checker: remove duplicate const error; fmt: force full path to consts

pull/8265/head
Alexander Medvednikov 2021-01-24 10:01:10 +01:00
parent 69e6ba7a64
commit 8bcb6c10cc
4 changed files with 85 additions and 61 deletions

View File

@ -55,7 +55,7 @@ fn parse_iso8601_date(s string) ?(int, int, int) {
year, month, day, dummy := 0, 0, 0, byte(0)
count := unsafe { C.sscanf(charptr(s.str), '%4d-%2d-%2d%c', &year, &month, &day, &dummy) }
if count != 3 {
return err_invalid_8601
return time.err_invalid_8601
}
return year, month, day
}
@ -81,12 +81,12 @@ fn parse_iso8601_time(s string) ?(int, int, int, int, i64, bool) {
count++ // Increment count because skipped microsecond
}
if count < 4 {
return err_invalid_8601
return time.err_invalid_8601
}
is_local_time := plus_min_z == `a` && count == 4
is_utc := plus_min_z == `Z` && count == 5
if !(count == 7 || is_local_time || is_utc) {
return err_invalid_8601
return time.err_invalid_8601
}
if plus_min_z != `+` && plus_min_z != `-` && !is_utc && !is_local_time {
return error('Invalid 8601 format, expected `Z` or `+` or `-` as time separator')
@ -113,7 +113,7 @@ pub fn parse_iso8601(s string) ?Time {
t_i := s.index('T') or { -1 }
parts := if t_i != -1 { [s[..t_i], s[t_i + 1..]] } else { s.split(' ') }
if !(parts.len == 1 || parts.len == 2) {
return err_invalid_8601
return time.err_invalid_8601
}
year, month, day := parse_iso8601_date(parts[0]) ?
mut hour, mut minute, mut second, mut microsecond, mut unix_offset, mut is_local_time := 0, 0, 0, 0, i64(0), true

View File

@ -13,9 +13,9 @@ const (
// but otherwise can be changed at will.
absolute_zero_year = i64(-292277022399) // as i64
seconds_per_minute = 60
seconds_per_hour = 60 * seconds_per_minute
seconds_per_day = 24 * seconds_per_hour
seconds_per_week = 7 * seconds_per_day
seconds_per_hour = 60 * time.seconds_per_minute
seconds_per_day = 24 * time.seconds_per_hour
seconds_per_week = 7 * time.seconds_per_day
days_per_400_years = 365 * 400 + 97
days_per_100_years = 365 * 100 + 24
days_per_4_years = 365 * 4 + 1
@ -141,7 +141,7 @@ pub fn (t Time) smonth() string {
return '---'
}
i := t.month - 1
return months_string[i * 3..(i + 1) * 3]
return time.months_string[i * 3..(i + 1) * 3]
}
// new_time returns a time struct with calculated Unix time.
@ -186,12 +186,12 @@ pub fn (t Time) add(d Duration) Time {
// add_seconds returns a new time struct with an added number of seconds.
pub fn (t Time) add_seconds(seconds int) Time {
return t.add(seconds * second)
return t.add(seconds * time.second)
}
// add_days returns a new time struct with an added number of days.
pub fn (t Time) add_days(days int) Time {
return t.add(days * 24 * hour)
return t.add(days * 24 * time.hour)
}
// since returns a number of seconds elapsed since a given time.
@ -300,13 +300,13 @@ pub fn (t Time) day_of_week() int {
// weekday_str returns the current day as a string.
pub fn (t Time) weekday_str() string {
i := t.day_of_week() - 1
return days_string[i * 3..(i + 1) * 3]
return time.days_string[i * 3..(i + 1) * 3]
}
// weekday_str returns the current day as a string.
pub fn (t Time) long_weekday_str() string {
i := t.day_of_week() - 1
return long_days[i]
return time.long_days[i]
}
// ticks returns a number of milliseconds elapsed since system start.
@ -362,7 +362,7 @@ pub fn days_in_month(month int, year int) ?int {
return error('Invalid month: $month')
}
extra := if month == 2 && is_leap_year(year) { 1 } else { 0 }
res := month_days[month - 1] + extra
res := time.month_days[month - 1] + extra
return res
}
@ -382,7 +382,7 @@ fn convert_ctime(t C.tm, microsecond int) Time {
hour: t.tm_hour
minute: t.tm_min
second: t.tm_sec
microsecond: microsecond
microsecond: time.microsecond
unix: u64(make_unix_time(t))
}
}
@ -392,11 +392,11 @@ pub type Duration = i64
pub const (
nanosecond = Duration(1)
microsecond = Duration(1000 * nanosecond)
millisecond = Duration(1000 * microsecond)
second = Duration(1000 * millisecond)
minute = Duration(60 * second)
hour = Duration(60 * minute)
microsecond = Duration(1000 * time.nanosecond)
millisecond = Duration(1000 * time.microsecond)
second = Duration(1000 * time.millisecond)
minute = Duration(60 * time.second)
hour = Duration(60 * time.minute)
infinite = Duration(-1)
)
@ -419,22 +419,22 @@ pub fn (d Duration) milliseconds() i64 {
// consider all of them in sub-one intervals
// seconds returns the duration as a floating point number of seconds.
pub fn (d Duration) seconds() f64 {
sec := d / second
nsec := d % second
sec := d / time.second
nsec := d % time.second
return f64(sec) + f64(nsec) / 1e9
}
// minutes returns the duration as a floating point number of minutes.
pub fn (d Duration) minutes() f64 {
min := d / minute
nsec := d % minute
min := d / time.minute
nsec := d % time.minute
return f64(min) + f64(nsec) / (60 * 1e9)
}
// hours returns the duration as a floating point number of hours.
pub fn (d Duration) hours() f64 {
hr := d / hour
nsec := d % hour
hr := d / time.hour
nsec := d % time.hour
return f64(hr) + f64(nsec) / (60 * 60 * 1e9)
}

View File

@ -215,7 +215,7 @@ fn (mut c Checker) check_file_in_main(file ast.File) bool {
match stmt {
ast.ConstDecl {
if stmt.is_pub {
c.warn('const $no_pub_in_main_warning', stmt.pos)
c.warn('const $checker.no_pub_in_main_warning', stmt.pos)
}
}
/*
@ -228,7 +228,7 @@ fn (mut c Checker) check_file_in_main(file ast.File) bool {
*/
ast.EnumDecl {
if stmt.is_pub {
c.warn('enum `$stmt.name` $no_pub_in_main_warning', stmt.pos)
c.warn('enum `$stmt.name` $checker.no_pub_in_main_warning', stmt.pos)
}
}
ast.FnDecl {
@ -257,7 +257,8 @@ fn (mut c Checker) check_file_in_main(file ast.File) bool {
}
}
if stmt.is_pub && !stmt.is_method {
c.warn('function `$stmt.name` $no_pub_in_main_warning', stmt.pos)
c.warn('function `$stmt.name` $checker.no_pub_in_main_warning',
stmt.pos)
}
}
if stmt.return_type != table.void_type {
@ -272,21 +273,24 @@ fn (mut c Checker) check_file_in_main(file ast.File) bool {
}
ast.StructDecl {
if stmt.is_pub {
c.warn('struct `$stmt.name` $no_pub_in_main_warning', stmt.pos)
c.warn('struct `$stmt.name` $checker.no_pub_in_main_warning', stmt.pos)
}
}
ast.TypeDecl {
if stmt is ast.AliasTypeDecl {
if stmt.is_pub {
c.warn('type alias `$stmt.name` $no_pub_in_main_warning', stmt.pos)
c.warn('type alias `$stmt.name` $checker.no_pub_in_main_warning',
stmt.pos)
}
} else if stmt is ast.SumTypeDecl {
if stmt.is_pub {
c.warn('sum type `$stmt.name` $no_pub_in_main_warning', stmt.pos)
c.warn('sum type `$stmt.name` $checker.no_pub_in_main_warning',
stmt.pos)
}
} else if stmt is ast.FnTypeDecl {
if stmt.is_pub {
c.warn('type alias `$stmt.name` $no_pub_in_main_warning', stmt.pos)
c.warn('type alias `$stmt.name` $checker.no_pub_in_main_warning',
stmt.pos)
}
}
}
@ -1084,7 +1088,7 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) {
pos = expr.pos
}
}
} else if expr.name in c.const_names {
} else if expr.obj is ast.ConstField && expr.name in c.const_names {
c.error('cannot modify constant `$expr.name`', expr.pos)
}
}
@ -1327,7 +1331,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
}
// TODO: remove this for actual methods, use only for compiler magic
// FIXME: Argument count != 1 will break these
if left_type_sym.kind == .array && method_name in array_builtin_methods {
if left_type_sym.kind == .array && method_name in checker.array_builtin_methods {
mut elem_typ := table.void_type
is_filter_map := method_name in ['filter', 'map']
is_sort := method_name == 'sort'
@ -2348,7 +2352,7 @@ pub fn (mut c Checker) enum_decl(decl ast.EnumDecl) {
match field.expr {
ast.IntegerLiteral {
val := field.expr.val.i64()
if val < int_min || val > int_max {
if val < checker.int_min || val > checker.int_max {
c.error('enum value `$val` overflows int', field.expr.pos)
} else if !decl.is_multi_allowed && i64(val) in seen {
c.error('enum value `$val` already exists', field.expr.pos)
@ -2372,7 +2376,7 @@ pub fn (mut c Checker) enum_decl(decl ast.EnumDecl) {
} else {
if seen.len > 0 {
last := seen[seen.len - 1]
if last == int_max {
if last == checker.int_max {
c.error('enum value overflows', field.pos)
}
seen << last + 1
@ -2453,7 +2457,8 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
mut is_large := false
if expr.val.len > 8 {
val := expr.val.i64()
if (!negative && val > int_max) || (negative && -val < int_min) {
if (!negative && val > checker.int_max)
|| (negative && -val < checker.int_min) {
is_large = true
}
}
@ -2511,10 +2516,12 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
}
*/
}
if is_decl {
if false && is_decl {
full_name := '${left.mod}.$left.name'
if full_name in c.const_names {
c.error('duplicate of a const name `$left.name`', left.pos)
if obj := c.file.global_scope.find(full_name) {
if obj is ast.ConstField {
c.warn('duplicate of a const name `$full_name', left.pos)
}
}
}
}
@ -4183,11 +4190,11 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym table.TypeS
mut err_details := 'match must be exhaustive'
if unhandled.len > 0 {
err_details += ' (add match branches for: '
if unhandled.len < match_exhaustive_cutoff_limit {
if unhandled.len < checker.match_exhaustive_cutoff_limit {
err_details += unhandled.join(', ')
} else {
remaining := unhandled.len - match_exhaustive_cutoff_limit
err_details += unhandled[0..match_exhaustive_cutoff_limit].join(', ')
remaining := unhandled.len - checker.match_exhaustive_cutoff_limit
err_details += unhandled[0..checker.match_exhaustive_cutoff_limit].join(', ')
err_details += ', and $remaining others ...'
}
err_details += ' or `else {}` at the end)'
@ -4684,13 +4691,13 @@ fn (mut c Checker) comp_if_branch(cond ast.Expr, pos token.Position) bool {
}
}
ast.Ident {
if cond.name in valid_comp_if_os {
if cond.name in checker.valid_comp_if_os {
return cond.name != c.pref.os.str().to_lower() // TODO hack
} else if cond.name in valid_comp_if_compilers {
} else if cond.name in checker.valid_comp_if_compilers {
return pref.cc_from_string(cond.name) != c.pref.ccompiler_type
} else if cond.name in valid_comp_if_platforms {
} else if cond.name in checker.valid_comp_if_platforms {
return false // TODO
} else if cond.name in valid_comp_if_other {
} else if cond.name in checker.valid_comp_if_other {
// TODO: This should probably be moved
match cond.name {
'js' { return c.pref.backend != .js }

View File

@ -107,8 +107,8 @@ pub fn (mut f Fmt) writeln(s string) {
}
fn (mut f Fmt) write_indent() {
if f.indent < tabs.len {
f.out.write(tabs[f.indent])
if f.indent < fmt.tabs.len {
f.out.write(fmt.tabs[f.indent])
} else {
// too many indents, do it the slow way:
for _ in 0 .. f.indent {
@ -122,7 +122,7 @@ pub fn (mut f Fmt) wrap_long_line(penalty_idx int, add_indent bool) bool {
if f.buffering {
return false
}
if f.line_len <= max_len[penalty_idx] {
if f.line_len <= fmt.max_len[penalty_idx] {
return false
}
if f.out.buf[f.out.buf.len - 1] == ` ` {
@ -556,7 +556,7 @@ fn (mut list []CommentAndExprAlignInfo) add_info(attrs_len int, type_len int, li
return
}
d_len := abs(list[i].max_attrs_len - attrs_len) + abs(list[i].max_type_len - type_len)
if !(d_len < threshold_to_align_struct) {
if !(d_len < fmt.threshold_to_align_struct) {
list.add_new_info(attrs_len, type_len, line)
return
}
@ -980,7 +980,7 @@ pub fn (mut f Fmt) or_expr(or_block ast.OrExpr) {
// so, since this'll all be on one line, trim any possible whitespace
str := f.stmt_str(or_block.stmts[0]).trim_space()
single_line := ' or { $str }'
if single_line.len + f.line_len <= max_len.last() {
if single_line.len + f.line_len <= fmt.max_len.last() {
f.write(single_line)
} else {
// if the line would be too long, make it multiline
@ -1144,6 +1144,24 @@ pub fn (mut f Fmt) ident(node ast.Ident) {
} else if node.kind == .blank_ident {
f.write('_')
} else {
// Force usage of full path to const in the same module:
// `println(minute)` => `println(time.minute)`
// This allows using the variable `minute` inside time's functions
// and also makes it clear that a module const is being used
// (since V's conts are no longer ALL_CAP).
if !node.name.contains('.') {
full_name := f.cur_mod + '.' + node.name
if obj := f.file.global_scope.find(full_name) {
if obj is ast.ConstField {
// "v.fmt.foo" => "fmt.foo"
vals := full_name.split('.')
short := vals[vals.len - 2] + '.' + vals[vals.len - 1]
// f.write(f.short_module(full_name))
f.write(short)
return
}
}
}
name := f.short_module(node.name)
// f.write('<$it.name => $name>')
f.write(name)
@ -1321,14 +1339,13 @@ pub fn (mut f Fmt) string_literal(node ast.StringLiteral) {
f.write("'$node.val'")
}
} else {
unescaped_val := node.val.replace('$bs$bs', '\x01').replace_each(["$bs'", "'", '$bs"',
'"',
])
unescaped_val := node.val.replace('$fmt.bs$fmt.bs', '\x01').replace_each(["$fmt.bs'", "'",
'$fmt.bs"', '"'])
if use_double_quote {
s := unescaped_val.replace_each(['\x01', '$bs$bs', '"', '$bs"'])
s := unescaped_val.replace_each(['\x01', '$fmt.bs$fmt.bs', '"', '$fmt.bs"'])
f.write('"$s"')
} else {
s := unescaped_val.replace_each(['\x01', '$bs$bs', "'", "$bs'"])
s := unescaped_val.replace_each(['\x01', '$fmt.bs$fmt.bs', "'", "$fmt.bs'"])
f.write("'$s'")
}
}
@ -1454,7 +1471,7 @@ pub fn (mut f Fmt) infix_expr(node ast.InfixExpr) {
}
if !buffering_save && f.buffering {
f.buffering = false
if !f.single_line_if && f.line_len > max_len.last() {
if !f.single_line_if && f.line_len > fmt.max_len.last() {
f.wrap_infix(infix_start, start_len)
}
}
@ -1506,7 +1523,7 @@ pub fn (mut f Fmt) wrap_infix(start_pos int, start_len int) {
}
for i, c in conditions {
cnd := c.trim_space()
if f.line_len + cnd.len < max_len[penalties[i]] {
if f.line_len + cnd.len < fmt.max_len[penalties[i]] {
if i > 0 && (!is_cond_infix || i < conditions.len - 1) {
f.write(' ')
}
@ -1558,7 +1575,7 @@ pub fn (mut f Fmt) if_expr(it ast.IfExpr) {
}
}
// When a single line if is really long, write it again as multiline
if single_line && f.line_len > max_len.last() {
if single_line && f.line_len > fmt.max_len.last() {
single_line = false
f.single_line_if = false
f.out.go_back(f.line_len - if_start)
@ -2021,7 +2038,7 @@ pub fn (mut f Fmt) struct_init(it ast.StructInit) {
f.comments(field.next_comments, inline: false, has_nl: true, level: .keep)
if single_line_fields
&& (field.comments.len > 0 || field.next_comments.len > 0 || !expr_is_single_line(field.expr)
|| f.line_len > max_len.last()) {
|| f.line_len > fmt.max_len.last()) {
single_line_fields = false
f.out.go_back_to(fields_start)
f.line_len = fields_start