11package dotty .tools .pc
22
3- import dotty .tools .dotc .ast .tpd
43import dotty .tools .dotc .ast .tpd .*
5- import dotty .tools .dotc .core .Constants .Constant
64import dotty .tools .dotc .core .Contexts .Context
75import dotty .tools .dotc .core .Flags
86import dotty .tools .dotc .core .StdNames
9- import dotty .tools .dotc .core .Symbols
107import dotty .tools .dotc .core .Symbols .defn
118import dotty .tools .dotc .core .Types .*
12- import dotty .tools .dotc .core .Types .Type
139import dotty .tools .dotc .interactive .Interactive
1410import dotty .tools .dotc .interactive .InteractiveDriver
1511import dotty .tools .dotc .typer .Applications .UnapplyArgs
@@ -76,7 +72,7 @@ object InterCompletionType:
7672 case Try (block, _, _) :: rest if block.span.contains(span) => inferType(rest, span)
7773 case CaseDef (_, _, body) :: Try (_, cases, _) :: rest if body.span.contains(span) && cases.exists(_.span.contains(span)) => inferType(rest, span)
7874 case If (cond, _, _) :: rest if ! cond.span.contains(span) => inferType(rest, span)
79- case If (cond, _, _) :: rest if cond.span.contains(span) => Some (Symbols . defn.BooleanType )
75+ case If (cond, _, _) :: rest if cond.span.contains(span) => Some (defn.BooleanType )
8076 case CaseDef (_, _, body) :: Match (_, cases) :: rest if body.span.contains(span) && cases.exists(_.span.contains(span)) =>
8177 inferType(rest, span)
8278 case NamedArg (_, arg) :: rest if arg.span.contains(span) => inferType(rest, span)
@@ -97,39 +93,38 @@ object InterCompletionType:
9793 if ind < 0 then None
9894 else Some (UnapplyArgs (fun.tpe.finalResultType, fun, pats, NoSourcePosition ).argTypes(ind))
9995 // f(@@)
100- case (app : Apply ) :: rest =>
101- val param =
102- for {
103- ind <- app.args.zipWithIndex.collectFirst {
104- case (arg, id) if arg.span.contains(span) => id
105- }
106- params <- app.symbol.paramSymss.find(! _.exists(_.isTypeParam))
107- param <- params.get(ind)
108- } yield param.info
109- param match
110- // def f[T](a: T): T = ???
111- // f[Int](@@)
112- // val _: Int = f(@@)
113- case Some (t : TypeRef ) if t.symbol.is(Flags .TypeParam ) =>
114- for {
115- (typeParams, args) <-
116- app match
117- case Apply (TypeApply (fun, args), _) =>
118- val typeParams = fun.symbol.paramSymss.headOption.filter(_.forall(_.isTypeParam))
119- typeParams.map((_, args.map(_.tpe)))
120- // val f: (j: "a") => Int
121- // f(@@)
122- case Apply (Select (v, StdNames .nme.apply), _) =>
123- v.symbol.info match
124- case AppliedType (des, args) =>
125- Some ((des.typeSymbol.typeParams, args))
126- case _ => None
127- case _ => None
128- ind = typeParams.indexOf(t.symbol)
129- tpe <- args.get(ind)
130- if ! tpe.isErroneous
131- } yield tpe
132- case Some (tpe) => Some (tpe)
133- case _ => None
96+ case ApplyExtractor (app) =>
97+ val argsAndParams = ApplyArgsExtractor .getArgsAndParams(None , app, span).headOption
98+ argsAndParams.flatMap:
99+ case (args, params) =>
100+ val idx = args.indexWhere(_.span.contains(span))
101+ val param =
102+ if idx >= 0 && params.length > idx then Some (params(idx).info)
103+ else None
104+ param match
105+ // def f[T](a: T): T = ???
106+ // f[Int](@@)
107+ // val _: Int = f(@@)
108+ case Some (t : TypeRef ) if t.symbol.is(Flags .TypeParam ) =>
109+ for
110+ (typeParams, args) <-
111+ app match
112+ case Apply (TypeApply (fun, args), _) =>
113+ val typeParams = fun.symbol.paramSymss.headOption.filter(_.forall(_.isTypeParam))
114+ typeParams.map((_, args.map(_.tpe)))
115+ // val f: (j: "a") => Int
116+ // f(@@)
117+ case Apply (Select (v, StdNames .nme.apply), _) =>
118+ v.symbol.info match
119+ case AppliedType (des, args) =>
120+ Some ((des.typeSymbol.typeParams, args))
121+ case _ => None
122+ case _ => None
123+ ind = typeParams.indexOf(t.symbol)
124+ tpe <- args.get(ind)
125+ if ! tpe.isErroneous
126+ yield tpe
127+ case Some (tpe) => Some (tpe)
128+ case _ => None
134129 case _ => None
135130
0 commit comments