1
1
package dotty .tools .pc
2
2
3
- import dotty .tools .dotc .ast .tpd
4
3
import dotty .tools .dotc .ast .tpd .*
5
- import dotty .tools .dotc .core .Constants .Constant
6
4
import dotty .tools .dotc .core .Contexts .Context
7
5
import dotty .tools .dotc .core .Flags
8
6
import dotty .tools .dotc .core .StdNames
9
- import dotty .tools .dotc .core .Symbols
10
7
import dotty .tools .dotc .core .Symbols .defn
11
8
import dotty .tools .dotc .core .Types .*
12
- import dotty .tools .dotc .core .Types .Type
13
9
import dotty .tools .dotc .interactive .Interactive
14
10
import dotty .tools .dotc .interactive .InteractiveDriver
15
11
import dotty .tools .dotc .typer .Applications .UnapplyArgs
@@ -76,7 +72,7 @@ object InterCompletionType:
76
72
case Try (block, _, _) :: rest if block.span.contains(span) => inferType(rest, span)
77
73
case CaseDef (_, _, body) :: Try (_, cases, _) :: rest if body.span.contains(span) && cases.exists(_.span.contains(span)) => inferType(rest, span)
78
74
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 )
80
76
case CaseDef (_, _, body) :: Match (_, cases) :: rest if body.span.contains(span) && cases.exists(_.span.contains(span)) =>
81
77
inferType(rest, span)
82
78
case NamedArg (_, arg) :: rest if arg.span.contains(span) => inferType(rest, span)
@@ -97,39 +93,38 @@ object InterCompletionType:
97
93
if ind < 0 then None
98
94
else Some (UnapplyArgs (fun.tpe.finalResultType, fun, pats, NoSourcePosition ).argTypes(ind))
99
95
// 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
134
129
case _ => None
135
130
0 commit comments