Skip to content
This repository was archived by the owner on Dec 23, 2024. It is now read-only.

Commit

Permalink
Better lexer symbol (dotnet#2056)
Browse files Browse the repository at this point in the history
* port lexer symbol lookup logic from VFPT and use it in DocumentHighlightsService

* QuickInfoProvider uses lexer symbol

* remove tryClassifyAtPosition

* do not show quick info if FCS return a list of single FSharpTooltipElement.None

* use standard Option combinators

remove Pervasive.fs
  • Loading branch information
vasily-kirichenko authored and KevinRansom committed Dec 20, 2016
1 parent 3d01ec4 commit 25162a8
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 130 deletions.
245 changes: 197 additions & 48 deletions Common/CommonHelpers.fs

Large diffs are not rendered by default.

14 changes: 5 additions & 9 deletions Common/Logging.fs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
namespace Microsoft.VisualStudio.FSharp.Logging
namespace Microsoft.VisualStudio.FSharp.Editor.Logging

open System
open System.Collections.Generic
open System.Windows.Media
Expand All @@ -11,6 +12,7 @@ open Microsoft.VisualStudio.Utilities
open Microsoft.VisualStudio.Shell
open Microsoft.VisualStudio.Shell.Interop
open Microsoft.VisualStudio.ComponentModelHost
open Microsoft.VisualStudio.FSharp.Editor

[<RequireQualifiedAccess>]
type LogType =
Expand All @@ -27,14 +29,11 @@ type LogType =


module Config =

let [<Literal>] fsharpOutputGuidString = "E721F849-446C-458C-997A-99E14A04CFD3"
let fsharpOutputGuid = Guid fsharpOutputGuidString

open Config



type [<Export>] Logger [<ImportingConstructor>]
([<Import(typeof<SVsServiceProvider>)>] serviceProvider: IServiceProvider) =
let outputWindow = serviceProvider.GetService<SVsOutputWindow,IVsOutputWindow>()
Expand All @@ -52,15 +51,14 @@ type [<Export>] Logger [<ImportingConstructor>]
static let mutable globalServiceProvider: IServiceProvider option = None

static member GlobalServiceProvider
with get () = globalServiceProvider |> Option.getOrElse (ServiceProvider.GlobalProvider :> IServiceProvider)
with get () = globalServiceProvider |> Option.defaultValue (ServiceProvider.GlobalProvider :> IServiceProvider)
and set v = globalServiceProvider <- Some v

member __.FSharpLoggingPane
with get () = getPane () |> function
| Some pane -> Some pane
| None -> createPane(); getPane()


member self.Log (msgType:LogType,msg:string) =
let time = DateTime.Now.ToString("hh:mm:ss tt")
match self.FSharpLoggingPane, msgType with
Expand All @@ -70,7 +68,6 @@ type [<Export>] Logger [<ImportingConstructor>]
| Some pane, LogType.Warn -> String.Format("[F#][{0}{1}] {2}{3}", "WARN " , time, msg, Environment.NewLine) |> pane.OutputString |> ignore
| Some pane, LogType.Error -> String.Format("[F#][{0}{1}] {2}{3}", "ERROR ", time, msg, Environment.NewLine) |> pane.OutputString |> ignore


[<AutoOpen>]
module Logging =

Expand All @@ -91,5 +88,4 @@ module Logging =
logErrorf "Exception Message: %s\nStack Trace: %s" ex.Message ex.StackTrace

let logExceptionWithContext(ex: Exception, context) =
logErrorf "Context: %s\nException Message: %s\nStack Trace: %s" context ex.Message ex.StackTrace

logErrorf "Context: %s\nException Message: %s\nStack Trace: %s" context ex.Message ex.StackTrace
17 changes: 0 additions & 17 deletions Common/Pervasive.fs

This file was deleted.

16 changes: 7 additions & 9 deletions DocumentHighlights/DocumentHighlightsService.fs
Original file line number Diff line number Diff line change
Expand Up @@ -68,29 +68,27 @@ type internal FSharpDocumentHighlightsService [<ImportingConstructor>] (checkerP
|> Seq.toArray

static member GetDocumentHighlights(checker: FSharpChecker, documentKey: DocumentId, sourceText: SourceText, filePath: string, position: int,
defines: string list, options: FSharpProjectOptions, textVersionHash: int, cancellationToken: CancellationToken) : Async<FSharpHighlightSpan[]> =
defines: string list, options: FSharpProjectOptions, textVersionHash: int) : Async<FSharpHighlightSpan[]> =
async {
let textLine = sourceText.Lines.GetLineFromPosition(position)
let textLinePos = sourceText.Lines.GetLinePosition(position)
let fcsTextLineNumber = textLinePos.Line + 1

match CommonHelpers.tryClassifyAtPosition(documentKey, sourceText, filePath, defines, position, SymbolSearchKind.IncludeRightColumn, cancellationToken) with
| Some (_, [], _) -> return [||]
| Some (islandEndColumn, qualifiers, _span) ->
match CommonHelpers.getSymbolAtPosition(documentKey, sourceText, position, filePath, defines, SymbolLookupKind.Fuzzy) with
| Some symbol ->
let! _parseResults, checkFileAnswer = checker.ParseAndCheckFileInProject(filePath, textVersionHash, sourceText.ToString(), options)
match checkFileAnswer with
| FSharpCheckFileAnswer.Aborted -> return [||]
| FSharpCheckFileAnswer.Succeeded(checkFileResults) ->
let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, islandEndColumn, textLine.ToString(), qualifiers)
let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, symbol.RightColumn, textLine.ToString(), [symbol.Text])
match symbolUse with
| Some symbolUse ->
let! symbolUses = checkFileResults.GetUsesOfSymbolInFile(symbolUse.Symbol)
let lastIdent = List.last qualifiers
return
[| for symbolUse in symbolUses do
yield { IsDefinition = symbolUse.IsFromDefinition
TextSpan = CommonRoslynHelpers.FSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate) } |]
|> fixInvalidSymbolSpans sourceText lastIdent
|> fixInvalidSymbolSpans sourceText symbol.Text
| None -> return [||]
| None -> return [||]
}
Expand All @@ -103,8 +101,8 @@ type internal FSharpDocumentHighlightsService [<ImportingConstructor>] (checkerP
let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask
let! textVersion = document.GetTextVersionAsync(cancellationToken) |> Async.AwaitTask
let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, options.OtherOptions |> Seq.toList)
let! spans = FSharpDocumentHighlightsService.GetDocumentHighlights(checkerProvider.Checker, document.Id, sourceText, document.FilePath, position, defines, options, textVersion.GetHashCode(), cancellationToken)

let! spans = FSharpDocumentHighlightsService.GetDocumentHighlights(checkerProvider.Checker, document.Id, sourceText, document.FilePath,
position, defines, options, textVersion.GetHashCode())
let highlightSpans = spans |> Array.map (fun span ->
let kind = if span.IsDefinition then HighlightSpanKind.Definition else HighlightSpanKind.Reference
HighlightSpan(span.TextSpan, kind))
Expand Down
26 changes: 13 additions & 13 deletions FSharp.Editor.fsproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
Expand All @@ -18,7 +18,8 @@
<TargetType>LIBRARY</TargetType>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<NoWarn>$(NoWarn);75</NoWarn>
<Tailcalls Condition="'$(CodeCoverage)' != ''">false</Tailcalls> <OtherFlags>$(OtherFlags) --warnon:1182 --subsystemversion:6.00</OtherFlags>
<Tailcalls Condition="'$(CodeCoverage)' != ''">false</Tailcalls>
<OtherFlags>$(OtherFlags) --warnon:1182 --subsystemversion:6.00</OtherFlags>
<ImportVSSDKTargets>true</ImportVSSDKTargets>
<CreateVsixContainer>false</CreateVsixContainer>
<DeployExtension>false</DeployExtension>
Expand All @@ -27,24 +28,23 @@
<IncludePkgdefInVSIXContainer>true</IncludePkgdefInVSIXContainer>
</PropertyGroup>
<ItemGroup>
<Compile Include="Common\AssemblyInfo.fs" />
<Compile Include="Common\AssemblyInfo.fs" />
<Compile Include="Common\CommonConstants.fs" />
<Compile Include="Common\CommonRoslynHelpers.fs" />
<Compile Include="Common\CommonHelpers.fs" />
<Compile Include="Common\Pervasive.fs" />
<Compile Include="Common\Logging.fs" />
<Compile Include="Common\ContentType.fs" />
<Compile Include="Common\LanguageService.fs" />
<Compile Include="Classification\ColorizationService.fs" />
<Compile Include="Formatting\BraceMatchingService.fs" />
<Compile Include="Formatting\IndentationService.fs"/>
<Compile Include="Debugging\BreakpointResolutionService.fs"/>
<Compile Include="Debugging\LanguageDebugInfoService.fs"/>
<Compile Include="Diagnostics\DocumentDiagnosticAnalyzer.fs"/>
<Compile Include="Diagnostics\ProjectDiagnosticAnalyzer.fs"/>
<Compile Include="Completion\CompletionProvider.fs"/>
<Compile Include="Completion\SignatureHelp.fs"/>
<Compile Include="QuickInfo\QuickInfoProvider.fs"/>
<Compile Include="Formatting\IndentationService.fs" />
<Compile Include="Debugging\BreakpointResolutionService.fs" />
<Compile Include="Debugging\LanguageDebugInfoService.fs" />
<Compile Include="Diagnostics\DocumentDiagnosticAnalyzer.fs" />
<Compile Include="Diagnostics\ProjectDiagnosticAnalyzer.fs" />
<Compile Include="Completion\CompletionProvider.fs" />
<Compile Include="Completion\SignatureHelp.fs" />
<Compile Include="QuickInfo\QuickInfoProvider.fs" />
<Compile Include="InlineRename\InlineRenameService.fs" />
<Compile Include="DocumentHighlights\DocumentHighlightsService.fs" />
<Compile Include="Navigation\GoToDefinitionService.fs" />
Expand All @@ -53,7 +53,7 @@
<Compile Include="Navigation\FindReferencesService.fs" />
<Compile Include="BlockComment\CommentUncommentService.fs" />
<Compile Include="Structure\BlockStructureService.fs" />
<Compile Include="Commands\HelpContextService.fs" />
<Compile Include="Commands\HelpContextService.fs" />
<Compile Include="Commands\FsiCommandService.fs" />
</ItemGroup>
<ItemGroup>
Expand Down
10 changes: 5 additions & 5 deletions InlineRename/InlineRenameService.fs
Original file line number Diff line number Diff line change
Expand Up @@ -178,21 +178,21 @@ type internal InlineRenameService
) =

static member GetInlineRenameInfo(checker: FSharpChecker, projectInfoManager: ProjectInfoManager, document: Document, sourceText: SourceText, position: int,
defines: string list, options: FSharpProjectOptions, textVersionHash: int, cancellationToken: CancellationToken) : Async<IInlineRenameInfo> =
defines: string list, options: FSharpProjectOptions, textVersionHash: int) : Async<IInlineRenameInfo> =
async {
let textLine = sourceText.Lines.GetLineFromPosition(position)
let textLinePos = sourceText.Lines.GetLinePosition(position)
let fcsTextLineNumber = textLinePos.Line + 1 // Roslyn line numbers are zero-based, FSharp.Compiler.Service line numbers are 1-based

match CommonHelpers.tryClassifyAtPosition(document.Id, sourceText, document.FilePath, defines, position, SymbolSearchKind.IncludeRightColumn, cancellationToken) with
| Some (islandColumn, qualifiers, _) ->
match CommonHelpers.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Fuzzy) with
| Some symbol ->
let! _parseResults, checkFileAnswer = checker.ParseAndCheckFileInProject(document.FilePath, textVersionHash, sourceText.ToString(), options)

match checkFileAnswer with
| FSharpCheckFileAnswer.Aborted -> return FailureInlineRenameInfo.Instance :> _
| FSharpCheckFileAnswer.Succeeded(checkFileResults) ->

let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, islandColumn, textLine.Text.ToString(), qualifiers)
let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, symbol.RightColumn, textLine.Text.ToString(), [symbol.Text])

match symbolUse with
| Some symbolUse ->
Expand All @@ -211,7 +211,7 @@ type internal InlineRenameService
let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask
let! textVersion = document.GetTextVersionAsync(cancellationToken) |> Async.AwaitTask
let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, options.OtherOptions |> Seq.toList)
return! InlineRenameService.GetInlineRenameInfo(checkerProvider.Checker, projectInfoManager, document, sourceText, position, defines, options, textVersion.GetHashCode(), cancellationToken)
return! InlineRenameService.GetInlineRenameInfo(checkerProvider.Checker, projectInfoManager, document, sourceText, position, defines, options, hash textVersion)
| None -> return FailureInlineRenameInfo.Instance :> _
}
|> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken)
8 changes: 4 additions & 4 deletions Navigation/FindReferencesService.fs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ type internal FSharpFindReferencesService
let lineNumber = sourceText.Lines.GetLinePosition(position).Line + 1
let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.FilePath, options.OtherOptions |> Seq.toList)

match CommonHelpers.tryClassifyAtPosition(document.Id, sourceText, document.FilePath, defines, position, SymbolSearchKind.IncludeRightColumn, context.CancellationToken) with
| Some (islandColumn, qualifiers, _) ->
let! symbolUse = checkFileResults.GetSymbolUseAtLocation(lineNumber, islandColumn, textLine, qualifiers)
match CommonHelpers.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Fuzzy) with
| Some symbol ->
let! symbolUse = checkFileResults.GetSymbolUseAtLocation(lineNumber, symbol.RightColumn, textLine, [symbol.Text])
match symbolUse with
| Some symbolUse ->
let! declaration = checkFileResults.GetDeclarationLocationAlternate (lineNumber, islandColumn, textLine, qualifiers, false)
let! declaration = checkFileResults.GetDeclarationLocationAlternate (lineNumber, symbol.RightColumn, textLine, [symbol.Text], false)
let declarationRange =
match declaration with
| FSharpFindDeclResult.DeclFound range -> Some range
Expand Down
10 changes: 5 additions & 5 deletions Navigation/GoToDefinitionService.fs
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,19 @@ type internal FSharpGoToDefinitionService
[<ImportMany>]presenters: IEnumerable<INavigableItemsPresenter>
) =

static member FindDefinition(checker: FSharpChecker, documentKey: DocumentId, sourceText: SourceText, filePath: string, position: int, defines: string list, options: FSharpProjectOptions, textVersionHash: int, cancellationToken: CancellationToken) : Async<Option<range>> =
static member FindDefinition(checker: FSharpChecker, documentKey: DocumentId, sourceText: SourceText, filePath: string, position: int, defines: string list, options: FSharpProjectOptions, textVersionHash: int) : Async<Option<range>> =
async {
let textLine = sourceText.Lines.GetLineFromPosition(position)
let textLinePos = sourceText.Lines.GetLinePosition(position)
let fcsTextLineNumber = textLinePos.Line + 1 // Roslyn line numbers are zero-based, FSharp.Compiler.Service line numbers are 1-based
match CommonHelpers.tryClassifyAtPosition(documentKey, sourceText, filePath, defines, position, SymbolSearchKind.IncludeRightColumn, cancellationToken) with
| Some (islandColumn, qualifiers, _) ->
match CommonHelpers.getSymbolAtPosition(documentKey, sourceText, position, filePath, defines, SymbolLookupKind.Fuzzy) with
| Some symbol ->
let! _parseResults, checkFileAnswer = checker.ParseAndCheckFileInProject(filePath, textVersionHash, sourceText.ToString(), options)
match checkFileAnswer with
| FSharpCheckFileAnswer.Aborted -> return None
| FSharpCheckFileAnswer.Succeeded(checkFileResults) ->

let! declarations = checkFileResults.GetDeclarationLocationAlternate (fcsTextLineNumber, islandColumn, textLine.ToString(), qualifiers, false)
let! declarations = checkFileResults.GetDeclarationLocationAlternate (fcsTextLineNumber, symbol.RightColumn, textLine.ToString(), [symbol.Text], false)

match declarations with
| FSharpFindDeclResult.DeclFound(range) -> return Some(range)
Expand All @@ -80,7 +80,7 @@ type internal FSharpGoToDefinitionService
let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask
let! textVersion = document.GetTextVersionAsync(cancellationToken) |> Async.AwaitTask
let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, options.OtherOptions |> Seq.toList)
let! definition = FSharpGoToDefinitionService.FindDefinition(checkerProvider.Checker, document.Id, sourceText, document.FilePath, position, defines, options, textVersion.GetHashCode(), cancellationToken)
let! definition = FSharpGoToDefinitionService.FindDefinition(checkerProvider.Checker, document.Id, sourceText, document.FilePath, position, defines, options, textVersion.GetHashCode())

match definition with
| Some(range) ->
Expand Down
Loading

0 comments on commit 25162a8

Please sign in to comment.