@@ -4098,7 +4098,9 @@ end
40984098# -------------------------------------------------------------------------------
40994099# Expand import / using / export
41004100
4101- function _append_importpath (ctx, path_spec, path)
4101+ function expand_importpath (path)
4102+ @chk kind (path) == K " importpath"
4103+ path_spec = Expr (:.)
41024104 prev_was_dot = true
41034105 for component in children (path)
41044106 k = kind (component)
@@ -4114,13 +4116,12 @@ function _append_importpath(ctx, path_spec, path)
41144116 throw (LoweringError (component, " invalid import path: `.` in identifier path" ))
41154117 end
41164118 prev_was_dot = is_dot
4117- push! (path_spec, @ast (ctx, component, name:: K"String" ))
4119+ push! (path_spec. args, Symbol ( name))
41184120 end
4119- path_spec
4121+ return path_spec
41204122end
41214123
4122- function expand_import (ctx, ex)
4123- is_using = kind (ex) == K " using"
4124+ function expand_import_or_using (ctx, ex)
41244125 if kind (ex[1 ]) == K " :"
41254126 # import M: x.y as z, w
41264127 # (import (: (importpath M) (as (importpath x y) z) (importpath w)))
@@ -4131,57 +4132,87 @@ function expand_import(ctx, ex)
41314132 # (call core.svec 2 "x" "y" "z" 1 "w" "w"))
41324133 @chk numchildren (ex[1 ]) >= 2
41334134 from = ex[1 ][1 ]
4134- @chk kind (from) == K " importpath"
4135- from_path = @ast ctx from [K " call"
4136- " svec" :: K"core"
4137- _append_importpath (ctx, SyntaxList (ctx), from)...
4138- ]
4135+ from_path = @ast ctx from QuoteNode (expand_importpath (from)):: K"Value"
41394136 paths = ex[1 ][2 : end ]
41404137 else
41414138 # import A.B
41424139 # (using (importpath A B))
4143- # (call module_import true nothing (call core.svec 1 "w"))
4140+ # (call eval_import true nothing (call core.svec 1 "w"))
41444141 @chk numchildren (ex) >= 1
4145- from_path = nothing_ (ctx, ex)
4142+ from_path = nothing
41464143 paths = children (ex)
41474144 end
4148- path_spec = SyntaxList (ctx)
4149- for path in paths
4145+ # Here we represent the paths as quoted `Expr` data structures
4146+ path_specs = SyntaxList (ctx)
4147+ for spec in paths
41504148 as_name = nothing
4151- if kind (path) == K " as"
4152- @chk numchildren (path) == 2
4153- as_name = path[2 ]
4154- @chk kind (as_name) == K " Identifier"
4155- path = path[1 ]
4149+ if kind (spec) == K " as"
4150+ @chk numchildren (spec) == 2
4151+ @chk kind (spec[2 ]) == K " Identifier"
4152+ as_name = Symbol (spec[2 ]. name_val)
4153+ path = QuoteNode (Expr (:as , expand_importpath (spec[1 ]), as_name))
4154+ else
4155+ path = QuoteNode (expand_importpath (spec))
41564156 end
4157- @chk kind (path) == K " importpath"
4158- push! (path_spec, @ast (ctx, path, numchildren (path):: K"Integer" ))
4159- _append_importpath (ctx, path_spec, path)
4160- push! (path_spec, isnothing (as_name) ? nothing_ (ctx, ex) :
4161- @ast (ctx, as_name, as_name. name_val:: K"String" ))
4157+ push! (path_specs, @ast ctx spec path:: K"Value" )
41624158 end
4163- @ast ctx ex [K " block"
4164- [K " assert" " toplevel_only" :: K"Symbol" [K " inert" ex]]
4165- [K " call"
4166- module_import :: K"Value"
4159+ is_using = kind (ex) == K " using"
4160+ stmts = SyntaxList (ctx)
4161+ if isnothing (from_path)
4162+ for spec in path_specs
4163+ if is_using
4164+ push! (stmts,
4165+ @ast ctx spec [K " call"
4166+ eval_using :: K"Value"
4167+ ctx. mod :: K"Value"
4168+ spec
4169+ ]
4170+ )
4171+ else
4172+ push! (stmts,
4173+ @ast ctx spec [K " call"
4174+ eval_import :: K"Value"
4175+ (! is_using) :: K"Bool"
4176+ ctx. mod :: K"Value"
4177+ " nothing" :: K"top"
4178+ spec
4179+ ]
4180+ )
4181+ end
4182+ # latestworld required between imports so that previous symbols
4183+ # become visible
4184+ push! (stmts, @ast ctx spec (:: K"latestworld" ))
4185+ end
4186+ else
4187+ push! (stmts, @ast ctx ex [K " call"
4188+ eval_import :: K"Value"
4189+ (! is_using) :: K"Bool"
41674190 ctx. mod :: K"Value"
4168- is_using :: K"Value"
41694191 from_path
4170- [K " call"
4171- " svec" :: K"core"
4172- path_spec...
4173- ]
4174- ]
4192+ path_specs...
4193+ ])
4194+ push! (stmts, @ast ctx ex (:: K"latestworld" ))
4195+ end
4196+ @ast ctx ex [K " block"
4197+ [K " assert" " toplevel_only" :: K"Symbol" [K " inert" ex]]
4198+ stmts...
4199+ [K " removable" " nothing" :: K"core" ]
41754200 ]
41764201end
41774202
41784203# Expand `public` or `export`
41794204function expand_public (ctx, ex)
4205+ identifiers = String[]
4206+ for e in children (ex)
4207+ @chk kind (e) == K " Identifier" (ex, " Expected identifier" )
4208+ push! (identifiers, e. name_val)
4209+ end
4210+ (e. name_val:: K"String" for e in children (ex))
41804211 @ast ctx ex [K " call"
4181- module_public :: K"Value"
4212+ eval_public :: K"Value"
41824213 ctx. mod:: K"Value"
41834214 (kind (ex) == K " export" ):: K"Bool"
4184- (e . name_val :: K"String" for e in children (ex)) . ..
4215+ identifiers :: K"Value"
41854216 ]
41864217end
41874218
@@ -4421,7 +4452,7 @@ function expand_forms_2(ctx::DesugaringContext, ex::SyntaxTree, docs=nothing)
44214452 elseif k == K " module"
44224453 expand_module (ctx, ex)
44234454 elseif k == K " import" || k == K " using"
4424- expand_import (ctx, ex)
4455+ expand_import_or_using (ctx, ex)
44254456 elseif k == K " export" || k == K " public"
44264457 expand_public (ctx, ex)
44274458 elseif k == K " abstract" || k == K " primitive"
0 commit comments