Skip to content

Commit f1440dc

Browse files
authored
Enable parsing of Base tests (#205)
The only weird case here is Base's test/syntax.jl which contains some pretty weird syntax cases. Cases where we don't really want to parse the same...
1 parent 1429841 commit f1440dc

File tree

2 files changed

+50
-24
lines changed

2 files changed

+50
-24
lines changed

test/parse_packages.jl

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,26 @@ end
2323
test_parse_all_in_path(base_path)
2424
end
2525

26-
if haskey(ENV, "PARSE_BASE_TEST")
27-
# TODO: Turn on by default
28-
2926
base_tests_path = joinpath(Sys.BINDIR, Base.DATAROOTDIR, "julia", "test")
3027
@testset "Parse Base tests at $base_tests_path" begin
31-
test_parse_all_in_path(base_tests_path)
32-
end
28+
for f in find_source_in_path(base_tests_path)
29+
@testset "Parse $(relpath(f, base_tests_path))" begin
30+
# In julia-1.6, test/copy.jl had spurious syntax which became the
31+
# multidimensional array syntax in 1.7.
32+
endswith(f, "copy.jl") && v"1.6" <= VERSION < v"1.7" && continue
33+
34+
# syntax.jl has some intentially weird syntax which we parse
35+
# differently than the flisp parser, and some cases which we've
36+
# decided are syntax errors.
37+
endswith(f, "syntax.jl") && continue
3338

39+
@test parsers_agree_on_file(f)
40+
# TODO:
41+
# exprs_equal = endswith(f, "syntax.jl") ?
42+
# exprs_roughly_equal : exprs_equal_no_linenum
43+
# @test parsers_agree_on_file(f; exprs_equal=exprs_equal)
44+
end
45+
end
3446
end
3547

3648
@testset "Parse Julia stdlib at $(Sys.STDLIB)" begin

test/test_utils.jl

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ function triple_string_roughly_equal(fl_str, str)
9999
return true
100100
end
101101

102+
function exprs_equal_no_linenum(fl_ex, ex)
103+
remove_all_linenums!(deepcopy(ex)) == remove_all_linenums!(deepcopy(fl_ex))
104+
end
105+
102106
# Compare Expr from reference parser expression to JuliaSyntax parser, ignoring
103107
# differences due to bugs in the reference parser.
104108
function exprs_roughly_equal(fl_ex, ex)
@@ -143,6 +147,15 @@ function exprs_roughly_equal(fl_ex, ex)
143147
if (h == :global || h == :local) && length(args) == 1 && Meta.isexpr(args[1], :tuple)
144148
# Allow invalid syntax like `global (x, y)`
145149
args = args[1].args
150+
elseif h == :function && Meta.isexpr(fl_args[1], :block)
151+
blockargs = filter(x->!(x isa LineNumberNode), fl_args[1].args)
152+
ps = blockargs[2:end]
153+
for i = 1:length(ps)
154+
if Meta.isexpr(ps[i], :(=))
155+
ps[i] = Expr(:kw, ps[i].args...)
156+
end
157+
end
158+
fl_args[1] = Expr(:tuple, Expr(:parameters, ps...), blockargs[1])
146159
end
147160
if length(fl_args) != length(args)
148161
return false
@@ -163,7 +176,8 @@ function exprs_roughly_equal(fl_ex, ex)
163176
return true
164177
end
165178

166-
function parsers_agree_on_file(filename; show_diff=false)
179+
function parsers_agree_on_file(filename; exprs_equal=exprs_equal_no_linenum,
180+
show_diff=false)
167181
text = try
168182
read(filename, String)
169183
catch
@@ -185,9 +199,7 @@ function parsers_agree_on_file(filename; show_diff=false)
185199
if show_diff && ex != fl_ex
186200
show_expr_text_diff(stdout, show, ex, fl_ex)
187201
end
188-
return !JuliaSyntax.any_error(stream) &&
189-
JuliaSyntax.remove_linenums!(ex) ==
190-
JuliaSyntax.remove_linenums!(fl_ex)
202+
return !JuliaSyntax.any_error(stream) && exprs_equal(fl_ex, ex)
191203
# Could alternatively use
192204
# exprs_roughly_equal(fl_ex, ex)
193205
catch exc
@@ -218,27 +230,29 @@ end
218230

219231
# Check whether a given SyntaxNode converts to the same Expr as the flisp
220232
# parser produces from the source text of the node.
221-
function equals_flisp_parse(tree)
233+
function equals_flisp_parse(exprs_equal, tree)
222234
node_text = sourcetext(tree)
223235
# Reparse with JuliaSyntax. This is a crude way to ensure we're not missing
224236
# some context from the parent node.
225-
ex = parseall(Expr, node_text)
226-
fl_ex = fl_parseall(node_text)
227-
if Meta.isexpr(fl_ex, :error)
228-
return true # Something went wrong in reduction; ignore these cases 😬
237+
fl_ex = fl_parseall(node_text, filename="none")
238+
if Meta.isexpr(fl_ex, :error) || (Meta.isexpr(fl_ex, :toplevel) &&
239+
length(fl_ex.args) >= 1 &&
240+
Meta.isexpr(fl_ex.args[end], :error))
241+
return true # Something went wrong in reduction; ignore these cases 😬
229242
end
230-
remove_all_linenums!(ex) == remove_all_linenums!(fl_ex)
243+
ex = parseall(Expr, node_text, filename="none", ignore_errors=true)
244+
exprs_equal(fl_ex, ex)
231245
end
232246

233247
"""
234-
reduce_test(text::AbstractString)
235-
reduce_test(tree::SyntaxNode)
248+
reduce_test(text::AbstractString; exprs_equal=exprs_equal_no_linenum)
249+
reduce_test(tree::SyntaxNode; exprs_equal=exprs_equal_no_linenum)
236250
237251
Select minimal subtrees of `text` or `tree` which are inconsistent between
238252
flisp and JuliaSyntax parsers.
239253
"""
240-
function reduce_test(failing_subtrees, tree)
241-
if equals_flisp_parse(tree)
254+
function reduce_test(failing_subtrees, tree; exprs_equal=exprs_equal_no_linenum)
255+
if equals_flisp_parse(exprs_equal, tree)
242256
return false
243257
end
244258
if !haschildren(tree)
@@ -251,7 +265,7 @@ function reduce_test(failing_subtrees, tree)
251265
if is_trivia(child) || !haschildren(child)
252266
continue
253267
end
254-
had_failing_subtrees |= reduce_test(failing_subtrees, child)
268+
had_failing_subtrees |= reduce_test(failing_subtrees, child; exprs_equal=exprs_equal)
255269
end
256270
end
257271
if !had_failing_subtrees
@@ -260,15 +274,15 @@ function reduce_test(failing_subtrees, tree)
260274
return true
261275
end
262276

263-
function reduce_test(tree::SyntaxNode)
277+
function reduce_test(tree::SyntaxNode; kws...)
264278
subtrees = Vector{typeof(tree)}()
265-
reduce_test(subtrees, tree)
279+
reduce_test(subtrees, tree; kws...)
266280
subtrees
267281
end
268282

269-
function reduce_test(text::AbstractString)
283+
function reduce_test(text::AbstractString; kws...)
270284
tree = parseall(SyntaxNode, text)
271-
reduce_test(tree)
285+
reduce_test(tree; kws...)
272286
end
273287

274288

0 commit comments

Comments
 (0)