@@ -341,7 +341,7 @@ impl Locals {
341
341
342
342
// deduping by name will effectively make locals in a child scope
343
343
// shadow the locals in its parent scopes
344
- all_locals. dedup_by ( |a, b| a. name == b. name ) ;
344
+ all_locals. dedup_by ( |a, b| a. name ( ) . is_some ( ) && a . name ( ) == b. name ( ) ) ;
345
345
346
346
all_locals
347
347
}
@@ -361,22 +361,28 @@ impl Locals {
361
361
}
362
362
363
363
#[ derive( Debug ) ]
364
- pub struct Local {
365
- pub name : Rc < str > ,
366
- pub kind : LocalKind ,
367
- }
368
-
369
- #[ derive( Debug ) ]
370
- pub enum LocalKind {
364
+ pub enum Local {
371
365
/// A local callable or UDT.
372
- Item ( ItemId ) ,
366
+ Item ( ItemId , Rc < str > ) ,
373
367
/// A type parameter.
374
- TyParam ( ParamId ) ,
368
+ TyParam ( ParamId , Rc < str > ) ,
375
369
/// A local variable or parameter.
376
- Var ( NodeId ) ,
370
+ Var ( NodeId , Rc < str > ) ,
371
+ /// A namespace import (`import Foo as A` or `open Foo`)
372
+ NamespaceImport ( NamespaceId , Option < Rc < str > > ) ,
377
373
}
378
374
379
- #[ derive( Debug , Default ) ]
375
+ impl Local {
376
+ #[ must_use]
377
+ pub fn name ( & self ) -> Option < & Rc < str > > {
378
+ match self {
379
+ Local :: Item ( _, name) | Local :: TyParam ( _, name) | Local :: Var ( _, name) => Some ( name) ,
380
+ Local :: NamespaceImport ( _, alias) => alias. as_ref ( ) ,
381
+ }
382
+ }
383
+ }
384
+
385
+ #[ derive( Debug , Default , Clone ) ]
380
386
pub struct GlobalScope {
381
387
/// Global names that are valid in a type context (UDTs, builtin types...)
382
388
tys : IndexMap < NamespaceId , FxHashMap < Rc < str > , Res > > ,
@@ -394,12 +400,17 @@ pub struct GlobalScope {
394
400
395
401
impl GlobalScope {
396
402
fn get ( & self , kind : NameKind , namespace : NamespaceId , name : & str ) -> Option < & Res > {
397
- let items = match kind {
403
+ self . table ( kind)
404
+ . get ( namespace)
405
+ . and_then ( |items| items. get ( name) )
406
+ }
407
+
408
+ pub fn table ( & self , kind : NameKind ) -> & IndexMap < NamespaceId , FxHashMap < Rc < str > , Res > > {
409
+ match kind {
398
410
NameKind :: Term => & self . terms ,
399
411
NameKind :: Ty => & self . tys ,
400
412
NameKind :: Importable => & self . importables ,
401
- } ;
402
- items. get ( namespace) . and_then ( |items| items. get ( name) )
413
+ }
403
414
}
404
415
405
416
/// Creates a namespace in the namespace mapping. Note that namespaces are tracked separately from their
@@ -419,7 +430,7 @@ impl GlobalScope {
419
430
}
420
431
421
432
/// Finds a namespace by its path.
422
- fn find_namespace < ' a > (
433
+ pub fn find_namespace < ' a > (
423
434
& self ,
424
435
name : impl IntoIterator < Item = & ' a str > ,
425
436
root : Option < NamespaceId > ,
@@ -459,12 +470,23 @@ impl GlobalScope {
459
470
}
460
471
461
472
/// Returns the full namespace path for a given namespace ID.
462
- fn format_namespace_name ( & self , namespace_id : NamespaceId ) -> String {
473
+ pub fn format_namespace_name ( & self , namespace_id : NamespaceId ) -> String {
463
474
self . namespaces
464
475
. find_namespace_by_id ( & namespace_id)
465
476
. 0
466
477
. join ( "." )
467
478
}
479
+
480
+ pub fn namespace_children ( & self , namespace_id : NamespaceId ) -> Vec < Rc < str > > {
481
+ self . namespaces
482
+ . find_namespace_by_id ( & namespace_id)
483
+ . 1
484
+ . borrow ( )
485
+ . children
486
+ . keys ( )
487
+ . cloned ( )
488
+ . collect ( )
489
+ }
468
490
}
469
491
470
492
#[ derive( Debug , Clone , Eq , PartialEq ) ]
@@ -475,7 +497,7 @@ enum ScopeKind {
475
497
}
476
498
477
499
#[ derive( Clone , Copy , Debug ) ]
478
- enum NameKind {
500
+ pub enum NameKind {
479
501
/// A name that is valid as an expression context: a callable or UDT
480
502
Term ,
481
503
/// A name that is valid in a type context: builtin or UDT
@@ -590,6 +612,10 @@ impl Resolver {
590
612
& self . locals
591
613
}
592
614
615
+ pub ( super ) fn globals ( & self ) -> & GlobalScope {
616
+ & self . globals
617
+ }
618
+
593
619
pub ( super ) fn drain_errors ( & mut self ) -> vec:: Drain < Error > {
594
620
self . errors . drain ( ..)
595
621
}
@@ -1271,6 +1297,11 @@ impl GlobalTable {
1271
1297
}
1272
1298
}
1273
1299
( global:: Kind :: Namespace ( item_id) , hir:: Visibility :: Public ) => {
1300
+ if package_root == Some ( namespace) && global. name . as_ref ( ) == "Main" {
1301
+ // If the namespace is `Main` and we have an alias, we treat it as the root of the package,
1302
+ // so there's no namespace prefix between the dependency alias and the defined items.
1303
+ continue ;
1304
+ }
1274
1305
let this_namespace = self
1275
1306
. scope
1276
1307
. insert_or_find_namespace ( vec ! [ global. name. clone( ) ] , Some ( namespace) ) ;
@@ -2014,10 +2045,7 @@ fn get_scope_locals(scope: &Scope, offset: u32, vars: bool) -> Vec<Local> {
2014
2045
// when a variable is later shadowed in the same scope,
2015
2046
// it is missed in the list. https://github.com/microsoft/qsharp/issues/897
2016
2047
if offset >= * valid_at {
2017
- Some ( Local {
2018
- name : name. clone ( ) ,
2019
- kind : LocalKind :: Var ( * id) ,
2020
- } )
2048
+ Some ( Local :: Var ( * id, name. clone ( ) ) )
2021
2049
} else {
2022
2050
None
2023
2051
}
@@ -2027,26 +2055,28 @@ fn get_scope_locals(scope: &Scope, offset: u32, vars: bool) -> Vec<Local> {
2027
2055
scope
2028
2056
. ty_vars
2029
2057
. iter ( )
2030
- . map ( |( name, ( id, _constraints) ) | Local {
2031
- name : name. clone ( ) ,
2032
- kind : LocalKind :: TyParam ( * id) ,
2033
- } ) ,
2058
+ . map ( |( name, ( id, _constraints) ) | Local :: TyParam ( * id, name. clone ( ) ) ) ,
2034
2059
) ;
2035
2060
}
2036
2061
2037
2062
// items
2038
- // skip adding newtypes since they're already in the terms map
2063
+ // gather from the terms table, since it happens to contain all the
2064
+ // declared and imported callables and newtypes
2039
2065
names. extend ( scope. terms . iter ( ) . filter_map ( |( name, res) | {
2040
2066
if let Res :: Item ( id, _) = res {
2041
- Some ( Local {
2042
- name : name. clone ( ) ,
2043
- kind : LocalKind :: Item ( * id) ,
2044
- } )
2067
+ Some ( Local :: Item ( * id, name. clone ( ) ) )
2045
2068
} else {
2046
2069
None
2047
2070
}
2048
2071
} ) ) ;
2049
2072
2073
+ // opens and namespace imports
2074
+ names. extend ( scope. opens . iter ( ) . flat_map ( |( alias, opens) | {
2075
+ opens
2076
+ . iter ( )
2077
+ . map ( |open| Local :: NamespaceImport ( open. namespace , alias. clone ( ) ) )
2078
+ } ) ) ;
2079
+
2050
2080
names
2051
2081
}
2052
2082
0 commit comments