Skip to content

Commit

Permalink
Fix parsing routines lost in merges (#11031)
Browse files Browse the repository at this point in the history
  • Loading branch information
cartermp authored Feb 6, 2021
1 parent 1ace492 commit 4a6552d
Showing 1 changed file with 65 additions and 12 deletions.
77 changes: 65 additions & 12 deletions src/fsharp/service/FSharpParseFileResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -179,23 +179,23 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput
let rec getIdentRangeForFuncExprInApp traverseSynExpr expr pos =
match expr with
| SynExpr.Ident ident -> Some ident.idRange

| SynExpr.LongIdent(_, _, _, range) -> Some range

| SynExpr.Paren(expr, _, _, range) when rangeContainsPos range pos ->
getIdentRangeForFuncExprInApp traverseSynExpr expr pos

| SynExpr.LongIdent (_, _, _, range) -> Some range

// This matches computation expressions like 'async { ... }'
| SynExpr.App(_, _, _, SynExpr.CompExpr (_, _, expr, range), _) when rangeContainsPos range pos ->
| SynExpr.Paren (expr, _, _, range) when rangeContainsPos range pos ->
getIdentRangeForFuncExprInApp traverseSynExpr expr pos

| SynExpr.App(_, _, funcExpr, argExpr, _) ->
| SynExpr.App (_, _, funcExpr, argExpr, _) ->
match argExpr with
| SynExpr.App (_, _, _, _, range) when rangeContainsPos range pos ->
getIdentRangeForFuncExprInApp traverseSynExpr argExpr pos

| SynExpr.Paren(SynExpr.Lambda(_, _, _args, body, _, _), _, _, _) when rangeContainsPos body.Range pos ->
getIdentRangeForFuncExprInApp traverseSynExpr body pos
// Special case: `async { ... }` is actually a CompExpr inside of the argExpr of a SynExpr.App
| SynExpr.CompExpr (_, _, expr, range) when rangeContainsPos range pos ->
getIdentRangeForFuncExprInApp traverseSynExpr expr pos

| SynExpr.Paren (expr, _, _, range) when rangeContainsPos range pos ->
getIdentRangeForFuncExprInApp traverseSynExpr expr pos

| _ ->
match funcExpr with
Expand All @@ -209,16 +209,68 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput
// of the identifier of the function we're after
getIdentRangeForFuncExprInApp traverseSynExpr funcExpr pos

| SynExpr.LetOrUse(_, _, bindings, body, range) when rangeContainsPos range pos ->
| SynExpr.LetOrUse (_, _, bindings, body, range) when rangeContainsPos range pos ->
let binding =
bindings
|> List.tryFind (fun x -> rangeContainsPos x.RangeOfBindingWithRhs pos)
match binding with
| Some(SynBinding(_, _, _, _, _, _, _, _, _, expr, _, _)) ->
| Some(SynBinding.SynBinding(_, _, _, _, _, _, _, _, _, expr, _, _)) ->
getIdentRangeForFuncExprInApp traverseSynExpr expr pos
| None ->
getIdentRangeForFuncExprInApp traverseSynExpr body pos

| SynExpr.IfThenElse (ifExpr, thenExpr, elseExpr, _, _, _, range) when rangeContainsPos range pos ->
if rangeContainsPos ifExpr.Range pos then
getIdentRangeForFuncExprInApp traverseSynExpr ifExpr pos
elif rangeContainsPos thenExpr.Range pos then
getIdentRangeForFuncExprInApp traverseSynExpr thenExpr pos
else
match elseExpr with
| None -> None
| Some expr ->
getIdentRangeForFuncExprInApp traverseSynExpr expr pos

| SynExpr.Match (_, expr, clauses, range) when rangeContainsPos range pos ->
if rangeContainsPos expr.Range pos then
getIdentRangeForFuncExprInApp traverseSynExpr expr pos
else
let clause = clauses |> List.tryFind (fun clause -> rangeContainsPos clause.Range pos)
match clause with
| None -> None
| Some clause ->
match clause with
| SynMatchClause.SynMatchClause (_, whenExpr, resultExpr, _, _) ->
match whenExpr with
| None ->
getIdentRangeForFuncExprInApp traverseSynExpr resultExpr pos
| Some whenExpr ->
if rangeContainsPos whenExpr.Range pos then
getIdentRangeForFuncExprInApp traverseSynExpr whenExpr pos
else
getIdentRangeForFuncExprInApp traverseSynExpr resultExpr pos


// Ex: C.M(x, y, ...) <--- We want to find where in the tupled application the call is being made
| SynExpr.Tuple(_, exprs, _, tupRange) when rangeContainsPos tupRange pos ->
let expr = exprs |> List.tryFind (fun expr -> rangeContainsPos expr.Range pos)
match expr with
| None -> None
| Some expr ->
getIdentRangeForFuncExprInApp traverseSynExpr expr pos

// Capture the body of a lambda, often nested in a call to a collection function
| SynExpr.Lambda(_, _, _args, body, _, _) when rangeContainsPos body.Range pos ->
getIdentRangeForFuncExprInApp traverseSynExpr body pos

| SynExpr.Do(expr, range) when rangeContainsPos range pos ->
getIdentRangeForFuncExprInApp traverseSynExpr expr pos

| SynExpr.Assert(expr, range) when rangeContainsPos range pos ->
getIdentRangeForFuncExprInApp traverseSynExpr expr pos

| SynExpr.ArbitraryAfterError (_debugStr, range) when rangeContainsPos range pos ->
Some range

| expr ->
traverseSynExpr expr
|> Option.map (fun expr -> expr)
Expand All @@ -234,6 +286,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput
})
| None -> None


member scope.GetAllArgumentsForFunctionApplicationAtPostion pos =
match input with
| Some input -> SynExprAppLocationsImpl.getAllCurriedArgsAtPosition pos input
Expand Down

0 comments on commit 4a6552d

Please sign in to comment.