diff --git a/src/fsharp/service/SemanticClassification.fs b/src/fsharp/service/SemanticClassification.fs index f715f26349..afd85d7db2 100644 --- a/src/fsharp/service/SemanticClassification.fs +++ b/src/fsharp/service/SemanticClassification.fs @@ -89,13 +89,33 @@ module TcResolutionsExtensions = | _ -> None | _ -> None + // Custome builders like 'async { }' are both Item.Value and Item.CustomBuilder. + // We should prefer the latter, otherwise they would not get classified as CEs. + let takeCustomBuilder (cnrs: CapturedNameResolution[]) = + assert (cnrs.Length > 0) + if cnrs.Length = 1 then + cnrs + elif cnrs.Length = 2 then + match cnrs.[0].Item, cnrs.[1].Item with + | Item.Value _, Item.CustomBuilder _ -> + [| cnrs.[1] |] + | Item.CustomBuilder _, Item.Value _ -> + [| cnrs.[0] |] + | _ -> + cnrs + else + cnrs + let resolutions = match range with | Some range -> - sResolutions.CapturedNameResolutions - |> Seq.filter (fun cnr -> rangeContainsPos range cnr.Range.Start || rangeContainsPos range cnr.Range.End) + sResolutions.CapturedNameResolutions.ToArray() + |> Array.filter (fun cnr -> rangeContainsPos range cnr.Range.Start || rangeContainsPos range cnr.Range.End) + |> Array.groupBy (fun cnr -> cnr.Range) + |> Array.map (fun (_, cnrs) -> takeCustomBuilder cnrs) + |> Array.concat | None -> - sResolutions.CapturedNameResolutions :> seq<_> + sResolutions.CapturedNameResolutions.ToArray() let isDisposableTy (ty: TType) = not (typeEquiv g ty g.system_IDisposable_ty) && @@ -129,11 +149,11 @@ module TcResolutionsExtensions = let inline add m typ = if duplicates.Add m then results.Add struct(m, typ) + resolutions - |> Seq.iter (fun cnr -> - match cnr.Item, cnr.ItemOccurence, cnr.DisplayEnv, cnr.NameResolutionEnv, cnr.AccessorDomain, cnr.Range with - // 'seq' in 'seq { ... }' gets colored as keywords - | (Item.Value vref), ItemOccurence.Use, _, _, _, m when valRefEq g g.seq_vref vref -> + |> Array.iter (fun cnr -> + match cnr.Item, cnr.ItemOccurence, cnr.DisplayEnv, cnr.NameResolutionEnv, cnr.AccessorDomain, cnr.Range with + | (Item.CustomBuilder _ | Item.CustomOperation _), ItemOccurence.Use, _, _, _, m -> add m SemanticClassificationType.ComputationExpression | (Item.Value vref), _, _, _, _, m when isValRefMutable vref -> @@ -208,9 +228,6 @@ module TcResolutionsExtensions = else add m SemanticClassificationType.Method - | (Item.CustomBuilder _ | Item.CustomOperation _), ItemOccurence.Use, _, _, _, m -> - add m SemanticClassificationType.ComputationExpression - // Special case measures for struct types | Item.Types(_, TType_app(tyconRef, TType_measure _ :: _) :: _), LegitTypeOccurence, _, _, _, m when isStructTyconRef tyconRef -> add m SemanticClassificationType.ValueType