// ĠCopyright Ġ 2 0 0 0 - 2 0 1 8 ĠJetBrains Ġs . r . o . ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense Ġthat Ġcan Ġbe Ġfound Ġin Ġthe ĠLICENSE Ġfile . Ċ Ċ @ file : Jvm Name (" Py Resolve Import Util ") Ċ package Ġcom . jetbrains . python . psi . resolve Ċ Ċ import Ġcom . google . common . base . Preconditions Ċ import Ġcom . intellij . facet . Facet Manager Ċ import Ġcom . intellij . openapi . application . Application Manager Ċ import Ġcom . intellij . openapi . module . Module Ċ import Ġcom . intellij . openapi . module . Module Manager Ċ import Ġcom . intellij . openapi . module . Module Util Core Ċ import Ġcom . intellij . openapi . project . Project Ċ import Ġcom . intellij . openapi . project Roots . Sdk Ċ import Ġcom . intellij . openapi . roots . File Index Facade Ċ import Ġcom . intellij . openapi . vfs . Virtual File Ċ import Ġcom . intellij . psi . Psi Directory Ċ import Ġcom . intellij . psi . Psi Element Ċ import Ġcom . intellij . psi . Psi FileSystem Item Ċ import Ġcom . intellij . psi . Psi Manager Ċ import Ġcom . intellij . psi . util . QualifiedName Ċ import Ġcom . jetbrains . python . code Insight . typing . Py Type S hed Ċ import Ġcom . jetbrains . python . code Insight . user S ke letons . Py User S ke letons Util Ċ import Ġcom . jetbrains . python . facet . Python Path Contributing Facet Ċ import Ġcom . jetbrains . python . psi . Language Level Ċ import Ġcom . jetbrains . python . psi . Py File Ċ import Ġcom . jetbrains . python . psi . Py Util Ċ import Ġcom . jetbrains . python . psi . impl . Py Builtin Cache Ċ import Ġcom . jetbrains . python . psi . impl . Py Import Resolver Ċ import Ġcom . jetbrains . python . py i . Py i File Ċ import Ġcom . jetbrains . python . sdk . Py Sdk Util Ċ import Ġcom . jetbrains . python . sdk . Python Sdk Type Ċ Ċ /** Ċ Ġ* ĠPython Ġresolve Ġutilities Ġfor Ġqualified Ġnames . Ċ Ġ* Ċ Ġ* ĠTODO : ĠMerge Ġwith ĠResolve Import Util , Ġmaybe Ġmake Ġthese Ġfunctions Ġthe Ġmethods Ġof ĠPy QualifiedName Resolve Context . Ċ Ġ* Ċ Ġ* Ġ@ author Ġvlan Ċ Ġ*/ Ċ Ċ /** Ċ Ġ* ĠRes olves Ġqualified Ġ[ name ] Ġto Ġthe Ġlist Ġof Ġpackages , Ġmodules Ġand , Ġsometimes , Ġclasses . Ċ Ġ* Ċ Ġ* ĠThis Ġmethod Ġdoes Ġnot Ġtake Ġinto Ġaccount Ġsource Ġroots Ġorder Ġ( see ĠPY - 2 8 3 2 1 Ġas Ġan Ġexample ). Ċ Ġ* ĠThe Ġsole Ġpurpose Ġof Ġthe Ġmethod Ġis Ġto Ġsupport Ġclasses Ġthat Ġrequire Ġclass Ġresolution Ġuntil Ġthey Ġcan Ġbe Ġmigrated Ġto Ġ[ resolve QualifiedName ]. Ċ Ġ* Ċ Ġ* Ġ@ see Ġresolve QualifiedName Ċ Ġ*/ Ċ @ Deprecated (" This Ġmethod Ġdoes Ġnot Ġprovide Ġproper Ġsource Ġroot Ġresolution ") Ċ fun Ġresolve QualifiedName With Classes ( name : ĠQual ified Name , Ġcontext : ĠPy QualifiedName Resolve Context ): ĠList < Psi Element > Ġ{ ĊĠ Ġreturn Ġresolve QualifiedName ( name , Ġcontext , Ġ:: results From Roots ) Ċ } Ċ Ċ /** Ċ Ġ* ĠRes olves Ġa Ġqualified Ġ[ name ] Ġto Ġthe Ġlist Ġof Ġpackages Ġand Ġmodules Ġaccording Ġto Ġthe Ġ[ context ]. Ċ Ġ* Ċ Ġ* Ġ@ see Ġresolve TopLevel Member Ċ Ġ*/ Ċ fun Ġresolve QualifiedName ( name : ĠQual ified Name , Ġcontext : ĠPy QualifiedName Resolve Context ): ĠList < Psi Element > Ġ{ ĊĠ Ġreturn Ġresolve QualifiedName ( name , Ġcontext , Ġ:: resolve Module From Roots ) Ċ } Ċ Ċ private Ġfun Ġresolve QualifiedName ( name : ĠQual ified Name , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext : ĠPy QualifiedName Resolve Context , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresolve From Roots : Ġ( QualifiedName , ĠPy QualifiedName Resolve Context ) Ġ-> ĠList < Psi Element >): ĠList < Psi Element > Ġ{ ĊĠ Ġcheck Access () ĊĠ Ġif Ġ(! context . isValid ) Ġ{ ĊĠĠĠ Ġreturn Ġempty List () ĊĠ Ġ} ĊĊĠ Ġval Ġrelative Directory Ġ= Ġcontext . containing Directory ĊĠ Ġval Ġrelative Results Ġ= Ġresolve With Relative Level ( name , Ġcontext ) ĊĠ Ġval Ġfound Relative Import Ġ= Ġrelative Directory Ġ!= Ġnull Ġ&& ĊĠĠĠĠĠ Ġrelative Results . any Ġ{ Ġis Relative Import Result ( name , Ġrelative Directory , Ġit , Ġcontext ) Ġ} ĊĊĠ Ġval Ġcache Ġ= Ġfind Cache ( context ) ĊĠ Ġval Ġmay Cache Ġ= Ġcache Ġ!= Ġnull Ġ&& Ġ! found Relative Import ĊĠ Ġval Ġkey Ġ= Ġcache Prefix ( context ). append ( name ) ĊĊĠ Ġif Ġ( may Cache ) Ġ{ ĊĠĠĠ Ġval Ġcached Results Ġ= Ġcache ?. get ( key ) ĊĠĠĠ Ġif Ġ( cached Results Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġreturn Ġrelative Results Ġ+ Ġcached Results ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġval Ġforeign Results Ġ= Ġforeign Results ( name , Ġcontext ) ĊĠ Ġval Ġpython Results Ġ= ĠlistOf ( relative Results , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġreplace Ġwith Ġresolve From Roots Ġwhen Ġnamespace Ġpackage Ġmagic Ġfeatures ĠPY - 1 6 6 8 8 , ĠPY - 2 3 0 8 7 Ġare Ġimplemented ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresults From Roots ( name , Ġcontext ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrelative Results From S ke letons ( name , Ġcontext )). flatten (). distinct () ĊĠ Ġval Ġall Results Ġ= Ġpython Results Ġ+ Ġforeign Results ĊĠ Ġval Ġresults Ġ= Ġif Ġ( name . component Count Ġ> Ġ 0 ) Ġfind First Results ( python Results , Ġcontext . module ) Ġ+ Ġforeign Results Ġelse Ġall Results ĊĊĠ Ġif Ġ( may Cache ) Ġ{ ĊĠĠĠ Ġcache ?. put ( key , Ġresults ) ĊĠ Ġ} ĊĊĠ Ġreturn Ġresults Ċ } Ċ Ċ /** Ċ Ġ* ĠRes olves Ġa Ġqualified Ġ[ name ] Ġto Ġthe Ġlist Ġof Ġpackages Ġand Ġmodules Ġwith ĠPython Ġsemantics Ġaccording Ġto Ġthe Ġ[ context ]. Ċ Ġ*/ Ċ private Ġfun Ġresolve Module From Roots ( name : ĠQual ified Name , Ġcontext : ĠPy QualifiedName Resolve Context ): ĠList < Psi Element > Ġ{ ĊĠ Ġval Ġhead Ġ= Ġname . remove Tail ( name . component Count Ġ- Ġ 1 ) ĊĠ Ġval Ġname No Head Ġ= Ġname . remove Head ( 1 ) ĊĠ Ġreturn Ġname No Head . components . fold ( results From Roots ( head , Ġcontext )) Ġ{ Ġresults , Ġcomponent Ġ-> ĊĠĠĠ Ġfind First Results ( results , Ġcontext . module ) ĊĠĠĠĠĠ Ġ. as Sequence () ĊĠĠĠĠĠ Ġ. filter Is Instance < Psi FileSystem Item >() ĊĠĠĠĠĠ Ġ. flatMap Ġ{ Ġresolve Module At ( QualifiedName . from Components ( component ), Ġit , Ġcontext ). as Sequence () Ġ} ĊĠĠĠĠĠ Ġ. toList () ĊĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠRes olves Ġa Ġ[ name ] Ġto Ġthe Ġfirst Ġmodule Ġmember Ġdefined Ġat Ġthe Ġtop - level . Ċ Ġ*/ Ċ fun Ġresolve TopLevel Member ( name : ĠQual ified Name , Ġcontext Ġ: ĠPy QualifiedName Resolve Context ): ĠPsi Element ? Ġ{ ĊĠ Ġcheck Access () ĊĠ Ġval Ġmember Name Ġ= Ġname . last Component Ġ?: Ġreturn Ġnull ĊĠ Ġreturn Ġresolve QualifiedName ( name . remove Last Component (), Ġcontext ) ĊĠĠĠĠĠ Ġ. as Sequence () ĊĠĠĠĠĠ Ġ. filter Is Instance ( Py File :: class . java ) ĊĠĠĠĠĠ Ġ. flatMap Ġ{ Ġit . multi Resolve Name ( member Name ). as Sequence () Ġ} ĊĠĠĠĠĠ Ġ. map Ġ{ Ġit . element Ġ} ĊĠĠĠĠĠ Ġ. first OrNull () Ċ } Ċ Ċ /** Ċ Ġ* ĠRes olves Ġa Ġ[ name ] Ġrelative Ġto Ġthe Ġspecified Ġ[ item ]. Ċ Ġ*/ Ċ fun Ġresolve Module At ( name : ĠQual ified Name , Ġitem : ĠPsi FileSystem Item ?, Ġcontext : ĠPy QualifiedName Resolve Context ): ĠList < Psi Element > Ġ{ ĊĠ Ġcheck Access () ĊĠ Ġval Ġempty Ġ= Ġempty List < Psi Element >() ĊĠ Ġif Ġ( item Ġ== Ġnull Ġ|| Ġ! item . isValid ) Ġ{ ĊĠĠĠ Ġreturn Ġempty ĊĠ Ġ} ĊĠ Ġreturn Ġname . components . fold ( listOf < Psi Element >( item )) Ġ{ Ġseek ers , Ġcomponent Ġ-> ĊĠĠĠ Ġif Ġ( component Ġ== Ġnull ) Ġempty ĊĠĠĠ Ġelse Ġseek ers . flatMap Ġ{ ĊĠĠĠĠĠ Ġval Ġchildren Ġ= ĠResolve Import Util . resolve Children ( it , Ġcomponent , Ġcontext . foo th old File , Ġ! context . with Members , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ! context . with Plain Directories , Ġcontext . without Stub s , Ġcontext . without Foreign ) ĊĠĠĠĠĠ ĠPy Util . filter Top Priority Results ( children . to Typed Array ()) ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠCreates Ġa Ġ[ Py QualifiedName Resolve Context ] Ġfrom Ġa Ġ[ foo th old ] Ġelement . Ċ Ġ*/ Ċ fun Ġfrom F ooth old ( foo th old : ĠPsi Element ): ĠPy QualifiedName Resolve Context Ġ{ ĊĠ Ġval Ġmodule Ġ= ĠModule Util Core . find Module For Psi Element ( foo th old . containing File Ġ?: Ġfoo th old ) ĊĠ Ġreturn ĠPy QualifiedName Resolve Context Impl ( foo th old . manager , Ġmodule , Ġfoo th old , ĠPython Sdk Type . find Python Sdk ( module )) Ċ } Ċ Ċ /** Ċ Ġ* ĠCreates Ġa Ġ[ Py QualifiedName Resolve Context ] Ġfrom Ġa Ġ[ module ]. Ċ Ġ*/ Ċ fun Ġfrom Module ( module : ĠModule ): ĠPy QualifiedName Resolve Context Ġ= ĊĠĠĠ ĠPy QualifiedName Resolve Context Impl ( Psi Manager . getInstance ( module . project ), Ġmodule , Ġnull , ĠPython Sdk Type . find Python Sdk ( module )) Ċ Ċ /** Ċ Ġ* ĠCreates Ġa Ġ[ Py QualifiedName Resolve Context ] Ġfrom Ġan Ġ[ sdk ]. Ċ Ġ*/ Ċ fun Ġfrom Sdk ( project : ĠProject , Ġsdk : ĠS dk ): ĠPy QualifiedName Resolve Context Ġ= ĊĠĠĠ ĠPy QualifiedName Resolve Context Impl ( Psi Manager . getInstance ( project ), Ġmodule Ġ= Ġnull , Ġfoo th old Ġ= Ġnull , Ġsdk Ġ= Ġsdk ) Ċ Ċ private Ġfun Ġcache Prefix ( context : ĠPy QualifiedName Resolve Context ): ĠQual ified Name Ġ{ ĊĠ Ġval Ġresults Ġ= Ġmutable ListOf < String >() ĊĠ Ġif Ġ( context . without Stub s ) Ġ{ ĊĠĠĠ Ġresults . add (" without - stubs ") ĊĠ Ġ} ĊĠ Ġif Ġ( context . without Foreign ) Ġ{ ĊĠĠĠ Ġresults . add (" without - foreign ") ĊĠ Ġ} ĊĠ Ġif Ġ( context . without Roots ) Ġ{ ĊĠĠĠ Ġresults . add (" without - roots ") ĊĠ Ġ} ĊĠ Ġreturn ĠQual ified Name . from Components ( results ) Ċ } Ċ Ċ private Ġfun Ġforeign Results ( name : ĠQual ified Name , Ġcontext : ĠPy QualifiedName Resolve Context ) Ġ= ĊĠĠĠ Ġif Ġ( context . without Foreign ) ĊĠĠĠĠĠ Ġempty List () ĊĠĠĠ Ġelse ĊĠĠĠĠĠ ĠPy Import Resolver . EP _ NAME . extension List ĊĠĠĠĠĠĠĠĠĠ Ġ. as Sequence () ĊĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . resolve Import Reference ( name , Ġcontext , Ġ! context . without Roots ) Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ. filter NotNull () ĊĠĠĠĠĠĠĠĠĠ Ġ. toList () Ċ Ċ private Ġfun Ġrelative Results From S ke letons ( name : ĠQual ified Name , Ġcontext : ĠPy QualifiedName Resolve Context ): ĠList < Psi Element > Ġ{ ĊĠ Ġval Ġfoo th old File Ġ= Ġcontext . foo th old File ĊĠ Ġif Ġ( context . without Roots Ġ&& Ġfoo th old File Ġ!= Ġnull ) Ġ{ ĊĠĠĠ Ġval Ġvirtual File Ġ= Ġfoo th old File . virtual File ĊĠĠĠ Ġif Ġ( virtual File Ġ== Ġnull Ġ|| ĠFile Index Facade . getInstance ( context . project ). isIn Content ( virtual File )) Ġ{ ĊĠĠĠĠĠ Ġreturn Ġempty List () ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġcontaining Directory Ġ= Ġcontext . containing Directory ĊĠĠĠ Ġif Ġ( containing Directory Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġval Ġcontaining Name Ġ= ĠQual ified Name Finder . find Canonical Import Path ( containing Directory , Ġnull ) ĊĠĠĠĠĠ Ġif Ġ( containing Name Ġ!= Ġnull Ġ&& Ġcontaining Name . component Count Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġabsolute Name Ġ= Ġcontaining Name . append ( name ) ĊĠĠĠĠĠĠĠ Ġval Ġsdk Ġ= ĠPython Sdk Type . find Python Sdk ( foo th old File ) Ġ?: Ġreturn Ġempty List () ĊĠĠĠĠĠĠĠ Ġval Ġs ke letons Virtual File Ġ= ĠPy Sdk Util . find S ke letons Dir ( sdk ) Ġ?: Ġreturn Ġempty List () ĊĠĠĠĠĠĠĠ Ġval Ġs ke letons Dir Ġ= Ġcontext . psi Manager . find Directory ( s ke letons Virtual File ) ĊĠĠĠĠĠĠĠ Ġreturn Ġresolve Module At ( absolute Name , Ġs ke letons Dir , Ġcontext . copy Without Foreign ()) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĠ Ġreturn Ġempty List () Ċ } Ċ Ċ fun Ġrelative Results For Stub s From Roots ( name : ĠQual ified Name , Ġcontext : ĠPy QualifiedName Resolve Context ): ĠList < Psi Element > Ġ{ ĊĠ Ġif Ġ( context . foo th old File Ġ! is ĠPy i File Ġ|| Ġcontext . relative Level Ġ<= Ġ 0 ) Ġ{ ĊĠĠĠ Ġreturn Ġempty List () ĊĠ Ġ} ĊĠ Ġval Ġcontaining Directory Ġ= Ġcontext . containing Directory Ġ?: Ġreturn Ġempty List () ĊĠ Ġval Ġcontaining Name Ġ= ĠQual ified Name Finder . find Canonical Import Path ( containing Directory , Ġnull ) Ġ?: Ġreturn Ġempty List () ĊĠ Ġif Ġ( containing Name . component Count Ġ<= Ġ 0 ) Ġ{ ĊĠĠĠ Ġreturn Ġempty List () ĊĠ Ġ} ĊĠ Ġval Ġabsolute Name Ġ= Ġcontaining Name . append ( name ) ĊĠ Ġreturn Ġresults From Roots ( absolute Name , Ġcontext . copy With Relative (- 1 ). copy With Roots ()) Ċ } Ċ Ċ /** Ċ Ġ* ĠFilters Ġthe Ġresults Ġaccording Ġto Ġtheir Ġimport Ġpriority Ġin Ġsys . path . Ċ Ġ*/ Ċ private Ġfun Ġfind First Results ( results : ĠList < Psi Element >, Ġmodule : ĠModule ?) Ġ= ĊĠĠĠ Ġif Ġ( results . all (:: is Namespace Package )) ĊĠĠĠĠĠ Ġresults ĊĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠ Ġval Ġresult Ġ= Ġresults . first OrNull Ġ{ Ġ! is Namespace Package ( it ) Ġ} ĊĠĠĠĠĠ Ġval Ġstub File Ġ= Ġresults . first OrNull Ġ{ Ġit Ġis ĠPy i File Ġ|| ĠPy Util . turn Dir Into Init ( it ) Ġis ĠPy i File Ġ} ĊĊĠĠĠĠĠ Ġval Ġresult V File Ġ= Ġ( result Ġas ? ĠPsi FileSystem Item )?. virtual File ĊĠĠĠĠĠ Ġval Ġstub V File Ġ= Ġ( stub File Ġas ? ĠPsi FileSystem Item )?. virtual File ĊĊĠĠĠĠĠ Ġif Ġ( stub File Ġ== Ġnull Ġ|| ĊĠĠĠĠĠĠĠĠĠ Ġmodule Ġ!= Ġnull Ġ&& ĊĠĠĠĠĠĠĠĠĠ Ġstub V File Ġ!= Ġnull Ġ&& ĠPy Type S hed . is Inside ( stub V File ) Ġ&& ĊĠĠĠĠĠĠĠĠĠ Ġresult V File Ġ!= Ġnull Ġ&& ĠModule Util Core . module Contains File ( module , Ġresult V File , Ġfalse )) Ġ{ ĊĠĠĠĠĠĠĠ ĠlistOf NotNull ( result ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠ ĠlistOf NotNull ( stub File ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ private Ġfun Ġis Namespace Package ( element : ĠPsi Element ): ĠBoolean Ġ{ ĊĠ Ġif Ġ( element Ġis ĠPsi Directory ) Ġ{ ĊĠĠĠ Ġval Ġlevel Ġ= ĠPy Util . get Language Level For Virtual File ( element . project , Ġelement . virtual File ) ĊĠĠĠ Ġif Ġ(! level . is Python 2 ) Ġ{ ĊĠĠĠĠĠ Ġreturn ĠPy Util . turn Dir Into Init ( element ) Ġ== Ġnull ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĠ Ġreturn Ġfalse Ċ } Ċ Ċ private Ġfun Ġresolve With Relative Level ( name : ĠQual ified Name , Ġcontext Ġ: ĠPy QualifiedName Resolve Context ): ĠList < Psi Element > Ġ{ ĊĠ Ġval Ġfoo th old File Ġ= Ġcontext . foo th old File ĊĠ Ġif Ġ( context . relative Level Ġ>= Ġ 0 Ġ&& Ġfoo th old File Ġ!= Ġnull Ġ&& Ġ! Py User S ke letons Util . is Under User S ke letons Directory ( foo th old File )) Ġ{ ĊĠĠĠ Ġreturn Ġresolve Module At ( name , Ġcontext . containing Directory , Ġcontext ) Ġ+ Ġrelative Results For Stub s From Roots ( name , Ġcontext ) ĊĠ Ġ} ĊĠ Ġreturn Ġempty List () Ċ } Ċ Ċ /** Ċ Ġ* ĠCollect s Ġresolve Ġresults Ġfrom Ġall Ġroots Ġavailable . Ċ Ġ* Ċ Ġ* ĠThe Ġret uning Ġ{@ code ĠList < Psi Element >} Ġcontains Ġall Ġelements Ġ{@ code Ġname } Ġreferences Ċ Ġ* Ġand Ġdoes Ġnot Ġtake Ġinto Ġaccount Ġroot Ġorder . Ċ Ġ*/ Ċ private Ġfun Ġresults From Roots ( name : ĠQual ified Name , Ġcontext : ĠPy QualifiedName Resolve Context ): ĠList < Psi Element > Ġ{ ĊĠ Ġif Ġ( context . without Roots ) Ġ{ ĊĠĠĠ Ġreturn Ġempty List () ĊĠ Ġ} ĊĊĠ Ġval Ġmodule Results Ġ= Ġmutable ListOf < Psi Element >() ĊĠ Ġval Ġsdk Results Ġ= Ġmutable ListOf < Psi Element >() ĊĊĠ Ġval Ġsdk Ġ= Ġcontext . effective Sdk ĊĠ Ġval Ġmodule Ġ= Ġcontext . module ĊĠ Ġval Ġfoo th old File Ġ= Ġcontext . foo th old File ĊĊĠ Ġval Ġvisitor Ġ= ĠRoot Visitor Ġ{ Ġroot , Ġmodule , Ġsdk , Ġis Module Source Ġ-> ĊĠĠĠ Ġval Ġresults Ġ= Ġif Ġ( is Module Source ) Ġmodule Results Ġelse Ġsdk Results ĊĠĠĠ Ġval Ġeffective Sdk Ġ= Ġsdk Ġ?: Ġcontext . effective Sdk ĊĠĠĠ Ġif Ġ(! root . isValid Ġ|| ĊĠĠĠĠĠĠĠ Ġroot Ġ== ĠPy User S ke letons Util . getUser S ke letons Directory () Ġ|| ĊĠĠĠĠĠĠĠ Ġeffective Sdk Ġ!= Ġnull Ġ&& ĠPy Type S hed . is Inside ( root ) Ġ&& Ġ! Py Type S hed . may Search For Stub In Root ( name , Ġroot , Ġeffective Sdk )) Ġ{ ĊĠĠĠĠĠ Ġreturn @ Root Visitor Ġtrue ĊĠĠĠ Ġ} ĊĠĠĠ Ġresults . addAll ( resolve In Root ( name , Ġroot , Ġcontext )) ĊĠĠĠ Ġif Ġ( is Accept Root As TopLevel Package ( context ) Ġ&& Ġname . matches Prefix ( QualifiedName . from Dot ted String ( root . name ))) Ġ{ ĊĠĠĠĠĠ Ġresults . addAll ( resolve In Root ( name , Ġroot . parent , Ġcontext )) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn @ Root Visitor Ġtrue ĊĠ Ġ} ĊĊĠ Ġwhen Ġ{ ĊĠĠĠ Ġcontext . visit All Modules Ġ-> Ġ{ ĊĠĠĠĠĠ ĠModule Manager . getInstance ( context . project ). modules . forEach Ġ{ ĊĠĠĠĠĠĠĠ ĠRoot Visitor Host . visit Roots ( it , Ġtrue , Ġvisitor ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġsdk Ġ!= Ġnull Ġ-> ĊĠĠĠĠĠĠĠĠĠ ĠRoot Visitor Host . visit Sdk Roots ( sdk , Ġvisitor ) ĊĠĠĠĠĠĠĠ Ġfoo th old File Ġ!= Ġnull Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRoot Visitor Host . visit Sdk Roots ( foo th old File , Ġvisitor ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġmodule Ġ!= Ġnull Ġ-> Ġ{ ĊĠĠĠĠĠ Ġval Ġother Sdk Ġ= Ġsdk Ġ!= Ġcontext . sdk ĊĠĠĠĠĠ ĠRoot Visitor Host . visit Roots ( module , Ġother Sdk , Ġvisitor ) ĊĠĠĠĠĠ Ġif Ġ( other Sdk Ġ&& Ġsdk Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ ĠRoot Visitor Host . visit Sdk Roots ( sdk , Ġvisitor ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġfoo th old File Ġ!= Ġnull Ġ-> Ġ{ ĊĠĠĠĠĠ ĠRoot Visitor Host . visit Roots ( foo th old File , Ġvisitor ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġsdk Ġ!= Ġnull Ġ-> Ġ{ ĊĠĠĠĠĠ ĠRoot Visitor Host . visit Sdk Roots ( sdk , Ġvisitor ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalStateException () ĊĠ Ġ} ĊĠ Ġreturn Ġmodule Results Ġ+ Ġsdk Results Ċ } Ċ Ċ private Ġfun Ġis Accept Root As TopLevel Package ( context : ĠPy QualifiedName Resolve Context ): ĠBoolean Ġ{ ĊĠ Ġcontext . module ?. let Ġ{ ĊĠĠĠ ĠFac et Manager . getInstance ( it ). all Fac ets . forEach Ġ{ ĊĠĠĠĠĠ Ġif Ġ( it Ġis ĠPython Path Contributing Facet Ġ&& Ġit . accept Root As TopLevel Package ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĠ Ġreturn Ġfalse Ċ } Ċ Ċ private Ġfun Ġresolve In Root ( name : ĠQual ified Name , Ġroot : ĠVirtual File , Ġcontext : ĠPy QualifiedName Resolve Context ): ĠList < Psi Element > Ġ{ ĊĠ Ġreturn Ġif Ġ( root . isDirectory ) Ġresolve Module At ( name , Ġcontext . psi Manager . find Directory ( root ), Ġcontext ) Ġelse Ġempty List () Ċ } Ċ Ċ private Ġfun Ġfind Cache ( context : ĠPy QualifiedName Resolve Context ): ĠPython Path Cache ? Ġ{ ĊĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠ Ġcontext . visit All Modules Ġ-> Ġnull ĊĠĠĠ Ġcontext . module Ġ!= Ġnull Ġ-> ĊĠĠĠĠĠ Ġif Ġ( context . effective Sdk Ġ!= Ġcontext . sdk ) Ġnull Ġelse ĠPython Module Path Cache . getInstance ( context . module ) ĊĠĠĠ Ġcontext . foo th old File Ġ!= Ġnull Ġ-> Ġ{ ĊĠĠĠĠĠ Ġval Ġsdk Ġ= ĠPy Builtin Cache . find Sdk For Non Module File ( context . foo th old File !! ) ĊĠĠĠĠĠ Ġif Ġ( sdk Ġ!= Ġnull ) ĠPython Sdk Path Cache . getInstance ( context . project , Ġsdk ) Ġelse Ġnull ĊĠĠĠ Ġ} ĊĠĠĠ Ġelse Ġ-> Ġnull ĊĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġis Relative Import Result ( name : ĠQual ified Name , Ġdirectory : ĠPsi Directory , Ġresult : ĠPsi Element , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext : ĠPy QualifiedName Resolve Context ): ĠBoolean Ġ{ ĊĠ Ġif Ġ( context . relative Level Ġ> Ġ 0 ) Ġ{ ĊĠĠĠ Ġreturn Ġtrue ĊĠ Ġ} ĊĠ Ġelse Ġ{ ĊĠĠĠ Ġval Ġpy 2 Ġ= ĠLanguage Level . for Element ( directory ). is Python 2 ĊĠĠĠ Ġreturn Ġcontext . relative Level Ġ== Ġ 0 Ġ&& Ġpy 2 Ġ&& ĠPy Util . is Package ( directory , Ġfalse , Ġnull ) Ġ&& ĊĠĠĠĠĠĠĠ Ġresult Ġis ĠPsi FileSystem Item Ġ&& Ġname Ġ!= ĠQual ified Name Finder . find Short est Import able QName ( result ) ĊĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġcheck Access () Ġ{ ĊĠ ĠPreconditions . check State ( Application Manager . getApplication (). is Read Access Allowed , Ġ" This Ġmethod Ġrequires Ġread Ġaccess ") Ċ } Ċ