/
githubmirror
/
julia
Обзор
Документация
Войти
/
githubmirror
/
julia
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
JuliaLowering/test/validation.jl
188 строк
5 KB
Em Chu
[JuliaLowering] Make `SyntaxTree` a standard tree (#62474)
29 июл 2026, 15:34
Не верифицирован
29 июл 2026, 15:34
92cca2d
Код
Авторство
О чём код?
# Basic tests that the validator accepts or rejects a given form. For testing # error messages, write an IR test instead. function vst1_ok(x::Expr) est = JuliaLowering.expr_to_est(x) JuliaSyntax.fill_context!(est, JuliaSyntax.SyntaxContext(@__MODULE__, v"1.13")) JuliaLowering.valid_st1(est).ok end let nonempty_heads = String[ "let", "if", "try", "function", "call", "'", ".", "do", "=", "return", "for", "while", "curly", "where", "->", "flatten", "generator", "comprehension", "typed_comprehension", "comparison", "::", ".&&", ".||", "const", "global", "local", "macrocall", "quote", "inert", "syntaxinert", "top", "opaque_closure", "symboliclabel", "symbolicgoto", "symbolicblock", "gc_preserve", "isdefined", "lambda", "foreigncall", "cfunction", "cconv", "tryfinally", "inline", "noinline", "inbounds", "islocal", "isglobal", "new", "splatnew", "thisfunction", "copyast", ":", "...", ".+=", "|=", ".=", "braces", "\$", "parameters", "kw", "outer", "macro", "struct", "abstract", "primitive", "module", "local-def", "::", "where", "curly", "ref", "ncat", "nrow", "typed_hcat", "typed_vcat", "typed_ncat", "import", "using", ] standalone_heads = String[ "block", "tuple", "public", "export", "string", "&&", "<:", ">:", "-->", "&&", "||", "toplevel", "locals", "vect", "hcat", "vcat", "meta", "boundscheck", "loopinfo", ] @testset for h in nonempty_heads @test !vst1_ok(Expr(Symbol(h))) end @testset for h in standalone_heads ex = Expr(Symbol(h)) @test !Meta.isexpr(:error, Meta.lower(@__MODULE__, ex)) @test vst1_ok(ex) end end if JL.DEBUG @test_throws ErrorException vst1_ok(Expr(:nothing)) else @test !vst1_ok(Expr(:nothing)) end @test vst1_ok(Expr(:block, nothing)) @test vst1_ok(Expr(:block, GlobalRef(Core, :nothing))) @test vst1_ok(Expr(:-->, 1)) @test vst1_ok(Expr(:-->, 1, 2)) @test vst1_ok(Expr(:-->, 1, 2, 3)) @test vst1_ok(Expr(:-->, Expr(:..., Expr(:tuple, 1, 2, 3)))) @test vst1_ok(Expr(:-->, Expr(:kw, :foo, 1))) @test vst1_ok(Expr(:const, :a, 1)) # vst1_dot_getproperty_rhs allows usually-invalid forms @testset "dot rhs forms" for rhs in [:_, :__, Symbol("#unused#"), :ccall, :cglobal, 1] @test vst1_ok(Expr(:., :Mod, rhs)) @test vst1_ok(Expr(:., :Mod, Expr(:inert, rhs))) @test vst1_ok(Expr(:., :Mod, QuoteNode(rhs))) @test vst1_ok(Expr(:., :Mod, string(rhs))) @test vst1_ok(Expr(:., :Mod, Expr(:inert, string(rhs)))) @test vst1_ok(Expr(:., :Mod, QuoteNode(string(rhs)))) end @test vst1_ok(:(using Mod: cglobal)) @test vst1_ok(:(Mod.cglobal)) @test vst1_ok(:(Mod._ = 1)) @testset "underscores that should probably not be valid" begin @test vst1_ok(:(Mod._)) @test vst1_ok(:(function f(x::_); x; end)) @test vst1_ok(:(global _)) @test vst1_ok(:(global _::Int)) @test vst1_ok(:(local _)) @test vst1_ok(:(local _::Int)) end @testset "empty symbol is valid" for e in [ Expr(:block, Symbol("")) Expr(:inert, Symbol("")) Expr(:(::), Symbol(""), :Int) Expr(:const, Expr(:(=), Symbol(""), 1)) Expr(:global, Expr(:(=), Symbol(""), 1)) Expr(:local, Expr(:(=), Symbol(""), 1)) Expr(:let, Expr(:block, Expr(:(=), Symbol(""), 1)), Expr(:block)) Expr(:function, Expr(:call, Symbol("")), Expr(:block)) ] @test vst1_ok(e) end @testset "import/using path" begin # `.` after identifier @test !vst1_ok(Expr(:import, Expr(:., :A, :., :B))) # leading `.` on a name @test !vst1_ok(Expr(:import, Expr(:(:), Expr(:., :M), Expr(:., :., :a)))) # non-identifier rename @test !vst1_ok(Expr(:import, Expr(:(:), Expr(:., :M), Expr(:as, Expr(:., :a), Expr(:call, :f))))) # empty path @test !vst1_ok(Expr(:import, Expr(:.))) # not an import path @test !vst1_ok(Expr(:import, Expr(:call, :f))) @test !vst1_ok(Expr(:import, 42)) end