-
-
Notifications
You must be signed in to change notification settings - Fork 423
Expand file tree
/
Copy pathboolean-context.lua
More file actions
87 lines (82 loc) · 2.27 KB
/
boolean-context.lua
File metadata and controls
87 lines (82 loc) · 2.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
local files = require 'files'
local guide = require 'parser.guide'
local vm = require 'vm'
local lang = require 'language'
local await = require 'await'
---@param node vm.node
---@return string|nil
local function getTruthiness(node)
if node:alwaysTruthy() then
return 'true'
end
if node:alwaysFalsy() then
return 'false'
end
return nil
end
---@param infer vm.infer
---@param uri uri
---@return boolean|nil
local function isBooleanOnly(infer, uri)
if infer:hasAny(uri) or infer:hasUnknown(uri) then
return nil
end
for view in infer:eachView(uri) do
if view ~= 'boolean'
and view ~= 'true'
and view ~= 'false' then
return false
end
end
return true
end
---@param source parser.object?
---@return boolean
---@param source parser.object?
---@param uri uri
---@param callback fun(result: diag.result)
local function checkExpression(source, uri, callback)
if not source then
return
end
local infer = vm.getInfer(source)
local onlyBoolean = isBooleanOnly(infer, uri)
if onlyBoolean == true or onlyBoolean == nil then
return
end
local node = vm.compileNode(source)
local truthiness = getTruthiness(node)
if truthiness then
callback {
start = source.start,
finish = source.finish,
message = lang.script('DIAG_BOOLEAN_CONTEXT_ALWAYS', truthiness),
}
return
end
callback {
start = source.start,
finish = source.finish,
message = lang.script('DIAG_BOOLEAN_CONTEXT_NONBOOLEAN', infer:view(uri)),
}
end
---@async
return function (uri, callback)
local state = files.getState(uri)
if not state then
return
end
---@async
guide.eachSourceTypes(state.ast, {'ifblock', 'elseifblock', 'while', 'repeat'}, function (source)
await.delay()
if source.filter
and source.filter.type == 'binary'
and source.filter.op
and (source.filter.op.type == 'and' or source.filter.op.type == 'or') then
checkExpression(source.filter[1], uri, callback)
checkExpression(source.filter[2], uri, callback)
return
end
checkExpression(source.filter, uri, callback)
end)
end