Skip to content

Commit 4b02f62

Browse files
committed
optimizations
1 parent b4e5da0 commit 4b02f62

6 files changed

Lines changed: 115 additions & 115 deletions

File tree

nattlua/analyzer/analyzer.lua

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -284,14 +284,16 @@ do
284284
return a.count > b.count
285285
end
286286

287+
local os_clock = os.clock
288+
287289
function META:CheckTimeout()
288-
local start_prof = os.clock()
290+
local start_prof = os_clock()
289291

290-
if not self.start_time then self.start_time = os.clock() end
292+
if not self.start_time then self.start_time = start_prof end
291293

292294
self.check_count = (self.check_count or 0) + 1
293295
local count = self.check_count
294-
local elapsed = os.clock() - self.start_time
296+
local elapsed = start_prof - self.start_time
295297

296298
if count < max_iterations and elapsed < max_time_seconds then return end
297299

nattlua/analyzer/base/lexical_scope.lua

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,21 @@ function META:SetParent(parent)
4646
end
4747

4848
function META:BuildParentCache()
49-
local parent = self
49+
self.ParentList[1] = self
50+
self.ParentMap[self] = self
51+
local parent = self.Parent
5052

51-
for i = 1, 1000 do
52-
if not parent then break end
53+
if not parent then
54+
self.Root = self
55+
return
56+
end
5357

54-
self.ParentList[i] = parent
55-
self.ParentMap[parent] = parent
56-
parent = parent.Parent
58+
for i, scope in ipairs(parent.ParentList) do
59+
self.ParentList[i + 1] = scope
60+
self.ParentMap[scope] = scope
5761
end
5862

59-
self.Root = parent or self
63+
self.Root = parent.Root
6064
end
6165

6266
function META:AddTrackedObject(val)

nattlua/code.lua

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,11 @@ if has_ffi--[[# as false]] then
9494
function META.New(lua_code--[[#: string]], name--[[#: string | nil]])
9595
name = name or callstack.get_line(2)
9696
local code = " " .. lua_code
97-
local self = ctype{
98-
Buffer = code,
99-
buffer_len = #code,
100-
Name = name,
101-
name_length = #name,
102-
}
97+
local self = ctype()
98+
self.Buffer = code
99+
self.buffer_len = #code
100+
self.Name = name
101+
self.name_length = #name
103102
--self.Buffer = self.Buffer + 1
104103
self.buffer_len = self.buffer_len - 1
105104

nattlua/types/shared.lua

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -444,24 +444,30 @@ function shared.IsSubsetOf(
444444
end
445445

446446
for _, a_val in ipairs(a.Data) do
447-
a:PushSuppress()
448-
449447
if b.Type == "union" then
450-
local b_val, reason = b:IsTypeObjectSubsetOf(a_val)
451-
a:PopSuppress()
448+
a:PushSuppress()
449+
local reasons
450+
local found = false
452451

453-
if not b_val then
454-
return false, error_messages.because(error_messages.subset(a_val, b), reason)
452+
for i, obj in ipairs(b.Data) do
453+
local ok, reason = shared.IsSubsetOf(a_val, obj)
454+
455+
if ok then
456+
found = true
457+
break
458+
end
459+
460+
reasons = reasons or {}
461+
reasons[i] = reason
455462
end
456463

457-
a:PushSuppress()
458-
local ok, reason = shared.IsSubsetOf(a_val, b_val)
459464
a:PopSuppress()
460465

461-
if not ok then
462-
return false, error_messages.because(error_messages.subset(a_val, b_val), reason)
466+
if not found then
467+
return false, error_messages.because(error_messages.subset(a_val, b), reasons)
463468
end
464469
else
470+
a:PushSuppress()
465471
local ok, reason = shared.IsSubsetOf(a_val, b)
466472
a:PopSuppress()
467473

nattlua/types/union.lua

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -310,21 +310,6 @@ function META:GetAtTupleIndexUnion(i--[[#: number]])
310310
return val, is_inf
311311
end
312312

313-
function META:IsTypeObjectSubsetOf(typ--[[#: TBaseType]])
314-
local errors
315-
316-
for i, obj in ipairs(self.Data) do
317-
local ok, reason = shared.IsSubsetOf(typ, obj)
318-
319-
if ok then return obj end
320-
321-
errors = errors or {}
322-
errors[i] = reason
323-
end
324-
325-
return false, errors
326-
end
327-
328313
function META:HasTypeObject(obj--[[#: TBaseType]])
329314
for i, v in ipairs(self.Data) do
330315
local ok, reason = shared.IsSubsetOf(obj, v)

test/helpers/coverage.lua

Lines changed: 78 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -15,97 +15,101 @@ local math_min = _G.math.min
1515
local math_max = _G.math.max
1616
local math_huge = _G.math.huge
1717

18-
function coverage.Preprocess(code, key)
19-
local expressions = {}
20-
21-
local function inject_call_expression(parser, node, start, stop)
22-
if node.environment == "typesystem" then return node end
18+
local function inject_call_expression(parser, node, start, stop)
19+
local expressions = parser.config.coverage_expressions
2320

24-
if node.Type == "expression_postfix_call" and node.type_call then return node end
21+
if node.environment == "typesystem" then return node end
2522

26-
if node.Type == "expression_function" then
27-
-- don't mark the funciton body as being called
28-
start, stop = node.tokens["function"].start, node.tokens["function"].stop
29-
end
23+
if node.Type == "expression_postfix_call" and node.type_call then return node end
3024

31-
if node.Type == "expression_table" then
32-
-- don't mark the funciton body as being called
33-
start, stop = node.tokens["{"].start, node.tokens["{"].stop
34-
end
25+
if node.Type == "expression_function" then
26+
-- don't mark the funciton body as being called
27+
start, stop = node.tokens["function"].start, node.tokens["function"].stop
28+
end
3529

36-
local call_expression = parser:ParseString(" " .. FUNC_NAME .. "(" .. start .. "," .. stop .. ",x)").statements[1].value
30+
if node.Type == "expression_table" then
31+
-- don't mark the funciton body as being called
32+
start, stop = node.tokens["{"].start, node.tokens["{"].stop
33+
end
3734

38-
if node.Type == "expression_postfix_call" and not node.tokens["call("] then
39-
node.tokens["call("] = parser:NewToken("symbol", "(")
40-
node.tokens["call)"] = parser:NewToken("symbol", ")")
41-
end
35+
local call_expression = parser:ParseString(" " .. FUNC_NAME .. "(" .. start .. "," .. stop .. ",x)").statements[1].value
4236

43-
call_expression.expressions[3] = node
37+
if node.Type == "expression_postfix_call" and not node.tokens["call("] then
38+
node.tokens["call("] = parser:NewToken("symbol", "(")
39+
node.tokens["call)"] = parser:NewToken("symbol", ")")
40+
end
4441

45-
if node.Type == "expression_binary_operator" and node.right then
46-
call_expression.right = node.right
47-
end
42+
call_expression.expressions[3] = node
4843

49-
table_insert(expressions, node)
50-
-- to prevent start stop messing up from previous injections
51-
call_expression.code_start = node.code_start
52-
call_expression.code_stop = node.code_stop
53-
return call_expression
44+
if node.Type == "expression_binary_operator" and node.right then
45+
call_expression.right = node.right
5446
end
5547

56-
local function inject_token(token)
57-
token:ReplaceValue(
58-
" " .. FUNC_NAME .. "(" .. token.start .. "," .. token.stop .. ",x) " .. token:GetValueString()
59-
)
48+
table_insert(expressions, node)
49+
-- to prevent start stop messing up from previous injections
50+
call_expression.code_start = node.code_start
51+
call_expression.code_stop = node.code_stop
52+
return call_expression
53+
end
54+
55+
local function inject_token(token)
56+
token:ReplaceValue(
57+
" " .. FUNC_NAME .. "(" .. token.start .. "," .. token.stop .. ",x) " .. token:GetValueString()
58+
)
59+
end
60+
61+
local function on_parsed_coverage_node(parser, node)
62+
if node.is_statement then
63+
-- inject a call right before the token itself which uses the token for range
64+
if node.Type == "statement_return" then
65+
inject_token(node.tokens["return"])
66+
elseif node.Type == "statement_break" then
67+
inject_token(node.tokens["break"])
68+
elseif node.Type == "statement_continue" then
69+
inject_token(node.tokens["continue"])
70+
elseif node.Type == "statement_call_expression" then
71+
local start, stop = node:GetStartStop()
72+
node.value = inject_call_expression(parser, node.value, start, stop)
73+
end
74+
elseif node.is_expression then
75+
if
76+
node.is_left_assignment or
77+
node.is_identifier or
78+
(
79+
node:GetStatement().Type == "statement_function" or
80+
node:GetStatement().Type == "statement_type_function"
81+
)
82+
or
83+
(
84+
node.Type == "expression_binary_operator" and
85+
node.value.sub_type == ":"
86+
)
87+
or
88+
(
89+
node.parent and
90+
node.parent.Type == "expression_binary_operator" and
91+
(
92+
node.parent.value.sub_type == "." or
93+
node.parent.value.sub_type == ":"
94+
)
95+
)
96+
then
97+
return
98+
end
99+
100+
return inject_call_expression(parser, node, node:GetStartStop())
60101
end
102+
end
61103

104+
function coverage.Preprocess(code, key)
105+
local expressions = {}
62106
local compiler = nl.Compiler(
63107
code,
64108
key,
65109
{
66110
parser = {
67-
on_parsed_node = function(parser, node)
68-
if node.is_statement then
69-
-- inject a call right before the token itself which uses the token for range
70-
if node.Type == "statement_return" then
71-
inject_token(node.tokens["return"])
72-
elseif node.Type == "statement_break" then
73-
inject_token(node.tokens["break"])
74-
elseif node.Type == "statement_continue" then
75-
inject_token(node.tokens["continue"])
76-
elseif node.Type == "statement_call_expression" then
77-
local start, stop = node:GetStartStop()
78-
node.value = inject_call_expression(parser, node.value, start, stop)
79-
end
80-
elseif node.is_expression then
81-
if
82-
node.is_left_assignment or
83-
node.is_identifier or
84-
(
85-
node:GetStatement().Type == "statement_function" or
86-
node:GetStatement().Type == "statement_type_function"
87-
)
88-
or
89-
(
90-
node.Type == "expression_binary_operator" and
91-
node.value.sub_type == ":"
92-
)
93-
or
94-
(
95-
node.parent and
96-
node.parent.Type == "expression_binary_operator" and
97-
(
98-
node.parent.value.sub_type == "." or
99-
node.parent.value.sub_type == ":"
100-
)
101-
)
102-
then
103-
return
104-
end
105-
106-
return inject_call_expression(parser, node, node:GetStartStop())
107-
end
108-
end,
111+
coverage_expressions = expressions,
112+
on_parsed_node = on_parsed_coverage_node,
109113
skip_import = true,
110114
},
111115
}

0 commit comments

Comments
 (0)