in scala/scala-impl/src/org/jetbrains/plugins/scala/editor/importOptimizer/ImportInfo.scala [136:305]
def createInfos(imp: ScImportStmt, isImportUsed: ImportUsed => Boolean = _ => true): Seq[ImportInfo] =
imp.importExprs.flatMap(ImportInfo.create(_, isImportUsed))
def create(imp: ScImportExpr, isImportUsed: ImportUsed => Boolean): Option[ImportInfo] = {
val qualifier = imp.qualifier.orNull
if (qualifier == null && !(imp.isInScala3File && imp.selectors.exists(_.isScala3StyleAliasImport)))
return None //ignore invalid imports
val isUnqualifiedScala3StyleAlias = qualifier == null
val isSource3 = imp.isSource3Enabled
val importsUsed = ArrayBuffer[ImportUsed]()
val allNames = mutable.HashSet[String]()
val singleNames = mutable.HashSet[String]()
val renames = mutable.HashMap[String, String]()
val hiddenNames = mutable.HashSet[String]()
var hasWildcard = false
var allNamesForWildcard = Set.empty[String]
var givenTypeTexts = Set.empty[String]
var hasGivenWildcard = false
var hasNonUsedImplicits = false
def addAllNames(ref: ScStableCodeReference, nameToAdd: String): Unit = {
if (ref.multiResolveScala(false).exists(shouldAddName))
allNames += nameToAdd
}
def isSource3WildcardGivenSelector(imp: ScImportSelector): Boolean = {
isSource3 && imp.isGivenSelector
}
// handle wildcards and source3-given-wildcards later
for (selector <- imp.selectors if !selector.isWildcardSelector && !isSource3WildcardGivenSelector(selector)) {
val importUsed: ImportSelectorUsed = new ImportSelectorUsed(selector)
if (isImportUsed(importUsed)) {
importsUsed += importUsed
if (selector.isGivenSelector) {
selector.givenTypeElement match {
case Some(typeElement) => givenTypeTexts += typeElement.getText
case None => hasGivenWildcard = true
}
} else {
for (reference <- selector.reference;
refName = reference.refName) {
if (selector.isAliasedImport) {
for (importedName <- selector.importedName) {
if (importedName == "_") {
hiddenNames += refName
} else if (importedName == refName) {
singleNames += refName
addAllNames(reference, refName)
} else {
renames += refName -> importedName
addAllNames(reference, importedName)
}
}
} else {
singleNames += refName
addAllNames(reference, refName)
}
}
}
}
}
if (ImportInfoProvider.providers.exists(_.isImportUsedWithFileCheck(imp)))
importsUsed += new ImportExprUsed(imp)
if (isUnqualifiedScala3StyleAlias) {
allNames --= hiddenNames
Option.when(importsUsed.nonEmpty)(
new ImportInfo(
prefixQualifier = None,
relative = None,
allNames = allNames.toSet,
singleNames = singleNames.toSet,
renames = renames.toMap,
hiddenNames = hiddenNames.toSet,
hasWildcard = hasWildcard,
rootUsed = false,
isStableImport = true,
allNamesForWildcard = allNamesForWildcard,
givenTypeTexts = givenTypeTexts,
hasGivenWildcard = hasGivenWildcard,
wildcardHasUnusedImplicit = hasNonUsedImplicits
)
)
} else {
val deepRef = deepestQualifier(qualifier)
val rootUsed = deepRef.textMatches(_root_prefix)
val (prefixQualifier, isRelative) =
if (rootUsed)
(explicitQualifierString(qualifier, withDeepest = false), false)
else {
val qualifiedDeepRef =
try qualifiedRef(deepRef)
catch {
case _: IllegalStateException => return None
}
val prefixQual = qualifiedDeepRef + withDot(explicitQualifierString(qualifier, withDeepest = false))
val relative = !deepRef.textMatches(qualifiedDeepRef)
(prefixQual, relative)
}
if (imp.hasWildcardSelector) {
val importUsed =
if (imp.selectorSet.isEmpty) new ImportExprUsed(imp)
else new ImportWildcardSelectorUsed(imp)
if (isImportUsed(importUsed)) {
importsUsed += importUsed
hasWildcard = true
val (namesForWildcard, implicitNames) = collectAllNamesAndImplicitsFromWildcard(prefixQualifier, imp)
allNames ++= namesForWildcard
allNamesForWildcard = namesForWildcard
hasNonUsedImplicits = (implicitNames -- singleNames).nonEmpty
if (isSource3) {
// in -Xsource:3, given selectors should be added iff the accompanying wildcard is used
for (givenSel <- imp.selectors.find(isSource3WildcardGivenSelector)) {
hasGivenWildcard = true
importsUsed += new ImportSelectorUsed(givenSel)
}
}
}
} else if (imp.selectorSet.isEmpty) {
val importUsed: ImportExprUsed = new ImportExprUsed(imp)
if (isImportUsed(importUsed)) {
importsUsed += importUsed
imp.reference match {
case Some(ref) =>
singleNames += ref.refName
addAllNames(ref, ref.refName)
case None => //something is not valid
}
}
}
val relativeQualifier =
if (isRelative) Some(explicitQualifierString(qualifier, withDeepest = true))
else None
val isStableImport = {
deepRef.resolve() match {
case named: PsiNamedElement => ScalaPsiUtil.hasStablePath(named)
case _ => false
}
}
allNames --= hiddenNames
Option.when(importsUsed.nonEmpty)(
new ImportInfo(
Some(prefixQualifier),
relativeQualifier,
allNames.toSet,
singleNames.toSet,
renames.toMap,
hiddenNames.toSet,
hasWildcard,
rootUsed,
isStableImport,
allNamesForWildcard,
givenTypeTexts,
hasGivenWildcard,
hasNonUsedImplicits
)
)
}
}