@@ -4,22 +4,25 @@ import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
4
4
import com .intellij .openapi .editor .Editor
5
5
import com .intellij .openapi .project .Project
6
6
import com .intellij .psi .search .GlobalSearchScope
7
- import com .intellij .psi .{PsiElement , PsiFile }
7
+ import com .intellij .psi .{PsiClass , PsiElement , PsiFile , PsiNamedElement , PsiPackage }
8
8
import org .jetbrains .plugins .scala .codeInsight .intention .types .AbstractTypeAnnotationIntention .complete
9
9
import org .jetbrains .plugins .scala .codeInsight .intention .types .{startTemplate , ChooseTypeTextExpression }
10
10
import org .jetbrains .plugins .scala .extensions ._
11
11
import org .jetbrains .plugins .scala .lang .psi .ScalaPsiUtil
12
12
import org .jetbrains .plugins .scala .lang .psi .api .base .types .{ScSimpleTypeElement , ScTypeElement }
13
13
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 }
15
15
import org .jetbrains .plugins .scala .lang .psi .impl .ScalaPsiManager
16
16
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 }
19
20
import org .jetbrains .plugins .scala .lang .psi .types .recursiveUpdate .ScSubstitutor
20
21
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
22
24
import org .jetbrains .plugins .scala .project .ProjectContext
25
+ import org .jetbrains .plugins .scala .settings .ScalaApplicationSettings
23
26
import org .jetbrains .plugins .scala .util .IntentionAvailabilityChecker .checkIntention
24
27
import zio .intellij .intentions .ZTypeAnnotationIntention
25
28
import zio .intellij .utils .TypeCheckUtils .{fromZioLayer , fromZioLike }
@@ -85,7 +88,7 @@ object SuggestTypeAlias {
85
88
(topLevelType(declaredType) +: matchingAliases).distinct
86
89
}
87
90
88
- def topLevelType (tpe : ScType ): ScType =
91
+ private def topLevelType (tpe : ScType ): ScType =
89
92
tpe.aliasType match {
90
93
case Some (AliasType (_, _, Right (value))) => value
91
94
case _ => tpe
@@ -104,7 +107,66 @@ object SuggestTypeAlias {
104
107
undefSubst(aliasType)
105
108
.conformanceSubstitutor(tpe)
106
109
.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) }
108
111
}
109
112
}
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
+ }
110
172
}
0 commit comments