-
-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add public keyword #320
Add public keyword #320
Conversation
Codecov Report
@@ Coverage Diff @@
## main #320 +/- ##
==========================================
- Coverage 96.56% 96.56% -0.01%
==========================================
Files 14 14
Lines 4138 4158 +20
==========================================
+ Hits 3996 4015 +19
- Misses 142 143 +1
|
Is this just to test stuff out? It seems from the discussion in JuliaLang/julia#50105 that the whole concept of a "scoped export" was not very liked, or? |
Yse this is just to test things out, and also I don't think we ever really got to discussing naming particularly thoroughly—most discussion was and still is focused on objections about supporting the notion of public symbols at all. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very cool!
I know this is just a prototype but I added a couple of comments.
A general comment - one tricky thing about using peek
is that it doesn't always do what you expect - it can be overly restrictive. For example, one would normally expect var"x"
to work in Julia syntax anywhere that x
works, and this is handled by parse_atom
. However, with the peek
s you've got here, you can't write
export var"scoped"=true A, B
Of course that's no loss for this particular syntax! But just a general note of caution that peek
ing into the coming tokens should be viewed with skepticism, especially if it's more than a couple of tokens ahead :-) It can be a sign that a parsing function may be doing work that should be done deeper into the tree of calls.
I don't think this is working as intended. Did you intend to restrict parsing of this to top level and to julia> parsestmt(SyntaxNode, "public A, B")
line:col│ tree │ file_name
1:1 │[public]
1:8 │ A
1:11 │ B
julia> parsestmt(SyntaxNode, "begin \n public A, B \n end")
line:col│ tree │ file_name
1:1 │[block]
2:2 │ [public]
2:9 │ A
2:12 │ B
julia> parsestmt(SyntaxNode, "module \n public A, B \n end")
line:col│ tree │ file_name
1:1 │[module]
2:2 │ public
2:8 │ [block]
2:9 │ [tuple]
2:9 │ A
2:12 │ B |
This is probably the source of your woes at JuliaLang/julia#50105 (comment) |
Thank you for looking at this, I definitely appreciate/need help figuring out those woes. However, I don't think this is the problem. Deep in the callstack, The examples you showed all seem good to me. The module example is weird because Here are some more examples that IMO have good behavior with respect to when public is treated as a keyword and when it is not:julia> parsestmt(SyntaxNode, "function f(public)\n public + 3\nend")
line:col│ tree │ file_name
1:1 │[function]
1:10 │ [call]
1:10 │ f
1:12 │ public
1:19 │ [block]
2:5 │ [call-i]
2:5 │ public
2:12 │ +
2:14 │ 3
julia> parsestmt(SyntaxNode, "public A, B")
line:col│ tree │ file_name
1:1 │[public]
1:8 │ A
1:11 │ B
julia> parsestmt(SyntaxNode, "begin \n public A, B \n end")
line:col│ tree │ file_name
1:1 │[block]
2:2 │ [public]
2:9 │ A
2:12 │ B
julia> parsestmt(SyntaxNode, "if true \n public A, B \n end") # throws
ERROR: ParseError:
# Error @ line 2:9
if true
# ┌────
public A, B
end
┘ ── Expected `end`
Stacktrace:
[1] _parse(rule::Symbol, need_eof::Bool, ::Type{…}, text::String, index::Int64; version::VersionNumber, ignore_trivia::Bool, filename::Nothing, first_line::Int64, ignore_errors::Bool, ignore_warnings::Bool, kws::@Kwargs{})
@ JuliaSyntax ~/.julia/dev/JuliaSyntax/src/parser_api.jl:87
[2] _parse(rule::Symbol, need_eof::Bool, ::Type{SyntaxNode}, text::String) (repeats 2 times)
@ JuliaSyntax ~/.julia/dev/JuliaSyntax/src/parser_api.jl:71 [inlined]
[3] parsestmt(::Type{SyntaxNode}, text::String; kws::@Kwargs{})
@ JuliaSyntax ~/.julia/dev/JuliaSyntax/src/parser_api.jl:134 [inlined]
[4] parsestmt(::Type{SyntaxNode}, text::String)
@ JuliaSyntax ~/.julia/dev/JuliaSyntax/src/parser_api.jl:134
[5] top-level scope
@ REPL[77]:1
Some type information was truncated. Use `show(err)` to see complete types.
julia> parsestmt(SyntaxNode, "if true \n public *= 4 \n end")
line:col│ tree │ file_name
1:1 │[if]
1:4 │ true
1:8 │ [block]
2:2 │ [*=]
2:2 │ public
2:12 │ 4
julia> parsestmt(SyntaxNode, "module Mod\n public A, B \n end")
line:col│ tree │ file_name
1:1 │[module]
1:8 │ Mod
1:11 │ [block]
2:2 │ [public]
2:9 │ A
2:12 │ B |
Of course. Yikes that's kind of obvious 😬 Did you consider adding julia> parsestmt(SyntaxNode, "struct abstract end")
line:col│ tree │ file_name
1:1 │[struct]
1:8 │ abstract
1:16 │ [block] but julia> parsestmt(SyntaxNode, "struct public end")
ERROR: ParseError:
# Error @ line 1:7
struct public end
# └─────┘ ── Invalid type name `public` |
Is the following intended? julia> parsestmt(SyntaxNode, """
function f()
begin
public A,B
end
end
""")
line:col│ tree │ file_name
1:5 │[function]
1:14 │ [call]
1:14 │ f
1:17 │ [block]
2:9 │ [block]
3:13 │ [public]
3:20 │ A
3:22 │ B |
Nope :) |
Hehe. In that case I think we've got two options.
|
That feels right. |
public(::String) = true to continue to parse the old way. |
I think this is good to go! |
Add public as a contextual keyword that is parsed as a keyword only when it is both at the top-level and not followed by `(`, `=`, or `[`. Aside from this, the `public` keyword uses the same syntax as the `export` keyword and lowers analogously. Emit a warning when parsing `public` at the top-level followed by a `(`, `=`, or `[`. Co-authored-by: Claire Foster <[email protected]>
Add public as a contextual keyword that is parsed as a keyword only when it is both at the top-level and not followed by `(`, `=`, or `[`. Aside from this, the `public` keyword uses the same syntax as the `export` keyword and lowers analogously. Emit a warning when parsing `public` at the top-level followed by a `(`, `=`, or `[`. Co-authored-by: Claire Foster <[email protected]>
This fixes a whole bunch of small but annoying bugs, as described in the JuliaSyntax-0.4.7 release notes https://github.com/JuliaLang/JuliaSyntax.jl/releases/tag/v0.4.7 I've been careful about cutting the JuliaSyntax-0.4.7 release from nonbreaking changes, so we should be able to backport this to 1.10. --- Extended notes about compatibility * The public keyword in JuliaLang/JuliaSyntax.jl#320 is released in JuliaSyntax-0.4.7 but JuliaSyntax is multi-version aware so this is disabled when used as the default parser in Julia 1.10, but is enabled in 1.11-DEV. So should be backportable. * We aim for parsing to `Expr` to always be stable in JuliaSyntax and independent of the host Julia `VERSION`, but we're not fully there yet for 1.11 / 1.10 due to JuliaLang/JuliaSyntax.jl#377. Thus some careful management of the JuliaSyntax-0.4.x branch for now.
This fixes a whole bunch of small but annoying bugs, as described in the JuliaSyntax-0.4.7 release notes https://github.com/JuliaLang/JuliaSyntax.jl/releases/tag/v0.4.7 I've been careful about cutting the JuliaSyntax-0.4.7 release from nonbreaking changes, so we should be able to backport this to 1.10. --- Extended notes about compatibility * The public keyword in JuliaLang/JuliaSyntax.jl#320 is released in JuliaSyntax-0.4.7 but JuliaSyntax is multi-version aware so this is disabled when used as the default parser in Julia 1.10, but is enabled in 1.11-DEV. So should be backportable. * We aim for parsing to `Expr` to always be stable in JuliaSyntax and independent of the host Julia `VERSION`, but we're not fully there yet for 1.11 / 1.10 due to JuliaLang/JuliaSyntax.jl#377. Thus some careful management of the JuliaSyntax-0.4.x branch for now. (cherry picked from commit 85d7cca)
This PR is a part of JuliaLang/julia#50105.