@@ -2,6 +2,7 @@ package dotty.tools.dotc
22package util
33
44import dotty .tools .dotc .ast .NavigateAST
5+ import dotty .tools .dotc .ast .Positioned
56import dotty .tools .dotc .ast .untpd
67import dotty .tools .dotc .core .NameOps .*
78import dotty .tools .dotc .core .StdNames .nme
@@ -99,7 +100,7 @@ object Signatures {
99100 findEnclosingApply(path, span) match
100101 case Apply (fun, params) => applyCallInfo(span, params, fun, false )
101102 case UnApply (fun, _, patterns) => unapplyCallInfo(span, fun, patterns)
102- case appliedTypeTree @ AppliedTypeTree (_, types) => appliedTypeTreeCallInfo(appliedTypeTree, types)
103+ case appliedTypeTree @ AppliedTypeTree (_, types) => appliedTypeTreeCallInfo(span, appliedTypeTree, types)
103104 case tp @ TypeApply (fun, types) => applyCallInfo(span, types, fun, isTypeApply = true )
104105 case _ => (0 , 0 , Nil )
105106
@@ -154,13 +155,14 @@ object Signatures {
154155 * @param fun Function tree which is being applied
155156 */
156157 private def appliedTypeTreeCallInfo (
158+ span : Span ,
157159 fun : tpd.Tree ,
158160 types : List [tpd.Tree ]
159161 )(using Context ): (Int , Int , List [Signature ]) =
160162 val typeName = fun.symbol.name.show
161163 val typeParams = fun.symbol.typeRef.typeParams.map(_.paramName.show).map(TypeParam .apply(_))
162164 val denot = fun.denot.asSingleDenotation
163- val activeParameter = (types.length - 1 ) max 0
165+ val activeParameter = findCurrentParamIndex (types, span, typeParams .length - 1 )
164166
165167 val signature = Signature (typeName, List (typeParams), Some (typeName) , None , Some (denot))
166168 (activeParameter, 0 , List (signature))
@@ -237,21 +239,8 @@ object Signatures {
237239 case _ :: untpd.TypeApply (_, args) :: _ => args
238240 case _ => Nil
239241
240- val currentParamsIndex = (untpdArgs.indexWhere(_.span.contains(span)) match
241- case - 1 if untpdArgs.isEmpty => 0
242- case - 1 =>
243- commaIndex(untpdArgs, span) match
244- // comma is before CURSOR, so we are in parameter b example: test("a", CURSOR)
245- case Some (index) if index <= span.end => untpdArgs.takeWhile(_.span.end < span.start).length
246- // comma is after CURSOR, so we are in parameter a example: test("a" CURSOR,)
247- case Some (index) => untpdArgs.takeWhile(_.span.start < span.end).length - 1
248- // we are either in first or last parameter
249- case None =>
250- if untpdArgs.head.span.start >= span.end then 0
251- else untpdArgs.length - 1 max 0
252-
253- case n => n
254- ) min (alternativeSymbol.paramSymss(safeParamssListIndex).length - 1 )
242+ val currentParamsIndex =
243+ findCurrentParamIndex(untpdArgs, span, alternativeSymbol.paramSymss(safeParamssListIndex).length - 1 )
255244
256245 val pre = treeQualifier(fun)
257246 val alternativesWithTypes = alternatives.map(_.asSeenFrom(pre.tpe.widenTermRefExpr))
@@ -263,13 +252,37 @@ object Signatures {
263252 else
264253 (0 , 0 , Nil )
265254
255+ /** Finds current parameter index
256+ * @param args List of currently applied arguments
257+ * @param span The position of the cursor
258+ * @param maxIndex The maximum index of the parameter in the current apply list
259+ *
260+ * @return Index of the current parameter
261+ */
262+ private def findCurrentParamIndex (args : List [Positioned ], span : Span , maxIndex : Int )(using Context ): Int =
263+ (args.indexWhere(_.span.contains(span)) match
264+ case - 1 if args.isEmpty => 0
265+ case - 1 =>
266+ commaIndex(args, span) match
267+ // comma is before CURSOR, so we are in parameter b example: test("a", CURSOR)
268+ case Some (index) if index <= span.end => args.takeWhile(_.span.end < span.start).length
269+ // comma is after CURSOR, so we are in parameter a example: test("a" CURSOR,)
270+ case Some (index) => args.takeWhile(_.span.start < span.end).length - 1
271+ // we are either in first or last parameter
272+ case None =>
273+ if args.head.span.start >= span.end then 0
274+ else args.length - 1 max 0
275+
276+ case n => n
277+ ) min maxIndex
278+
266279 /** Parser ignores chars between arguments, we have to manually find the index of comma
267280 * @param untpdArgs List of applied untyped arguments
268281 * @param span The position of the cursor
269282 *
270283 * @return None if we are in first or last parameter, comma index otherwise
271284 */
272- private def commaIndex (untpdArgs : List [untpd. Tree ], span : Span )(using Context ): Option [Int ] =
285+ private def commaIndex (untpdArgs : List [Positioned ], span : Span )(using Context ): Option [Int ] =
273286 val previousArgIndex = untpdArgs.lastIndexWhere(_.span.end < span.end)
274287 for
275288 previousArg <- untpdArgs.lift(previousArgIndex)
@@ -301,7 +314,7 @@ object Signatures {
301314 val paramTypes = extractParamTypess(resultType, denot, patterns.size).flatten.map(stripAllAnnots)
302315 val paramNames = extractParamNamess(resultType, denot).flatten
303316
304- val activeParameter = patterns.takeWhile(_.span.end < span.start).length min ( paramTypes.length - 1 )
317+ val activeParameter = findCurrentParamIndex(patterns, span, paramTypes.length - 1 )
305318 val unapplySignature = toUnapplySignature(denot.asSingleDenotation, paramNames, paramTypes).toList
306319
307320 (activeParameter, 0 , unapplySignature)
0 commit comments