From 5ad20d1c73da2f77c0804569721d002188a4fc22 Mon Sep 17 00:00:00 2001 From: kerams Date: Fri, 30 Jun 2023 18:55:13 +0200 Subject: [PATCH 1/8] Suggest identifier names in patterns --- src/Compiler/Checking/ConstraintSolver.fs | 37 +----- src/Compiler/FSComp.txt | 1 + src/Compiler/Service/FSharpCheckerResults.fs | 107 ++++++++++++++++- .../Service/ServiceDeclarationLists.fs | 9 +- .../Service/ServiceDeclarationLists.fsi | 1 + src/Compiler/Service/ServiceParsedInputOps.fs | 109 ++++++++++++++++-- .../Service/ServiceParsedInputOps.fsi | 20 +++- src/Compiler/TypedTree/TypedTreeOps.fs | 31 +++++ src/Compiler/TypedTree/TypedTreeOps.fsi | 21 ++++ src/Compiler/xlf/FSComp.txt.cs.xlf | 5 + src/Compiler/xlf/FSComp.txt.de.xlf | 5 + src/Compiler/xlf/FSComp.txt.es.xlf | 5 + src/Compiler/xlf/FSComp.txt.fr.xlf | 5 + src/Compiler/xlf/FSComp.txt.it.xlf | 5 + src/Compiler/xlf/FSComp.txt.ja.xlf | 5 + src/Compiler/xlf/FSComp.txt.ko.xlf | 5 + src/Compiler/xlf/FSComp.txt.pl.xlf | 5 + src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 5 + src/Compiler/xlf/FSComp.txt.ru.xlf | 5 + src/Compiler/xlf/FSComp.txt.tr.xlf | 5 + src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 5 + src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 5 + ...ervice.SurfaceArea.netstandard20.debug.bsl | 54 ++++++++- ...vice.SurfaceArea.netstandard20.release.bsl | 54 ++++++++- .../Completion/CompletionUtils.fs | 1 + .../CompletionProviderTests.fs | 88 ++++++++++++++ 26 files changed, 532 insertions(+), 66 deletions(-) diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs index f80916c325e..34b25ba36a1 100644 --- a/src/Compiler/Checking/ConstraintSolver.fs +++ b/src/Compiler/Checking/ConstraintSolver.fs @@ -397,53 +397,22 @@ let rec isNativeIntegerTy g ty = typeEquivAux EraseMeasures g g.unativeint_ty ty || (isEnumTy g ty && isNativeIntegerTy g (underlyingTypeOfEnumTy g ty)) -let isSignedIntegerTy g ty = - typeEquivAux EraseMeasures g g.sbyte_ty ty || - typeEquivAux EraseMeasures g g.int16_ty ty || - typeEquivAux EraseMeasures g g.int32_ty ty || - typeEquivAux EraseMeasures g g.nativeint_ty ty || - typeEquivAux EraseMeasures g g.int64_ty ty - -let isUnsignedIntegerTy g ty = - typeEquivAux EraseMeasures g g.byte_ty ty || - typeEquivAux EraseMeasures g g.uint16_ty ty || - typeEquivAux EraseMeasures g g.uint32_ty ty || - typeEquivAux EraseMeasures g g.unativeint_ty ty || - typeEquivAux EraseMeasures g g.uint64_ty ty - let rec IsIntegerOrIntegerEnumTy g ty = isSignedIntegerTy g ty || isUnsignedIntegerTy g ty || (isEnumTy g ty && IsIntegerOrIntegerEnumTy g (underlyingTypeOfEnumTy g ty)) -let isIntegerTy g ty = - isSignedIntegerTy g ty || - isUnsignedIntegerTy g ty - let isStringTy g ty = typeEquiv g g.string_ty ty let isCharTy g ty = typeEquiv g g.char_ty ty let isBoolTy g ty = typeEquiv g g.bool_ty ty -/// float or float32 or float<_> or float32<_> -let isFpTy g ty = - typeEquivAux EraseMeasures g g.float_ty ty || - typeEquivAux EraseMeasures g g.float32_ty ty - -/// decimal or decimal<_> -let isDecimalTy g ty = - typeEquivAux EraseMeasures g g.decimal_ty ty - let IsNonDecimalNumericOrIntegralEnumType g ty = IsIntegerOrIntegerEnumTy g ty || isFpTy g ty let IsNumericOrIntegralEnumType g ty = IsNonDecimalNumericOrIntegralEnumType g ty || isDecimalTy g ty -let IsNonDecimalNumericType g ty = isIntegerTy g ty || isFpTy g ty - -let IsNumericType g ty = IsNonDecimalNumericType g ty || isDecimalTy g ty - -let IsRelationalType g ty = IsNumericType g ty || isStringTy g ty || isCharTy g ty || isBoolTy g ty +let IsRelationalType g ty = isNumericType g ty || isStringTy g ty || isCharTy g ty || isBoolTy g ty let IsCharOrStringType g ty = isCharTy g ty || isStringTy g ty @@ -1517,12 +1486,12 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload // We pretend for uniformity that the numeric types have a static property called Zero and One // As with constants, only zero is polymorphic in its units | [], [ty], false, "get_Zero", [] - when IsNumericType g ty || isCharTy g ty -> + when isNumericType g ty || isCharTy g ty -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy ty return TTraitBuiltIn | [], [ty], false, "get_One", [] - when IsNumericType g ty || isCharTy g ty -> + when isNumericType g ty || isCharTy g ty -> do! SolveDimensionlessNumericType csenv ndeep m2 trace ty do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy ty return TTraitBuiltIn diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 764f3faf17b..c14f2f8760f 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -962,6 +962,7 @@ typeInfoFromFirst,"from %s" typeInfoFromNext,"also from %s" typeInfoGeneratedProperty,"generated property" typeInfoGeneratedType,"generated type" +suggestedName,"(Suggested name)" 1089,recursiveClassHierarchy,"Recursive class hierarchy in type '%s'" 1090,InvalidRecursiveReferenceToAbstractSlot,"Invalid recursive reference to an abstract slot" 1091,eventHasNonStandardType,"The event '%s' has a non-standard type. If this event is declared in another CLI language, you may need to access this event using the explicit %s and %s methods for the event. If this event is declared in F#, make the type of the event an instantiation of either 'IDelegateEvent<_>' or 'IEvent<_,_>'." diff --git a/src/Compiler/Service/FSharpCheckerResults.fs b/src/Compiler/Service/FSharpCheckerResults.fs index 4a4aefa818d..fbba5351539 100644 --- a/src/Compiler/Service/FSharpCheckerResults.fs +++ b/src/Compiler/Service/FSharpCheckerResults.fs @@ -49,11 +49,6 @@ open FSharp.Compiler.Text.Range open FSharp.Compiler.TypedTree open FSharp.Compiler.TypedTreeBasics open FSharp.Compiler.TypedTreeOps -open FSharp.Compiler.AbstractIL -open System.Reflection.PortableExecutable -open FSharp.Compiler.CreateILModule -open FSharp.Compiler.IlxGen -open FSharp.Compiler.BuildGraph open Internal.Utilities open Internal.Utilities.Collections @@ -937,6 +932,61 @@ type internal TypeCheckInfo let DefaultCompletionItem item = CompletionItem ValueNone ValueNone item + let CompletionItemSuggestedName displayName = + { + ItemWithInst = ItemWithNoInst(Item.NewDef(Ident(displayName, range0))) + MinorPriority = 0 + Type = None + Kind = CompletionItemKind.SuggestedName + IsOwnMember = false + Unresolved = None + } + + /// Check whether the suggested name is unused and add it to the list. + /// In the future we could use an increasing numeric suffix for conflict resolution + let PostProcessSuggestedPatternName (pos: pos) name list = + let name = String.lowerCaseFirstChar name + + let unused = + sResolutions.CapturedNameResolutions + |> ResizeArray.forall (fun r -> + match r.Item with + | Item.Value vref when r.Pos.Line = pos.Line -> vref.DisplayName <> name + | _ -> true) + + if unused then + CompletionItemSuggestedName name :: list + else + list + + /// Suggest name based on type, add it to the list + let SuggestNameBasedOnType g pos ty list = + if isNumericType g ty then + PostProcessSuggestedPatternName pos "num" list + else + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> PostProcessSuggestedPatternName pos tcref.DisplayName list + | _ -> list + + /// Suggest name based on field name and type, add it to the list + let SuggestNameForUnionCaseFieldPattern g pos (uci: UnionCaseInfo) indexOrName list = + let field = + match indexOrName with + | Choice1Of2 index -> + // Index is None when parentheses were not used, i.e. "| Some v ->" - suggest a name only when the case has a single field + match uci.UnionCase.RecdFieldsArray, index with + | [| field |], None -> Some field + | [| _ |], Some _ + | _, None -> None + | arr, Some index -> arr |> Array.tryItem index + | Choice2Of2 name -> uci.UnionCase.RecdFieldsArray |> Array.tryFind (fun x -> x.DisplayName = name) + + field + |> Option.map (fun f -> + SuggestNameBasedOnType g pos f.FormalType list + |> PostProcessSuggestedPatternName pos f.DisplayName) + |> Option.defaultValue list + let getItem (x: ItemWithInst) = x.Item let GetDeclaredItems @@ -1403,7 +1453,7 @@ type internal TypeCheckInfo m) // Completion at '(x: ...)" - | Some CompletionContext.PatternType + | Some (CompletionContext.Pattern PatternContext.Type) // Completion at '| Case1 of ...' | Some CompletionContext.UnionCaseFieldsDeclaration // Completion at 'type Long = int6...' or 'type SomeUnion = Abc...' @@ -1437,6 +1487,51 @@ type internal TypeCheckInfo denv, m) + | Some (CompletionContext.Pattern patternContext) -> + let declaredItems = + GetDeclaredItems( + parseResultsOpt, + lineStr, + origLongIdentOpt, + colAtEndOfNamesAndResidue, + residueOpt, + lastDotPos, + line, + loc, + filterCtors, + resolveOverloads, + false, + getAllSymbols + ) + |> Option.map (fun (items, denv, range) -> + let filtered = + items + |> List.filter (fun item -> + match item.Item with + | Item.Value v -> v.LiteralValue.IsSome + | _ -> true) + + filtered, denv, range) + + let indexOrName, caseIdRange = + match patternContext with + | PatternContext.PositionalUnionCaseField (index, m) -> Choice1Of2 index, m + | PatternContext.NamedUnionCaseField (name, m) -> Choice2Of2 name, m + | PatternContext.Type // This is handled separately above + | PatternContext.Other -> Choice1Of2 None, range0 + + if equals caseIdRange range0 then + declaredItems + else + GetCapturedNameResolutions caseIdRange.End ResolveOverloads.Yes + |> ResizeArray.tryPick (fun r -> + match r.Item with + | Item.UnionCase (uci, _) -> + let list = declaredItems |> Option.map p13 |> Option.defaultValue [] + Some(SuggestNameForUnionCaseFieldPattern g caseIdRange.End uci indexOrName list, r.DisplayEnv, r.Range) + | _ -> None) + |> Option.orElse declaredItems + // Other completions | cc -> match residueOpt |> Option.bind Seq.tryHead with diff --git a/src/Compiler/Service/ServiceDeclarationLists.fs b/src/Compiler/Service/ServiceDeclarationLists.fs index a0da4745902..267380b330f 100644 --- a/src/Compiler/Service/ServiceDeclarationLists.fs +++ b/src/Compiler/Service/ServiceDeclarationLists.fs @@ -66,6 +66,7 @@ type ToolTipText = [] type CompletionItemKind = + | SuggestedName | Field | Property | Method of isExtension : bool @@ -1035,10 +1036,12 @@ type DeclarationListItem(textInDeclList: string, textInCode: string, fullName: s member _.NameInCode = textInCode member _.Description = - match info with - | Choice1Of2 (items: CompletionItem list, infoReader, ad, m, denv) -> + match kind, info with + | CompletionItemKind.SuggestedName, _ -> + ToolTipText [ ToolTipElement.Single ([| tagText (FSComp.SR.suggestedName()) |], FSharpXmlDoc.None) ] + | _, Choice1Of2 (items: CompletionItem list, infoReader, ad, m, denv) -> ToolTipText(items |> List.map (fun x -> FormatStructuredDescriptionOfItem true infoReader ad m denv x.ItemWithInst None None)) - | Choice2Of2 result -> + | _, Choice2Of2 result -> result member _.Glyph = glyph diff --git a/src/Compiler/Service/ServiceDeclarationLists.fsi b/src/Compiler/Service/ServiceDeclarationLists.fsi index c0de77f5251..4611ff86a16 100644 --- a/src/Compiler/Service/ServiceDeclarationLists.fsi +++ b/src/Compiler/Service/ServiceDeclarationLists.fsi @@ -60,6 +60,7 @@ type public ToolTipText = [] type public CompletionItemKind = + | SuggestedName | Field | Property | Method of isExtension: bool diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs index a0f8a810ccb..1bd88019aba 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fs +++ b/src/Compiler/Service/ServiceParsedInputOps.fs @@ -49,6 +49,20 @@ type RecordContext = | New of path: CompletionPath * isFirstField: bool | Declaration of isInIdentifier: bool +[] +type PatternContext = + /// Completing pattern type (e.g. foo (x: |)) + | Type + + /// Completing union case field in a pattern (e.g. fun (Some v|) -> ) + /// fieldIndex None signifies that the case identifier is followed by a single field, outside of parentheses + | PositionalUnionCaseField of fieldIndex: int option * caseIdRange: range + + /// Completing union case field in a pattern (e.g. fun (Some (Value = v|) -> ) + | NamedUnionCaseField of fieldName: string * caseIdRange: range + + | Other + [] type CompletionContext = /// Completion context cannot be determined due to errors @@ -71,9 +85,6 @@ type CompletionContext = | OpenDeclaration of isOpenType: bool - /// Completing pattern type (e.g. foo (x: |)) - | PatternType - /// Completing union case fields declaration (e.g. 'A of stri|' but not 'B of tex|: string') | UnionCaseFieldsDeclaration @@ -81,6 +92,9 @@ type CompletionContext = /// or a single case union without a bar (type SomeUnion = Abc|) | TypeAbbreviationOrSingleCaseUnion + /// Completing a pattern in a match clause, member/let binding or lambda + | Pattern of context: PatternContext + type ShortIdent = string type ShortIdents = ShortIdent[] @@ -1266,6 +1280,69 @@ module ParsedInput = None | _ -> None + let rec TryGetCompletionContextInPattern isInMemberDefinition (pat: SynPat) previousContext pos = + match pat with + | SynPat.LongIdent (argPats = SynArgPats.NamePatPairs (pats = pats); longDotId = id) -> + pats + |> List.tryPick (fun (patId, _, pat) -> + if rangeContainsPos patId.idRange pos then + Some CompletionContext.Invalid + else + let context = Some(PatternContext.NamedUnionCaseField(patId.idText, id.Range)) + TryGetCompletionContextInPattern isInMemberDefinition pat context pos) + | SynPat.LongIdent (argPats = SynArgPats.Pats pats; longDotId = id) -> + match pats with + | [ SynPat.Named _ as pat ] -> + TryGetCompletionContextInPattern + isInMemberDefinition + pat + (Some(PatternContext.PositionalUnionCaseField(None, id.Range))) + pos + | [ SynPat.Paren (SynPat.Tuple _ | SynPat.Named _ as pat, _) ] -> + TryGetCompletionContextInPattern + isInMemberDefinition + pat + (Some(PatternContext.PositionalUnionCaseField(Some 0, id.Range))) + pos + | _ -> + pats + |> List.tryPick (fun pat -> TryGetCompletionContextInPattern isInMemberDefinition pat None pos) + | SynPat.Ands (pats = pats) + | SynPat.ArrayOrList (elementPats = pats) -> + pats + |> List.tryPick (fun pat -> TryGetCompletionContextInPattern isInMemberDefinition pat None pos) + | SynPat.Tuple (elementPats = pats) -> + pats + |> List.indexed + |> List.tryPick (fun (i, pat) -> + let context = + match previousContext with + | Some (PatternContext.PositionalUnionCaseField (_, caseIdRange)) -> + Some(PatternContext.PositionalUnionCaseField(Some i, caseIdRange)) + | _ -> + // No preceding LongIdent => this is a tuple deconstruction + None + + TryGetCompletionContextInPattern isInMemberDefinition pat context pos) + | SynPat.Named (range = m) when rangeContainsPos m pos -> + // In member definitions show no completions on identifiers + if isInMemberDefinition then + Some CompletionContext.Invalid + else + previousContext + |> Option.defaultValue PatternContext.Other + |> CompletionContext.Pattern + |> Some + | SynPat.Attrib (pat = pat) -> TryGetCompletionContextInPattern isInMemberDefinition pat previousContext pos + | SynPat.Paren (pat, _) -> TryGetCompletionContextInPattern isInMemberDefinition pat None pos + | SynPat.ListCons (lhsPat = pat1; rhsPat = pat2) + | SynPat.As (lhsPat = pat1; rhsPat = pat2) + | SynPat.Or (lhsPat = pat1; rhsPat = pat2) -> + TryGetCompletionContextInPattern isInMemberDefinition pat1 None pos + |> Option.orElseWith (fun () -> TryGetCompletionContextInPattern isInMemberDefinition pat2 None pos) + | SynPat.IsInst (_, m) when rangeContainsPos m pos -> Some(CompletionContext.Pattern PatternContext.Type) + | _ -> None + /// Try to determine completion context for the given pair (row, columns) let TryGetCompletionContext (pos, parsedInput: ParsedInput, lineStr: string) : CompletionContext option = @@ -1304,7 +1381,15 @@ module ParsedInput = | SynExpr.Record (None, None, [], _) -> Some(CompletionContext.RecordField RecordContext.Empty) // Unchecked.defaultof - | SynExpr.TypeApp (typeArgsRange = range) when rangeContainsPos range pos -> Some CompletionContext.PatternType + | SynExpr.TypeApp (typeArgsRange = range) when rangeContainsPos range pos -> + Some(CompletionContext.Pattern PatternContext.Type) + + // fun (Some v$ ) -> + | SynExpr.Lambda(parsedData = Some (pats, _)) -> + pats + |> List.tryPick (fun pat -> TryGetCompletionContextInPattern false pat None pos) + |> Option.orElseWith (fun () -> defaultTraverse expr) + | _ -> defaultTraverse expr member _.VisitRecordField(path, copyOpt, field) = @@ -1445,15 +1530,19 @@ module ParsedInput = Some CompletionContext.Invalid // fun (x: int|) -> elif rangeContainsPos synType.Range pos then - Some CompletionContext.PatternType + Some(CompletionContext.Pattern PatternContext.Type) else None | _ -> None) - member _.VisitPat(_, defaultTraverse, pat) = - match pat with - | SynPat.IsInst (_, range) when rangeContainsPos range pos -> Some CompletionContext.PatternType - | _ -> defaultTraverse pat + member _.VisitPat(path, defaultTraverse, pat) = + let isInMemberDefinition = + match path with + | _ :: SyntaxNode.SynMemberDefn _ :: _ -> true + | _ -> false + + TryGetCompletionContextInPattern isInMemberDefinition pat None pos + |> Option.orElseWith (fun () -> defaultTraverse pat) member _.VisitModuleDecl(_, defaultTraverse, decl) = match decl with @@ -1485,7 +1574,7 @@ module ParsedInput = member _.VisitType(_, defaultTraverse, ty) = match ty with - | SynType.LongIdent _ when rangeContainsPos ty.Range pos -> Some CompletionContext.PatternType + | SynType.LongIdent _ when rangeContainsPos ty.Range pos -> Some(CompletionContext.Pattern PatternContext.Type) | _ -> defaultTraverse ty member _.VisitRecordDefn(_, fields, _) = diff --git a/src/Compiler/Service/ServiceParsedInputOps.fsi b/src/Compiler/Service/ServiceParsedInputOps.fsi index 5fb5e85d8cd..fa19e13ac72 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fsi +++ b/src/Compiler/Service/ServiceParsedInputOps.fsi @@ -22,6 +22,20 @@ type public RecordContext = | New of path: CompletionPath * isFirstField: bool | Declaration of isInIdentifier: bool +[] +type public PatternContext = + /// Completing pattern type (e.g. foo (x: |)) + | Type + + /// Completing union case field in a pattern (e.g. fun (Some v|) -> ) + /// fieldIndex None signifies that the case identifier is followed by a single field, outside of parentheses + | PositionalUnionCaseField of fieldIndex: int option * caseIdRange: range + + /// Completing union case field in a pattern (e.g. fun (Some (Value = v|) -> ) + | NamedUnionCaseField of fieldName: string * caseIdRange: range + + | Other + [] type public CompletionContext = /// Completion context cannot be determined due to errors @@ -44,9 +58,6 @@ type public CompletionContext = | OpenDeclaration of isOpenType: bool - /// Completing pattern type (e.g. foo (x: |)) - | PatternType - /// Completing union case fields declaration (e.g. 'A of stri|' but not 'B of tex|: string') | UnionCaseFieldsDeclaration @@ -54,6 +65,9 @@ type public CompletionContext = /// or a single case union without a bar (type SomeUnion = Abc|) | TypeAbbreviationOrSingleCaseUnion + /// Completing a pattern in a match clause, member/let binding or lambda + | Pattern of context: PatternContext + type public ModuleKind = { IsAutoOpen: bool HasModuleSuffix: bool } diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs index c5c9e5a4b13..c99016e26c1 100644 --- a/src/Compiler/TypedTree/TypedTreeOps.fs +++ b/src/Compiler/TypedTree/TypedTreeOps.fs @@ -2004,6 +2004,37 @@ let isEnumTy g ty = | ValueNone -> false | ValueSome tcref -> tcref.IsEnumTycon +let isSignedIntegerTy g ty = + typeEquivAux EraseMeasures g g.sbyte_ty ty || + typeEquivAux EraseMeasures g g.int16_ty ty || + typeEquivAux EraseMeasures g g.int32_ty ty || + typeEquivAux EraseMeasures g g.nativeint_ty ty || + typeEquivAux EraseMeasures g g.int64_ty ty + +let isUnsignedIntegerTy g ty = + typeEquivAux EraseMeasures g g.byte_ty ty || + typeEquivAux EraseMeasures g g.uint16_ty ty || + typeEquivAux EraseMeasures g g.uint32_ty ty || + typeEquivAux EraseMeasures g g.unativeint_ty ty || + typeEquivAux EraseMeasures g g.uint64_ty ty + +let isIntegerTy g ty = + isSignedIntegerTy g ty || + isUnsignedIntegerTy g ty + +/// float or float32 or float<_> or float32<_> +let isFpTy g ty = + typeEquivAux EraseMeasures g g.float_ty ty || + typeEquivAux EraseMeasures g g.float32_ty ty + +/// decimal or decimal<_> +let isDecimalTy g ty = + typeEquivAux EraseMeasures g g.decimal_ty ty + +let isNonDecimalNumericType g ty = isIntegerTy g ty || isFpTy g ty + +let isNumericType g ty = isNonDecimalNumericType g ty || isDecimalTy g ty + let actualReturnTyOfSlotSig parentTyInst methTyInst (TSlotSig(_, _, parentFormalTypars, methFormalTypars, _, formalRetTy)) = let methTyInst = mkTyparInst methFormalTypars methTyInst let parentTyInst = mkTyparInst parentFormalTypars parentTyInst diff --git a/src/Compiler/TypedTree/TypedTreeOps.fsi b/src/Compiler/TypedTree/TypedTreeOps.fsi index b3e763f9d8a..8ba51ea5ee2 100755 --- a/src/Compiler/TypedTree/TypedTreeOps.fsi +++ b/src/Compiler/TypedTree/TypedTreeOps.fsi @@ -1698,6 +1698,27 @@ val isClassTy: TcGlobals -> TType -> bool /// Determine if a type is an enum type val isEnumTy: TcGlobals -> TType -> bool +/// Determine if a type is a signed integer type +val isSignedIntegerTy: TcGlobals -> TType -> bool + +/// Determine if a type is an unsigned integer type +val isUnsignedIntegerTy: TcGlobals -> TType -> bool + +/// Determine if a type is an integer type +val isIntegerTy: TcGlobals -> TType -> bool + +/// Determine if a type is a floating point type +val isFpTy: TcGlobals -> TType -> bool + +/// Determine if a type is a decimal type +val isDecimalTy: TcGlobals -> TType -> bool + +/// Determine if a type is a non-decimal numeric type type +val isNonDecimalNumericType: TcGlobals -> TType -> bool + +/// Determine if a type is a numeric type type +val isNumericType: TcGlobals -> TType -> bool + /// Determine if a type is a struct, record or union type val isStructRecordOrUnionTyconTy: TcGlobals -> TType -> bool diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index ca6b200d289..2e52e0de6d3 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -942,6 +942,11 @@ Sadu .NET SDK pro tento skript nešlo určit. Pokud se skript nachází v adresáři používajícím global.json, zkontrolujte, jestli je nainstalovaná odpovídající sada .NET SDK. Neočekávaná chyba {0}. + + (Suggested name) + (Suggested name) + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} Tento výraz má typ {0} a je kompatibilní pouze s typem {1} prostřednictvím nejednoznačného implicitního převodu. Zvažte použití explicitního volání op_Implicit. Použitelnými implicitními převody jsou: {2} diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index bdf17adf380..76e55c3a8a8 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -942,6 +942,11 @@ Das .NET SDK für dieses Skript konnte nicht ermittelt werden. Wenn sich das Skript in einem Verzeichnis mit "global.json" befindet, stellen Sie sicher, dass das entsprechende .NET SDK installiert ist. Unerwarteter Fehler: {0}. + + (Suggested name) + (Suggested name) + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} Dieser Ausdruck weist den Typ "{0}" auf und wird nur durch eine mehrdeutige implizite Konvertierung mit dem Typ "{1}" kompatibel gemacht. Erwägen Sie die Verwendung eines expliziten Aufrufs an "op_Implicit". Die anwendbaren impliziten Konvertierungen sind: {2} diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index c5007a50061..736a22eef0f 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -942,6 +942,11 @@ No se pudo determinar el SDK de .NET para este script. Si el script está en un directorio que usa una instancia de "global.json", asegúrese de que el SDK de .NET pertinente esté instalado. Error inesperado: "{0}". + + (Suggested name) + (Suggested name) + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} Esta expresión tiene el tipo "{0}" y solo se hace compatible con el tipo "{1}" mediante una conversión implícita ambigua. Considere la posibilidad de usar una llamada explícita a 'op_Implicit'. Las conversiones implícitas aplicables son:{2} diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index c2463e00d85..dac3888b938 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -942,6 +942,11 @@ Le kit SDK .NET de ce script n'a pas pu être déterminé. Si le script se trouve dans un répertoire utilisant un fichier 'global.json', vérifiez que le kit SDK .NET approprié est installé. Erreur inattendue '{0}'. + + (Suggested name) + (Suggested name) + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} Cette expression a le type « {0} » et est uniquement compatible avec le type « {1} » via une conversion implicite ambiguë. Envisagez d’utiliser un appel explicite à’op_Implicit'. Les conversions implicites applicables sont : {2} diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 5ebbcba622c..87e0c9c2fc9 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -942,6 +942,11 @@ Non è stato possibile determinare la versione di .NET SDK per questo script. Se lo script si trova in una directory che usa un file 'global.json', assicurarsi che sia installata la versione pertinente di .NET SDK. Errore imprevisto: '{0}'. + + (Suggested name) + (Suggested name) + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} Questa espressione di tipo '{0}' è resa compatibile con il tipo '{1}' solo tramite una conversione implicita ambigua. Provare a usare una chiamata esplicita a 'op_Implicit'. Le conversioni implicite applicabili sono: {2} diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index c1386905952..2f161955089 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -942,6 +942,11 @@ このスクリプトの .NET SDK を特定できませんでした。このスクリプトが、'global.json' が使用されているディレクトリにある場合は、関連する .NET SDK がインストールされていることを確認してください。予期しないエラー '{0}'。 + + (Suggested name) + (Suggested name) + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} この式の型は '{0}' であり、あいまいで暗黙的な変換によってのみ、型 '{1}' と互換性を持たせることが可能です。' op_Implicit' の明示的な呼び出しを使用することを検討してください。該当する暗黙的な変換は次のとおりです: {2} diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 0eb30c8dded..0956aac96fa 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -942,6 +942,11 @@ 이 스크립트에 대한 .NET SDK를 확인할 수 없습니다. 스크립트가 'global.json'을 사용하는 디렉터리에 있는 경우 관련 .NET SDK가 설치되어 있는지 확인하세요. 예기치 않은 오류 '{0}'. + + (Suggested name) + (Suggested name) + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} 이 식은 ‘{0}’ 형식이며 모호한 암시적 변환을 통해 ‘{1}’ 형식하고만 호환됩니다. ‘op_Implicit’에 대한 명시적 호출을 사용하십시오. 해당하는 암시적 변환은 ‘{2}’입니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 3f6fea05549..3339859a6cb 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -942,6 +942,11 @@ Nie można określić zestawu .NET SDK dla tego skryptu. Jeśli skrypt znajduje się w katalogu korzystającym z pliku „global.json”, upewnij się, że zainstalowano odpowiedni zestaw .NET SDK. Nieoczekiwany błąd: „{0}”. + + (Suggested name) + (Suggested name) + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} To wyrażenie ma typ "{0}" i jest zgodne tylko z typem "{1}" za pośrednictwem niejednoznacznie bezwarunkowej konwersji. Rozważ użycie jednoznacznego wywołania elementu "op_Implicit". Odpowiednimi jednoznacznymi konwersjami są: {2} diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index f6266c53e42..40f35ade1da 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -942,6 +942,11 @@ Não foi possível determinar o SDK do .NET deste script. Se o script estiver em um diretório que usa um 'global.json', verifique se o SDK do .NET relevante está instalado. Erro inesperado '{0}'. + + (Suggested name) + (Suggested name) + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} Essa expressão possui o tipo '{0}' e só é compatível com o tipo '{1}' por uma conversão implícita ambígua. Considere usar uma chamada explícita para 'op_Implicit'. As conversões implícitas aplicáveis são:{2} diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index ecdcfa32b82..c895683d01e 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -942,6 +942,11 @@ Не удалось определить пакет SDK .NET для этого скрипта. Если сценарий находится в каталоге с использованием файла "global.json", убедитесь, что установлен соответствующий пакет SDK .NET. Непредвиденная ошибка "{0}". + + (Suggested name) + (Suggested name) + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} Это выражение имеет тип "{0}" и совместимо только с типом "{1}" посредством неоднозначного неявного преобразования. Рассмотрите возможность использования явного вызова "op_Implicit". Применимые неявные преобразования: {2} diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 0fa9a39ce0e..f61fdaacaa3 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -942,6 +942,11 @@ Bu betik için .NET SDK belirlenemedi. Betik 'global.json' kullanan bir dizindeyse, ilgili .NET SDK'nın yüklü olduğundan emin olun. Beklenmeyen hata '{0}'. + + (Suggested name) + (Suggested name) + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} Bu ifade '{0}' türüne sahip ve yalnızca belirsiz bir örtük dönüştürme aracılığıyla ’{1}' türüyle uyumlu hale getirilir. 'op_Implicit' için açık bir çağrı kullanmayı düşünün. Uygulanabilir örtük dönüştürmeler şunlardır: {2} diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 99389653fa3..69248e82dba 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -942,6 +942,11 @@ 无法确定此脚本的 .NET SDK。如果脚本在使用 "global.json" 的目录中,请确保已安装相关的 .NET SDK。出现意外错误“{0}”。 + + (Suggested name) + (Suggested name) + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} 此表达式的类型为“{0}”,仅可通过不明确的隐式转换使其与类型“{1}”兼容。请考虑使用显式调用“op_Implicit”。适用的隐式转换为: {2} diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 3eb9b4952ab..b6ae7eb21e9 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -942,6 +942,11 @@ 無法判斷這個指令碼的 .NET SDK。如果指令碼位於使用 'global.json' 的目錄中,請確認已安裝相關的 .NET SDK。未預期的錯誤 '{0}'。 + + (Suggested name) + (Suggested name) + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} 此運算式的類型為 '{0}',僅可透過不明確的隱含轉換使其與類型 '{1}' 相容。請考慮使用明確呼叫 'op_Implicit'。適用的隱含轉換為: {2} diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl index 5ba81eb678d..ff15e43c0e9 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl @@ -2540,6 +2540,8 @@ FSharp.Compiler.EditorServices.CompletionContext+ParameterList: FSharp.Compiler. FSharp.Compiler.EditorServices.CompletionContext+ParameterList: FSharp.Compiler.Text.Position get_Item1() FSharp.Compiler.EditorServices.CompletionContext+ParameterList: System.Collections.Generic.HashSet`1[System.String] Item2 FSharp.Compiler.EditorServices.CompletionContext+ParameterList: System.Collections.Generic.HashSet`1[System.String] get_Item2() +FSharp.Compiler.EditorServices.CompletionContext+Pattern: FSharp.Compiler.EditorServices.PatternContext context +FSharp.Compiler.EditorServices.CompletionContext+Pattern: FSharp.Compiler.EditorServices.PatternContext get_context() FSharp.Compiler.EditorServices.CompletionContext+RecordField: FSharp.Compiler.EditorServices.RecordContext context FSharp.Compiler.EditorServices.CompletionContext+RecordField: FSharp.Compiler.EditorServices.RecordContext get_context() FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 AttributeApplication @@ -2547,7 +2549,7 @@ FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 Inherit FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 Invalid FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 OpenDeclaration FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 ParameterList -FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 PatternType +FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 Pattern FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 RangeOperator FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 RecordField FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 TypeAbbreviationOrSingleCaseUnion @@ -2560,7 +2562,7 @@ FSharp.Compiler.EditorServices.CompletionContext: Boolean IsInherit FSharp.Compiler.EditorServices.CompletionContext: Boolean IsInvalid FSharp.Compiler.EditorServices.CompletionContext: Boolean IsOpenDeclaration FSharp.Compiler.EditorServices.CompletionContext: Boolean IsParameterList -FSharp.Compiler.EditorServices.CompletionContext: Boolean IsPatternType +FSharp.Compiler.EditorServices.CompletionContext: Boolean IsPattern FSharp.Compiler.EditorServices.CompletionContext: Boolean IsRangeOperator FSharp.Compiler.EditorServices.CompletionContext: Boolean IsRecordField FSharp.Compiler.EditorServices.CompletionContext: Boolean IsTypeAbbreviationOrSingleCaseUnion @@ -2570,7 +2572,7 @@ FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsInherit() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsInvalid() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsOpenDeclaration() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsParameterList() -FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsPatternType() +FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsPattern() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsRangeOperator() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsRecordField() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsTypeAbbreviationOrSingleCaseUnion() @@ -2580,20 +2582,20 @@ FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewInherit(FSharp.Compiler.EditorServices.InheritanceContext, System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.String],Microsoft.FSharp.Core.FSharpOption`1[System.String]]) FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewOpenDeclaration(Boolean) FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewParameterList(FSharp.Compiler.Text.Position, System.Collections.Generic.HashSet`1[System.String]) +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewPattern(FSharp.Compiler.EditorServices.PatternContext) FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewRecordField(FSharp.Compiler.EditorServices.RecordContext) -FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext PatternType FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext RangeOperator FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext TypeAbbreviationOrSingleCaseUnion FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext UnionCaseFieldsDeclaration FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_AttributeApplication() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_Invalid() -FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_PatternType() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_RangeOperator() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_TypeAbbreviationOrSingleCaseUnion() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_UnionCaseFieldsDeclaration() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+Inherit FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+OpenDeclaration FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+ParameterList +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+Pattern FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+RecordField FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+Tags FSharp.Compiler.EditorServices.CompletionContext: Int32 GetHashCode() @@ -2610,6 +2612,7 @@ FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 Field FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 Method FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 Other FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 Property +FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 SuggestedName FSharp.Compiler.EditorServices.CompletionItemKind: Boolean Equals(FSharp.Compiler.EditorServices.CompletionItemKind) FSharp.Compiler.EditorServices.CompletionItemKind: Boolean Equals(System.Object) FSharp.Compiler.EditorServices.CompletionItemKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) @@ -2620,6 +2623,7 @@ FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsField FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsMethod FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsOther FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsProperty +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsSuggestedName FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsArgument() FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsCustomOperation() FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsEvent() @@ -2627,6 +2631,7 @@ FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsField() FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsMethod() FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsOther() FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsProperty() +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsSuggestedName() FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind Argument FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind CustomOperation FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind Event @@ -2634,12 +2639,14 @@ FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorService FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind NewMethod(Boolean) FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind Other FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind Property +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind SuggestedName FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_Argument() FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_CustomOperation() FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_Event() FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_Field() FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_Other() FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_Property() +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_SuggestedName() FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind+Method FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind+Tags FSharp.Compiler.EditorServices.CompletionItemKind: Int32 CompareTo(FSharp.Compiler.EditorServices.CompletionItemKind) @@ -3551,6 +3558,43 @@ FSharp.Compiler.EditorServices.PartialLongName: System.String PartialIdent FSharp.Compiler.EditorServices.PartialLongName: System.String ToString() FSharp.Compiler.EditorServices.PartialLongName: System.String get_PartialIdent() FSharp.Compiler.EditorServices.PartialLongName: Void .ctor(Microsoft.FSharp.Collections.FSharpList`1[System.String], System.String, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +FSharp.Compiler.EditorServices.PatternContext+NamedUnionCaseField: FSharp.Compiler.Text.Range caseIdRange +FSharp.Compiler.EditorServices.PatternContext+NamedUnionCaseField: FSharp.Compiler.Text.Range get_caseIdRange() +FSharp.Compiler.EditorServices.PatternContext+NamedUnionCaseField: System.String fieldName +FSharp.Compiler.EditorServices.PatternContext+NamedUnionCaseField: System.String get_fieldName() +FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: FSharp.Compiler.Text.Range caseIdRange +FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: FSharp.Compiler.Text.Range get_caseIdRange() +FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] fieldIndex +FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] get_fieldIndex() +FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 NamedUnionCaseField +FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 Other +FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 PositionalUnionCaseField +FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 Type +FSharp.Compiler.EditorServices.PatternContext: Boolean Equals(FSharp.Compiler.EditorServices.PatternContext) +FSharp.Compiler.EditorServices.PatternContext: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.PatternContext: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.PatternContext: Boolean IsNamedUnionCaseField +FSharp.Compiler.EditorServices.PatternContext: Boolean IsOther +FSharp.Compiler.EditorServices.PatternContext: Boolean IsPositionalUnionCaseField +FSharp.Compiler.EditorServices.PatternContext: Boolean IsType +FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsNamedUnionCaseField() +FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsOther() +FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsPositionalUnionCaseField() +FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsType() +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext NewNamedUnionCaseField(System.String, FSharp.Compiler.Text.Range) +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext NewPositionalUnionCaseField(Microsoft.FSharp.Core.FSharpOption`1[System.Int32], FSharp.Compiler.Text.Range) +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext Other +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext Type +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext get_Other() +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext get_Type() +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+NamedUnionCaseField +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+Tags +FSharp.Compiler.EditorServices.PatternContext: Int32 GetHashCode() +FSharp.Compiler.EditorServices.PatternContext: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.PatternContext: Int32 Tag +FSharp.Compiler.EditorServices.PatternContext: Int32 get_Tag() +FSharp.Compiler.EditorServices.PatternContext: System.String ToString() FSharp.Compiler.EditorServices.QuickParse: Boolean TestMemberOrOverrideDeclaration(FSharp.Compiler.Tokenization.FSharpTokenInfo[]) FSharp.Compiler.EditorServices.QuickParse: FSharp.Compiler.EditorServices.PartialLongName GetPartialLongNameEx(System.String, Int32) FSharp.Compiler.EditorServices.QuickParse: Int32 CorrectIdentifierToken(System.String, Int32) diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl index d464f63b50f..e1b19ed36be 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl @@ -2540,6 +2540,8 @@ FSharp.Compiler.EditorServices.CompletionContext+ParameterList: FSharp.Compiler. FSharp.Compiler.EditorServices.CompletionContext+ParameterList: FSharp.Compiler.Text.Position get_Item1() FSharp.Compiler.EditorServices.CompletionContext+ParameterList: System.Collections.Generic.HashSet`1[System.String] Item2 FSharp.Compiler.EditorServices.CompletionContext+ParameterList: System.Collections.Generic.HashSet`1[System.String] get_Item2() +FSharp.Compiler.EditorServices.CompletionContext+Pattern: FSharp.Compiler.EditorServices.PatternContext context +FSharp.Compiler.EditorServices.CompletionContext+Pattern: FSharp.Compiler.EditorServices.PatternContext get_context() FSharp.Compiler.EditorServices.CompletionContext+RecordField: FSharp.Compiler.EditorServices.RecordContext context FSharp.Compiler.EditorServices.CompletionContext+RecordField: FSharp.Compiler.EditorServices.RecordContext get_context() FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 AttributeApplication @@ -2547,7 +2549,7 @@ FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 Inherit FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 Invalid FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 OpenDeclaration FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 ParameterList -FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 PatternType +FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 Pattern FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 RangeOperator FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 RecordField FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 TypeAbbreviationOrSingleCaseUnion @@ -2560,7 +2562,7 @@ FSharp.Compiler.EditorServices.CompletionContext: Boolean IsInherit FSharp.Compiler.EditorServices.CompletionContext: Boolean IsInvalid FSharp.Compiler.EditorServices.CompletionContext: Boolean IsOpenDeclaration FSharp.Compiler.EditorServices.CompletionContext: Boolean IsParameterList -FSharp.Compiler.EditorServices.CompletionContext: Boolean IsPatternType +FSharp.Compiler.EditorServices.CompletionContext: Boolean IsPattern FSharp.Compiler.EditorServices.CompletionContext: Boolean IsRangeOperator FSharp.Compiler.EditorServices.CompletionContext: Boolean IsRecordField FSharp.Compiler.EditorServices.CompletionContext: Boolean IsTypeAbbreviationOrSingleCaseUnion @@ -2570,7 +2572,7 @@ FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsInherit() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsInvalid() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsOpenDeclaration() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsParameterList() -FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsPatternType() +FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsPattern() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsRangeOperator() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsRecordField() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsTypeAbbreviationOrSingleCaseUnion() @@ -2580,20 +2582,20 @@ FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewInherit(FSharp.Compiler.EditorServices.InheritanceContext, System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.String],Microsoft.FSharp.Core.FSharpOption`1[System.String]]) FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewOpenDeclaration(Boolean) FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewParameterList(FSharp.Compiler.Text.Position, System.Collections.Generic.HashSet`1[System.String]) +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewPattern(FSharp.Compiler.EditorServices.PatternContext) FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewRecordField(FSharp.Compiler.EditorServices.RecordContext) -FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext PatternType FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext RangeOperator FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext TypeAbbreviationOrSingleCaseUnion FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext UnionCaseFieldsDeclaration FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_AttributeApplication() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_Invalid() -FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_PatternType() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_RangeOperator() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_TypeAbbreviationOrSingleCaseUnion() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_UnionCaseFieldsDeclaration() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+Inherit FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+OpenDeclaration FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+ParameterList +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+Pattern FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+RecordField FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+Tags FSharp.Compiler.EditorServices.CompletionContext: Int32 GetHashCode() @@ -2610,6 +2612,7 @@ FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 Field FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 Method FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 Other FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 Property +FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 SuggestedName FSharp.Compiler.EditorServices.CompletionItemKind: Boolean Equals(FSharp.Compiler.EditorServices.CompletionItemKind) FSharp.Compiler.EditorServices.CompletionItemKind: Boolean Equals(System.Object) FSharp.Compiler.EditorServices.CompletionItemKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) @@ -2620,6 +2623,7 @@ FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsField FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsMethod FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsOther FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsProperty +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsSuggestedName FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsArgument() FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsCustomOperation() FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsEvent() @@ -2627,6 +2631,7 @@ FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsField() FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsMethod() FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsOther() FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsProperty() +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsSuggestedName() FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind Argument FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind CustomOperation FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind Event @@ -2634,12 +2639,14 @@ FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorService FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind NewMethod(Boolean) FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind Other FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind Property +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind SuggestedName FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_Argument() FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_CustomOperation() FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_Event() FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_Field() FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_Other() FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_Property() +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_SuggestedName() FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind+Method FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind+Tags FSharp.Compiler.EditorServices.CompletionItemKind: Int32 CompareTo(FSharp.Compiler.EditorServices.CompletionItemKind) @@ -3551,6 +3558,43 @@ FSharp.Compiler.EditorServices.PartialLongName: System.String PartialIdent FSharp.Compiler.EditorServices.PartialLongName: System.String ToString() FSharp.Compiler.EditorServices.PartialLongName: System.String get_PartialIdent() FSharp.Compiler.EditorServices.PartialLongName: Void .ctor(Microsoft.FSharp.Collections.FSharpList`1[System.String], System.String, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +FSharp.Compiler.EditorServices.PatternContext+NamedUnionCaseField: FSharp.Compiler.Text.Range caseIdRange +FSharp.Compiler.EditorServices.PatternContext+NamedUnionCaseField: FSharp.Compiler.Text.Range get_caseIdRange() +FSharp.Compiler.EditorServices.PatternContext+NamedUnionCaseField: System.String fieldName +FSharp.Compiler.EditorServices.PatternContext+NamedUnionCaseField: System.String get_fieldName() +FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: FSharp.Compiler.Text.Range caseIdRange +FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: FSharp.Compiler.Text.Range get_caseIdRange() +FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] fieldIndex +FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] get_fieldIndex() +FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 NamedUnionCaseField +FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 Other +FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 PositionalUnionCaseField +FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 Type +FSharp.Compiler.EditorServices.PatternContext: Boolean Equals(FSharp.Compiler.EditorServices.PatternContext) +FSharp.Compiler.EditorServices.PatternContext: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.PatternContext: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.PatternContext: Boolean IsNamedUnionCaseField +FSharp.Compiler.EditorServices.PatternContext: Boolean IsOther +FSharp.Compiler.EditorServices.PatternContext: Boolean IsPositionalUnionCaseField +FSharp.Compiler.EditorServices.PatternContext: Boolean IsType +FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsNamedUnionCaseField() +FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsOther() +FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsPositionalUnionCaseField() +FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsType() +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext NewNamedUnionCaseField(System.String, FSharp.Compiler.Text.Range) +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext NewPositionalUnionCaseField(Microsoft.FSharp.Core.FSharpOption`1[System.Int32], FSharp.Compiler.Text.Range) +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext Other +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext Type +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext get_Other() +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext get_Type() +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+NamedUnionCaseField +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField +FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+Tags +FSharp.Compiler.EditorServices.PatternContext: Int32 GetHashCode() +FSharp.Compiler.EditorServices.PatternContext: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.PatternContext: Int32 Tag +FSharp.Compiler.EditorServices.PatternContext: Int32 get_Tag() +FSharp.Compiler.EditorServices.PatternContext: System.String ToString() FSharp.Compiler.EditorServices.QuickParse: Boolean TestMemberOrOverrideDeclaration(FSharp.Compiler.Tokenization.FSharpTokenInfo[]) FSharp.Compiler.EditorServices.QuickParse: FSharp.Compiler.EditorServices.PartialLongName GetPartialLongNameEx(System.String, Int32) FSharp.Compiler.EditorServices.QuickParse: Int32 CorrectIdentifierToken(System.String, Int32) diff --git a/vsintegration/src/FSharp.Editor/Completion/CompletionUtils.fs b/vsintegration/src/FSharp.Editor/Completion/CompletionUtils.fs index e2cf7b2e114..13297581532 100644 --- a/vsintegration/src/FSharp.Editor/Completion/CompletionUtils.fs +++ b/vsintegration/src/FSharp.Editor/Completion/CompletionUtils.fs @@ -123,6 +123,7 @@ module internal CompletionUtils = let inline getKindPriority kind = match kind with + | CompletionItemKind.SuggestedName | CompletionItemKind.CustomOperation -> 0 | CompletionItemKind.Property -> 1 | CompletionItemKind.Field -> 2 diff --git a/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs b/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs index 8173eb6e2ce..f6ba5a81ac4 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs @@ -1460,3 +1460,91 @@ x[0]. """ VerifyCompletionListExactly(fileContents, "x[0].", [ "Foo"; "Goo"; "Equals"; "GetHashCode"; "GetType"; "ToString" ]) + + [] + let ``Completion list contains suggested names for union case field pattern with one field, and no valrefs other than literals`` () = + let fileContents = + """ +let logV = 1 +let [] logLit = 1 + +type DU = A of logField: int + +match A 1 with +| A l -> () +""" + + VerifyCompletionList(fileContents, "| A l", [ "logField"; "logLit"; "num" ], [ "logV"; "log" ]) + + [] + let ``Completion list contains suggested names for union case field pattern in a match clause`` () = + let fileContents = + """ +type Du = + | C of first: Du * rest: Du list + | D of int + +let x du = + match du with + | C (f, [ D i; C (first = s) ]) -> () + | C (rest = r) -> () + | _ -> () +""" + + VerifyCompletionList(fileContents, "| C (f", [ "first"; "du" ], [ "rest"; "item"; "num" ]) + VerifyCompletionList(fileContents, "| C (f, [ D i", [ "num"; "item" ], [ "rest"; "first"; "du" ]) + VerifyCompletionList(fileContents, "| C (f, [ D i; C (first = s", [ "first"; "du" ], [ "rest"; "num" ]) + VerifyCompletionList(fileContents, "| C (rest = r", [ "rest"; "list" ], [ "first"; "du"; "item"; "num" ]) + + [] + let ``Completion list does not contain suggested names which are already used in the same pattern`` () = + let fileContents = + """ +type Du = + | C of first: string option * rest: Du list + +let x (du: Du list) = + match du with + | [ C (first = first); C (first = f) ] -> () + | [ C (first, rest); C (f, l) ] -> () + | _ -> () +""" + + VerifyCompletionList(fileContents, "| [ C (first = first); C (first = f", [ "option" ], [ "first" ]) + VerifyCompletionList(fileContents, "| [ C (first, rest); C (f", [ "option" ], [ "first" ]) + VerifyCompletionList(fileContents, "| [ C (first, rest); C (f, l", [ "list" ], [ "rest" ]) + + [] + let ``Completion list contains suggested names for union case field pattern in a let binding and lambda`` () = + let fileContents = + """ +type Ids = Ids of customerId: int * orderId: string option + +let x (Ids (c)) = () +let xy (Ids (c, o)) = () +let xyz (Ids c) = () + +fun (Ids (c, o)) -> () +""" + + VerifyCompletionList(fileContents, "let x (Ids (c", [ "customerId"; "num" ], []) + VerifyCompletionList(fileContents, "let xy (Ids (c", [ "customerId"; "num" ], []) + VerifyCompletionList(fileContents, "let xy (Ids (c, o", [ "orderId"; "option" ], []) + VerifyCompletionList(fileContents, "let xyz (Ids c", [ "option" ], [ "customerId"; "orderId"; "num" ]) // option is on the list as a type + VerifyCompletionList(fileContents, "fun (Ids (c", [ "customerId"; "num" ], []) + VerifyCompletionList(fileContents, "fun (Ids (c, o", [ "orderId"; "option" ], []) + + [] + let ``Completion list does not contain suggested names in tuple deconstruction`` () = + let fileContents = + """ +match Some (1, 2) with +| Some v -> () +| Some (a, b) -> () +| Some (c) -> () +""" + + VerifyCompletionList(fileContents, "| Some v", [ "value" ], []) + VerifyCompletionList(fileContents, "| Some (a", [], [ "value" ]) + VerifyCompletionList(fileContents, "| Some (a, b", [], [ "value" ]) + VerifyCompletionList(fileContents, "| Some (c", [], [ "value" ]) From a04cb36b161871b7fcc2b73423d6a7c381ddb71f Mon Sep 17 00:00:00 2001 From: kerams Date: Sat, 1 Jul 2023 10:54:09 +0200 Subject: [PATCH 2/8] Refactor, fix test --- src/Compiler/Service/ServiceParsedInputOps.fs | 110 ++++++++---------- .../CompletionProviderTests.fs | 11 +- 2 files changed, 60 insertions(+), 61 deletions(-) diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs index 1bd88019aba..da99c84a228 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fs +++ b/src/Compiler/Service/ServiceParsedInputOps.fs @@ -1193,11 +1193,6 @@ module ParsedInput = None | _ -> None - let (|SkipFromParseErrorPat|) pat = - match pat with - | SynPat.FromParseError (pat, _) -> pat - | _ -> pat - let rec parseLidAux pos plid (parts: Ident list) (dots: range list) = match parts, dots with | [], _ -> Some(plid, None) @@ -1280,7 +1275,19 @@ module ParsedInput = None | _ -> None - let rec TryGetCompletionContextInPattern isInMemberDefinition (pat: SynPat) previousContext pos = + // In member, function and lambda definitions (but not in match clauses) we suppress completions on outer identifiers + // + // fun x| -> + // member _.X (a| ) = + // let f x| = + // + // As soon as union case deconstruction is used, we *do* want to see completions on identifiers, in particular to suggest identifier names + // + // fun (SingleCase (v1, v| )) -> + // member _.X (SingleCase (v1, v| )) = + // let f (SingleCase (v1, v| )) = + // + let rec TryGetCompletionContextInPattern suppressIdentifierCompletions (pat: SynPat) previousContext pos = match pat with | SynPat.LongIdent (argPats = SynArgPats.NamePatPairs (pats = pats); longDotId = id) -> pats @@ -1289,28 +1296,28 @@ module ParsedInput = Some CompletionContext.Invalid else let context = Some(PatternContext.NamedUnionCaseField(patId.idText, id.Range)) - TryGetCompletionContextInPattern isInMemberDefinition pat context pos) + TryGetCompletionContextInPattern suppressIdentifierCompletions pat context pos) | SynPat.LongIdent (argPats = SynArgPats.Pats pats; longDotId = id) -> match pats with | [ SynPat.Named _ as pat ] -> TryGetCompletionContextInPattern - isInMemberDefinition + false pat (Some(PatternContext.PositionalUnionCaseField(None, id.Range))) pos | [ SynPat.Paren (SynPat.Tuple _ | SynPat.Named _ as pat, _) ] -> TryGetCompletionContextInPattern - isInMemberDefinition + false pat (Some(PatternContext.PositionalUnionCaseField(Some 0, id.Range))) pos | _ -> pats - |> List.tryPick (fun pat -> TryGetCompletionContextInPattern isInMemberDefinition pat None pos) + |> List.tryPick (fun pat -> TryGetCompletionContextInPattern false pat None pos) | SynPat.Ands (pats = pats) | SynPat.ArrayOrList (elementPats = pats) -> pats - |> List.tryPick (fun pat -> TryGetCompletionContextInPattern isInMemberDefinition pat None pos) + |> List.tryPick (fun pat -> TryGetCompletionContextInPattern suppressIdentifierCompletions pat None pos) | SynPat.Tuple (elementPats = pats) -> pats |> List.indexed @@ -1323,24 +1330,32 @@ module ParsedInput = // No preceding LongIdent => this is a tuple deconstruction None - TryGetCompletionContextInPattern isInMemberDefinition pat context pos) + TryGetCompletionContextInPattern suppressIdentifierCompletions pat context pos) | SynPat.Named (range = m) when rangeContainsPos m pos -> - // In member definitions show no completions on identifiers - if isInMemberDefinition then + if suppressIdentifierCompletions then Some CompletionContext.Invalid else previousContext |> Option.defaultValue PatternContext.Other |> CompletionContext.Pattern |> Some - | SynPat.Attrib (pat = pat) -> TryGetCompletionContextInPattern isInMemberDefinition pat previousContext pos - | SynPat.Paren (pat, _) -> TryGetCompletionContextInPattern isInMemberDefinition pat None pos + | SynPat.FromParseError (pat = pat) + | SynPat.Attrib (pat = pat) -> TryGetCompletionContextInPattern suppressIdentifierCompletions pat previousContext pos + | SynPat.Paren (pat, _) -> TryGetCompletionContextInPattern suppressIdentifierCompletions pat None pos | SynPat.ListCons (lhsPat = pat1; rhsPat = pat2) | SynPat.As (lhsPat = pat1; rhsPat = pat2) | SynPat.Or (lhsPat = pat1; rhsPat = pat2) -> - TryGetCompletionContextInPattern isInMemberDefinition pat1 None pos - |> Option.orElseWith (fun () -> TryGetCompletionContextInPattern isInMemberDefinition pat2 None pos) + TryGetCompletionContextInPattern suppressIdentifierCompletions pat1 None pos + |> Option.orElseWith (fun () -> TryGetCompletionContextInPattern suppressIdentifierCompletions pat2 None pos) | SynPat.IsInst (_, m) when rangeContainsPos m pos -> Some(CompletionContext.Pattern PatternContext.Type) + | SynPat.Wild m when rangeContainsPos m pos -> Some CompletionContext.Invalid + | SynPat.Typed (pat = pat; targetType = synType) -> + if rangeContainsPos pat.Range pos then + TryGetCompletionContextInPattern suppressIdentifierCompletions pat previousContext pos + elif rangeContainsPos synType.Range pos then + Some(CompletionContext.Pattern PatternContext.Type) + else + None | _ -> None /// Try to determine completion context for the given pair (row, columns) @@ -1387,7 +1402,7 @@ module ParsedInput = // fun (Some v$ ) -> | SynExpr.Lambda(parsedData = Some (pats, _)) -> pats - |> List.tryPick (fun pat -> TryGetCompletionContextInPattern false pat None pos) + |> List.tryPick (fun pat -> TryGetCompletionContextInPattern true pat None pos) |> Option.orElseWith (fun () -> defaultTraverse expr) | _ -> defaultTraverse expr @@ -1442,37 +1457,15 @@ module ParsedInput = member _.VisitBinding(_, defaultTraverse, (SynBinding (headPat = headPat) as synBinding)) = - let visitParam (SkipFromParseErrorPat pat) = - match pat with - | SynPat.Named (range = range) - | SynPat.As (_, SynPat.Named (range = range), _) when rangeContainsPos range pos -> - // parameter without type hint, no completion - Some CompletionContext.Invalid - | SynPat.Typed (SynPat.Named (_, _, _, range), _, _) when rangeContainsPos range pos -> - // parameter with type hint, but we are on its name, no completion - Some CompletionContext.Invalid - | _ -> defaultTraverse synBinding - match headPat with - | SynPat.LongIdent (longDotId = lidwd) when rangeContainsPos lidwd.Range pos -> - // let fo|o x = () - Some CompletionContext.Invalid - | SynPat.LongIdent (argPats = ctorArgs; range = range) when rangeContainsPos range pos -> - match ctorArgs with - | SynArgPats.Pats pats -> + | SynPat.LongIdent (longDotId = lidwd; argPats = SynArgPats.Pats pats; range = m) when rangeContainsPos m pos -> + if rangeContainsPos lidwd.Range pos then + // let fo|o x = () + Some CompletionContext.Invalid + else pats - |> List.tryPick (fun (SkipFromParseErrorPat pat) -> - match pat with - | SynPat.Paren (pat, _) -> - match pat with - | SynPat.Tuple (elementPats = pats) -> pats |> List.tryPick visitParam - | _ -> visitParam pat - | SynPat.Wild range - | SynPat.FromParseError (SynPat.Named _, range) when rangeContainsPos range pos -> - // let foo (x| - Some CompletionContext.Invalid - | _ -> visitParam pat) - | _ -> defaultTraverse synBinding + |> List.tryPick (fun pat -> TryGetCompletionContextInPattern true pat None pos) + |> Option.orElseWith (fun () -> defaultTraverse synBinding) | SynPat.Named (range = range) | SynPat.As (_, SynPat.Named (range = range), _) when rangeContainsPos range pos -> // let fo|o = 1 @@ -1518,30 +1511,27 @@ module ParsedInput = | _ -> None member _.VisitSimplePats(_, pats) = + // Lambdas and their patterns are processed above in VisitExpr, + // so VisitSimplePats is only called for primary constructors + pats |> List.tryPick (fun pat -> - // No completions in an identifier in a pattern match pat with - // fun x| -> + // type C (x| ) | SynSimplePat.Id (range = range) when rangeContainsPos range pos -> Some CompletionContext.Invalid - | SynSimplePat.Typed (SynSimplePat.Id (range = idRange), synType, _) -> - // fun (x|: int) -> + | SynSimplePat.Typed (pat = SynSimplePat.Id (range = idRange); targetType = synType) -> + // type C (x|: int) -> if rangeContainsPos idRange pos then Some CompletionContext.Invalid - // fun (x: int|) -> + // type C (x: int|) -> elif rangeContainsPos synType.Range pos then Some(CompletionContext.Pattern PatternContext.Type) else None | _ -> None) - member _.VisitPat(path, defaultTraverse, pat) = - let isInMemberDefinition = - match path with - | _ :: SyntaxNode.SynMemberDefn _ :: _ -> true - | _ -> false - - TryGetCompletionContextInPattern isInMemberDefinition pat None pos + member _.VisitPat(_, defaultTraverse, pat) = + TryGetCompletionContextInPattern false pat None pos |> Option.orElseWith (fun () -> defaultTraverse pat) member _.VisitModuleDecl(_, defaultTraverse, decl) = diff --git a/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs b/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs index f6ba5a81ac4..e6f740bbdec 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs @@ -876,6 +876,7 @@ type T() = """ VerifyNoCompletionList(fileContents, "member this.M(p:int, h") + VerifyNoCompletionList(fileContents, "member this.M(p") [] let ``Completion list on abstract member type signature contains modules and types but not keywords or functions`` = @@ -932,6 +933,7 @@ type T(p:int, h) = """ VerifyNoCompletionList(fileContents, "type T(p:int, h") + VerifyNoCompletionList(fileContents, "type T(p") [] let ``Provide completion on implicit constructor argument type hint`` () = @@ -1515,7 +1517,7 @@ let x (du: Du list) = VerifyCompletionList(fileContents, "| [ C (first, rest); C (f, l", [ "list" ], [ "rest" ]) [] - let ``Completion list contains suggested names for union case field pattern in a let binding and lambda`` () = + let ``Completion list contains suggested names for union case field pattern in a let binding, lambda and member`` () = let fileContents = """ type Ids = Ids of customerId: int * orderId: string option @@ -1525,6 +1527,10 @@ let xy (Ids (c, o)) = () let xyz (Ids c) = () fun (Ids (c, o)) -> () +fun (Some v) -> () + +type C = + member _.M (Ids (c, o)) = () """ VerifyCompletionList(fileContents, "let x (Ids (c", [ "customerId"; "num" ], []) @@ -1533,6 +1539,9 @@ fun (Ids (c, o)) -> () VerifyCompletionList(fileContents, "let xyz (Ids c", [ "option" ], [ "customerId"; "orderId"; "num" ]) // option is on the list as a type VerifyCompletionList(fileContents, "fun (Ids (c", [ "customerId"; "num" ], []) VerifyCompletionList(fileContents, "fun (Ids (c, o", [ "orderId"; "option" ], []) + VerifyCompletionList(fileContents, "fun (Some v", [ "value" ], []) + VerifyCompletionList(fileContents, "member _.M (Ids (c", [ "customerId"; "num" ], [ "orderId" ]) + VerifyCompletionList(fileContents, "member _.M (Ids (c, o", [ "orderId"; "option" ], [ "customerId"; "num" ]) [] let ``Completion list does not contain suggested names in tuple deconstruction`` () = From 38db43d5b8b4c3d7b6aeaabe6b519b5110e57285 Mon Sep 17 00:00:00 2001 From: kerams Date: Sat, 1 Jul 2023 10:57:56 +0200 Subject: [PATCH 3/8] Obey Fantomas --- src/Compiler/Service/ServiceParsedInputOps.fs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs index da99c84a228..1ef30395693 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fs +++ b/src/Compiler/Service/ServiceParsedInputOps.fs @@ -1300,17 +1300,9 @@ module ParsedInput = | SynPat.LongIdent (argPats = SynArgPats.Pats pats; longDotId = id) -> match pats with | [ SynPat.Named _ as pat ] -> - TryGetCompletionContextInPattern - false - pat - (Some(PatternContext.PositionalUnionCaseField(None, id.Range))) - pos + TryGetCompletionContextInPattern false pat (Some(PatternContext.PositionalUnionCaseField(None, id.Range))) pos | [ SynPat.Paren (SynPat.Tuple _ | SynPat.Named _ as pat, _) ] -> - TryGetCompletionContextInPattern - false - pat - (Some(PatternContext.PositionalUnionCaseField(Some 0, id.Range))) - pos + TryGetCompletionContextInPattern false pat (Some(PatternContext.PositionalUnionCaseField(Some 0, id.Range))) pos | _ -> pats |> List.tryPick (fun pat -> TryGetCompletionContextInPattern false pat None pos) From 35a9cf642f9e4dbbc7b196cd2af88c85a688dc72 Mon Sep 17 00:00:00 2001 From: kerams Date: Sun, 2 Jul 2023 23:59:54 +0200 Subject: [PATCH 4/8] Suggest names based on generic type solution --- src/Compiler/Service/FSharpCheckerResults.fs | 28 +++++++++++++------ .../CompletionProviderTests.fs | 25 +++++++++++++++++ 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/Compiler/Service/FSharpCheckerResults.fs b/src/Compiler/Service/FSharpCheckerResults.fs index fbba5351539..76345cd49b8 100644 --- a/src/Compiler/Service/FSharpCheckerResults.fs +++ b/src/Compiler/Service/FSharpCheckerResults.fs @@ -965,11 +965,11 @@ type internal TypeCheckInfo PostProcessSuggestedPatternName pos "num" list else match tryTcrefOfAppTy g ty with - | ValueSome tcref -> PostProcessSuggestedPatternName pos tcref.DisplayName list + | ValueSome tcref when not (tyconRefEq g g.system_Object_tcref tcref) -> PostProcessSuggestedPatternName pos tcref.DisplayName list | _ -> list /// Suggest name based on field name and type, add it to the list - let SuggestNameForUnionCaseFieldPattern g pos (uci: UnionCaseInfo) indexOrName list = + let SuggestNameForUnionCaseFieldPattern g caseIdPos fieldPatternPos (uci: UnionCaseInfo) indexOrName list = let field = match indexOrName with | Choice1Of2 index -> @@ -982,9 +982,21 @@ type internal TypeCheckInfo | Choice2Of2 name -> uci.UnionCase.RecdFieldsArray |> Array.tryFind (fun x -> x.DisplayName = name) field - |> Option.map (fun f -> - SuggestNameBasedOnType g pos f.FormalType list - |> PostProcessSuggestedPatternName pos f.DisplayName) + |> Option.map (fun field -> + let ty = + // If the field type is generic, suggest a name based on the solution + if isTyparTy g field.FormalType then + sResolutions.CapturedNameResolutions + |> ResizeArray.tryPick (fun r -> + match r.Item with + | Item.Value vref when r.Pos = fieldPatternPos -> Some(stripTyparEqnsAux true vref.Type) + | _ -> None) + |> Option.defaultValue field.FormalType + else + field.FormalType + + let list = SuggestNameBasedOnType g caseIdPos ty list + PostProcessSuggestedPatternName caseIdPos field.DisplayName list) |> Option.defaultValue list let getItem (x: ItemWithInst) = x.Item @@ -1235,10 +1247,10 @@ type internal TypeCheckInfo | atStart when atStart = 0 -> 0 | otherwise -> otherwise - 1 + let pos = mkPos line colAtEndOfNamesAndResidue + // Look for a "special" completion context let completionContext = - let pos = mkPos line colAtEndOfNamesAndResidue - // If the completion context we have computed higher up the stack is for the same position, // reuse it, otherwise recompute match completionContextAtPos with @@ -1528,7 +1540,7 @@ type internal TypeCheckInfo match r.Item with | Item.UnionCase (uci, _) -> let list = declaredItems |> Option.map p13 |> Option.defaultValue [] - Some(SuggestNameForUnionCaseFieldPattern g caseIdRange.End uci indexOrName list, r.DisplayEnv, r.Range) + Some(SuggestNameForUnionCaseFieldPattern g caseIdRange.End pos uci indexOrName list, r.DisplayEnv, r.Range) | _ -> None) |> Option.orElse declaredItems diff --git a/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs b/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs index e6f740bbdec..a83e914cd58 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs @@ -1557,3 +1557,28 @@ match Some (1, 2) with VerifyCompletionList(fileContents, "| Some (a", [], [ "value" ]) VerifyCompletionList(fileContents, "| Some (a, b", [], [ "value" ]) VerifyCompletionList(fileContents, "| Some (c", [], [ "value" ]) + + [] + let ``Completion list contains suggested names for union case field pattern based on the name of the generic type's solution`` () = + let fileContents = + """ +type Tab = + | A + | B + +match Some A with +| Some a -> () + +type G<'x, 'y> = + | U1 of xxx: 'x * yyy: 'y + | U2 of fff: string + +match U1 (1, A) with +| U2 s -> () +| U1 (x, y) -> () +""" + + VerifyCompletionList(fileContents, "| Some a", [ "value"; "tab" ], []) + VerifyCompletionList(fileContents, "| U2 s", [ "fff"; "string" ], [ "tab"; "xxx"; "yyy" ]) + VerifyCompletionList(fileContents, "| U1 (x", [ "xxx"; "num" ], [ "tab"; "yyy"; "fff" ]) + VerifyCompletionList(fileContents, "| U1 (x, y", [ "yyy"; "tab" ], [ "xxx"; "num"; "fff" ]) From 0014c94f5e31c633b0abce6c41db2a61b2907c24 Mon Sep 17 00:00:00 2001 From: kerams Date: Mon, 3 Jul 2023 09:31:08 +0200 Subject: [PATCH 5/8] Refactor --- src/Compiler/Service/FSharpCheckerResults.fs | 30 ++++++++++--------- src/Compiler/Service/ServiceParsedInputOps.fs | 1 + .../Service/ServiceParsedInputOps.fsi | 1 + src/Compiler/Utilities/illib.fs | 5 ++++ src/Compiler/Utilities/illib.fsi | 2 ++ 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/Compiler/Service/FSharpCheckerResults.fs b/src/Compiler/Service/FSharpCheckerResults.fs index 76345cd49b8..46ea166e7b6 100644 --- a/src/Compiler/Service/FSharpCheckerResults.fs +++ b/src/Compiler/Service/FSharpCheckerResults.fs @@ -942,9 +942,9 @@ type internal TypeCheckInfo Unresolved = None } - /// Check whether the suggested name is unused and add it to the list. + /// Checks whether the suggested name is unused. /// In the future we could use an increasing numeric suffix for conflict resolution - let PostProcessSuggestedPatternName (pos: pos) name list = + let CreateCompletionItemForSuggestedPatternName (pos: pos) name = let name = String.lowerCaseFirstChar name let unused = @@ -955,21 +955,22 @@ type internal TypeCheckInfo | _ -> true) if unused then - CompletionItemSuggestedName name :: list + Some(CompletionItemSuggestedName name) else - list + None - /// Suggest name based on type, add it to the list - let SuggestNameBasedOnType g pos ty list = + /// Suggest name based on type + let SuggestNameBasedOnType g pos ty = if isNumericType g ty then - PostProcessSuggestedPatternName pos "num" list + CreateCompletionItemForSuggestedPatternName pos "num" else match tryTcrefOfAppTy g ty with - | ValueSome tcref when not (tyconRefEq g g.system_Object_tcref tcref) -> PostProcessSuggestedPatternName pos tcref.DisplayName list - | _ -> list + | ValueSome tcref when not (tyconRefEq g g.system_Object_tcref tcref) -> + CreateCompletionItemForSuggestedPatternName pos tcref.DisplayName + | _ -> None - /// Suggest name based on field name and type, add it to the list - let SuggestNameForUnionCaseFieldPattern g caseIdPos fieldPatternPos (uci: UnionCaseInfo) indexOrName list = + /// Suggest names based on field name and type, add them to the list + let SuggestNameForUnionCaseFieldPattern g caseIdPos fieldPatternPos (uci: UnionCaseInfo) indexOrName completions = let field = match indexOrName with | Choice1Of2 index -> @@ -995,9 +996,10 @@ type internal TypeCheckInfo else field.FormalType - let list = SuggestNameBasedOnType g caseIdPos ty list - PostProcessSuggestedPatternName caseIdPos field.DisplayName list) - |> Option.defaultValue list + completions + |> List.prependIfSome (SuggestNameBasedOnType g caseIdPos ty) + |> List.prependIfSome (CreateCompletionItemForSuggestedPatternName caseIdPos field.DisplayName)) + |> Option.defaultValue completions let getItem (x: ItemWithInst) = x.Item diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs index 1ef30395693..574e0642d1c 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fs +++ b/src/Compiler/Service/ServiceParsedInputOps.fs @@ -61,6 +61,7 @@ type PatternContext = /// Completing union case field in a pattern (e.g. fun (Some (Value = v|) -> ) | NamedUnionCaseField of fieldName: string * caseIdRange: range + /// Any other position in a pattern that does not need special handling | Other [] diff --git a/src/Compiler/Service/ServiceParsedInputOps.fsi b/src/Compiler/Service/ServiceParsedInputOps.fsi index fa19e13ac72..15a8c9a19c1 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fsi +++ b/src/Compiler/Service/ServiceParsedInputOps.fsi @@ -34,6 +34,7 @@ type public PatternContext = /// Completing union case field in a pattern (e.g. fun (Some (Value = v|) -> ) | NamedUnionCaseField of fieldName: string * caseIdRange: range + /// Any other position in a pattern that does not need special handling | Other [] diff --git a/src/Compiler/Utilities/illib.fs b/src/Compiler/Utilities/illib.fs index 244fd4608c1..fd59c3c24d9 100644 --- a/src/Compiler/Utilities/illib.fs +++ b/src/Compiler/Utilities/illib.fs @@ -571,6 +571,11 @@ module List = | [ _ ] -> true | _ -> false + let prependIfSome x l = + match x with + | Some x -> x :: l + | _ -> l + module ResizeArray = /// Split a ResizeArray into an array of smaller chunks. diff --git a/src/Compiler/Utilities/illib.fsi b/src/Compiler/Utilities/illib.fsi index 7272dace378..111bc0c8f77 100644 --- a/src/Compiler/Utilities/illib.fsi +++ b/src/Compiler/Utilities/illib.fsi @@ -211,6 +211,8 @@ module internal List = val isSingleton: xs: 'T list -> bool + val prependIfSome: x: 'a option -> l: 'a list -> 'a list + module internal ResizeArray = /// Split a ResizeArray into an array of smaller chunks. From 3053ef124b9af70eeaacd23b768f6965434c855e Mon Sep 17 00:00:00 2001 From: kerams Date: Mon, 3 Jul 2023 11:22:52 +0200 Subject: [PATCH 6/8] Do not use generated union case field names for suggestions --- src/Compiler/Service/FSharpCheckerResults.fs | 36 ++++++++++++------- .../CompletionProviderTests.fs | 4 +-- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/Compiler/Service/FSharpCheckerResults.fs b/src/Compiler/Service/FSharpCheckerResults.fs index 46ea166e7b6..991b48643de 100644 --- a/src/Compiler/Service/FSharpCheckerResults.fs +++ b/src/Compiler/Service/FSharpCheckerResults.fs @@ -945,19 +945,22 @@ type internal TypeCheckInfo /// Checks whether the suggested name is unused. /// In the future we could use an increasing numeric suffix for conflict resolution let CreateCompletionItemForSuggestedPatternName (pos: pos) name = - let name = String.lowerCaseFirstChar name + if String.IsNullOrWhiteSpace name then + None + else + let name = String.lowerCaseFirstChar name - let unused = - sResolutions.CapturedNameResolutions - |> ResizeArray.forall (fun r -> - match r.Item with - | Item.Value vref when r.Pos.Line = pos.Line -> vref.DisplayName <> name - | _ -> true) + let unused = + sResolutions.CapturedNameResolutions + |> ResizeArray.forall (fun r -> + match r.Item with + | Item.Value vref when r.Pos.Line = pos.Line -> vref.DisplayName <> name + | _ -> true) - if unused then - Some(CompletionItemSuggestedName name) - else - None + if unused then + Some(CompletionItemSuggestedName name) + else + None /// Suggest name based on type let SuggestNameBasedOnType g pos ty = @@ -990,15 +993,22 @@ type internal TypeCheckInfo sResolutions.CapturedNameResolutions |> ResizeArray.tryPick (fun r -> match r.Item with - | Item.Value vref when r.Pos = fieldPatternPos -> Some(stripTyparEqnsAux true vref.Type) + | Item.Value vref when r.Pos = fieldPatternPos -> Some(stripTyparEqns vref.Type) | _ -> None) |> Option.defaultValue field.FormalType else field.FormalType + let fieldName = + // If the field has not been given an explicit name, do not suggest the generated one + if field.rfield_name_generated then + "" + else + field.DisplayName + completions |> List.prependIfSome (SuggestNameBasedOnType g caseIdPos ty) - |> List.prependIfSome (CreateCompletionItemForSuggestedPatternName caseIdPos field.DisplayName)) + |> List.prependIfSome (CreateCompletionItemForSuggestedPatternName caseIdPos fieldName)) |> Option.defaultValue completions let getItem (x: ItemWithInst) = x.Item diff --git a/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs b/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs index a83e914cd58..44f09f9ef84 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs @@ -1479,7 +1479,7 @@ match A 1 with VerifyCompletionList(fileContents, "| A l", [ "logField"; "logLit"; "num" ], [ "logV"; "log" ]) [] - let ``Completion list contains suggested names for union case field pattern in a match clause`` () = + let ``Completion list contains suggested names for union case field pattern in a match clause unless the field name is generated`` () = let fileContents = """ type Du = @@ -1494,7 +1494,7 @@ let x du = """ VerifyCompletionList(fileContents, "| C (f", [ "first"; "du" ], [ "rest"; "item"; "num" ]) - VerifyCompletionList(fileContents, "| C (f, [ D i", [ "num"; "item" ], [ "rest"; "first"; "du" ]) + VerifyCompletionList(fileContents, "| C (f, [ D i", [ "num" ], [ "rest"; "first"; "du"; "item" ]) VerifyCompletionList(fileContents, "| C (f, [ D i; C (first = s", [ "first"; "du" ], [ "rest"; "num" ]) VerifyCompletionList(fileContents, "| C (rest = r", [ "rest"; "list" ], [ "first"; "du"; "item"; "num" ]) From bf8a44b8f000bc6c2fba64db5f001dfc22895617 Mon Sep 17 00:00:00 2001 From: kerams Date: Sat, 8 Jul 2023 12:03:05 +0200 Subject: [PATCH 7/8] Refactor --- src/Compiler/Service/FSharpCheckerResults.fs | 4 ++-- src/Compiler/Service/ServiceParsedInputOps.fs | 17 +++++++++-------- src/Compiler/Service/ServiceParsedInputOps.fsi | 7 ++++--- ....Service.SurfaceArea.netstandard20.debug.bsl | 10 +++++----- ...ervice.SurfaceArea.netstandard20.release.bsl | 10 +++++----- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/Compiler/Service/FSharpCheckerResults.fs b/src/Compiler/Service/FSharpCheckerResults.fs index 68262b2f1e5..572ef8f9e17 100644 --- a/src/Compiler/Service/FSharpCheckerResults.fs +++ b/src/Compiler/Service/FSharpCheckerResults.fs @@ -1474,7 +1474,7 @@ type internal TypeCheckInfo m) // Completion at '(x: ...)" - | Some (CompletionContext.Pattern PatternContext.Type) + | Some CompletionContext.Type // Completion at '| Case1 of ...' | Some CompletionContext.UnionCaseFieldsDeclaration // Completion at 'type Long = int6...' or 'type SomeUnion = Abc...' @@ -1538,9 +1538,9 @@ type internal TypeCheckInfo match patternContext with | PatternContext.PositionalUnionCaseField (index, m) -> Choice1Of2 index, m | PatternContext.NamedUnionCaseField (name, m) -> Choice2Of2 name, m - | PatternContext.Type // This is handled separately above | PatternContext.Other -> Choice1Of2 None, range0 + // No special handling for PatternContext.Other other than filtering out non-literal values if equals caseIdRange range0 then declaredItems else diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs index 574e0642d1c..b9985090a3a 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fs +++ b/src/Compiler/Service/ServiceParsedInputOps.fs @@ -51,9 +51,6 @@ type RecordContext = [] type PatternContext = - /// Completing pattern type (e.g. foo (x: |)) - | Type - /// Completing union case field in a pattern (e.g. fun (Some v|) -> ) /// fieldIndex None signifies that the case identifier is followed by a single field, outside of parentheses | PositionalUnionCaseField of fieldIndex: int option * caseIdRange: range @@ -86,6 +83,10 @@ type CompletionContext = | OpenDeclaration of isOpenType: bool + /// Completing a type annotation (e.g. foo (x: |)) + /// Completing a type application (e.g. typeof) + | Type + /// Completing union case fields declaration (e.g. 'A of stri|' but not 'B of tex|: string') | UnionCaseFieldsDeclaration @@ -1340,13 +1341,13 @@ module ParsedInput = | SynPat.Or (lhsPat = pat1; rhsPat = pat2) -> TryGetCompletionContextInPattern suppressIdentifierCompletions pat1 None pos |> Option.orElseWith (fun () -> TryGetCompletionContextInPattern suppressIdentifierCompletions pat2 None pos) - | SynPat.IsInst (_, m) when rangeContainsPos m pos -> Some(CompletionContext.Pattern PatternContext.Type) + | SynPat.IsInst (_, m) when rangeContainsPos m pos -> Some CompletionContext.Type | SynPat.Wild m when rangeContainsPos m pos -> Some CompletionContext.Invalid | SynPat.Typed (pat = pat; targetType = synType) -> if rangeContainsPos pat.Range pos then TryGetCompletionContextInPattern suppressIdentifierCompletions pat previousContext pos elif rangeContainsPos synType.Range pos then - Some(CompletionContext.Pattern PatternContext.Type) + Some CompletionContext.Type else None | _ -> None @@ -1390,7 +1391,7 @@ module ParsedInput = // Unchecked.defaultof | SynExpr.TypeApp (typeArgsRange = range) when rangeContainsPos range pos -> - Some(CompletionContext.Pattern PatternContext.Type) + Some CompletionContext.Type // fun (Some v$ ) -> | SynExpr.Lambda(parsedData = Some (pats, _)) -> @@ -1518,7 +1519,7 @@ module ParsedInput = Some CompletionContext.Invalid // type C (x: int|) -> elif rangeContainsPos synType.Range pos then - Some(CompletionContext.Pattern PatternContext.Type) + Some CompletionContext.Type else None | _ -> None) @@ -1557,7 +1558,7 @@ module ParsedInput = member _.VisitType(_, defaultTraverse, ty) = match ty with - | SynType.LongIdent _ when rangeContainsPos ty.Range pos -> Some(CompletionContext.Pattern PatternContext.Type) + | SynType.LongIdent _ when rangeContainsPos ty.Range pos -> Some CompletionContext.Type | _ -> defaultTraverse ty member _.VisitRecordDefn(_, fields, _) = diff --git a/src/Compiler/Service/ServiceParsedInputOps.fsi b/src/Compiler/Service/ServiceParsedInputOps.fsi index 15a8c9a19c1..0f70080f1ff 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fsi +++ b/src/Compiler/Service/ServiceParsedInputOps.fsi @@ -24,9 +24,6 @@ type public RecordContext = [] type public PatternContext = - /// Completing pattern type (e.g. foo (x: |)) - | Type - /// Completing union case field in a pattern (e.g. fun (Some v|) -> ) /// fieldIndex None signifies that the case identifier is followed by a single field, outside of parentheses | PositionalUnionCaseField of fieldIndex: int option * caseIdRange: range @@ -59,6 +56,10 @@ type public CompletionContext = | OpenDeclaration of isOpenType: bool + /// Completing a type annotation (e.g. foo (x: |)) + /// Completing a type application (e.g. typeof) + | Type + /// Completing union case fields declaration (e.g. 'A of stri|' but not 'B of tex|: string') | UnionCaseFieldsDeclaration diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl index ff15e43c0e9..f24cc753d9e 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl @@ -2552,6 +2552,7 @@ FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 ParameterList FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 Pattern FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 RangeOperator FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 RecordField +FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 Type FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 TypeAbbreviationOrSingleCaseUnion FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 UnionCaseFieldsDeclaration FSharp.Compiler.EditorServices.CompletionContext: Boolean Equals(FSharp.Compiler.EditorServices.CompletionContext) @@ -2565,6 +2566,7 @@ FSharp.Compiler.EditorServices.CompletionContext: Boolean IsParameterList FSharp.Compiler.EditorServices.CompletionContext: Boolean IsPattern FSharp.Compiler.EditorServices.CompletionContext: Boolean IsRangeOperator FSharp.Compiler.EditorServices.CompletionContext: Boolean IsRecordField +FSharp.Compiler.EditorServices.CompletionContext: Boolean IsType FSharp.Compiler.EditorServices.CompletionContext: Boolean IsTypeAbbreviationOrSingleCaseUnion FSharp.Compiler.EditorServices.CompletionContext: Boolean IsUnionCaseFieldsDeclaration FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsAttributeApplication() @@ -2575,6 +2577,7 @@ FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsParameterList() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsPattern() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsRangeOperator() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsRecordField() +FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsType() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsTypeAbbreviationOrSingleCaseUnion() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsUnionCaseFieldsDeclaration() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext AttributeApplication @@ -2585,11 +2588,13 @@ FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewPattern(FSharp.Compiler.EditorServices.PatternContext) FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewRecordField(FSharp.Compiler.EditorServices.RecordContext) FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext RangeOperator +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext Type FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext TypeAbbreviationOrSingleCaseUnion FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext UnionCaseFieldsDeclaration FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_AttributeApplication() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_Invalid() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_RangeOperator() +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_Type() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_TypeAbbreviationOrSingleCaseUnion() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_UnionCaseFieldsDeclaration() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+Inherit @@ -3569,24 +3574,19 @@ FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: Microsof FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 NamedUnionCaseField FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 Other FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 PositionalUnionCaseField -FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 Type FSharp.Compiler.EditorServices.PatternContext: Boolean Equals(FSharp.Compiler.EditorServices.PatternContext) FSharp.Compiler.EditorServices.PatternContext: Boolean Equals(System.Object) FSharp.Compiler.EditorServices.PatternContext: Boolean Equals(System.Object, System.Collections.IEqualityComparer) FSharp.Compiler.EditorServices.PatternContext: Boolean IsNamedUnionCaseField FSharp.Compiler.EditorServices.PatternContext: Boolean IsOther FSharp.Compiler.EditorServices.PatternContext: Boolean IsPositionalUnionCaseField -FSharp.Compiler.EditorServices.PatternContext: Boolean IsType FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsNamedUnionCaseField() FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsOther() FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsPositionalUnionCaseField() -FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsType() FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext NewNamedUnionCaseField(System.String, FSharp.Compiler.Text.Range) FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext NewPositionalUnionCaseField(Microsoft.FSharp.Core.FSharpOption`1[System.Int32], FSharp.Compiler.Text.Range) FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext Other -FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext Type FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext get_Other() -FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext get_Type() FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+NamedUnionCaseField FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+Tags diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl index e1b19ed36be..99db85a7aca 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl @@ -2552,6 +2552,7 @@ FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 ParameterList FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 Pattern FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 RangeOperator FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 RecordField +FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 Type FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 TypeAbbreviationOrSingleCaseUnion FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 UnionCaseFieldsDeclaration FSharp.Compiler.EditorServices.CompletionContext: Boolean Equals(FSharp.Compiler.EditorServices.CompletionContext) @@ -2565,6 +2566,7 @@ FSharp.Compiler.EditorServices.CompletionContext: Boolean IsParameterList FSharp.Compiler.EditorServices.CompletionContext: Boolean IsPattern FSharp.Compiler.EditorServices.CompletionContext: Boolean IsRangeOperator FSharp.Compiler.EditorServices.CompletionContext: Boolean IsRecordField +FSharp.Compiler.EditorServices.CompletionContext: Boolean IsType FSharp.Compiler.EditorServices.CompletionContext: Boolean IsTypeAbbreviationOrSingleCaseUnion FSharp.Compiler.EditorServices.CompletionContext: Boolean IsUnionCaseFieldsDeclaration FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsAttributeApplication() @@ -2575,6 +2577,7 @@ FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsParameterList() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsPattern() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsRangeOperator() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsRecordField() +FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsType() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsTypeAbbreviationOrSingleCaseUnion() FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsUnionCaseFieldsDeclaration() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext AttributeApplication @@ -2585,11 +2588,13 @@ FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewPattern(FSharp.Compiler.EditorServices.PatternContext) FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewRecordField(FSharp.Compiler.EditorServices.RecordContext) FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext RangeOperator +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext Type FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext TypeAbbreviationOrSingleCaseUnion FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext UnionCaseFieldsDeclaration FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_AttributeApplication() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_Invalid() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_RangeOperator() +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_Type() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_TypeAbbreviationOrSingleCaseUnion() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_UnionCaseFieldsDeclaration() FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+Inherit @@ -3569,24 +3574,19 @@ FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: Microsof FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 NamedUnionCaseField FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 Other FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 PositionalUnionCaseField -FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 Type FSharp.Compiler.EditorServices.PatternContext: Boolean Equals(FSharp.Compiler.EditorServices.PatternContext) FSharp.Compiler.EditorServices.PatternContext: Boolean Equals(System.Object) FSharp.Compiler.EditorServices.PatternContext: Boolean Equals(System.Object, System.Collections.IEqualityComparer) FSharp.Compiler.EditorServices.PatternContext: Boolean IsNamedUnionCaseField FSharp.Compiler.EditorServices.PatternContext: Boolean IsOther FSharp.Compiler.EditorServices.PatternContext: Boolean IsPositionalUnionCaseField -FSharp.Compiler.EditorServices.PatternContext: Boolean IsType FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsNamedUnionCaseField() FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsOther() FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsPositionalUnionCaseField() -FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsType() FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext NewNamedUnionCaseField(System.String, FSharp.Compiler.Text.Range) FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext NewPositionalUnionCaseField(Microsoft.FSharp.Core.FSharpOption`1[System.Int32], FSharp.Compiler.Text.Range) FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext Other -FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext Type FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext get_Other() -FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext get_Type() FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+NamedUnionCaseField FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+Tags From a61571d56615b96b61ff969548a24d129cbd2a74 Mon Sep 17 00:00:00 2001 From: kerams Date: Sat, 8 Jul 2023 12:07:30 +0200 Subject: [PATCH 8/8] . --- src/Compiler/Service/ServiceParsedInputOps.fs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs index b9985090a3a..eb416e9494d 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fs +++ b/src/Compiler/Service/ServiceParsedInputOps.fs @@ -1390,8 +1390,7 @@ module ParsedInput = | SynExpr.Record (None, None, [], _) -> Some(CompletionContext.RecordField RecordContext.Empty) // Unchecked.defaultof - | SynExpr.TypeApp (typeArgsRange = range) when rangeContainsPos range pos -> - Some CompletionContext.Type + | SynExpr.TypeApp (typeArgsRange = range) when rangeContainsPos range pos -> Some CompletionContext.Type // fun (Some v$ ) -> | SynExpr.Lambda(parsedData = Some (pats, _)) ->