@@ -334,46 +334,38 @@ private void SetVariableForImportedMember(IModule module, NameExpression importN
334
334
}
335
335
336
336
public override bool Walk ( FromImportStatement node ) {
337
- var rootNames = node . Root . Names . Select ( n => n . Name ) ;
338
- var availableImports = node . Root is RelativeModuleName relativeName
339
- ? _pathResolver . GetAvailableImportsFromRelativePath ( _filePath , relativeName . DotCount , rootNames )
340
- : _pathResolver . GetAvailableImportsFromAbsolutePath ( _filePath , rootNames ) ;
341
-
342
- switch ( availableImports ) {
343
- case AvailableModuleImports moduleImports :
344
- ImportMembersFromModule ( node , moduleImports ) ;
337
+ var importSearchResult = _pathResolver . FindImports ( _filePath , node ) ;
338
+
339
+ switch ( importSearchResult ) {
340
+ case ModuleImport moduleImports when TryGetModule ( node . Root , moduleImports , out var module ) :
341
+ case PossibleModuleImport possibleModuleImport when TryGetModule ( node . Root , possibleModuleImport , out module ) :
342
+ ImportMembersFromModule ( node , module ) ;
345
343
return false ;
346
- case AvailablePackageImports packageImports :
344
+ case PackageImport packageImports :
347
345
ImportModulesFromPackage ( node , packageImports ) ;
348
346
return false ;
347
+ case ImportNotFound notFound :
348
+ MakeUnresolvedImport ( notFound . FullName , node . Root ) ;
349
+ return false ;
349
350
default :
350
- _unit . DeclaringModule . AddUnresolvedModule ( node . Root . MakeString ( ) , node . ForceAbsolute ) ;
351
351
return false ;
352
352
}
353
353
}
354
354
355
- private void ImportMembersFromModule ( FromImportStatement node , AvailableModuleImports moduleImports ) {
356
- if ( ! ProjectState . Modules . TryImport ( moduleImports . FullName , out var moduleReference ) ) {
357
- return ;
358
- }
359
-
360
- _unit . DeclaringModule . AddModuleReference ( moduleImports . FullName , moduleReference ) ;
361
- var module = moduleReference . Module ;
362
- module . Imported ( _unit ) ;
363
-
364
- if ( node . Names . Count == 1 && node . Names [ 0 ] . Name == "*" ) {
355
+ private void ImportMembersFromModule ( FromImportStatement node , IModule module ) {
356
+ var names = node . Names ;
357
+ if ( names . Count == 1 && names [ 0 ] . Name == "*" ) {
365
358
// import all module public members
366
- var publicMembers = moduleReference . Module
359
+ var publicMembers = module
367
360
. GetModuleMemberNames ( GlobalScope . InterpreterContext )
368
361
. Where ( n => ! n . StartsWithOrdinal ( "_" ) ) ;
369
362
foreach ( var member in publicMembers ) {
370
363
// Don't add references to "*" node
371
- SetVariableForImportedMember ( module , node . Names [ 0 ] , member , null , member , false ) ;
364
+ SetVariableForImportedMember ( module , names [ 0 ] , member , null , member , false ) ;
372
365
}
373
366
return ;
374
367
}
375
368
376
- var names = node . Names ;
377
369
var asNames = node . AsNames ;
378
370
379
371
var len = Math . Min ( names . Count , asNames . Count ) ;
@@ -390,23 +382,26 @@ private void ImportMembersFromModule(FromImportStatement node, AvailableModuleIm
390
382
}
391
383
}
392
384
393
- private void ImportModulesFromPackage ( FromImportStatement node , AvailablePackageImports packageImports ) {
385
+ private void ImportModulesFromPackage ( FromImportStatement node , PackageImport packageImport ) {
394
386
var names = node . Names ;
395
387
var asNames = node . AsNames ;
396
388
397
389
var importNames = names . Select ( n => n . Name ) . ToArray ( ) ;
398
390
if ( importNames . Length == 1 && importNames [ 0 ] == "*" ) {
399
391
// TODO: Need tracking of previous imports to determine possible imports for namespace package
392
+ MakeUnresolvedImport ( packageImport . Name , node . Root ) ;
400
393
return ;
401
394
}
402
395
403
- foreach ( var module in packageImports . Modules ) {
396
+ foreach ( var module in packageImport . Modules ) {
404
397
var index = importNames . IndexOf ( module . Name , StringExtensions . EqualsOrdinal ) ;
405
398
if ( index == - 1 ) {
399
+ MakeUnresolvedImport ( module . FullName , node . Root ) ;
406
400
continue ;
407
401
}
408
402
409
403
if ( ! ProjectState . Modules . TryImport ( module . FullName , out var moduleReference ) ) {
404
+ MakeUnresolvedImport ( module . FullName , node . Root ) ;
410
405
continue ;
411
406
}
412
407
@@ -498,48 +493,108 @@ public override bool Walk(IfStatement node) {
498
493
public override bool Walk ( ImportStatement node ) {
499
494
var len = Math . Min ( node . Names . Count , node . AsNames . Count ) ;
500
495
for ( var i = 0 ; i < len ; i ++ ) {
501
- var curName = node . Names [ i ] ;
502
- var asName = node . AsNames [ i ] ;
503
-
504
- var imports = _pathResolver . GetAvailableImportsFromAbsolutePath ( _filePath , curName . Names . Select ( n => n . Name ) ) ;
505
- if ( ! ( imports is AvailableModuleImports moduleImports ) ) {
506
- continue ;
496
+ var moduleImportExpression = node . Names [ i ] ;
497
+ var asNameExpression = node . AsNames [ i ] ;
498
+
499
+ var imports = _pathResolver . GetImportsFromAbsoluteName ( _filePath , moduleImportExpression . Names . Select ( n => n . Name ) , node . ForceAbsolute ) ;
500
+ switch ( imports ) {
501
+ case ModuleImport moduleImports when TryGetModule ( moduleImportExpression , moduleImports , out var module ) :
502
+ case PossibleModuleImport possibleModuleImport when TryGetModule ( moduleImportExpression , possibleModuleImport , out module ) :
503
+ ImportModule ( node , module , moduleImportExpression , asNameExpression ) ;
504
+ break ;
505
+ default :
506
+ MakeUnresolvedImport ( moduleImportExpression . MakeString ( ) , moduleImportExpression ) ;
507
+ break ;
507
508
}
508
-
509
- ImportModule ( node , moduleImports , curName , asName ) ;
510
509
}
511
510
return true ;
512
511
}
513
512
514
- private void ImportModule ( ImportStatement node , AvailableModuleImports moduleImports , DottedName moduleImportExpression , NameExpression asNameExpression ) {
515
- if ( ! ProjectState . Modules . TryImport ( moduleImports . FullName , out var moduleReference ) ) {
516
- return ;
517
- }
518
-
519
- _unit . DeclaringModule . AddModuleReference ( moduleImports . FullName , moduleReference ) ;
520
- var module = moduleReference . Module ;
521
- module . Imported ( _unit ) ;
513
+ private void MakeUnresolvedImport ( string name , Node spanNode ) {
514
+ _unit . DeclaringModule . AddUnresolvedModule ( name ) ;
515
+ ProjectState . AddDiagnostic ( spanNode , _unit , ErrorMessages . UnresolvedImport ( name ) , DiagnosticSeverity . Warning , ErrorMessages . UnresolvedImportCode ) ;
516
+ }
522
517
518
+ private void ImportModule ( in ImportStatement node , in IModule module , in DottedName moduleImportExpression , in NameExpression asNameExpression ) {
523
519
// "import fob.oar as baz" is handled as
524
520
// baz = import_module('fob.oar')
525
521
if ( asNameExpression != null ) {
526
- AssignImportedModuleOrMember ( asNameExpression . Name , moduleReference . AnalysisModule , true , node . Names . LastOrDefault ( ) , asNameExpression ) ;
522
+ AssignImportedModuleOrMember ( asNameExpression . Name , module , true , node . Names . LastOrDefault ( ) , asNameExpression ) ;
527
523
return ;
528
524
}
529
525
530
526
// "import fob.oar" is handled as
531
527
// import_module('fob.oar')
532
528
// fob = import_module('fob')
533
- var firstImportNameExpression = moduleImportExpression . Names [ 0 ] ;
529
+ var importNames = moduleImportExpression . Names ;
530
+
531
+ var existingDepth = 0 ;
532
+ PythonPackage pythonPackage = null ;
533
+ if ( Scope . TryGetVariable ( importNames [ 0 ] . Name , out var importVariable ) ) {
534
+ var childPackage = importVariable . Types . OfType < PythonPackage > ( ) . FirstOrDefault ( ) ;
535
+ while ( childPackage != null && existingDepth < importNames . Count - 1 ) {
536
+ existingDepth ++ ;
537
+ pythonPackage = childPackage ;
538
+ childPackage = pythonPackage . GetChildPackage ( null , importNames [ existingDepth ] . Name ) as PythonPackage ;
539
+ }
540
+ }
534
541
535
- // Should be able to just get the module, as we only just imported it
536
- if ( ! ProjectState . Modules . TryGetImportedModule ( firstImportNameExpression . Name , out moduleReference ) ) {
537
- Debug . Fail ( $ "Failed to get module { firstImportNameExpression . Name } we just imported") ;
538
- Scope . CreateEphemeralVariable ( firstImportNameExpression , _unit , firstImportNameExpression . Name , true ) ;
539
- return ;
542
+ var child = module ;
543
+ for ( var i = importNames . Count - 2 ; i >= existingDepth ; i -- ) {
544
+ var childName = importNames [ i + 1 ] . Name ;
545
+ var parentName = importNames [ i ] . Name ;
546
+ var parent = new PythonPackage ( parentName , ProjectState ) ;
547
+ parent . AddChildModule ( childName , child ) ;
548
+ child = parent ;
540
549
}
541
550
542
- AssignImportedModuleOrMember ( firstImportNameExpression . Name , moduleReference . AnalysisModule , true , firstImportNameExpression , null ) ;
551
+ if ( pythonPackage == null ) {
552
+ AssignImportedModuleOrMember ( importNames [ 0 ] . Name , child , true , importNames [ 0 ] , null ) ;
553
+ } else {
554
+ pythonPackage . AddChildModule ( importNames [ existingDepth ] . Name , child ) ;
555
+ }
556
+ }
557
+
558
+ private bool TryGetModule ( Node importNode , ModuleImport moduleImport , out IModule module ) {
559
+ var fullName = moduleImport . FullName ;
560
+ if ( ! ProjectState . Modules . TryImport ( fullName , out var moduleReference ) ) {
561
+ MakeUnresolvedImport ( fullName , importNode ) ;
562
+ module = default ;
563
+ return false ;
564
+ }
565
+
566
+ _unit . DeclaringModule . AddModuleReference ( fullName , moduleReference ) ;
567
+ module = moduleReference . Module ;
568
+ module . Imported ( _unit ) ;
569
+ return true ;
570
+ }
571
+
572
+ private bool TryGetModule ( Node importNode , PossibleModuleImport possibleModuleImport , out IModule module ) {
573
+ var fullName = possibleModuleImport . PrecedingModuleFullName ;
574
+ if ( ! ProjectState . Modules . TryImport ( fullName , out var moduleReference ) ) {
575
+ MakeUnresolvedImport ( fullName , importNode ) ;
576
+ module = default ;
577
+ return false ;
578
+ }
579
+
580
+ _unit . DeclaringModule . AddModuleReference ( fullName , moduleReference ) ;
581
+ module = moduleReference . Module ;
582
+ module . Imported ( _unit ) ;
583
+
584
+ var nameParts = possibleModuleImport . RemainingNameParts ;
585
+ for ( var i = 0 ; i < nameParts . Count ; i ++ ) {
586
+ var namePart = nameParts [ i ] ;
587
+ if ( ! module . Scope . TryGetVariable ( namePart , out var variable ) || ! variable . Types . OfType < IModule > ( ) . Any ( ) ) {
588
+ var unresolvedModuleName = string . Join ( "." , nameParts . Take ( i + 1 ) . Prepend ( fullName ) ) ;
589
+ MakeUnresolvedImport ( unresolvedModuleName , importNode ) ;
590
+ return false ;
591
+ }
592
+
593
+ module = variable . Types . OfType < IModule > ( ) . First ( ) ;
594
+ module . Imported ( _unit ) ;
595
+ }
596
+
597
+ return true ;
543
598
}
544
599
545
600
public override bool Walk ( ReturnStatement node ) {
0 commit comments