Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ type internal FSharpColorizationService
let colorizationData = checkResults.GetSemanticClassification (Some targetRange) |> Array.distinctBy fst

for (range, classificationType) in colorizationData do
let span = Tokenizer.fixupSpan(sourceText, RoslynHelpers.FSharpRangeToTextSpan(sourceText, range))
result.Add(ClassifiedSpan(span, FSharpClassificationTypes.getClassificationTypeName(classificationType)))
match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range) with
| None -> ()
| Some span ->
let span = Tokenizer.fixupSpan(sourceText, span)
result.Add(ClassifiedSpan(span, FSharpClassificationTypes.getClassificationTypeName(classificationType)))
}
|> Async.Ignore |> RoslynHelpers.StartAsyncUnitAsTask cancellationToken

Expand Down
4 changes: 2 additions & 2 deletions vsintegration/src/FSharp.Editor/Common/RoslynHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ module internal RoslynHelpers =

let FSharpRangeToTextSpan(sourceText: SourceText, range: range) =
// Roslyn TextLineCollection is zero-based, F# range lines are one-based
let startPosition = sourceText.Lines.[range.StartLine - 1].Start + range.StartColumn
let endPosition = sourceText.Lines.[range.EndLine - 1].Start + range.EndColumn
let startPosition = sourceText.Lines.[max 0 (range.StartLine - 1)].Start + range.StartColumn
let endPosition = sourceText.Lines.[min (range.EndLine - 1) (sourceText.Lines.Count - 1)].Start + range.EndColumn
TextSpan(startPosition, endPosition - startPosition)

let TryFSharpRangeToTextSpan(sourceText: SourceText, range: range) : TextSpan option =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ type internal FSharpBreakpointResolutionService
let! options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document)
let! sourceText = document.GetTextAsync(cancellationToken)
let! range = FSharpBreakpointResolutionService.GetBreakpointLocation(checkerProvider.Checker, sourceText, document.Name, textSpan, options)
return BreakpointResolutionResult.CreateSpanResult(document, RoslynHelpers.FSharpRangeToTextSpan(sourceText, range))
let! span = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range)
return BreakpointResolutionResult.CreateSpanResult(document, span)
}
|> Async.map Option.toObj
|> RoslynHelpers.StartAsyncAsTask cancellationToken
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,11 @@ type internal FSharpDocumentHighlightsService [<ImportingConstructor>] (checkerP
let! symbolUses = checkFileResults.GetUsesOfSymbolInFile(symbolUse.Symbol) |> liftAsync
return
[| for symbolUse in symbolUses do
yield { IsDefinition = symbolUse.IsFromDefinition
TextSpan = RoslynHelpers.FSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate) } |]
match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate) with
| None -> ()
| Some span ->
yield { IsDefinition = symbolUse.IsFromDefinition
TextSpan = span } |]
|> fixInvalidSymbolSpans sourceText symbol.Ident.idText
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ type internal FSharpBraceMatchingService
static member GetBraceMatchingResult(checker: FSharpChecker, sourceText, fileName, options, position: int) =
async {
let! matchedBraces = checker.MatchBraces(fileName, sourceText.ToString(), options, userOpName = userOpName)
let isPositionInRange range = RoslynHelpers.FSharpRangeToTextSpan(sourceText, range).Contains(position)
let isPositionInRange range =
match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range) with
| None -> false
| Some range -> range.Contains(position)
return matchedBraces |> Array.tryFind(fun (left, right) -> isPositionInRange left || isPositionInRange right)
}

Expand All @@ -29,10 +32,9 @@ type internal FSharpBraceMatchingService
let! options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document)
let! sourceText = document.GetTextAsync(cancellationToken)
let! (left, right) = FSharpBraceMatchingService.GetBraceMatchingResult(checkerProvider.Checker, sourceText, document.Name, options, position)
return
BraceMatchingResult(
RoslynHelpers.FSharpRangeToTextSpan(sourceText, left),
RoslynHelpers.FSharpRangeToTextSpan(sourceText, right))
let! leftSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, left)
let! rightSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, right)
return BraceMatchingResult(leftSpan, rightSpan)
}
|> Async.map Option.toNullable
|> RoslynHelpers.StartAsyncAsTask cancellationToken
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ type internal InlineRenameInfo
checker: FSharpChecker,
projectInfoManager: ProjectInfoManager,
document: Document,
sourceText: SourceText,
triggerSpan: TextSpan,
lexerSymbol: LexerSymbol,
symbolUse: FSharpSymbolUse,
declLoc: SymbolDeclarationLocation,
Expand All @@ -89,10 +89,6 @@ type internal InlineRenameInfo
| true, text -> text
| _ -> document.GetTextAsync(cancellationToken).Result

let triggerSpan =
let span = RoslynHelpers.FSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate)
Tokenizer.fixupSpan(sourceText, span)

let symbolUses =
SymbolHelpers.getSymbolUsesInSolution(symbolUse.Symbol, declLoc, checkFileResults, projectInfoManager, checker, document.Project.Solution, userOpName)
|> Async.cache
Expand Down Expand Up @@ -126,9 +122,12 @@ type internal InlineRenameInfo
let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask
let locations =
symbolUses
|> Array.map (fun symbolUse ->
let textSpan = Tokenizer.fixupSpan(sourceText, RoslynHelpers.FSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate))
InlineRenameLocation(document, textSpan))
|> Array.choose (fun symbolUse ->
RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate)
|> Option.map (fun span ->
let textSpan = Tokenizer.fixupSpan(sourceText, span)
InlineRenameLocation(document, textSpan)))

return { Document = document; Locations = locations }
})
|> Async.Parallel
Expand Down Expand Up @@ -158,7 +157,11 @@ type internal InlineRenameService
let! _, _, checkFileResults = checker.ParseAndCheckDocument(document, options, allowStaleResults = true, userOpName = userOpName)
let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, symbol.Ident.idRange.EndColumn, textLine.Text.ToString(), symbol.FullIsland, userOpName=userOpName)
let! declLoc = symbolUse.GetDeclarationLocation(document)
return InlineRenameInfo(checker, projectInfoManager, document, sourceText, symbol, symbolUse, declLoc, checkFileResults) :> IInlineRenameInfo

let! span = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate)
let triggerSpan = Tokenizer.fixupSpan(sourceText, span)

return InlineRenameInfo(checker, projectInfoManager, document, triggerSpan, symbol, symbolUse, declLoc, checkFileResults) :> IInlineRenameInfo
}

interface IEditorInlineRenameService with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,12 @@ module internal SymbolHelpers =
let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask
let mutable sourceText = sourceText
for symbolUse in symbolUses do
let textSpan = Tokenizer.fixupSpan(sourceText, RoslynHelpers.FSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate))
sourceText <- sourceText.Replace(textSpan, newText)
solution <- solution.WithDocumentText(documentId, sourceText)
match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate) with
| None -> ()
| Some span ->
let textSpan = Tokenizer.fixupSpan(sourceText, span)
sourceText <- sourceText.Replace(textSpan, newText)
solution <- solution.WithDocumentText(documentId, sourceText)
return solution
} |> RoslynHelpers.StartAsyncAsTask cancellationToken),
originalText
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: Project
let refDocument = document.Project.Solution.GetDocument refDocumentId
let! cancellationToken = Async.CancellationToken
let! refSourceText = refDocument.GetTextAsync(cancellationToken) |> Async.AwaitTask
let refTextSpan = RoslynHelpers.FSharpRangeToTextSpan (refSourceText, range)
return Some (FSharpNavigableItem (refDocument, refTextSpan))
match RoslynHelpers.TryFSharpRangeToTextSpan (refSourceText, range) with
| None -> return None
| Some refTextSpan -> return Some (FSharpNavigableItem (refDocument, refTextSpan))
else return None
}

Expand All @@ -59,7 +60,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: Project
asyncMaybe {
let! projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject originDocument
let defines = CompilerEnvironment.GetCompilationDefinesForEditing (originDocument.FilePath, projectOptions.OtherOptions |> Seq.toList)
let originTextSpan = RoslynHelpers.FSharpRangeToTextSpan (sourceText, originRange)
let! originTextSpan = RoslynHelpers.TryFSharpRangeToTextSpan (sourceText, originRange)
let position = originTextSpan.Start
let! lexerSymbol = Tokenizer.getSymbolAtPosition (originDocument.Id, sourceText, position, originDocument.FilePath, defines, SymbolLookupKind.Greedy, false)

Expand All @@ -83,7 +84,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: Project
let! _, _, checkFileResults = checker.ParseAndCheckDocument (implDoc, projectOptions, allowStaleResults=true, sourceText=implSourceText, userOpName = userOpName)
let! symbolUses = checkFileResults.GetUsesOfSymbolInFile symbol |> liftAsync
let! implSymbol = symbolUses |> Array.tryHead
let implTextSpan = RoslynHelpers.FSharpRangeToTextSpan (implSourceText, implSymbol.RangeAlternate)
let! implTextSpan = RoslynHelpers.TryFSharpRangeToTextSpan (implSourceText, implSymbol.RangeAlternate)
return FSharpNavigableItem (implDoc, implTextSpan)
else
let! targetDocument = originDocument.Project.Solution.TryGetDocumentFromFSharpRange fsSymbolUse.RangeAlternate
Expand Down Expand Up @@ -241,7 +242,7 @@ type internal FSharpGoToDefinitionService
let! targetRange =
gotoDefinition.FindSymbolDeclarationInFile(targetSymbolUse, implFilePath, implSourceText.ToString(), projectOptions, implVersion.GetHashCode())

let implTextSpan = RoslynHelpers.FSharpRangeToTextSpan (implSourceText, targetRange)
let! implTextSpan = RoslynHelpers.TryFSharpRangeToTextSpan (implSourceText, targetRange)
let navItem = FSharpNavigableItem (implDocument, implTextSpan)
return navItem
else // jump from implementation to the corresponding signature
Expand All @@ -250,7 +251,7 @@ type internal FSharpGoToDefinitionService
| FSharpFindDeclResult.DeclFound targetRange ->
let! sigDocument = originDocument.Project.Solution.TryGetDocumentFromPath targetRange.FileName
let! sigSourceText = sigDocument.GetTextAsync () |> liftTaskAsync
let sigTextSpan = RoslynHelpers.FSharpRangeToTextSpan (sigSourceText, targetRange)
let! sigTextSpan = RoslynHelpers.TryFSharpRangeToTextSpan (sigSourceText, targetRange)
let navItem = FSharpNavigableItem (sigDocument, sigTextSpan)
return navItem
| _ -> return! None
Expand All @@ -260,7 +261,7 @@ type internal FSharpGoToDefinitionService
else
let! sigDocument = originDocument.Project.Solution.TryGetDocumentFromPath targetRange.FileName
let! sigSourceText = sigDocument.GetTextAsync () |> liftTaskAsync
let sigTextSpan = RoslynHelpers.FSharpRangeToTextSpan (sigSourceText, targetRange)
let! sigTextSpan = RoslynHelpers.TryFSharpRangeToTextSpan (sigSourceText, targetRange)
// if the gotodef call originated from a signature and the returned target is a signature, navigate there
if isSignatureFile targetRange.FileName && preferSignature then
let navItem = FSharpNavigableItem (sigDocument, sigTextSpan)
Expand All @@ -280,7 +281,7 @@ type internal FSharpGoToDefinitionService
let! targetRange =
gotoDefinition.FindSymbolDeclarationInFile(targetSymbolUse, implFilePath, implSourceText.ToString(), projectOptions, implVersion.GetHashCode())

let implTextSpan = RoslynHelpers.FSharpRangeToTextSpan (implSourceText, targetRange)
let! implTextSpan = RoslynHelpers.TryFSharpRangeToTextSpan (implSourceText, targetRange)
let navItem = FSharpNavigableItem (implDocument, implTextSpan)
return navItem
| _ -> return! None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,13 @@ type internal FSharpNavigateToSearchService
match parseResults.ParseTree |> Option.map NavigateTo.getNavigableItems with
| Some items ->
[| for item in items do
let sourceSpan = RoslynHelpers.FSharpRangeToTextSpan(sourceText, item.Range)
let glyph = Utils.navigateToItemKindToGlyph item.Kind
let kind = Utils.navigateToItemKindToRoslynKind item.Kind
let additionalInfo = Utils.containerToString item.Container document.Project
yield NavigableItem(document, sourceSpan, glyph, item.Name, kind, additionalInfo) |]
match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, item.Range) with
| None -> ()
| Some sourceSpan ->
let glyph = Utils.navigateToItemKindToGlyph item.Kind
let kind = Utils.navigateToItemKindToRoslynKind item.Kind
let additionalInfo = Utils.containerToString item.Container document.Project
yield NavigableItem(document, sourceSpan, glyph, item.Name, kind, additionalInfo) |]
| None -> [||]
}

Expand Down
10 changes: 6 additions & 4 deletions vsintegration/src/FSharp.Editor/QuickInfo/QuickInfoProvider.fs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ module private FSharpQuickInfo =
let! extDocId = solution.GetDocumentIdsWithFilePath declRange.FileName |> Seq.tryHead
let extDocument = solution.GetProject(extDocId.ProjectId).GetDocument extDocId
let! extSourceText = extDocument.GetTextAsync cancellationToken
let extSpan = RoslynHelpers.FSharpRangeToTextSpan (extSourceText, declRange)
let! extSpan = RoslynHelpers.TryFSharpRangeToTextSpan (extSourceText, declRange)
let extLineText = (extSourceText.Lines.GetLineFromPosition extSpan.Start).ToString()

// project options need to be retrieved because the signature file could be in another project
Expand All @@ -69,9 +69,10 @@ module private FSharpQuickInfo =
| extTooltipText ->
let! extSymbolUse =
extCheckFileResults.GetSymbolUseAtLocation(declRange.StartLine, extLexerSymbol.Ident.idRange.EndColumn, extLineText, extLexerSymbol.FullIsland, userOpName=userOpName)
let! span = RoslynHelpers.TryFSharpRangeToTextSpan (extSourceText, extLexerSymbol.Range)

return { StructuredText = extTooltipText
Span = RoslynHelpers.FSharpRangeToTextSpan (extSourceText, extLexerSymbol.Range)
Span = span
Symbol = extSymbolUse.Symbol
SymbolKind = extLexerSymbol.Kind }
}
Expand Down Expand Up @@ -110,7 +111,7 @@ module private FSharpQuickInfo =
| FSharpToolTipText []
| FSharpToolTipText [FSharpStructuredToolTipElement.None] -> return! None
| _ ->
let targetTextSpan = RoslynHelpers.FSharpRangeToTextSpan (sourceText, lexerSymbol.Range)
let! targetTextSpan = RoslynHelpers.TryFSharpRangeToTextSpan (sourceText, lexerSymbol.Range)
return { StructuredText = targetTooltip
Span = targetTextSpan
Symbol = symbolUse.Symbol
Expand Down Expand Up @@ -180,7 +181,8 @@ type internal FSharpQuickInfoProvider
| FSharpToolTipText [FSharpStructuredToolTipElement.None] -> return! None
| _ ->
let! symbolUse = checkFileResults.GetSymbolUseAtLocation (textLineNumber, symbol.Ident.idRange.EndColumn, textLine.ToString(), symbol.FullIsland, userOpName=FSharpQuickInfo.userOpName)
return res, RoslynHelpers.FSharpRangeToTextSpan (sourceText, symbol.Range), symbolUse.Symbol, symbol.Kind
let! symbolSpan = RoslynHelpers.TryFSharpRangeToTextSpan (sourceText, symbol.Range)
return res, symbolSpan, symbolUse.Symbol, symbol.Kind
}

interface IQuickInfoProvider with
Expand Down