Skip to content

Commit fc4aba9

Browse files
authored
Merge pull request #274 from xuhuanzy/diagnostic
diagnostic
2 parents 8c7e093 + 26b67ec commit fc4aba9

35 files changed

Lines changed: 673 additions & 114 deletions

crates/emmylua_code_analysis/locales/lint.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ Should not reassign to iter variable:
6868
zh_CN: '不应重新赋值给迭代变量'
6969
zh_HK: '不應重新指定迭代變數'
7070

71-
expected `%{source}` but found `%{found}`:
72-
en: expected `%{source}` but found `%{found}`
73-
zh_CN: '预期 `%{source}`,但得到 `%{found}`'
74-
zh_HK: '期望 `%{source}`,但得到 `%{found}`'
71+
expected `%{source}` but found `%{found}`. %{reason}:
72+
en: expected `%{source}` but found `%{found}`. %{reason}
73+
zh_CN: '预期 `%{source}`,但得到 `%{found}`。 %{reason}'
74+
zh_HK: '期望 `%{source}`,但得到 `%{found}`。 %{reason}'
7575
function %{name} may be nil:
7676
en: function %{name} may be nil
7777
zh_CN: '函数 %{name} 可能为 nil'

crates/emmylua_code_analysis/resources/std/debug.lua

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,11 @@ function debug.getregistry() end
146146
---
147147
--- Variable names starting with '(' (open parenthesis) represent variables with
148148
--- no known names (variables from chunks saved without debug information).
149-
---@param f integer
149+
---@param f async fun(...):any...
150150
---@param up integer
151-
---@return table
151+
---@return string name
152+
---@return any value
153+
---@nodiscard
152154
function debug.getupvalue(f, up) end
153155

154156
---
@@ -236,6 +238,7 @@ function debug.setlocal(thread, level, var, value) end
236238
---@param value T
237239
---@param meta? table
238240
---@return T value
241+
---@overload fun(value: table, meta: T): T
239242
function debug.setmetatable(value, meta) end
240243

241244
---

crates/emmylua_code_analysis/resources/std/global.lua

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,7 @@ function dofile(filename) end
8787
--- `error` function was called. Level 2 points the error to where the function
8888
--- that called `error` was called; and so on. Passing a level 0 avoids the
8989
--- addition of error position information to the message.
90-
---@overload fun(message:string)
91-
---@param message string
90+
---@param message any
9291
---@param level? integer
9392
function error(message, level) end
9493

@@ -114,7 +113,7 @@ function getmetatable(object) end
114113
--- will iterate over the key–value pairs (1,`t[1]`), (2,`t[2]`), ..., up to
115114
--- the first absent index.
116115
---@generic V
117-
---@param t V[] | table<any, V>
116+
---@param t V[] | table<any, V> | {[any]: V}
118117
---@return fun(tbl: any):int, std.NotNull<V>
119118
function ipairs(t) end
120119

@@ -232,7 +231,7 @@ function next(table, index) end
232231
--- See function `next` for the caveats of modifying the table during its
233232
--- traversal.
234233
---@generic K, V
235-
---@param t table<K, V>
234+
---@param t table<K, V> | V[] | {[K]: V}
236235
---@return fun(tbl: any):K, std.NotNull<V>
237236
function pairs(t) end
238237
---

crates/emmylua_code_analysis/resources/std/io.lua

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,25 @@ function io.output(file) end
9494
---@return file
9595
function io.popen(prog, mode) end
9696

97+
---@alias std.readmode
98+
---| integer
99+
---| string
100+
---| "n" # Reads a number, returning a float or integer based on Lua's conversion grammar.
101+
---| "a" # Reads the entire file starting from the current position.
102+
---| "l" # Reads a line and ignores the end-of-line marker.
103+
---| "L" # Reads a line and preserves the end-of-line marker.
104+
---| "*n" # Reads a number, returning a float or integer based on Lua's conversion grammar.
105+
---| "*a" # Reads the entire file starting from the current position.
106+
---| "*l" # Reads a line and ignores the end-of-line marker.
107+
---| "*L" # Reads a line and preserves the end-of-line marker.
108+
97109
---
98110
--- Equivalent to `io.input():read(···)`.
99-
--- @param format '*n' | '*a' | '*l' | integer
100-
--- @return string | integer | nil
101-
--- @overload fun(format:'*n'): integer
102-
--- @overload fun(format:'*a' | '*l' | integer): string | nil
103-
function io.read(format) end
111+
---@param ... std.readmode
112+
---@return any
113+
---@return any ...
114+
---@nodiscard
115+
function io.read(...) end
104116

105117
---
106118
--- In case of success, returns a handle for a temporary file. This file is
@@ -195,11 +207,11 @@ function file:lines(...) end
195207
--- *number*: reads a string with up to this number of bytes, returning **nil**
196208
--- on end of file. If `number` is zero, it reads nothing and returns an
197209
--- empty string, or **nil** on end of file.
198-
--- @param format '*n' | '*a' | '*l' | integer
199-
--- @return string | integer | nil
200-
--- @overload fun(format:'*n'): integer
201-
--- @overload fun(format:'*a' | '*l' | integer): string | nil
202-
function file:read(format) end
210+
---@param ... std.readmode
211+
---@return any
212+
---@return any ...
213+
---@nodiscard
214+
function file:read(...) end
203215

204216
---
205217
--- Sets and gets the file position, measured from the beginning of the

crates/emmylua_code_analysis/resources/std/string.lua

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,14 @@ function string.dump(func, strip) end
7575
---
7676
--- If the pattern has captures, then in a successful match the captured values
7777
--- are also returned, after the two indices.
78-
---@overload fun(s:string, pattern:string):integer, integer, string...
79-
---@param s string
80-
---@param pattern string
81-
---@param init? integer
82-
---@param plain? boolean
83-
---@return integer, integer, string...
78+
---@param s string|number
79+
---@param pattern string|number
80+
---@param init? integer
81+
---@param plain? boolean
82+
---@return integer|nil start
83+
---@return integer|nil end
84+
---@return string ... captured
85+
---@nodiscard
8486
function string.find(s, pattern, init, plain) end
8587

8688
---
@@ -276,11 +278,11 @@ function string.reverse(s) end
276278
--- corrected to 1. If `j` is greater than the string length, it is corrected to
277279
--- that length. If, after these corrections, `i` is greater than `j`, the
278280
--- function returns the empty string.
279-
---@overload fun(s:string, i:integer):string
280-
---@param s string
281-
---@param i integer
282-
---@param j integer
281+
---@param s string|number
282+
---@param i integer
283+
---@param j? integer
283284
---@return string
285+
---@nodiscard
284286
function string.sub(s, i, j) end
285287

286288
---@version >5.3

crates/emmylua_code_analysis/resources/std/table.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,9 @@ function table.sort(list, comp) end
109109
--- return `list[i]`, `list[i+1]`, `···`, `list[j]`
110110
--- By default, i is 1 and j is #list.
111111
---@generic T
112+
---@param list [T...] | table<any, T>
112113
---@param i? integer
113114
---@param j? integer
114-
---@param list [T...]
115115
---@return T...
116116
function table.unpack(list, i, j) end
117117

crates/emmylua_code_analysis/resources/std/utf8.lua

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,14 @@ function utf8.codepoint(s, i, j) end
6060
--- positions `i` and `j` (both inclusive). The default for `i` is 1 and for
6161
--- `j` is -1. If it finds any invalid byte sequence, returns a false value
6262
--- plus the position of the first invalid byte.
63-
---@overload fun(s:string):number
64-
---@param s string
65-
---@param i? number
66-
---@param j? number
67-
---@return number
68-
function utf8.len(s, i, j) end
63+
---@param s string
64+
---@param i? integer
65+
---@param j? integer
66+
---@param lax? boolean
67+
---@return integer?
68+
---@return integer? errpos
69+
---@nodiscard
70+
function utf8.len(s, i, j, lax) end
6971

7072
---
7173
--- Returns the position (in bytes) where the encoding of the `n`-th character

crates/emmylua_code_analysis/src/compilation/analyzer/decl/exprs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,9 @@ pub fn analyze_table_expr(analyzer: &mut DeclAnalyzer, expr: LuaTableExpr) -> Op
202202
);
203203

204204
let decl_feature = if analyzer.is_meta {
205-
LuaMemberFeature::MetaFieldDecl
205+
LuaMemberFeature::MetaDefine
206206
} else {
207-
LuaMemberFeature::FileFieldDecl
207+
LuaMemberFeature::FileDefine
208208
};
209209

210210
let member_id = LuaMemberId::new(field.get_syntax_id(), file_id);

crates/emmylua_code_analysis/src/compilation/analyzer/flow/var_analyze.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -132,16 +132,35 @@ fn broadcast_up(
132132
if let Some(ne_type_assert) = type_assert.get_negation() {
133133
if let Some(else_stat) = if_stat.get_else_clause() {
134134
let block_range = else_stat.get_range();
135-
flow_chain.add_type_assert(path, ne_type_assert, block_range, actual_range);
136-
} else if is_block_has_return(if_stat.get_block()?).unwrap_or(false) {
135+
flow_chain.add_type_assert(
136+
path,
137+
ne_type_assert.clone(),
138+
block_range,
139+
actual_range,
140+
);
141+
} else if is_block_has_return(if_stat.get_block()).unwrap_or(false) {
137142
let parent_block = if_stat.get_parent::<LuaBlock>()?;
138143
let parent_range = parent_block.get_range();
139144
let if_range = if_stat.get_range();
140145
if if_range.end() < parent_range.end() {
141146
let range = TextRange::new(if_range.end(), parent_range.end());
142-
flow_chain.add_type_assert(path, ne_type_assert, range, actual_range);
147+
flow_chain.add_type_assert(
148+
path,
149+
ne_type_assert.clone(),
150+
range,
151+
actual_range,
152+
);
143153
}
144154
}
155+
for else_if_clause in if_stat.get_else_if_clause_list() {
156+
let block_range = else_if_clause.get_range();
157+
flow_chain.add_type_assert(
158+
path,
159+
ne_type_assert.clone(),
160+
block_range,
161+
actual_range,
162+
);
163+
}
145164
}
146165
}
147166
LuaAst::LuaWhileStat(while_stat) => {
@@ -445,10 +464,12 @@ fn infer_lua_type_assert(
445464
Some(())
446465
}
447466

448-
fn is_block_has_return(block: LuaBlock) -> Option<bool> {
449-
for stat in block.get_stats() {
450-
if is_stat_change_flow(stat.clone()).unwrap_or(false) {
451-
return Some(true);
467+
fn is_block_has_return(block: Option<LuaBlock>) -> Option<bool> {
468+
if let Some(block) = block {
469+
for stat in block.get_stats() {
470+
if is_stat_change_flow(stat.clone()).unwrap_or(false) {
471+
return Some(true);
472+
}
452473
}
453474
}
454475

@@ -469,9 +490,7 @@ fn is_stat_change_flow(stat: LuaStat) -> Option<bool> {
469490
Some(false)
470491
}
471492
LuaStat::ReturnStat(_) => Some(true),
472-
LuaStat::DoStat(do_stat) => {
473-
Some(is_block_has_return(do_stat.get_block()?).unwrap_or(false))
474-
}
493+
LuaStat::DoStat(do_stat) => Some(is_block_has_return(do_stat.get_block()).unwrap_or(false)),
475494
_ => Some(false),
476495
}
477496
}

crates/emmylua_code_analysis/src/compilation/test/flow.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,4 +278,26 @@ print(a.field)
278278
"#
279279
));
280280
}
281+
282+
#[test]
283+
fn test_elseif() {
284+
let mut ws = VirtualWorkspace::new();
285+
286+
assert!(ws.check_code_for(
287+
DiagnosticCode::NeedCheckNil,
288+
r#"
289+
---@class D11
290+
---@field public a string
291+
292+
---@type D11|nil
293+
local a
294+
295+
if not a then
296+
elseif a.a then
297+
print(a.a)
298+
end
299+
300+
"#
301+
));
302+
}
281303
}

0 commit comments

Comments
 (0)