@@ -22,10 +22,27 @@ function resolve_import_block(x::EXPR, state::State, root, usinged, markfinal=tr
2222            elseif  root isa  Scope &&  parentof (root) != =  nothing 
2323                root =  parentof (root)
2424            else 
25+                 #  Too many dots
26+                 seterror! (arg, RelativeImportTooManyDots)
2527                return 
2628            end 
2729        elseif  isidentifier (arg) ||  (i ==  n &&  (CSTParser. ismacroname (arg) ||  isoperator (arg)))
28-             root =  maybe_lookup (hasref (arg) ?  refof (arg) :  _get_field (root, arg, state), state)
30+             cand =  hasref (arg) ?  refof (arg) :  _get_field (root, arg, state)
31+             if  cand ===  nothing 
32+                 #  Cannot resolve now (e.g. sibling not yet defined). Schedule a retry.
33+                 if  state isa  Toplevel
34+                     #  the import/using expression
35+                     imp =  StaticLint. get_parent_fexpr (arg, y ->  headof (y) ===  :using  ||  headof (y) ===  :import )
36+                     # imp !== nothing && push!(state.resolveonly, imp)
37+                     imp != =  nothing  &&  (imp ∈  state. resolveonly ||  push! (state. resolveonly, imp))
38+                     #  the enclosing module (so we re-resolve refs within it)
39+                     mod =  StaticLint. maybe_get_parent_fexpr (imp, CSTParser. defines_module)
40+                     # mod !== nothing && push!(state.resolveonly, mod)
41+                     mod != =  nothing  &&  (mod ∈  state. resolveonly ||  push! (state. resolveonly, mod))
42+                 end 
43+                 return 
44+             end 
45+             root =  maybe_lookup (cand, state)
2946            setref! (arg, root)
3047            if  i ==  n
3148                markfinal &&  _mark_import_arg (arg, root, state, usinged)
@@ -38,12 +55,21 @@ function resolve_import_block(x::EXPR, state::State, root, usinged, markfinal=tr
3855end 
3956
4057function  resolve_import (x:: EXPR , state:: State , root= getsymbols (state))
41-     if  headof (x) ===  :using  ||  headof (x) ===  :import 
42-         usinged =  headof (x) ===  :using 
58+     if  ( headof (x) ===  :using  ||  headof (x) ===  :import ) 
59+         usinged =  ( headof (x) ===  :using ) 
4360        if  length (x. args) >  0  &&  isoperator (headof (x. args[1 ])) &&  valof (headof (x. args[1 ])) ==  " :" 
44-             root =  resolve_import_block (x. args[1 ]. args[1 ], state, root, false , false )
61+             root2 =  resolve_import_block (x. args[1 ]. args[1 ], state, root, false , false )
62+             if  root2 ===  nothing 
63+                 #  schedule a retry like above
64+                 if  state isa  Toplevel
65+                     push! (state. resolveonly, x)
66+                     mod =  StaticLint. maybe_get_parent_fexpr (x, CSTParser. defines_module)
67+                     mod != =  nothing  &&  push! (state. resolveonly, mod)
68+                 end 
69+                 return 
70+             end 
4571            for  i =  2 : length (x. args[1 ]. args)
46-                 resolve_import_block (x. args[1 ]. args[i], state, root , usinged)
72+                 resolve_import_block (x. args[1 ]. args[i], state, root2 , usinged)
4773            end 
4874        else 
4975            for  i =  1 : length (x. args)
@@ -80,6 +106,9 @@ function _mark_import_arg(arg, par, state, usinged)
80106            elseif  par isa  Binding &&  par. val isa  Binding &&  par. val. val isa  EXPR &&  CSTParser. defines_module (par. val. val)
81107                add_to_imported_modules (state. scope, Symbol (valofid (arg)), scopeof (par. val. val))
82108            end 
109+         else 
110+            #  import binds the name in the current scope
111+            state. scope. names[valofid (arg)] =  bindingof (arg)
83112        end 
84113    end 
85114end 
@@ -97,7 +126,7 @@ function add_to_imported_modules(scope::Scope, name::Symbol, val)
97126    if  scope. modules isa  Dict
98127        scope. modules[name] =  val
99128    else 
100-         Dict (name =>  val)
129+         scope . modules  =   Dict {Symbol,Any} (name =>  val)
101130    end 
102131end 
103132no_modules_above (s:: Scope ) =  ! CSTParser. defines_module (s. expr) ||  s. parent ===  nothing  ||  no_modules_above (s. parent)
0 commit comments