@@ -11,7 +11,6 @@ import core.Names._
1111import core .Types ._
1212import util .Spans .Span
1313import reporting ._
14- import dotty .tools .dotc .core .NameKinds
1514
1615
1716object Signatures {
@@ -49,11 +48,12 @@ object Signatures {
4948 * being called, the list of overloads of this function).
5049 */
5150 def callInfo (path : List [tpd.Tree ], span : Span )(using Context ): (Int , Int , List [SingleDenotation ]) =
52- val enclosingApply = path.find {
53- case Apply (fun, _) => ! fun.span.contains(span)
54- case UnApply (fun, _, _) => ! fun.span.contains(span)
55- case _ => false
56- }
51+ val enclosingApply = path.dropWhile {
52+ case Apply (fun, _) => fun.span.contains(span)
53+ case unapply @ UnApply (fun, _, _) =>
54+ fun.span.contains(span) || ctx.definitions.isTupleClass(unapply.fun.symbol.owner.companionClass)
55+ case _ => true
56+ }.headOption
5757
5858 enclosingApply.map {
5959 case UnApply (fun, _, patterns) => unapplyCallInfo(span, fun, patterns)
@@ -85,12 +85,50 @@ object Signatures {
8585
8686 (paramIndex, alternativeIndex, alternatives)
8787
88- private def unapplyCallInfo (span : Span ,
88+ private def unapplyCallInfo (
89+ span : Span ,
8990 fun : tpd.Tree ,
9091 patterns : List [tpd.Tree ]
9192 )(using Context ): (Int , Int , List [SingleDenotation ]) =
92- val paramIndex = patterns.indexWhere(_.span.contains(span)) max 0
93- (paramIndex, 0 , fun.symbol.asSingleDenotation.mapInfo(_ => fun.tpe) :: Nil )
93+ val patternPosition = patterns.indexWhere(_.span.contains(span))
94+ val activeParameter = extractParamTypess(fun.tpe.finalResultType.widen).headOption.map { params =>
95+ if patternPosition == - 1 then
96+ if patterns.length > 0 then
97+ (params.size - 1 )
98+ else
99+ 0
100+ else
101+ (params.size - 1 ) min patternPosition
102+ }.getOrElse(patternPosition)
103+
104+ (activeParameter, 0 , fun.symbol.asSingleDenotation.mapInfo(_ => fun.tpe) :: Nil )
105+
106+ private def extractParamTypess (resultType : Type )(using Context ): List [List [Type ]] =
107+ resultType match {
108+ case ref : TypeRef if ! ref.symbol.isPrimitiveValueClass =>
109+ if (
110+ ref.symbol.asClass.baseClasses.contains(ctx.definitions.ProductClass ) &&
111+ ! ref.symbol.is(Flags .CaseClass )
112+ ) || ref.symbol.isStaticOwner then
113+ val productAccessors = ref.memberDenots(
114+ underscoreMembersFilter,
115+ (name, buf) => buf += ref.member(name).asSingleDenotation
116+ )
117+ List (productAccessors.map(_.info.finalResultType).toList)
118+ else
119+ ref.symbol.primaryConstructor.paramInfo.paramInfoss
120+ case AppliedType (TypeRef (_, cls), (appliedType @ AppliedType (tycon, args)) :: Nil )
121+ if (cls == ctx.definitions.OptionClass || cls == ctx.definitions.SomeClass ) =>
122+ tycon match
123+ case TypeRef (_, cls) if cls == ctx.definitions.SeqClass => List (List (appliedType))
124+ case _ => List (args)
125+ case AppliedType (_, args) =>
126+ List (args)
127+ case MethodTpe (_, _, resultType) =>
128+ extractParamTypess(resultType.widenDealias)
129+ case _ =>
130+ Nil
131+ }
94132
95133 def toSignature (denot : SingleDenotation )(using Context ): Option [Signature ] = {
96134 val symbol = denot.symbol
@@ -111,7 +149,8 @@ object Signatures {
111149 Nil
112150 }
113151 val params = tp.paramNames.zip(tp.paramInfos).map { case (name, info) =>
114- Signatures .Param (name.show,
152+ Signatures .Param (
153+ name.show,
115154 info.widenTermRefExpr.show,
116155 docComment.flatMap(_.paramDoc(name)),
117156 isImplicit = tp.isImplicitMethod)
@@ -123,45 +162,22 @@ object Signatures {
123162 /**
124163 * This function is a hack which allows Signatures API to remain unchanged
125164 *
126- * @return true if denot is "unapply", false otherwise
165+ * @return true if denot is "unapply" or "unapplySeq" , false otherwise
127166 */
128- def isUnapplyDenotation : Boolean = List (core.Names .termName(" unapply" ), core.Names .termName(" unapplySeq" )) contains denot.name
167+ def isUnapplyDenotation : Boolean =
168+ List (core.Names .termName(" unapply" ), core.Names .termName(" unapplySeq" )) contains denot.name
129169
130170 def extractParamNamess (resultType : Type ): List [List [Name ]] =
131- if resultType.resultType.widen. typeSymbol.flags.is(Flags .CaseClass ) && symbol.flags.is(Flags .Synthetic ) then
132- resultType.resultType.widen. typeSymbol.primaryConstructor.paramInfo.paramNamess
171+ if resultType.typeSymbol.flags.is(Flags .CaseClass ) && symbol.flags.is(Flags .Synthetic ) then
172+ resultType.typeSymbol.primaryConstructor.paramInfo.paramNamess
133173 else
134174 Nil
135175
136- def extractParamTypess (resultType : Type ): List [List [Type ]] =
137- resultType match {
138- case ref : TypeRef if ! ref.symbol.isPrimitiveValueClass =>
139- if (
140- ref.symbol.asClass.baseClasses.contains(ctx.definitions.ProductClass ) &&
141- ! ref.symbol.is(Flags .CaseClass )
142- ) || ref.symbol.isStaticOwner then
143- val productAccessors = ref.memberDenots(
144- underscoreMembersFilter,
145- (name, buf) => buf += ref.member(name).asSingleDenotation
146- )
147- List (productAccessors.map(_.info.finalResultType).toList)
148- else
149- ref.symbol.primaryConstructor.paramInfo.paramInfoss
150- case AppliedType (TypeRef (_, cls), (appliedType @ AppliedType (tycon, args)) :: Nil )
151- if (cls == ctx.definitions.OptionClass || cls == ctx.definitions.SomeClass ) =>
152- tycon match
153- case TypeRef (_, cls) if cls == ctx.definitions.SeqClass => List (List (appliedType))
154- case _ => List (args)
155- case AppliedType (_, args) =>
156- List (args)
157- case MethodTpe (_, _, resultType) =>
158- extractParamTypess(resultType.widenDealias)
159- case _ =>
160- Nil
161- }
162-
163176 def toUnapplyParamss (method : Type )(using Context ): List [Param ] = {
164- val resultType = method.finalResultType.widenDealias
177+ val resultType = method.finalResultType.widenDealias match
178+ case methodType : MethodType => methodType.resultType.widen
179+ case other => other
180+
165181 val paramNames = extractParamNamess(resultType).flatten
166182 val paramTypes = extractParamTypess(resultType).flatten
167183
0 commit comments