Skip to content

Commit f74dc43

Browse files
committed
A temporary hack to fix Suggest Type Alias removing the dot in zio.
1 parent da635ca commit f74dc43

File tree

1 file changed

+69
-7
lines changed

1 file changed

+69
-7
lines changed

src/main/scala/zio/intellij/intentions/suggestions/SuggestTypeAlias.scala

+69-7
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,25 @@ import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
44
import com.intellij.openapi.editor.Editor
55
import com.intellij.openapi.project.Project
66
import com.intellij.psi.search.GlobalSearchScope
7-
import com.intellij.psi.{PsiElement, PsiFile}
7+
import com.intellij.psi.{PsiClass, PsiElement, PsiFile, PsiNamedElement, PsiPackage}
88
import org.jetbrains.plugins.scala.codeInsight.intention.types.AbstractTypeAnnotationIntention.complete
99
import org.jetbrains.plugins.scala.codeInsight.intention.types.{startTemplate, ChooseTypeTextExpression}
1010
import org.jetbrains.plugins.scala.extensions._
1111
import org.jetbrains.plugins.scala.lang.psi.ScalaPsiUtil
1212
import org.jetbrains.plugins.scala.lang.psi.api.base.types.{ScSimpleTypeElement, ScTypeElement}
1313
import org.jetbrains.plugins.scala.lang.psi.api.statements.{ScTypeAlias, ScTypeAliasDefinition}
14-
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.typedef.{ScObject, ScTypeDefinition}
14+
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.typedef.{ScMember, ScObject, ScTypeDefinition}
1515
import org.jetbrains.plugins.scala.lang.psi.impl.ScalaPsiManager
1616
import org.jetbrains.plugins.scala.lang.psi.types.api.designator.ScDesignatorType
17-
import org.jetbrains.plugins.scala.lang.psi.types.api.presentation.ScTypeText
18-
import org.jetbrains.plugins.scala.lang.psi.types.api.{ParameterizedType, UndefinedType}
17+
import org.jetbrains.plugins.scala.lang.psi.types.api.presentation.TypePresentation.PresentationOptions
18+
import org.jetbrains.plugins.scala.lang.psi.types.api.presentation.{NameRenderer, ScTypeText, TypePresentation}
19+
import org.jetbrains.plugins.scala.lang.psi.types.api.{ParameterizedType, UndefinedType, ValueType}
1920
import org.jetbrains.plugins.scala.lang.psi.types.recursiveUpdate.ScSubstitutor
2021
import org.jetbrains.plugins.scala.lang.psi.types.result.Typeable
21-
import org.jetbrains.plugins.scala.lang.psi.types.{AliasType, ScType, TypePresentationContext}
22+
import org.jetbrains.plugins.scala.lang.psi.types.{AliasType, ScType, ScalaTypeVisitor, TypePresentationContext}
23+
import org.jetbrains.plugins.scala.lang.refactoring.util.ScalaNamesUtil
2224
import org.jetbrains.plugins.scala.project.ProjectContext
25+
import org.jetbrains.plugins.scala.settings.ScalaApplicationSettings
2326
import org.jetbrains.plugins.scala.util.IntentionAvailabilityChecker.checkIntention
2427
import zio.intellij.intentions.ZTypeAnnotationIntention
2528
import zio.intellij.utils.TypeCheckUtils.{fromZioLayer, fromZioLike}
@@ -85,7 +88,7 @@ object SuggestTypeAlias {
8588
(topLevelType(declaredType) +: matchingAliases).distinct
8689
}
8790

88-
def topLevelType(tpe: ScType): ScType =
91+
private def topLevelType(tpe: ScType): ScType =
8992
tpe.aliasType match {
9093
case Some(AliasType(_, _, Right(value))) => value
9194
case _ => tpe
@@ -104,7 +107,66 @@ object SuggestTypeAlias {
104107
undefSubst(aliasType)
105108
.conformanceSubstitutor(tpe)
106109
.map(subst => subst.apply(ParameterizedType(ScDesignatorType(alias), undefParams)))
107-
.collect { case t: ScType if checker(t) => t }
110+
.collect { case t: ScType if checker(t) => canonicalTextHack(t) }
108111
}
109112
}
113+
114+
private def canonicalTextHack(tpe: ScType): ScType = new ScType {
115+
private val isPreciseText = ScalaApplicationSettings.getInstance().PRECISE_TEXT
116+
117+
override def isValue: Boolean = tpe.isValue
118+
119+
override def inferValueType: ValueType = tpe.inferValueType
120+
121+
override def visitType(visitor: ScalaTypeVisitor): Unit = tpe.visitType(visitor)
122+
123+
override implicit def projectContext: ProjectContext = tpe.projectContext
124+
125+
// TODO temp hack: restores the old behavior of canonicalText from before this change:
126+
// https://github.com/JetBrains/intellij-scala/commit/0669994c02f3eb15d9c67f09f9c696227c83060f
127+
// which caused some type aliases to be displayed as e.g `zioIO` instead of `zio.IO`
128+
override def canonicalText(context: TypePresentationContext): String = {
129+
val renderer: NameRenderer = new NameRenderer {
130+
override def renderName(e: PsiNamedElement): String = nameFun(e, withPoint = false)
131+
override def renderNameWithPoint(e: PsiNamedElement): String = nameFun(e, withPoint = true)
132+
133+
private def nameFun(e: PsiNamedElement, withPoint: Boolean): String = {
134+
val str = e match {
135+
case c: PsiClass =>
136+
val qname = c.qualifiedName
137+
if (qname == null || (!isPreciseText && qname == c.name)) c.name // SCL-21184
138+
else "_root_." + qname
139+
case p: PsiPackage =>
140+
"_root_." + p.getQualifiedName
141+
case _ =>
142+
e.nameContext match {
143+
case m: ScMember =>
144+
m.containingClass match {
145+
case o: ScObject =>
146+
(if (isPreciseText && o.isStatic) "_root_." else "") + nameFun(
147+
o,
148+
withPoint = true
149+
) + e.name // SCL-21182
150+
case _ => e.name
151+
}
152+
case _ => e.name
153+
}
154+
}
155+
removeKeywords(str) + pointStr(withPoint)
156+
}
157+
}
158+
159+
typeSystem.typeText(tpe, renderer, PresentationOptions(renderStdTypes = isPreciseText, canonicalForm = true))(
160+
context
161+
)
162+
}
163+
164+
override def presentableText(implicit context: TypePresentationContext): String = tpe.presentableText
165+
166+
private def removeKeywords(text: String): String =
167+
ScalaNamesUtil.escapeKeywordsFqn(text)
168+
169+
private def pointStr(withPoint: Boolean): String =
170+
if (withPoint) "." else ""
171+
}
110172
}

0 commit comments

Comments
 (0)