提交 aad7c302 编写于 作者: V Vasily Kirichenko 提交者: Kevin Ransom (msft)

Fixed: "Attribute" suffix is not truncated on completion commit (#2781)

* fixed: "Attribute" suffix is not truncated on completion commit

* fix tests

* fix tests
上级 379f729d
......@@ -1380,10 +1380,10 @@ type FSharpAccessibility(a:Accessibility, ?isProtected) =
/// An intellisense declaration
[<Sealed>]
type FSharpDeclarationListItem(name: string, nameInCode: string, fullName: string, glyph: FSharpGlyph, info, isAttribute: bool, accessibility: FSharpAccessibility option,
type FSharpDeclarationListItem(name: string, nameInCode: string, fullName: string, glyph: FSharpGlyph, info, accessibility: FSharpAccessibility option,
kind: CompletionItemKind, isOwnMember: bool, priority: int, isResolved: bool, namespaceToOpen: string option) =
let mutable descriptionTextHolder:FSharpToolTipText<_> option = None
let mutable descriptionTextHolder: FSharpToolTipText<_> option = None
let mutable task = null
member decl.Name = name
......@@ -1436,7 +1436,6 @@ type FSharpDeclarationListItem(name: string, nameInCode: string, fullName: strin
member decl.DescriptionText = decl.StructuredDescriptionText |> Tooltips.ToFSharpToolTipText
member decl.Glyph = glyph
member decl.IsAttribute = isAttribute
member decl.Accessibility = accessibility
member decl.Kind = kind
member decl.IsOwnMember = isOwnMember
......@@ -1453,7 +1452,7 @@ type FSharpDeclarationListInfo(declarations: FSharpDeclarationListItem[], isForT
member self.IsError = isError
// Make a 'Declarations' object for a set of selected items
static member Create(infoReader:InfoReader, m, denv, getAccessibility, items: CompletionItem list, reactor, currentNamespaceOrModule: string[] option, checkAlive) =
static member Create(infoReader:InfoReader, m, denv, getAccessibility, items: CompletionItem list, reactor, currentNamespaceOrModule: string[] option, isAttributeApplicationContext: bool, checkAlive) =
let g = infoReader.g
let isForType = items |> List.exists (fun x -> x.Type.IsSome)
let items = items |> ItemDescriptionsImpl.RemoveExplicitlySuppressedCompletionItems g
......@@ -1538,8 +1537,8 @@ type FSharpDeclarationListInfo(declarations: FSharpDeclarationListItem[], isForT
| resolved, _ -> resolved
let item = items.Head
let glyph = ItemDescriptionsImpl.GlyphOfItem(denv, item.Item)
let name, nameInCode =
if displayName.StartsWith "( " && displayName.EndsWith " )" then
let cleanName = displayName.[2..displayName.Length - 3]
......@@ -1549,8 +1548,17 @@ type FSharpDeclarationListInfo(declarations: FSharpDeclarationListItem[], isForT
displayName,
match item.Unresolved with
| Some _ -> displayName
| None -> Lexhelp.Keywords.QuoteIdentifierIfNeeded displayName
| None -> Lexhelp.Keywords.QuoteIdentifierIfNeeded displayName
let isAttribute = ItemDescriptionsImpl.IsAttribute infoReader item.Item
let cutAttributeSuffix (name: string) =
if isAttributeApplicationContext && isAttribute && name <> "Attribute" && name.EndsWith "Attribute" then
name.[0..name.Length - "Attribute".Length - 1]
else name
let name = cutAttributeSuffix name
let nameInCode = cutAttributeSuffix nameInCode
let fullName = ItemDescriptionsImpl.FullNameOfItem g item.Item
let namespaceToOpen =
......@@ -1571,14 +1579,14 @@ type FSharpDeclarationListInfo(declarations: FSharpDeclarationListItem[], isForT
| ns -> Some (ns |> String.concat "."))
FSharpDeclarationListItem(
name, nameInCode, fullName, glyph, Choice1Of2 (items, infoReader, m, denv, reactor, checkAlive), ItemDescriptionsImpl.IsAttribute infoReader item.Item,
getAccessibility item.Item, item.Kind, item.IsOwnMember, item.MinorPriority, item.Unresolved.IsNone, namespaceToOpen))
name, nameInCode, fullName, glyph, Choice1Of2 (items, infoReader, m, denv, reactor, checkAlive), getAccessibility item.Item,
item.Kind, item.IsOwnMember, item.MinorPriority, item.Unresolved.IsNone, namespaceToOpen))
new FSharpDeclarationListInfo(Array.ofList decls, isForType, false)
static member Error msg =
new FSharpDeclarationListInfo(
[| FSharpDeclarationListItem("<Note>", "<Note>", "<Note>", FSharpGlyph.Error, Choice2Of2 (FSharpToolTipText [FSharpStructuredToolTipElement.CompositionError msg]),
false, None, CompletionItemKind.Other, false, 0, false, None) |], false, true)
None, CompletionItemKind.Other, false, 0, false, None) |], false, true)
static member Empty = FSharpDeclarationListInfo([| |], false, false)
......@@ -112,7 +112,6 @@ type internal FSharpDeclarationListItem =
member StructuredDescriptionTextAsync : Async<FSharpStructuredToolTipText>
member DescriptionTextAsync : Async<FSharpToolTipText>
member Glyph : FSharpGlyph
member IsAttribute : bool
member Accessibility : FSharpAccessibility option
member Kind : CompletionItemKind
member IsOwnMember : bool
......@@ -144,7 +143,7 @@ type internal FSharpDeclarationListInfo =
member IsError : bool
// Implementation details used by other code in the compiler
static member internal Create : infoReader:InfoReader * m:range * denv:DisplayEnv * getAccessibility:(Item -> FSharpAccessibility option) * items:CompletionItem list * reactor:IReactorOperations * currentNamespace:string[] option * checkAlive:(unit -> bool) -> FSharpDeclarationListInfo
static member internal Create : infoReader:InfoReader * m:range * denv:DisplayEnv * getAccessibility:(Item -> FSharpAccessibility option) * items:CompletionItem list * reactor:IReactorOperations * currentNamespace:string[] option * isAttributeApplicationContex:bool * checkAlive:(unit -> bool) -> FSharpDeclarationListInfo
static member internal Error : message:string -> FSharpDeclarationListInfo
static member Empty : FSharpDeclarationListInfo
......
......@@ -1121,7 +1121,8 @@ type TypeCheckInfo
/// Get the auto-complete items at a particular location.
let GetDeclItemsForNamesAtPosition(ctok: CompilationThreadToken, parseResultsOpt: FSharpParseFileResults option, origLongIdentOpt: string list option,
residueOpt:string option, line:int, lineStr:string, colAtEndOfNamesAndResidue, filterCtors, resolveOverloads,
getAllSymbols: unit -> AssemblySymbol list, hasTextChangedSinceLastTypecheck: (obj * range -> bool)) : (CompletionItem list * DisplayEnv * range) option =
getAllSymbols: unit -> AssemblySymbol list, hasTextChangedSinceLastTypecheck: (obj * range -> bool))
: (CompletionItem list * DisplayEnv * CompletionContext option * range) option =
RequireCompilationThread ctok // the operations in this method need the reactor thread
let loc =
......@@ -1132,97 +1133,100 @@ type TypeCheckInfo
| otherwise -> otherwise - 1
// Look for a "special" completion context
match UntypedParseImpl.TryGetCompletionContext(mkPos line colAtEndOfNamesAndResidue, parseResultsOpt, lineStr) with
// Invalid completion locations
| Some CompletionContext.Invalid -> None
// Completion at 'inherit C(...)"
| Some (CompletionContext.Inherit(InheritanceContext.Class, (plid, _))) ->
GetEnvironmentLookupResolutionsAtPosition(mkPos line loc, plid, filterCtors, false)
|> FilterRelevantItemsBy id None GetBaseClassCandidates
|> Option.map toCompletionItems
// Completion at 'interface ..."
| Some (CompletionContext.Inherit(InheritanceContext.Interface, (plid, _))) ->
GetEnvironmentLookupResolutionsAtPosition(mkPos line loc, plid, filterCtors, false)
|> FilterRelevantItemsBy id None GetInterfaceCandidates
|> Option.map toCompletionItems
// Completion at 'implement ..."
| Some (CompletionContext.Inherit(InheritanceContext.Unknown, (plid, _))) ->
GetEnvironmentLookupResolutionsAtPosition(mkPos line loc, plid, filterCtors, false)
|> FilterRelevantItemsBy id None (fun t -> GetBaseClassCandidates t || GetInterfaceCandidates t)
|> Option.map toCompletionItems
// Completion at ' { XXX = ... } "
| Some(CompletionContext.RecordField(RecordContext.New(plid, residue))) ->
// { x. } can be either record construction or computation expression. Try to get all visible record fields first
match GetClassOrRecordFieldsEnvironmentLookupResolutions(mkPos line loc, plid, residue) |> toCompletionItems with
| [],_,_ ->
// no record fields found, return completion list as if we were outside any computation expression
GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, line, loc, filterCtors,resolveOverloads, hasTextChangedSinceLastTypecheck, false, fun() -> [])
| result -> Some(result)
// Completion at ' { XXX = ... with ... } "
| Some(CompletionContext.RecordField(RecordContext.CopyOnUpdate(r, (plid, residue)))) ->
match GetRecdFieldsForExpr(r) with
| None ->
Some (GetClassOrRecordFieldsEnvironmentLookupResolutions(mkPos line loc, plid, residue))
let completionContext = UntypedParseImpl.TryGetCompletionContext(mkPos line colAtEndOfNamesAndResidue, parseResultsOpt, lineStr)
let res =
match completionContext with
// Invalid completion locations
| Some CompletionContext.Invalid -> None
// Completion at 'inherit C(...)"
| Some (CompletionContext.Inherit(InheritanceContext.Class, (plid, _))) ->
GetEnvironmentLookupResolutionsAtPosition(mkPos line loc, plid, filterCtors, false)
|> FilterRelevantItemsBy id None GetBaseClassCandidates
|> Option.map toCompletionItems
// Completion at 'interface ..."
| Some (CompletionContext.Inherit(InheritanceContext.Interface, (plid, _))) ->
GetEnvironmentLookupResolutionsAtPosition(mkPos line loc, plid, filterCtors, false)
|> FilterRelevantItemsBy id None GetInterfaceCandidates
|> Option.map toCompletionItems
// Completion at 'implement ..."
| Some (CompletionContext.Inherit(InheritanceContext.Unknown, (plid, _))) ->
GetEnvironmentLookupResolutionsAtPosition(mkPos line loc, plid, filterCtors, false)
|> FilterRelevantItemsBy id None (fun t -> GetBaseClassCandidates t || GetInterfaceCandidates t)
|> Option.map toCompletionItems
// Completion at ' { XXX = ... } "
| Some(CompletionContext.RecordField(RecordContext.New(plid, residue))) ->
// { x. } can be either record construction or computation expression. Try to get all visible record fields first
match GetClassOrRecordFieldsEnvironmentLookupResolutions(mkPos line loc, plid, residue) |> toCompletionItems with
| [],_,_ ->
// no record fields found, return completion list as if we were outside any computation expression
GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, line, loc, filterCtors,resolveOverloads, hasTextChangedSinceLastTypecheck, false, fun() -> [])
| result -> Some(result)
// Completion at ' { XXX = ... with ... } "
| Some(CompletionContext.RecordField(RecordContext.CopyOnUpdate(r, (plid, residue)))) ->
match GetRecdFieldsForExpr(r) with
| None ->
Some (GetClassOrRecordFieldsEnvironmentLookupResolutions(mkPos line loc, plid, residue))
|> Option.map toCompletionItems
| x -> x |> Option.map toCompletionItems
// Completion at ' { XXX = ... with ... } "
| Some(CompletionContext.RecordField(RecordContext.Constructor(typeName))) ->
Some(GetClassOrRecordFieldsEnvironmentLookupResolutions(mkPos line loc, [typeName], None))
|> Option.map toCompletionItems
| x -> x |> Option.map toCompletionItems
// Completion at ' { XXX = ... with ... } "
| Some(CompletionContext.RecordField(RecordContext.Constructor(typeName))) ->
Some(GetClassOrRecordFieldsEnvironmentLookupResolutions(mkPos line loc, [typeName], None))
|> Option.map toCompletionItems
// Completion at ' SomeMethod( ... ) ' with named arguments
| Some(CompletionContext.ParameterList (endPos, fields)) ->
let results = GetNamedParametersAndSettableFields endPos hasTextChangedSinceLastTypecheck
let declaredItems =
GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, line, loc, filterCtors, resolveOverloads,
hasTextChangedSinceLastTypecheck, false, getAllSymbols)
match results with
| NameResResult.Members(items, denv, m) ->
let filtered =
items
|> RemoveDuplicateItems g
|> RemoveExplicitlySuppressed g
|> List.filter (fun m -> not (fields.Contains m.DisplayName))
|> List.map (fun x ->
{ Item = x
Kind = CompletionItemKind.Argument
MinorPriority = 0
IsOwnMember = false
Type = None
Unresolved = None })
match declaredItems with
| None -> Some (toCompletionItems (items, denv, m))
| Some (declItems, declaredDisplayEnv, declaredRange) -> Some (filtered @ declItems, declaredDisplayEnv, declaredRange)
| _ -> declaredItems
| Some(CompletionContext.AttributeApplication) ->
GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, line, loc, filterCtors, resolveOverloads, hasTextChangedSinceLastTypecheck, false, getAllSymbols)
|> Option.map (fun (items, denv, m) ->
items
|> List.filter (fun cItem ->
match cItem.Item with
| Item.Types _
| Item.ModuleOrNamespaces _ -> true
| _ -> false), denv, m)
| Some(CompletionContext.OpenDeclaration) ->
GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, line, loc, filterCtors, resolveOverloads, hasTextChangedSinceLastTypecheck, false, getAllSymbols)
|> Option.map (fun (items, denv, m) ->
items |> List.filter (fun x -> match x.Item with Item.ModuleOrNamespaces _ -> true | _ -> false), denv, m)
// Other completions
| cc ->
let isInRangeOperator = (match cc with Some (CompletionContext.RangeOperator) -> true | _ -> false)
GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, line, loc, filterCtors,resolveOverloads, hasTextChangedSinceLastTypecheck, isInRangeOperator, getAllSymbols)
// Completion at ' SomeMethod( ... ) ' with named arguments
| Some(CompletionContext.ParameterList (endPos, fields)) ->
let results = GetNamedParametersAndSettableFields endPos hasTextChangedSinceLastTypecheck
let declaredItems =
GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, line, loc, filterCtors, resolveOverloads,
hasTextChangedSinceLastTypecheck, false, getAllSymbols)
match results with
| NameResResult.Members(items, denv, m) ->
let filtered =
items
|> RemoveDuplicateItems g
|> RemoveExplicitlySuppressed g
|> List.filter (fun m -> not (fields.Contains m.DisplayName))
|> List.map (fun x ->
{ Item = x
Kind = CompletionItemKind.Argument
MinorPriority = 0
IsOwnMember = false
Type = None
Unresolved = None })
match declaredItems with
| None -> Some (toCompletionItems (items, denv, m))
| Some (declItems, declaredDisplayEnv, declaredRange) -> Some (filtered @ declItems, declaredDisplayEnv, declaredRange)
| _ -> declaredItems
| Some(CompletionContext.AttributeApplication) ->
GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, line, loc, filterCtors, resolveOverloads, hasTextChangedSinceLastTypecheck, false, getAllSymbols)
|> Option.map (fun (items, denv, m) ->
items
|> List.filter (fun cItem ->
match cItem.Item with
| Item.ModuleOrNamespaces _ -> true
| _ when IsAttribute infoReader cItem.Item -> true
| _ -> false), denv, m)
| Some(CompletionContext.OpenDeclaration) ->
GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, line, loc, filterCtors, resolveOverloads, hasTextChangedSinceLastTypecheck, false, getAllSymbols)
|> Option.map (fun (items, denv, m) ->
items |> List.filter (fun x -> match x.Item with Item.ModuleOrNamespaces _ -> true | _ -> false), denv, m)
// Other completions
| cc ->
let isInRangeOperator = (match cc with Some (CompletionContext.RangeOperator) -> true | _ -> false)
GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, line, loc, filterCtors,resolveOverloads, hasTextChangedSinceLastTypecheck, isInRangeOperator, getAllSymbols)
res |> Option.map (fun (items, denv, m) -> items, denv, completionContext, m)
/// Return 'false' if this is not a completion item valid in an interface file.
let IsValidSignatureFileItem item =
......@@ -1250,14 +1254,15 @@ type TypeCheckInfo
(fun () ->
match GetDeclItemsForNamesAtPosition(ctok, parseResultsOpt, Some qualifyingNames, Some partialName, line, lineStr, colAtEndOfNamesAndResidue, ResolveTypeNamesToCtors, ResolveOverloads.Yes, getAllSymbols, hasTextChangedSinceLastTypecheck) with
| None -> FSharpDeclarationListInfo.Empty
| Some (items, denv, m) ->
| Some (items, denv, ctx, m) ->
let items = if isInterfaceFile then items |> List.filter (fun x -> IsValidSignatureFileItem x.Item) else items
let getAccessibility item = FSharpSymbol.GetAccessibility (FSharpSymbol.Create(g, thisCcu, tcImports, item))
let currentNamespaceOrModule =
parseResultsOpt
|> Option.bind (fun x -> x.ParseTree)
|> Option.map (fun parsedInput -> UntypedParseImpl.GetFullNameOfSmallestModuleOrNamespaceAtPoint(parsedInput, mkPos line 0))
FSharpDeclarationListInfo.Create(infoReader,m,denv,getAccessibility,items,reactorOps,currentNamespaceOrModule,checkAlive))
let isAttributeApplication = ctx = Some CompletionContext.AttributeApplication
FSharpDeclarationListInfo.Create(infoReader,m,denv,getAccessibility,items,reactorOps,currentNamespaceOrModule,isAttributeApplication,checkAlive))
(fun msg -> FSharpDeclarationListInfo.Error msg)
/// Get the symbols for auto-complete items at a location
......@@ -1267,7 +1272,7 @@ type TypeCheckInfo
(fun () ->
match GetDeclItemsForNamesAtPosition(ctok, parseResultsOpt, Some qualifyingNames, Some partialName, line, lineStr, colAtEndOfNamesAndResidue, ResolveTypeNamesToCtors, ResolveOverloads.Yes, (fun () -> []), hasTextChangedSinceLastTypecheck) with
| None -> List.Empty
| Some (items, _denv, _m) ->
| Some (items, denv, _, m) ->
let items = if isInterfaceFile then items |> List.filter (fun x -> IsValidSignatureFileItem x.Item) else items
//do filtering like Declarationset
......@@ -1320,7 +1325,7 @@ type TypeCheckInfo
| items ->
items
|> List.map (fun item -> let symbol = FSharpSymbol.Create(g, thisCcu, tcImports, item.Item)
FSharpSymbolUse(g, _denv, symbol, ItemOccurence.Use, _m)))
FSharpSymbolUse(g, denv, symbol, ItemOccurence.Use, m)))
//end filtering
items)
......@@ -1367,7 +1372,7 @@ type TypeCheckInfo
(fun () ->
match GetDeclItemsForNamesAtPosition(ctok, None,Some(names),None,line,lineStr,colAtEndOfNames,ResolveTypeNamesToCtors,ResolveOverloads.Yes,(fun() -> []),fun _ -> false) with
| None -> FSharpToolTipText []
| Some(items, denv, m) ->
| Some(items, denv, _, m) ->
FSharpToolTipText(items |> List.map (fun x -> FormatStructuredDescriptionOfItem false infoReader m denv x.Item)))
(fun err -> FSharpToolTipText [FSharpStructuredToolTipElement.CompositionError err])
......@@ -1390,7 +1395,7 @@ type TypeCheckInfo
(fun () ->
match GetDeclItemsForNamesAtPosition(ctok, None, Some names, None, line, lineStr, colAtEndOfNames, ResolveTypeNamesToCtors, ResolveOverloads.No,(fun() -> []), fun _ -> false) with // F1 Keywords do not distinguish between overloads
| None -> None
| Some (items: CompletionItem list, _, _) ->
| Some (items: CompletionItem list, _,_, _) ->
match items with
| [] -> None
| [item] ->
......@@ -1420,14 +1425,14 @@ type TypeCheckInfo
(fun () ->
match GetDeclItemsForNamesAtPosition(ctok, None,namesOpt,None,line,lineStr,colAtEndOfNames,ResolveTypeNamesToCtors,ResolveOverloads.No,(fun() -> []),fun _ -> false) with
| None -> FSharpMethodGroup("",[| |])
| Some (items, denv, m) -> FSharpMethodGroup.Create(infoReader,m,denv,items |> List.map (fun x -> x.Item)))
| Some (items, denv,_, m) -> FSharpMethodGroup.Create(infoReader,m,denv,items |> List.map (fun x -> x.Item)))
(fun msg ->
FSharpMethodGroup(msg,[| |]))
member scope.GetMethodsAsSymbols (ctok, line, lineStr, colAtEndOfNames, names) =
match GetDeclItemsForNamesAtPosition (ctok, None,Some(names), None, line, lineStr, colAtEndOfNames, ResolveTypeNamesToCtors, ResolveOverloads.No,(fun() -> []),fun _ -> false) with
| None | Some ([], _, _) -> None
| Some (items, denv, m) ->
| None | Some ([],_,_,_) -> None
| Some (items, denv, _, m) ->
let allItems =
items
|> List.collect (fun item ->
......@@ -1460,8 +1465,8 @@ type TypeCheckInfo
member scope.GetDeclarationLocation (ctok, line, lineStr, colAtEndOfNames, names, preferFlag) =
match GetDeclItemsForNamesAtPosition (ctok, None,Some(names), None, line, lineStr, colAtEndOfNames, ResolveTypeNamesToCtors,ResolveOverloads.Yes,(fun() -> []), fun _ -> false) with
| None
| Some ([], _, _) -> FSharpFindDeclResult.DeclNotFound FSharpFindDeclFailureReason.Unknown
| Some (item :: _ , _, _) ->
| Some ([], _, _, _) -> FSharpFindDeclResult.DeclNotFound FSharpFindDeclFailureReason.Unknown
| Some (item :: _ , _, _, _) ->
// For IL-based entities, switch to a different item. This is because
// rangeOfItem, ccuOfItem don't work on IL methods or fields.
......@@ -1501,8 +1506,8 @@ type TypeCheckInfo
member scope.GetSymbolUseAtLocation (ctok, line, lineStr, colAtEndOfNames, names) =
match GetDeclItemsForNamesAtPosition (ctok, None,Some(names), None, line, lineStr, colAtEndOfNames, ResolveTypeNamesToCtors, ResolveOverloads.Yes,(fun() -> []), fun _ -> false) with
| None | Some ([], _, _) -> None
| Some (item :: _ , denv, m) ->
| None | Some ([], _, _, _) -> None
| Some (item :: _ , denv, _, m) ->
let symbol = FSharpSymbol.Create(g, thisCcu, tcImports, item.Item)
Some (symbol, denv, m)
......
......@@ -51,7 +51,6 @@ type internal FSharpCompletionProvider
let xmlMemberIndexService = serviceProvider.GetService(typeof<IVsXMLMemberIndexService>) :?> IVsXMLMemberIndexService
let documentationBuilder = XmlDocumentation.CreateDocumentationBuilder(xmlMemberIndexService, serviceProvider.DTE)
static let attributeSuffixLength = "Attribute".Length
static let noCommitOnSpaceRules =
CompletionItemRules.Default.WithCommitCharacterRule(CharacterSetModificationRule.Create(CharacterSetModificationKind.Remove, ' ', '.', '<', '>', '(', ')', '!'))
......@@ -86,7 +85,7 @@ type internal FSharpCompletionProvider
static member ProvideCompletionsAsyncAux(checker: FSharpChecker, sourceText: SourceText, caretPosition: int, options: FSharpProjectOptions, filePath: string,
textVersionHash: int, getAllSymbols: unit -> AssemblySymbol list) =
asyncMaybe {
let! parseResults, parsedInput, checkFileResults = checker.ParseAndCheckDocument(filePath, textVersionHash, sourceText.ToString(), options, allowStaleResults = true)
let! parseResults, _, checkFileResults = checker.ParseAndCheckDocument(filePath, textVersionHash, sourceText.ToString(), options, allowStaleResults = true)
//#if DEBUG
//Logging.Logging.logInfof "AST:\n%+A" parsedInput
......@@ -94,8 +93,6 @@ type internal FSharpCompletionProvider
let textLines = sourceText.Lines
let caretLinePos = textLines.GetLinePosition(caretPosition)
let entityKind = UntypedParseImpl.GetEntityKind(Pos.fromZ caretLinePos.Line caretLinePos.Character, parsedInput)
let caretLine = textLines.GetLineFromPosition(caretPosition)
let fcsCaretLineNumber = Line.fromZ caretLinePos.Line // Roslyn line numbers are zero-based, FSharp.Compiler.Service line numbers are 1-based
let caretLineColumn = caretLinePos.Character
......@@ -142,11 +139,8 @@ type internal FSharpCompletionProvider
sortedDeclItems |> Array.iteri (fun number declItem ->
let glyph = Tokenizer.FSharpGlyphToRoslynGlyph (declItem.Glyph, declItem.Accessibility)
let name =
match entityKind, declItem.NamespaceToOpen with
| Some EntityKind.Attribute, _ when declItem.IsAttribute && declItem.Name.EndsWith "Attribute" ->
declItem.Name.[0..declItem.Name.Length - attributeSuffixLength - 1]
| _, Some namespaceToOpen ->
sprintf "%s (open %s)" declItem.Name namespaceToOpen
match declItem.NamespaceToOpen with
| Some namespaceToOpen -> sprintf "%s (open %s)" declItem.Name namespaceToOpen
| _ -> declItem.Name
let filterText =
......
......@@ -182,8 +182,9 @@ type UsingMSBuild() as this =
shouldContain // should contain
shouldNotContain
member public this.AutoCompleteBug70080Helper(programText:string) =
this.AutoCompleteBug70080HelperHelper(programText, ["AttributeUsageAttribute"], [])
member public this.AutoCompleteBug70080Helper(programText:string, ?withSuffix: bool) =
let expected = if defaultArg withSuffix false then "AttributeUsageAttribute" else "AttributeUsage"
this.AutoCompleteBug70080HelperHelper(programText, [expected], [])
member private this.testAutoCompleteAdjacentToDot op =
let text = sprintf "System.Console%s" op
......@@ -3516,17 +3517,17 @@ let x = query { for bbbb in abbbbc(*D0*) do
[<Test>]
member public this.``Attribute.WhenAttachedToType.Bug70080``() =
this.AutoCompleteBug70080Helper @"
this.AutoCompleteBug70080Helper(@"
open System
[<Attr // expect AttributeUsageAttribute from System namespace
type MyAttr() = inherit Attribute()"
type MyAttr() = inherit Attribute()", true)
[<Test>]
member public this.``Attribute.WhenAttachedToNothing.Bug70080``() =
this.AutoCompleteBug70080Helper @"
this.AutoCompleteBug70080Helper(@"
open System
[<Attr // expect AttributeUsageAttribute from System namespace
// nothing here"
// nothing here", true)
[<Test>]
member public this.``Attribute.WhenAttachedToLetInNamespace.Bug70080``() =
......@@ -3538,36 +3539,36 @@ let x = query { for bbbb in abbbbc(*D0*) do
[<Test>]
member public this.``Attribute.WhenAttachedToTypeInNamespace.Bug70080``() =
this.AutoCompleteBug70080Helper @"
this.AutoCompleteBug70080Helper(@"
namespace Foo
open System
[<Attr // expect AttributeUsageAttribute from System namespace
type MyAttr() = inherit Attribute()"
type MyAttr() = inherit Attribute()", true)
[<Test>]
member public this.``Attribute.WhenAttachedToNothingInNamespace.Bug70080``() =
this.AutoCompleteBug70080Helper @"
this.AutoCompleteBug70080Helper(@"
namespace Foo
open System
[<Attr // expect AttributeUsageAttribute from System namespace
// nothing here"
// nothing here", true)
[<Test>]
member public this.``Attribute.WhenAttachedToModuleInNamespace.Bug70080``() =
this.AutoCompleteBug70080Helper @"
this.AutoCompleteBug70080Helper(@"
namespace Foo
open System
[<Attr // expect AttributeUsageAttribute from System namespace
module Foo =
let x = 42"
let x = 42", true)
[<Test>]
member public this.``Attribute.WhenAttachedToModule.Bug70080``() =
this.AutoCompleteBug70080Helper @"
this.AutoCompleteBug70080Helper(@"
open System
[<Attr // expect AttributeUsageAttribute from System namespace
module Foo =
let x = 42"
let x = 42", true)
[<Test>]
member public this.``Identifer.InMatchStatemente.Bug72595``() =
......@@ -6030,7 +6031,7 @@ let rec f l =
let f (x:MyNamespace1.MyModule(*Maftervariable4*)) = 10
let y = int System.IO(*Maftervariable5*)""",
marker = "(*Maftervariable2*)",
list = ["DuType";"Pet";"Dog"])
list = [])
[<Test>]
member this.``VariableIdentifier.MethodsInheritFomeBase``() =
......@@ -6107,7 +6108,7 @@ let rec f l =
type TestAttribute() =
member x.print() = "print" """,
marker = "(*Mattribute*)",
list = ["Int32";"ObsoleteAttribute"])
list = ["Obsolete"])
[<Test>]
member this.``ImportStatment.System.ImportDirectly``() =
......@@ -6207,7 +6208,7 @@ let rec f l =
let result5 = CopyFile_Arrays(tempFile1.ToCharArray(), tempFile2.ToCharArray(), false)
printfn "WithAttribute %A" result5""",
marker = "(*Mpinvokeattribute*)",
list = ["SomeAttrib";"myclass"])
list = ["SomeAttrib"])
[<Test>]
member this.``LongIdent.PInvoke.AsParameterType``() =
......@@ -6296,7 +6297,7 @@ let rec f l =
let f (x:int) = MyNamespace1.MyModule.DuType(*Mtypeparameter2*)
let typeFunc<[<MyNamespace1.MyModule(*Mtypeparameter3*)>] 'a> = 10""",
marker = "(*Mtypeparameter3*)",
list = ["Dog";"DuType"])
list = [])
[<Test>]
member this.``RedefinedIdentifier.DiffScope.InScope.Positive``() =
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册