@@ -8,8 +8,19 @@ open FSharp.Compiler.Text.Range
88open FSharp.Compiler .Syntax
99open FSharp.Compiler .SyntaxTreeOps
1010
11+ type TupledArgumentLocation = { IsNamedArgument: bool ; ArgumentRange: range }
12+
1113[<Sealed>]
12- type ParameterLocations ( longId : string list , longIdRange : range , openParenLocation : pos , tupleEndLocations : pos list , isThereACloseParen : bool , namedParamNames : string option list ) =
14+ type ParameterLocations
15+ (
16+ longId: string list,
17+ longIdRange: range,
18+ openParenLocation: pos,
19+ argRanges: TupledArgumentLocation list,
20+ tupleEndLocations: pos list,
21+ isThereACloseParen: bool,
22+ namedParamNames: string option list
23+ ) =
1324
1425 let tupleEndLocations = Array.ofList tupleEndLocations
1526 let namedParamNames = Array.ofList namedParamNames
@@ -30,6 +41,7 @@ type ParameterLocations(longId: string list, longIdRange: range, openParenLocati
3041 member this.TupleEndLocations = tupleEndLocations
3142 member this.IsThereACloseParen = isThereACloseParen
3243 member this.NamedParamNames = namedParamNames
44+ member this.ArgumentLocations = argRanges |> Array.ofList
3345
3446[<AutoOpen>]
3547module internal ParameterLocationsImpl =
@@ -54,7 +66,7 @@ module internal ParameterLocationsImpl =
5466 | _ -> None
5567
5668 type FindResult =
57- | Found of openParen : pos * commasAndCloseParen : ( pos * string option ) list * hasClosedParen : bool
69+ | Found of openParen : pos * argRanges : TupledArgumentLocation list * commasAndCloseParen : ( pos * string option ) list * hasClosedParen : bool
5870 | NotFound
5971
6072 let digOutIdentFromStaticArg ( StripParenTypes synType ) =
@@ -90,7 +102,8 @@ module internal ParameterLocationsImpl =
90102 match inner with
91103 | None ->
92104 if SyntaxTraversal.rangeContainsPosLeftEdgeExclusiveAndRightEdgeInclusive parenRange pos then
93- Found ( parenRange.Start, [( parenRange.End, getNamedParamName synExpr)], rpRangeOpt.IsSome), None
105+ let argRanges = [{ IsNamedArgument = ( getNamedParamName synExpr). IsSome; ArgumentRange = synExpr.Range }]
106+ Found ( parenRange.Start, argRanges, [( parenRange.End, getNamedParamName synExpr)], rpRangeOpt.IsSome), None
94107 else
95108 NotFound, None
96109 | _ -> NotFound, None
@@ -107,8 +120,12 @@ module internal ParameterLocationsImpl =
107120 match inner with
108121 | None ->
109122 if SyntaxTraversal.rangeContainsPosLeftEdgeExclusiveAndRightEdgeInclusive parenRange pos then
123+ // argRange, isNamed
124+ let argRanges =
125+ synExprList
126+ |> List.map ( fun e -> { IsNamedArgument = ( getNamedParamName e) .IsSome; ArgumentRange = e.Range })
110127 let commasAndCloseParen = (( synExprList, commaRanges@[ parenRange]) ||> List.map2 ( fun e c -> c.End, getNamedParamName e))
111- let r = Found ( parenRange.Start, commasAndCloseParen, rpRangeOpt.IsSome)
128+ let r = Found ( parenRange.Start, argRanges , commasAndCloseParen, rpRangeOpt.IsSome)
112129 r, None
113130 else
114131 NotFound, None
@@ -127,14 +144,14 @@ module internal ParameterLocationsImpl =
127144
128145 | SynExpr.ArbitraryAfterError (_ debugStr, range) -> // single argument when e.g. after open paren you hit EOF
129146 if SyntaxTraversal.rangeContainsPosEdgesExclusive range pos then
130- let r = Found ( range.Start, [( range.End, None)], false )
147+ let r = Found ( range.Start, [], [ ( range.End, None)], false )
131148 r, None
132149 else
133150 NotFound, None
134151
135152 | SynExpr.Const ( SynConst.Unit, unitRange) ->
136153 if SyntaxTraversal.rangeContainsPosEdgesExclusive unitRange pos then
137- let r = Found ( unitRange.Start, [( unitRange.End, None)], true )
154+ let r = Found ( unitRange.Start, [], [ ( unitRange.End, None)], true )
138155 r, None
139156 else
140157 NotFound, None
@@ -145,7 +162,7 @@ module internal ParameterLocationsImpl =
145162 | None ->
146163 if SyntaxTraversal.rangeContainsPosEdgesExclusive e.Range pos then
147164 // any other expression doesn't start with parens, so if it was the target of an App, then it must be a single argument e.g. "f x"
148- Found ( e.Range.Start, [ ( e.Range.End, None) ], false ), Some inner
165+ Found ( e.Range.Start, [], [ ( e.Range.End, None) ], false ), Some inner
149166 else
150167 NotFound, Some inner
151168 | _ -> NotFound, Some inner
@@ -157,7 +174,7 @@ module internal ParameterLocationsImpl =
157174 let betweenTheBrackets = mkRange wholem.FileName openm.Start wholem.End
158175 if SyntaxTraversal.rangeContainsPosEdgesExclusive betweenTheBrackets pos && args |> List.forall isStaticArg then
159176 let commasAndCloseParen = [ for c in commas -> c.End ] @ [ wholem.End ]
160- Some ( ParameterLocations( pathOfLid lid, lidm, openm.Start, commasAndCloseParen, closemOpt.IsSome, args |> List.map digOutIdentFromStaticArg))
177+ Some ( ParameterLocations( pathOfLid lid, lidm, openm.Start, [], commasAndCloseParen, closemOpt.IsSome, args |> List.map digOutIdentFromStaticArg))
161178 else
162179 None
163180 | _ ->
@@ -173,9 +190,9 @@ module internal ParameterLocationsImpl =
173190 | SynExpr.New (_, synType, synExpr, _) ->
174191 let constrArgsResult , cacheOpt = searchSynArgExpr traverseSynExpr pos synExpr
175192 match constrArgsResult, cacheOpt with
176- | Found( parenLoc, args , isThereACloseParen), _ ->
193+ | Found( parenLoc, argRanges , commasAndCloseParen , isThereACloseParen), _ ->
177194 let typeName = getTypeName synType
178- Some ( ParameterLocations( typeName, synType.Range, parenLoc, args |> List.map fst, isThereACloseParen, args |> List.map snd))
195+ Some ( ParameterLocations( typeName, synType.Range, parenLoc, argRanges , commasAndCloseParen |> List.map fst, isThereACloseParen, commasAndCloseParen |> List.map snd))
179196 | NotFound, Some cache ->
180197 cache
181198 | _ ->
@@ -194,7 +211,7 @@ module internal ParameterLocationsImpl =
194211 if SyntaxTraversal.rangeContainsPosEdgesExclusive typeArgsm pos then
195212 // We found it, dig out ident
196213 match digOutIdentFromFuncExpr synExpr with
197- | Some( lid, lidRange) -> Some ( ParameterLocations( lid, lidRange, op.idRange.Start, [ wholem.End ], false , []))
214+ | Some( lid, lidRange) -> Some ( ParameterLocations( lid, lidRange, op.idRange.Start, [], [ wholem.End ], false , []))
198215 | None -> None
199216 else
200217 None
@@ -209,7 +226,7 @@ module internal ParameterLocationsImpl =
209226 // Search the argument
210227 let xResult , cacheOpt = searchSynArgExpr traverseSynExpr pos synExpr2
211228 match xResult, cacheOpt with
212- | Found( parenLoc, args , isThereACloseParen), _ ->
229+ | Found( parenLoc, argRanges , commasAndCloseParen , isThereACloseParen), _ ->
213230 // We found it, dig out ident
214231 match digOutIdentFromFuncExpr synExpr with
215232 | Some( lid, lidRange) ->
@@ -219,7 +236,7 @@ module internal ParameterLocationsImpl =
219236 // For now, we don't support infix operators.
220237 None
221238 else
222- Some ( ParameterLocations( lid, lidRange, parenLoc, args |> List.map fst, isThereACloseParen, args |> List.map snd))
239+ Some ( ParameterLocations( lid, lidRange, parenLoc, argRanges , commasAndCloseParen |> List.map fst, isThereACloseParen, commasAndCloseParen |> List.map snd))
223240 | None -> None
224241 | NotFound, Some cache -> cache
225242 | _ -> traverseSynExpr synExpr2
@@ -232,7 +249,8 @@ module internal ParameterLocationsImpl =
232249 let typeArgsm = mkRange openm.FileName openm.Start wholem.End
233250 if SyntaxTraversal.rangeContainsPosEdgesExclusive typeArgsm pos && tyArgs |> List.forall isStaticArg then
234251 let commasAndCloseParen = [ for c in commas -> c.End ] @ [ wholem.End ]
235- let r = ParameterLocations([ " dummy" ], synExpr.Range, openm.Start, commasAndCloseParen, closemOpt.IsSome, tyArgs |> List.map digOutIdentFromStaticArg)
252+ let argRanges = tyArgs |> List.map ( fun tyarg -> { IsNamedArgument = false ; ArgumentRange = tyarg.Range })
253+ let r = ParameterLocations([ " dummy" ], synExpr.Range, openm.Start, argRanges, commasAndCloseParen, closemOpt.IsSome, tyArgs |> List.map digOutIdentFromStaticArg)
236254 Some r
237255 else
238256 None
@@ -253,10 +271,10 @@ module internal ParameterLocationsImpl =
253271 // inherit ty(expr) --- treat it like an application (constructor call)
254272 let xResult , _cacheOpt = searchSynArgExpr defaultTraverse pos expr
255273 match xResult with
256- | Found( parenLoc, args , isThereACloseParen) ->
274+ | Found( parenLoc, argRanges , commasAndCloseParen , isThereACloseParen) ->
257275 // we found it, dig out ident
258276 let typeName = getTypeName ty
259- let r = ParameterLocations( typeName, ty.Range, parenLoc, args |> List.map fst, isThereACloseParen, args |> List.map snd)
277+ let r = ParameterLocations( typeName, ty.Range, parenLoc, argRanges , commasAndCloseParen |> List.map fst, isThereACloseParen, commasAndCloseParen |> List.map snd)
260278 Some r
261279 | NotFound -> None
262280 else None
@@ -276,7 +294,6 @@ type ParameterLocations with
276294 r
277295 | _ -> None
278296
279-
280297module internal SynExprAppLocationsImpl =
281298 let rec private searchSynArgExpr traverseSynExpr expr ranges =
282299 match expr with
0 commit comments