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

Refactor QuickInfoProvider (#2778)

* refactor QuickInfoProvider

* fix wrong "this symbol range"

* further refactoring
上级 720f0b4d
......@@ -101,7 +101,7 @@ type internal FSharpAddOpenCodeFixProvider
let! symbol =
asyncMaybe {
let! lexerSymbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, context.Span.End, document.FilePath, defines, Tokenizer.SymbolLookupKind.Greedy)
let! lexerSymbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, context.Span.End, document.FilePath, defines, SymbolLookupKind.Greedy)
return! checkResults.GetSymbolUseAtLocation(Line.fromZ linePos.Line, lexerSymbol.Ident.idRange.EndColumn, line.ToString(), lexerSymbol.FullIsland)
} |> liftAsync
......
......@@ -169,7 +169,7 @@ type internal FSharpImplementInterfaceCodeFixProvider
| _ ->
Some context.Span.End
let! interfaceState = queryInterfaceState appendBracketAt interfacePos tokens parsedInput
let! symbol = Tokenizer.getSymbolAtPosition(context.Document.Id, sourceText, fixupPosition, context.Document.FilePath, defines, Tokenizer.SymbolLookupKind.Greedy)
let! symbol = Tokenizer.getSymbolAtPosition(context.Document.Id, sourceText, fixupPosition, context.Document.FilePath, defines, SymbolLookupKind.Greedy)
let fcsTextLineNumber = textLine.LineNumber + 1
let lineContents = textLine.ToString()
let! options = context.Document.GetOptionsAsync(cancellationToken)
......
......@@ -13,10 +13,9 @@ open Microsoft.FSharp.Compiler
open Microsoft.FSharp.Compiler.Layout
open Microsoft.FSharp.Compiler.SourceCodeServices
open Microsoft.FSharp.Compiler.Range
open Microsoft.FSharp.Compiler.Ast
open Microsoft.FSharp.Compiler.SourceCodeServices
open Microsoft.VisualStudio.FSharp.LanguageService
[<RequireQualifiedAccess>]
module internal RoslynHelpers =
let FSharpRangeToTextSpan(sourceText: SourceText, range: range) =
......
......@@ -21,8 +21,6 @@ open Microsoft.VisualStudio.Shell.Interop
open Microsoft.FSharp.Compiler
open Microsoft.FSharp.Compiler.Range
open Microsoft.FSharp.Compiler.SourceCodeServices
open Tokenizer
type internal FSharpCompletionProvider
(
......@@ -142,7 +140,7 @@ type internal FSharpCompletionProvider
let maxHints = if mruItems.Values.Count = 0 then 0 else Seq.max mruItems.Values
sortedDeclItems |> Array.iteri (fun number declItem ->
let glyph = FSharpGlyphToRoslynGlyph (declItem.Glyph, declItem.Accessibility)
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" ->
......
......@@ -56,7 +56,7 @@ type internal FSharpDocumentHighlightsService [<ImportingConstructor>] (checkerP
let textLine = sourceText.Lines.GetLineFromPosition(position)
let textLinePos = sourceText.Lines.GetLinePosition(position)
let fcsTextLineNumber = Line.fromZ textLinePos.Line
let! symbol = Tokenizer.getSymbolAtPosition(documentKey, sourceText, position, filePath, defines, Tokenizer.SymbolLookupKind.Greedy)
let! symbol = Tokenizer.getSymbolAtPosition(documentKey, sourceText, position, filePath, defines, SymbolLookupKind.Greedy)
let! _, _, checkFileResults = checker.ParseAndCheckDocument(filePath, textVersionHash, sourceText.ToString(), options, allowStaleResults = true)
let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, symbol.Ident.idRange.EndColumn, textLine.ToString(), symbol.FullIsland)
let! symbolUses = checkFileResults.GetUsesOfSymbolInFile(symbolUse.Symbol) |> liftAsync
......
......@@ -17,10 +17,8 @@ open Microsoft.CodeAnalysis.Text
open Microsoft.FSharp.Compiler
open Microsoft.FSharp.Compiler.Range
open Microsoft.FSharp.Compiler.SourceCodeServices
open Tokenizer
open Symbols
type internal FailureInlineRenameInfo private () =
interface IInlineRenameInfo with
member __.CanRename = false
......
......@@ -8,15 +8,11 @@ open Microsoft.CodeAnalysis.Text
open Microsoft.FSharp.Compiler
open Microsoft.FSharp.Compiler.Ast
open Microsoft.FSharp.Compiler.SourceCodeServices
open Tokenizer
open Symbols
open TypedAstUtils
type CheckResults =
| Ready of (FSharpParseFileResults * FSharpCheckFileResults) option
| StillRunning of Async<(FSharpParseFileResults * FSharpCheckFileResults) option>
type FSharpChecker with
member this.ParseDocument(document: Document, options: FSharpProjectOptions, sourceText: string) =
......
......@@ -65,7 +65,7 @@ module internal SymbolHelpers =
do! Option.guard (originalText.Length > 0)
let! options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject document
let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, options.OtherOptions |> Seq.toList)
let! symbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, symbolSpan.Start, document.FilePath, defines, Tokenizer.SymbolLookupKind.Greedy)
let! symbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, symbolSpan.Start, document.FilePath, defines, SymbolLookupKind.Greedy)
let! _, _, checkFileResults = checker.ParseAndCheckDocument(document, options, allowStaleResults = true)
let textLine = sourceText.Lines.GetLineFromPosition(symbolSpan.Start)
let textLinePos = sourceText.Lines.GetLinePosition(symbolSpan.Start)
......
module internal Microsoft.VisualStudio.FSharp.Editor.TypedAstUtils
open System
open Microsoft.FSharp.Compiler.Ast
open Microsoft.FSharp.Compiler.SourceCodeServices
open Microsoft.VisualStudio.FSharp.Editor
open System.Text.RegularExpressions
let isAttribute<'T> (attribute: FSharpAttribute) =
......@@ -43,7 +41,6 @@ let private UnnamedUnionFieldRegex = Regex("^Item(\d+)?$", RegexOptions.Compiled
let isUnnamedUnionCaseField (field: FSharpField) = UnnamedUnionFieldRegex.IsMatch(field.Name)
module TypedAstPatterns =
let (|AbbreviatedType|_|) (entity: FSharpEntity) =
......
......@@ -54,7 +54,7 @@ type internal FSharpFindUsagesService
let lineNumber = sourceText.Lines.GetLinePosition(position).Line + 1
let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.FilePath, options.OtherOptions |> Seq.toList)
let! symbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, Tokenizer.SymbolLookupKind.Greedy)
let! symbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy)
let! symbolUse = checkFileResults.GetSymbolUseAtLocation(lineNumber, symbol.Ident.idRange.EndColumn, textLine, symbol.FullIsland)
let! declaration = checkFileResults.GetDeclarationLocationAlternate (lineNumber, symbol.Ident.idRange.EndColumn, textLine, symbol.FullIsland, false) |> liftAsync
let tags = GlyphTags.GetTags(Tokenizer.GetGlyphForSymbol (symbolUse.Symbol, symbol.Kind))
......
......@@ -45,7 +45,7 @@ module internal FSharpGoToDefinition =
let textLine = sourceText.Lines.GetLineFromPosition position
let textLinePos = sourceText.Lines.GetLinePosition position
let fcsTextLineNumber = Line.fromZ textLinePos.Line
let! lexerSymbol = Tokenizer.getSymbolAtPosition(documentKey, sourceText, position, filePath, defines, Tokenizer.SymbolLookupKind.Greedy)
let! lexerSymbol = Tokenizer.getSymbolAtPosition(documentKey, sourceText, position, filePath, defines, SymbolLookupKind.Greedy)
let! _, _, checkFileResults =
checker.ParseAndCheckDocument
(filePath, textVersionHash, sourceText.ToString(), options, allowStaleResults = preferSignature)
......@@ -82,22 +82,17 @@ module internal FSharpGoToDefinition =
asyncMaybe {
let! projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject originDocument
let defines = CompilerEnvironment.GetCompilationDefinesForEditing (originDocument.FilePath, projectOptions.OtherOptions |> Seq.toList)
let originTextSpan = RoslynHelpers.FSharpRangeToTextSpan (sourceText, originRange)
let position = originTextSpan.Start
let! lexerSymbol =
Tokenizer.getSymbolAtPosition
(originDocument.Id, sourceText, position, originDocument.FilePath, defines, Tokenizer.SymbolLookupKind.Greedy)
let! lexerSymbol = Tokenizer.getSymbolAtPosition(originDocument.Id, sourceText, position, originDocument.FilePath, defines, SymbolLookupKind.Greedy)
let textLinePos = sourceText.Lines.GetLinePosition position
let fcsTextLineNumber = Line.fromZ textLinePos.Line
let lineText = (sourceText.Lines.GetLineFromPosition position).ToString()
let! _, _, checkFileResults =
checker.ParseAndCheckDocument (originDocument,projectOptions,allowStaleResults=true,sourceText=sourceText)
let idRange = lexerSymbol.Ident.idRange
let! fsSymbolUse = checkFileResults.GetSymbolUseAtLocation (fcsTextLineNumber, idRange.EndColumn, lineText, lexerSymbol.FullIsland)
let symbol = fsSymbolUse.Symbol
// if the tooltip was spawned in an implementation file and we have a range targeting
......@@ -109,10 +104,7 @@ module internal FSharpGoToDefinition =
let! implDoc = originDocument.Project.Solution.TryGetDocumentFromPath fsfilePath
let! implSourceText = implDoc.GetTextAsync ()
let! projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject implDoc
let! _, _, checkFileResults =
checker.ParseAndCheckDocument (implDoc, projectOptions, allowStaleResults=true, sourceText=implSourceText)
let! _, _, checkFileResults = checker.ParseAndCheckDocument (implDoc, projectOptions, allowStaleResults=true, sourceText=implSourceText)
let! symbolUses = checkFileResults.GetUsesOfSymbolInFile symbol |> liftAsync
let! implSymbol = symbolUses |> Array.tryHead
let implTextSpan = RoslynHelpers.FSharpRangeToTextSpan (implSourceText, implSymbol.RangeAlternate)
......@@ -127,12 +119,10 @@ module internal FSharpGoToDefinition =
(targetDocument:Document, symbolRange:range, targetSource:SourceText, checker: FSharpChecker, projectInfoManager: ProjectInfoManager) =
findSymbolHelper (targetDocument, symbolRange, targetSource,true, checker, projectInfoManager)
/// find the definition location (implementation file/.fs) of the target symbol
let findDefinitionOfSymbolAtRange
(targetDocument:Document, symbolRange:range, targetSourceText:SourceText, checker: FSharpChecker, projectInfoManager: ProjectInfoManager) =
findSymbolHelper (targetDocument, symbolRange, targetSourceText,false, checker, projectInfoManager)
/// use the targetSymbol to find the first instance of its presence in the provided source file
let findSymbolDeclarationInFile
......@@ -148,7 +138,6 @@ module internal FSharpGoToDefinition =
return implSymbol.RangeAlternate
}
open FSharpGoToDefinition
[<Shared>]
......@@ -213,7 +202,6 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>]
clearStatusBarAfter 4000
true
/// Navigate to the positon of the textSpan in the provided document
// used by quickinfo link navigation when the tooltip contains the correct destination range
member this.TryNavigateToTextSpan (document:Document, textSpan:TextSpan) =
......@@ -227,7 +215,6 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>]
clearStatusBarAfter 4000
false
/// find the declaration location (signature file/.fsi) of the target symbol if possible, fall back to definition
member this.NavigateToSymbolDeclarationAsync (targetDocument:Document, targetSourceText:SourceText, symbolRange:range) = async {
......@@ -236,7 +223,6 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>]
(targetDocument, symbolRange, targetSourceText, checkerProvider.Checker, projectInfoManager)
return tryNavigateToItem navresult
}
/// find the definition location (implementation file/.fs) of the target symbol
member this.NavigateToSymbolDefinitionAsync (targetDocument:Document, targetSourceText:SourceText, symbolRange:range)= async{
......@@ -246,14 +232,13 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>]
return tryNavigateToItem navresult
}
static member FindDefinition
(checker: FSharpChecker, documentKey: DocumentId, sourceText: SourceText, filePath: string, position: int,
defines: string list, options: FSharpProjectOptions, textVersionHash: int) : Option<range> = maybe {
let textLine = sourceText.Lines.GetLineFromPosition position
let textLinePos = sourceText.Lines.GetLinePosition position
let fcsTextLineNumber = Line.fromZ textLinePos.Line
let! lexerSymbol = Tokenizer.getSymbolAtPosition(documentKey, sourceText, position, filePath, defines, Tokenizer.SymbolLookupKind.Greedy)
let! lexerSymbol = Tokenizer.getSymbolAtPosition(documentKey, sourceText, position, filePath, defines, SymbolLookupKind.Greedy)
let! _, _, checkFileResults =
checker.ParseAndCheckDocument
(filePath, textVersionHash, sourceText.ToString(), options, allowStaleResults = true) |> Async.RunSynchronously
......@@ -267,7 +252,6 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>]
| _ -> return! None
}
/// Construct a task that will return a navigation target for the implementation definition of the symbol
/// at the provided position in the document
member this.FindDefinitionsTask (originDocument:Document, position:int, cancellationToken:CancellationToken) =
......@@ -288,7 +272,7 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>]
let! lexerSymbol =
Tokenizer.getSymbolAtPosition
(originDocument.Id, sourceText, position,originDocument.FilePath, defines, Tokenizer.SymbolLookupKind.Greedy)
(originDocument.Id, sourceText, position,originDocument.FilePath, defines, SymbolLookupKind.Greedy)
let idRange = lexerSymbol.Ident.idRange
let! declarations =
......@@ -362,13 +346,10 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>]
} |> Async.map (Option.defaultValue Seq.empty)
|> RoslynHelpers.StartAsyncAsTask cancellationToken
interface IGoToDefinitionService with
// used for 'definition peek'
member this.FindDefinitionsAsync (document: Document, position: int, cancellationToken: CancellationToken) =
this.FindDefinitionsTask (document, position, cancellationToken)
// used for 'goto definition' proper
/// Try to navigate to the definiton of the symbol at the symbolRange in the originDocument
......@@ -413,4 +394,4 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>]
stopSearchAnimation ()
statusBarMessage "Could Not Navigate to Definition of Symbol Under Caret"
clearStatusBarAfter 4000
true // we always return true to prevent the dialog box from appearing
true // we always return true to prevent the dialog box from appearing
\ No newline at end of file
......@@ -10,7 +10,6 @@ open Microsoft.CodeAnalysis.Classification
open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.Text
open Microsoft.VisualStudio.FSharp.Editor
open RoslynHelpers
[<TestFixture>][<Category "Roslyn Services">]
type ColorizationServiceTests() =
......@@ -36,7 +35,6 @@ type ColorizationServiceTests() =
| None -> Assert.Fail("Cannot find colorization data for end of marker")
| Some(classifiedSpan) -> Assert.AreEqual(classificationType, classifiedSpan.ClassificationType, "Classification data doesn't match for end of marker")
[<Test>]
member this.Comment_SingleLine() =
this.VerifyColorizerAtEndOfMarker(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册