Skip to content

Commit 6a7e539

Browse files
authored
Merge pull request #388 from julia-vscode/sp/public
feat: handle public kw
2 parents 94852f4 + 949d780 commit 6a7e539

File tree

11 files changed

+102
-33
lines changed

11 files changed

+102
-33
lines changed

.github/workflows/jlpkgbutler-ci-master-workflow.yml

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,13 @@ jobs:
1212
runs-on: ${{ matrix.os }}
1313
strategy:
1414
matrix:
15-
julia-version: ['1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', '1.9', '1.10']
16-
julia-arch: [x64, x86]
17-
os: [ubuntu-latest, windows-latest, macOS-latest]
18-
exclude:
19-
- os: macOS-latest
20-
julia-arch: x86
21-
15+
julia-version: ['1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', '1.9', '1.10', '1.11']
16+
os: [ubuntu-latest, windows-latest]
2217
steps:
23-
- uses: actions/checkout@v3
24-
- uses: julia-actions/setup-julia@v1
18+
- uses: actions/checkout@v4
19+
- uses: julia-actions/install-juliaup@v1
2520
with:
26-
version: ${{ matrix.julia-version }}
27-
arch: ${{ matrix.julia-arch }}
21+
julia-version: ${{ matrix.julia-version }}
2822
- uses: julia-actions/julia-buildpkg@v1
2923
env:
3024
PYTHON: ""
@@ -37,4 +31,3 @@ jobs:
3731
files: ./lcov.info
3832
flags: unittests
3933
token: ${{ secrets.CODECOV_TOKEN }}
40-

.github/workflows/jlpkgbutler-ci-pr-workflow.yml

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,14 @@ jobs:
99
runs-on: ${{ matrix.os }}
1010
strategy:
1111
matrix:
12-
julia-version: ['1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', '1.9', '1.10']
13-
julia-arch: [x64, x86]
14-
os: [ubuntu-latest, windows-latest, macOS-latest]
15-
exclude:
16-
- os: macOS-latest
17-
julia-arch: x86
12+
julia-version: ['1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', '1.9', '1.10', '1.11']
13+
os: [ubuntu-latest, windows-latest]
1814

1915
steps:
20-
- uses: actions/checkout@v3
21-
- uses: julia-actions/setup-julia@v1
16+
- uses: actions/checkout@v4
17+
- uses: julia-actions/install-juliaup@v1
2218
with:
23-
version: ${{ matrix.julia-version }}
24-
arch: ${{ matrix.julia-arch }}
19+
julia-version: ${{matrix.julia-version}}
2520
- uses: julia-actions/julia-buildpkg@v1
2621
env:
2722
PYTHON: ""

src/components/internals.jl

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,10 @@ function parse_comma_sep(ps::ParseState, args::Vector{EXPR}, trivia::Vector{EXPR
152152
@nocloser ps :inwhere @nocloser ps :newline @closer ps :comma while !closer(ps)
153153
a = parse_expression(ps)
154154
if kw && _do_kw_convert(ps, a)
155-
a = _kw_convert(a)
155+
b = _do_block_convert(a)
156+
a = _kw_convert(a, b)
156157
end
158+
157159
push!(args, a)
158160
if iscomma(ps.nt)
159161
if istuple
@@ -366,6 +368,21 @@ function parse_nonstd_identifier(ps)
366368
end
367369
end
368370

371+
function parse_public_item(ps::ParseState)
372+
if kindof(ps.nt) === Tokens.AT_SIGN
373+
parse_macroname(next(ps))
374+
elseif kindof(ps.nt) === Tokens.EX_OR
375+
parse_unary(ps, INSTANCE(next(ps)))
376+
elseif isoperator(ps.nt)
377+
next(ps)
378+
EXPR(:OPERATOR, ps.nt.startbyte - ps.t.startbyte, 1 + ps.t.endbyte - ps.t.startbyte, val(ps.t, ps))
379+
elseif is_nonstd_identifier(ps)
380+
parse_nonstd_identifier(ps)
381+
else
382+
INSTANCE(next(ps))
383+
end
384+
end
385+
369386
function parse_importexport_item(ps, is_colon = false)
370387
if kindof(ps.nt) === Tokens.AT_SIGN
371388
parse_macroname(next(ps))

src/components/keywords.jl

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
Dispatch function for when the parser has reached a keyword.
55
"""
6-
function parse_kw(ps::ParseState)
6+
function parse_kw(ps::ParseState; is_toplevel = false)
77
k = kindof(ps.t)
88
if ps.closer.precedence == 20 && ps.lt.kind === Tokens.EX_OR && k !== Tokens.END
99
return EXPR(:IDENTIFIER, ps)
@@ -72,6 +72,12 @@ function parse_kw(ps::ParseState)
7272
return @default ps parse_abstract(ps)
7373
elseif k === Tokens.PRIMITIVE
7474
return @default ps parse_primitive(ps)
75+
elseif k === Tokens.PUBLIC
76+
if is_toplevel
77+
return @default ps parse_public(ps)
78+
else
79+
return EXPR(:IDENTIFIER, ps)
80+
end
7581
elseif k === Tokens.TYPE
7682
return EXPR(:IDENTIFIER, ps)
7783
elseif k === Tokens.STRUCT
@@ -157,6 +163,23 @@ function parse_primitive(ps::ParseState)
157163
return ret
158164
end
159165

166+
function parse_public(ps::ParseState)
167+
args = EXPR[]
168+
trivia = EXPR[EXPR(ps)]
169+
170+
push!(args, parse_importexport_item(ps))
171+
172+
prevpos = position(ps)
173+
while iscomma(ps.nt)
174+
push!(trivia, EXPR(next(ps)))
175+
arg = parse_importexport_item(ps)
176+
push!(args, arg)
177+
prevpos = loop_check(ps, prevpos)
178+
end
179+
180+
return EXPR(:public, args, trivia)
181+
end
182+
160183
function parse_mutable(ps::ParseState)
161184
if kindof(ps.nt) === Tokens.STRUCT
162185
kw = EXPR(ps)

src/interface.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
isidentifier(x::EXPR) = headof(x) === :IDENTIFIER || headof(x) === :NONSTDIDENTIFIER
33
isoperator(x::EXPR) = headof(x) === :OPERATOR
44
isnonstdid(x::EXPR) = headof(x) === :NONSTDIDENTIFIER
5-
iskeyword(x::EXPR) = headof(x) in (:ABSTRACT, :BAREMODULE, :BEGIN, :BREAK, :CATCH, :CONST, :CONTINUE, :DO, :ELSE, :ELSEIF, :END, :EXPORT, :FINALLY, :FOR, :FUNCTION, :GLOBAL, :IF, :IMPORT, :importall, :LET, :LOCAL, :MACRO, :MODULE, :MUTABLE, :NEW, :OUTER, :PRIMITIVE, :QUOTE, :RETURN, :STRUCT, :TRY, :TYPE, :USING, :WHILE)
5+
iskeyword(x::EXPR) = headof(x) in (:ABSTRACT, :BAREMODULE, :BEGIN, :BREAK, :CATCH, :CONST, :CONTINUE, :DO, :ELSE, :ELSEIF, :END, :EXPORT, :FINALLY, :FOR, :FUNCTION, :GLOBAL, :IF, :IMPORT, :importall, :LET, :LOCAL, :MACRO, :MODULE, :MUTABLE, :NEW, :OUTER, :PRIMITIVE, :PUBLIC, :QUOTE, :RETURN, :STRUCT, :TRY, :TYPE, :USING, :WHILE)
66
isliteral(x::EXPR) = isstringliteral(x) || iscmd(x) || ischar(x) || headof(x) in (:INTEGER, :BININT, :HEXINT, :OCTINT, :FLOAT, :NOTHING, :TRUE, :FALSE)
77
ispunctuation(x::EXPR) = is_comma(x) || is_lparen(x) || is_rparen(x) || is_lsquare(x) || is_rsquare(x) || is_lbrace(x) || is_rbrace(x) || headof(x) === :ATSIGN || headof(x) === :DOT
88
isstringliteral(x) = headof(x) === :STRING || headof(x) === :TRIPLESTRING

src/packagedef.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Acceptable starting tokens are:
3333
+ An `@`.
3434
3535
"""
36-
function parse_expression(ps::ParseState, esc_on_error = false)
36+
function parse_expression(ps::ParseState, esc_on_error = false; is_toplevel = false)
3737
if kindof(ps.nt) === Tokens.ENDMARKER
3838
ret = mErrorToken(ps, UnexpectedToken)
3939
elseif (esc_on_error && ps.nt.kind == Tokens.ERROR)
@@ -47,7 +47,7 @@ function parse_expression(ps::ParseState, esc_on_error = false)
4747
else
4848
next(ps)
4949
if iskeyword(kindof(ps.t)) && kindof(ps.t) != Tokens.DO
50-
ret = parse_kw(ps)
50+
ret = parse_kw(ps; is_toplevel=is_toplevel)
5151
elseif kindof(ps.t) === Tokens.LPAREN
5252
ret = parse_paren(ps)
5353
elseif kindof(ps.t) === Tokens.LSQUARE
@@ -212,14 +212,14 @@ function parse_doc(ps::ParseState)
212212
elseif isbinaryop(ps.nt) && !closer(ps)
213213
ret = parse_compound_recur(ps, doc)
214214
else
215-
ret = parse_expression(ps)
215+
ret = parse_expression(ps; is_toplevel = true)
216216
ret = EXPR(:macrocall, EXPR[EXPR(:globalrefdoc, 0, 0), EXPR(:NOTHING, 0, 0), doc, ret], nothing)
217217
end
218218
else
219-
ret = parse_expression(ps)
219+
ret = parse_expression(ps; is_toplevel = true)
220220
end
221221
if _continue_doc_parse(ps, ret)
222-
push!(ret, parse_expression(ps))
222+
push!(ret, parse_expression(ps; is_toplevel = true))
223223
end
224224
return ret
225225
end

src/spec.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,8 @@ function tokenkindtoheadmap(k::Tokens.Kind)
387387
return :OUTER
388388
elseif k === Tokens.PRIMITIVE
389389
return :PRIMITIVE
390+
elseif k === Tokens.PUBLIC
391+
return :PUBLIC
390392
elseif k === Tokens.QUOTE
391393
return :QUOTE
392394
elseif k === Tokens.RETURN

src/utils.jl

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -607,12 +607,24 @@ Should `a` be converted to a keyword-argument expression?
607607
"""
608608
_do_kw_convert(ps::ParseState, a::EXPR) = !ps.closer.brace && isassignment(a)
609609

610+
_do_block_convert(a::EXPR) =
611+
a.args[1] !== nothing && isoperator(a.args[1].head) && a.args[1].args !== nothing && a.args[1].args[1].head === :call
612+
610613
"""
611-
_kw_convert(ps::ParseState, a::EXPR)
614+
_kw_convert(a::EXPR, blockwrap = false)
612615
613616
Converted an assignment expression to a keyword-argument expression.
614617
"""
615-
_kw_convert(x::EXPR) = EXPR(:kw, EXPR[x.args[1], x.args[2]], EXPR[x.head], x.fullspan, x.span)
618+
_kw_convert(x::EXPR, blockwrap = false) = EXPR(
619+
:kw,
620+
EXPR[
621+
x.args[1],
622+
# in some specific cases, the reference parser wraps the RHS of kwargs in an extra block
623+
blockwrap ?
624+
EXPR(:block, EXPR[x.args[2]], EXPR[], x.args[2].fullspan, x.args[2].span) :
625+
x.args[2]
626+
],
627+
EXPR[x.head], x.fullspan, x.span)
616628

617629
"""
618630
convertsigtotuple(sig::EXPR)

test/parser/test_keyword_blocks.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,23 @@ end""" |> test_expr
189189
end""" |> test_expr
190190
@test "f() do x body end" |> test_expr
191191
end
192+
193+
if VERSION > v"1.11-"
194+
@testitem "public" begin
195+
using CSTParser: remlineinfo!
196+
include("../shared.jl")
197+
198+
@test "public foo" |> test_expr
199+
@test "public foo, bar" |> test_expr
200+
@test """
201+
public foo,
202+
bar
203+
""" |> test_expr
204+
@test "f() = public" |> test_expr
205+
@test """
206+
let
207+
public
208+
end
209+
""" |> test_expr
210+
end
211+
end

test/test_check_base.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@
160160
# CSTParser does not support right now. This does not mean that we
161161
# cannot parse that file though, just that Expr conversion doesn't
162162
# work well
163-
if v"1.10-" <= VERSION < v"1.11-" && basename(file) == "syntax.jl"
163+
if v"1.10-" <= VERSION < v"1.12-" && basename(file) == "syntax.jl"
164164
@test_broken false
165165
else
166166
@test false

0 commit comments

Comments
 (0)