Skip to content

Commit

Permalink
A temporary hack to fix Suggest Type Alias removing the dot in zio.
Browse files Browse the repository at this point in the history
  • Loading branch information
hmemcpy committed Dec 26, 2023
1 parent da635ca commit ddb7e0d
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,25 @@ import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.{PsiElement, PsiFile}
import com.intellij.psi.{PsiClass, PsiElement, PsiFile, PsiNamedElement, PsiPackage}
import org.jetbrains.plugins.scala.codeInsight.intention.types.AbstractTypeAnnotationIntention.complete
import org.jetbrains.plugins.scala.codeInsight.intention.types.{startTemplate, ChooseTypeTextExpression}
import org.jetbrains.plugins.scala.extensions._
import org.jetbrains.plugins.scala.lang.psi.ScalaPsiUtil
import org.jetbrains.plugins.scala.lang.psi.api.base.types.{ScSimpleTypeElement, ScTypeElement}
import org.jetbrains.plugins.scala.lang.psi.api.statements.{ScTypeAlias, ScTypeAliasDefinition}
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.typedef.{ScObject, ScTypeDefinition}
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.typedef.{ScMember, ScObject, ScTypeDefinition}
import org.jetbrains.plugins.scala.lang.psi.impl.ScalaPsiManager
import org.jetbrains.plugins.scala.lang.psi.types.api.designator.ScDesignatorType
import org.jetbrains.plugins.scala.lang.psi.types.api.presentation.ScTypeText
import org.jetbrains.plugins.scala.lang.psi.types.api.{ParameterizedType, UndefinedType}
import org.jetbrains.plugins.scala.lang.psi.types.api.presentation.TypePresentation.PresentationOptions
import org.jetbrains.plugins.scala.lang.psi.types.api.presentation.{NameRenderer, ScTypeText, TypePresentation}
import org.jetbrains.plugins.scala.lang.psi.types.api.{ParameterizedType, UndefinedType, ValueType}
import org.jetbrains.plugins.scala.lang.psi.types.recursiveUpdate.ScSubstitutor
import org.jetbrains.plugins.scala.lang.psi.types.result.Typeable
import org.jetbrains.plugins.scala.lang.psi.types.{AliasType, ScType, TypePresentationContext}
import org.jetbrains.plugins.scala.lang.psi.types.{AliasType, ScType, ScalaTypeVisitor, TypePresentationContext}
import org.jetbrains.plugins.scala.lang.refactoring.util.ScalaNamesUtil
import org.jetbrains.plugins.scala.project.ProjectContext
import org.jetbrains.plugins.scala.settings.ScalaApplicationSettings
import org.jetbrains.plugins.scala.util.IntentionAvailabilityChecker.checkIntention
import zio.intellij.intentions.ZTypeAnnotationIntention
import zio.intellij.utils.TypeCheckUtils.{fromZioLayer, fromZioLike}
Expand Down Expand Up @@ -70,8 +73,11 @@ object SuggestTypeAlias {
qualifier.toList.flatMap { fqn =>
val manager = ScalaPsiManager.instance(context)
manager.getCachedClass(scope, fqn) match {
case Some(z: ScObject) => z.aliases.toList
case _ => Nil
case Some(z: ScObject) =>
val aliases = z.aliases.toList
println(aliases)
aliases
case _ => Nil
}
}
}
Expand All @@ -85,7 +91,7 @@ object SuggestTypeAlias {
(topLevelType(declaredType) +: matchingAliases).distinct
}

def topLevelType(tpe: ScType): ScType =
private def topLevelType(tpe: ScType): ScType =
tpe.aliasType match {
case Some(AliasType(_, _, Right(value))) => value
case _ => tpe
Expand All @@ -104,7 +110,66 @@ object SuggestTypeAlias {
undefSubst(aliasType)
.conformanceSubstitutor(tpe)
.map(subst => subst.apply(ParameterizedType(ScDesignatorType(alias), undefParams)))
.collect { case t: ScType if checker(t) => t }
.collect { case t: ScType if checker(t) => canonicalTextHack(t) }
}
}

private def canonicalTextHack(tpe: ScType): ScType = new ScType {
private val isPreciseText = ScalaApplicationSettings.getInstance().PRECISE_TEXT

override def isValue: Boolean = tpe.isValue

override def inferValueType: ValueType = tpe.inferValueType

override def visitType(visitor: ScalaTypeVisitor): Unit = tpe.visitType(visitor)

override implicit def projectContext: ProjectContext = tpe.projectContext

// TODO temp hack: restores the old behavior of canonicalText from before this change:
// https://github.com/JetBrains/intellij-scala/commit/0669994c02f3eb15d9c67f09f9c696227c83060f
// which caused some type aliases to be displayed as e.g `zioIO` instead of `zio.IO`
override def canonicalText(context: TypePresentationContext): String = {
val renderer: NameRenderer = new NameRenderer {
override def renderName(e: PsiNamedElement): String = nameFun(e, withPoint = false)
override def renderNameWithPoint(e: PsiNamedElement): String = nameFun(e, withPoint = true)

private def nameFun(e: PsiNamedElement, withPoint: Boolean): String = {
val str = e match {
case c: PsiClass =>
val qname = c.qualifiedName
if (qname == null || (!isPreciseText && qname == c.name)) c.name // SCL-21184
else "_root_." + qname
case p: PsiPackage =>
"_root_." + p.getQualifiedName
case _ =>
e.nameContext match {
case m: ScMember =>
m.containingClass match {
case o: ScObject =>
(if (isPreciseText && o.isStatic) "_root_." else "") + nameFun(
o,
withPoint = true
) + e.name // SCL-21182
case _ => e.name
}
case _ => e.name
}
}
removeKeywords(str) + pointStr(withPoint)
}
}

typeSystem.typeText(tpe, renderer, PresentationOptions(renderStdTypes = isPreciseText, canonicalForm = true))(
context
)
}

override def presentableText(implicit context: TypePresentationContext): String = tpe.presentableText

private def removeKeywords(text: String): String =
ScalaNamesUtil.escapeKeywordsFqn(text)

private def pointStr(withPoint: Boolean): String =
if (withPoint) "." else ""
}
}
9 changes: 8 additions & 1 deletion src/main/scala/zio/intellij/utils/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,14 @@ import org.jetbrains.plugins.scala.lang.psi.types.result.Typeable
import org.jetbrains.plugins.scala.lang.refactoring.ScTypePresentationExt
import org.jetbrains.plugins.scala.lang.refactoring.util.ScalaNamesUtil
import org.jetbrains.plugins.scala.project.settings.ScalaCompilerConfiguration
import org.jetbrains.plugins.scala.project.{LibraryExt, ModuleExt, ProjectContext, ProjectExt, ProjectPsiElementExt, ScalaLanguageLevel}
import org.jetbrains.plugins.scala.project.{
LibraryExt,
ModuleExt,
ProjectContext,
ProjectExt,
ProjectPsiElementExt,
ScalaLanguageLevel
}
import org.jetbrains.sbt.SbtUtil
import org.jetbrains.sbt.SbtUtil.getDefaultLauncher
import org.jetbrains.sbt.project.SbtExternalSystemManager
Expand Down

0 comments on commit ddb7e0d

Please sign in to comment.