From 57b7bbbd529c0d2bccbec01dd9c69d6f1be00b80 Mon Sep 17 00:00:00 2001 From: Vasily Kirichenko Date: Sat, 3 Dec 2016 13:19:33 +0300 Subject: [PATCH 1/2] do not throw exception if LanguageDebugInfoService.GetDataTipInfoAsync do not run to completion --- .../FSharp.Editor/LanguageDebugInfoService.fs | 43 ++++++++----------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/LanguageDebugInfoService.fs b/vsintegration/src/FSharp.Editor/LanguageDebugInfoService.fs index e512e4d8abb..7468941a2f7 100644 --- a/vsintegration/src/FSharp.Editor/LanguageDebugInfoService.fs +++ b/vsintegration/src/FSharp.Editor/LanguageDebugInfoService.fs @@ -4,29 +4,17 @@ namespace Microsoft.VisualStudio.FSharp.Editor open System open System.Composition -open System.Collections.Concurrent open System.Collections.Generic open System.Threading open System.Threading.Tasks -open System.Linq open Microsoft.CodeAnalysis open Microsoft.CodeAnalysis.Classification -open Microsoft.CodeAnalysis.Editor open Microsoft.CodeAnalysis.Editor.Implementation.Debugging -open Microsoft.CodeAnalysis.Editor.Implementation -open Microsoft.CodeAnalysis.Editor.Shared.Utilities -open Microsoft.CodeAnalysis.Formatting open Microsoft.CodeAnalysis.Host.Mef open Microsoft.CodeAnalysis.Text open Microsoft.VisualStudio.FSharp.LanguageService -open Microsoft.VisualStudio.Text -open Microsoft.VisualStudio.Text.Tagging - -open Microsoft.FSharp.Compiler.Parser -open Microsoft.FSharp.Compiler.SourceCodeServices -open Microsoft.FSharp.Compiler.Range [] [, FSharpCommonConstants.FSharpLanguageName)>] @@ -45,10 +33,10 @@ type internal FSharpLanguageDebugInfoService let token = tokens.[tokenIndex.Value] match token.ClassificationType with - + | ClassificationTypeNames.StringLiteral -> Some(token.TextSpan) - + | ClassificationTypeNames.Identifier -> let textLine = sourceText.Lines.GetLineFromPosition(position) let textLinePos = sourceText.Lines.GetLinePosition(position) @@ -58,10 +46,9 @@ type internal FSharpLanguageDebugInfoService | Some(island, islandEnd, _) -> let islandDocumentStart = textLine.Start + islandEnd - island.Length Some(TextSpan.FromBounds(islandDocumentStart, islandDocumentStart + island.Length)) - + | _ -> None - interface ILanguageDebugInfoService with // FSROSLYNTODO: This is used to get function names in breakpoint window. It should return fully qualified function name and line offset from the start of the function. @@ -69,16 +56,20 @@ type internal FSharpLanguageDebugInfoService Task.FromResult(Unchecked.defaultof) member this.GetDataTipInfoAsync(document: Document, position: int, cancellationToken: CancellationToken): Task = - async { + let computation = + async { let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) - let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask - let textSpan = TextSpan.FromBounds(0, sourceText.Length) - let tokens = CommonHelpers.getColorizationData(document.Id, sourceText, textSpan, Some(document.Name), defines, cancellationToken) - let result = - match FSharpLanguageDebugInfoService.GetDataTipInformation(sourceText, position, tokens) with - | None -> DebugDataTipInfo() - | Some(textSpan) -> DebugDataTipInfo(textSpan, sourceText.GetSubText(textSpan).ToString()) - return result - } |> CommonRoslynHelpers.StartAsyncAsTask cancellationToken + let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask + let textSpan = TextSpan.FromBounds(0, sourceText.Length) + let tokens = CommonHelpers.getColorizationData(document.Id, sourceText, textSpan, Some(document.Name), defines, cancellationToken) + let result = + match FSharpLanguageDebugInfoService.GetDataTipInformation(sourceText, position, tokens) with + | None -> + DebugDataTipInfo() + | Some textSpan -> + DebugDataTipInfo(textSpan, sourceText.GetSubText(textSpan).ToString()) + return result + } + Async.StartAsTask(computation, TaskCreationOptions.None, cancellationToken) \ No newline at end of file From b02f6b3d3c6e1374038be113fc06b914de3940bc Mon Sep 17 00:00:00 2001 From: Vasily Kirichenko Date: Sun, 4 Dec 2016 10:39:29 +0300 Subject: [PATCH 2/2] CommonRoslynHelpers.StartAsyncAsTask catches exceptions and transform them to Assert.Exception instead of reraising --- .../src/FSharp.Editor/CommonRoslynHelpers.fs | 10 +++++-- .../FSharp.Editor/LanguageDebugInfoService.fs | 27 +++++++++---------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/CommonRoslynHelpers.fs b/vsintegration/src/FSharp.Editor/CommonRoslynHelpers.fs index 8e9bc510eb0..ed4a279dc0d 100644 --- a/vsintegration/src/FSharp.Editor/CommonRoslynHelpers.fs +++ b/vsintegration/src/FSharp.Editor/CommonRoslynHelpers.fs @@ -20,7 +20,6 @@ module internal CommonRoslynHelpers = let endPosition = sourceText.Lines.[range.EndLine - 1].Start + range.EndColumn TextSpan(startPosition, endPosition - startPosition) - let GetCompletedTaskResult(task: Task<'TResult>) = if task.Status = TaskStatus.RanToCompletion then task.Result @@ -29,8 +28,15 @@ module internal CommonRoslynHelpers = raise(task.Exception.GetBaseException()) let StartAsyncAsTask cancellationToken computation = + let computation = + async { + try + return! computation + with e -> + Assert.Exception(e) + return Unchecked.defaultof<_> + } Async.StartAsTask(computation, TaskCreationOptions.None, cancellationToken) - .ContinueWith(GetCompletedTaskResult, cancellationToken) let StartAsyncUnitAsTask cancellationToken (computation:Async) = StartAsyncAsTask cancellationToken computation :> Task diff --git a/vsintegration/src/FSharp.Editor/LanguageDebugInfoService.fs b/vsintegration/src/FSharp.Editor/LanguageDebugInfoService.fs index 7468941a2f7..6da1a0092d2 100644 --- a/vsintegration/src/FSharp.Editor/LanguageDebugInfoService.fs +++ b/vsintegration/src/FSharp.Editor/LanguageDebugInfoService.fs @@ -56,20 +56,19 @@ type internal FSharpLanguageDebugInfoService Task.FromResult(Unchecked.defaultof) member this.GetDataTipInfoAsync(document: Document, position: int, cancellationToken: CancellationToken): Task = - let computation = - async { + async { let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) - let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask - let textSpan = TextSpan.FromBounds(0, sourceText.Length) - let tokens = CommonHelpers.getColorizationData(document.Id, sourceText, textSpan, Some(document.Name), defines, cancellationToken) - let result = - match FSharpLanguageDebugInfoService.GetDataTipInformation(sourceText, position, tokens) with - | None -> - DebugDataTipInfo() - | Some textSpan -> - DebugDataTipInfo(textSpan, sourceText.GetSubText(textSpan).ToString()) - return result - } - Async.StartAsTask(computation, TaskCreationOptions.None, cancellationToken) + let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask + let textSpan = TextSpan.FromBounds(0, sourceText.Length) + let tokens = CommonHelpers.getColorizationData(document.Id, sourceText, textSpan, Some(document.Name), defines, cancellationToken) + let result = + match FSharpLanguageDebugInfoService.GetDataTipInformation(sourceText, position, tokens) with + | None -> + DebugDataTipInfo() + | Some textSpan -> + DebugDataTipInfo(textSpan, sourceText.GetSubText(textSpan).ToString()) + return result + } + |> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken) \ No newline at end of file