summaryrefslogtreecommitdiff
path: root/script/core/diagnostics/ambiguity-1.lua
blob: 0b8385d8ef49a5aa39d51424230ba5f88f72a872 (plain)
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
local files    = require 'files'
local searcher = require 'core.searcher'
local lang     = require 'language'

local opMap = {
    ['+']  = true,
    ['-']  = true,
    ['*']  = true,
    ['/']  = true,
    ['//'] = true,
    ['^']  = true,
    ['<<'] = true,
    ['>>'] = true,
    ['&']  = true,
    ['|']  = true,
    ['~']  = true,
    ['..'] = true,
}

local literalMap = {
    ['number']  = true,
    ['boolean'] = true,
    ['string']  = true,
    ['table']   = true,
}

return function (uri, callback)
    local ast = files.getAst(uri)
    if not ast then
        return
    end
    local text = files.getText(uri)
    searcher.eachSourceType(ast.ast, 'binary', function (source)
        if source.op.type ~= 'or' then
            return
        end
        local first  = source[1]
        local second = source[2]
        -- a + (b or 0) --> (a + b) or 0
        do
            if opMap[first.op and first.op.type]
                and first.type ~= 'unary'
                and not second.op
                and literalMap[second.type]
                and not literalMap[first[2].type]
            then
                callback {
                    start   = source.start,
                    finish  = source.finish,
                    message = lang.script('DIAG_AMBIGUITY_1', text:sub(first.start, first.finish))
                }
            end
        end
        -- (a or 0) + c --> a or (0 + c)
        do
            if opMap[second.op and second.op.type]
                and second.type ~= 'unary'
                and not first.op
                and literalMap[second[1].type]
            then
                callback {
                    start   = source.start,
                    finish  = source.finish,
                    message = lang.script('DIAG_AMBIGUITY_1', text:sub(second.start, second.finish))
                }
            end
        end
    end)
end