From 8d8c9de789e159275c38291a1cbf8505db469507 Mon Sep 17 00:00:00 2001 From: Claire Foster Date: Fri, 26 Jul 2024 14:43:48 +1000 Subject: [PATCH] Make `using :A` an error; fix `using A: (..)` warning --- src/parser.jl | 10 ++++++---- test/diagnostics.jl | 5 ++++- test/parser.jl | 5 +++++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/parser.jl b/src/parser.jl index ad99e4c0..94a7b8da 100644 --- a/src/parser.jl +++ b/src/parser.jl @@ -2403,6 +2403,8 @@ function parse_atsym(ps::ParseState, allow_quotes=true) # export outer ==> (export outer) # export ($f) ==> (export ($ f)) mark = position(ps) + # Syntax Edition TODO: make all the various ways to quote things inside + # import paths an error and require `var""` in the few remaining cases. if allow_quotes && peek(ps) == K":" && !is_closing_token(ps, peek(ps,2)) # import A.:+ ==> (import (importpath A (quote-: +))) emit_diagnostic(ps, warning="quoting with `:` is not required here") @@ -2423,10 +2425,10 @@ function parse_atsym(ps::ParseState, allow_quotes=true) warn_parens = true end end - if warn_parens + b = peek_behind(ps, pos) + if warn_parens && b.orig_kind != K".." emit_diagnostic(ps, mark, warning="parentheses are not required here") end - b = peek_behind(ps, pos) ok = (b.is_leaf && (b.kind == K"Identifier" || is_operator(b.kind))) || (!b.is_leaf && b.kind in KSet"$ var") if !ok @@ -2497,7 +2499,7 @@ function parse_import(ps::ParseState, word, has_import_prefix) # import A: x as y ==> (import (: (importpath A) (as (importpath x) y))) # using A: x as y ==> (using (: (importpath A) (as (importpath x) y))) bump(ps, TRIVIA_FLAG) - parse_atsym(ps) + parse_atsym(ps, false) emit(ps, mark, K"as") if word == K"using" && !has_import_prefix # using A as B ==> (using (error (as (importpath A) B))) @@ -2552,7 +2554,7 @@ function parse_import_path(ps::ParseState) else # import @x ==> (import (importpath @x)) # import $A ==> (import (importpath ($ A))) - parse_atsym(ps) + parse_atsym(ps, false) end while true t = peek_token(ps) diff --git a/test/diagnostics.jl b/test/diagnostics.jl index 1d1f9e5d..ee9dfaeb 100644 --- a/test/diagnostics.jl +++ b/test/diagnostics.jl @@ -124,12 +124,15 @@ end Diagnostic(9, 9, :warning, "space between dots in import path") @test diagnostic("import A.:+") == Diagnostic(10, 10, :warning, "quoting with `:` is not required here") - # No warning for import `:` symbol + # No warnings for imports of `:` and parenthesized `(..)` @test diagnostic("import A.:, :", allow_multiple=true) == [] + @test diagnostic("import A: (..)", allow_multiple=true) == [] @test diagnostic("import A.(:+)") == Diagnostic(10, 13, :warning, "parentheses are not required here") @test diagnostic("export (x)") == Diagnostic(8, 10, :warning, "parentheses are not required here") + @test diagnostic("import :A") == + Diagnostic(8, 9, :error, "expected identifier") @test diagnostic("export :x") == Diagnostic(8, 9, :error, "expected identifier") @test diagnostic("public = 4", version=v"1.11") == diff --git a/test/parser.jl b/test/parser.jl index ef6c5df5..b7b7839d 100644 --- a/test/parser.jl +++ b/test/parser.jl @@ -676,6 +676,11 @@ tests = [ "import A.⋆.f" => "(import (importpath A ⋆ f))" "import A..." => "(import (importpath A ..))" "import A; B" => "(import (importpath A))" + # Colons not allowed first in import paths + # but are allowed in trailing components (#473) + "using :A" => "(using (importpath (error (quote-: A))))" + "using A: :b" => "(using (: (importpath A) (importpath (error (quote-: b)))))" + "using A: b.:c" => "(using (: (importpath A) (importpath b (quote-: c))))" ], JuliaSyntax.parse_iteration_specs => [ "i = rhs" => "(iteration (in i rhs))"