提交 fbf7ea0c 编写于 作者: J Jared Hester 提交者: Kevin Ransom (msft)

Editor refactor (#2780)

* split out language service into dedicated dir

* dedicated extensions module

* trim pervasive

* rename constants

* symbols module

* typedastutils module

* FSharpChecker extensions

* rename roslyn helpers

* editor rename cleanup

* fix test renaming
上级 8cfd8878
...@@ -5,7 +5,7 @@ open Microsoft.CodeAnalysis.Host.Mef ...@@ -5,7 +5,7 @@ open Microsoft.CodeAnalysis.Host.Mef
open System.Composition open System.Composition
[<Shared>] [<Shared>]
[<ExportLanguageService(typeof<ICommentUncommentService>, FSharpCommonConstants.FSharpLanguageName)>] [<ExportLanguageService(typeof<ICommentUncommentService>, FSharpConstants.FSharpLanguageName)>]
type CommentUncommentService() = type CommentUncommentService() =
interface ICommentUncommentService with interface ICommentUncommentService with
member this.SingleLineCommentString = "//" member this.SingleLineCommentString = "//"
......
...@@ -14,7 +14,7 @@ open Microsoft.CodeAnalysis.Text ...@@ -14,7 +14,7 @@ open Microsoft.CodeAnalysis.Text
open Microsoft.FSharp.Compiler.SourceCodeServices open Microsoft.FSharp.Compiler.SourceCodeServices
[<ExportLanguageService(typeof<IEditorClassificationService>, FSharpCommonConstants.FSharpLanguageName)>] [<ExportLanguageService(typeof<IEditorClassificationService>, FSharpConstants.FSharpLanguageName)>]
type internal FSharpColorizationService type internal FSharpColorizationService
[<ImportingConstructor>] [<ImportingConstructor>]
( (
...@@ -30,8 +30,8 @@ type internal FSharpColorizationService ...@@ -30,8 +30,8 @@ type internal FSharpColorizationService
async { async {
let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document)
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
result.AddRange(CommonHelpers.getColorizationData(document.Id, sourceText, textSpan, Some(document.FilePath), defines, cancellationToken)) result.AddRange(Tokenizer.getColorizationData(document.Id, sourceText, textSpan, Some(document.FilePath), defines, cancellationToken))
} |> CommonRoslynHelpers.StartAsyncUnitAsTask cancellationToken } |> RoslynHelpers.StartAsyncUnitAsTask cancellationToken
member this.AddSemanticClassificationsAsync(document: Document, textSpan: TextSpan, result: List<ClassifiedSpan>, cancellationToken: CancellationToken) = member this.AddSemanticClassificationsAsync(document: Document, textSpan: TextSpan, result: List<ClassifiedSpan>, cancellationToken: CancellationToken) =
asyncMaybe { asyncMaybe {
...@@ -39,14 +39,14 @@ type internal FSharpColorizationService ...@@ -39,14 +39,14 @@ type internal FSharpColorizationService
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let! _, _, checkResults = checkerProvider.Checker.ParseAndCheckDocument(document, options, sourceText = sourceText, allowStaleResults = false) let! _, _, checkResults = checkerProvider.Checker.ParseAndCheckDocument(document, options, sourceText = sourceText, allowStaleResults = false)
// it's crucial to not return duplicated or overlapping `ClassifiedSpan`s because Find Usages service crashes. // it's crucial to not return duplicated or overlapping `ClassifiedSpan`s because Find Usages service crashes.
let targetRange = CommonRoslynHelpers.TextSpanToFSharpRange(document.FilePath, textSpan, sourceText) let targetRange = RoslynHelpers.TextSpanToFSharpRange(document.FilePath, textSpan, sourceText)
let colorizationData = checkResults.GetSemanticClassification (Some targetRange) |> Array.distinctBy fst let colorizationData = checkResults.GetSemanticClassification (Some targetRange) |> Array.distinctBy fst
for (range, classificationType) in colorizationData do for (range, classificationType) in colorizationData do
let span = CommonHelpers.fixupSpan(sourceText, CommonRoslynHelpers.FSharpRangeToTextSpan(sourceText, range)) let span = Tokenizer.fixupSpan(sourceText, RoslynHelpers.FSharpRangeToTextSpan(sourceText, range))
result.Add(ClassifiedSpan(span, FSharpClassificationTypes.getClassificationTypeName(classificationType))) result.Add(ClassifiedSpan(span, FSharpClassificationTypes.getClassificationTypeName(classificationType)))
} }
|> Async.Ignore |> CommonRoslynHelpers.StartAsyncUnitAsTask cancellationToken |> Async.Ignore |> RoslynHelpers.StartAsyncUnitAsTask cancellationToken
// Do not perform classification if we don't have project options (#defines matter) // Do not perform classification if we don't have project options (#defines matter)
member this.AdjustStaleClassification(_: SourceText, classifiedSpan: ClassifiedSpan) : ClassifiedSpan = classifiedSpan member this.AdjustStaleClassification(_: SourceText, classifiedSpan: ClassifiedSpan) : ClassifiedSpan = classifiedSpan
......
...@@ -11,7 +11,7 @@ open Microsoft.CodeAnalysis.Text ...@@ -11,7 +11,7 @@ open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.CodeFixes open Microsoft.CodeAnalysis.CodeFixes
open Microsoft.CodeAnalysis.CodeActions open Microsoft.CodeAnalysis.CodeActions
[<ExportCodeFixProvider(FSharpCommonConstants.FSharpLanguageName, Name = "AddNewKeyword"); Shared>] [<ExportCodeFixProvider(FSharpConstants.FSharpLanguageName, Name = "AddNewKeyword"); Shared>]
type internal FSharpAddNewKeywordCodeFixProvider() = type internal FSharpAddNewKeywordCodeFixProvider() =
inherit CodeFixProvider() inherit CodeFixProvider()
...@@ -27,7 +27,7 @@ type internal FSharpAddNewKeywordCodeFixProvider() = ...@@ -27,7 +27,7 @@ type internal FSharpAddNewKeywordCodeFixProvider() =
async { async {
let! sourceText = context.Document.GetTextAsync() let! sourceText = context.Document.GetTextAsync()
return context.Document.WithText(sourceText.WithChanges(TextChange(TextSpan(context.Span.Start, 0), "new "))) return context.Document.WithText(sourceText.WithChanges(TextChange(TextSpan(context.Span.Start, 0), "new ")))
} |> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken)), } |> RoslynHelpers.StartAsyncAsTask(cancellationToken)),
title), context.Diagnostics |> Seq.filter (fun x -> this.FixableDiagnosticIds.Contains x.Id) |> Seq.toImmutableArray) title), context.Diagnostics |> Seq.filter (fun x -> this.FixableDiagnosticIds.Contains x.Id) |> Seq.toImmutableArray)
} |> CommonRoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) } |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken)
\ No newline at end of file
...@@ -17,7 +17,7 @@ open Microsoft.FSharp.Compiler.Range ...@@ -17,7 +17,7 @@ open Microsoft.FSharp.Compiler.Range
open Microsoft.FSharp.Compiler.SourceCodeServices open Microsoft.FSharp.Compiler.SourceCodeServices
open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
[<ExportCodeFixProvider(FSharpCommonConstants.FSharpLanguageName, Name = "AddOpen"); Shared>] [<ExportCodeFixProvider(FSharpConstants.FSharpLanguageName, Name = "AddOpen"); Shared>]
type internal FSharpAddOpenCodeFixProvider type internal FSharpAddOpenCodeFixProvider
[<ImportingConstructor>] [<ImportingConstructor>]
( (
...@@ -38,7 +38,7 @@ type internal FSharpAddOpenCodeFixProvider ...@@ -38,7 +38,7 @@ type internal FSharpAddOpenCodeFixProvider
async { async {
let! sourceText = context.Document.GetTextAsync() let! sourceText = context.Document.GetTextAsync()
return context.Document.WithText(sourceText.Replace(context.Span, qualifier)) return context.Document.WithText(sourceText.Replace(context.Span, qualifier))
} |> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken)) } |> RoslynHelpers.StartAsyncAsTask(cancellationToken))
let openNamespaceFix (context: CodeFixContext) ctx name ns multipleNames = let openNamespaceFix (context: CodeFixContext) ctx name ns multipleNames =
let displayText = "open " + ns + if multipleNames then " (" + name + ")" else "" let displayText = "open " + ns + if multipleNames then " (" + name + ")" else ""
...@@ -50,7 +50,7 @@ type internal FSharpAddOpenCodeFixProvider ...@@ -50,7 +50,7 @@ type internal FSharpAddOpenCodeFixProvider
let! sourceText = context.Document.GetTextAsync() let! sourceText = context.Document.GetTextAsync()
let changedText, _ = OpenDeclarationHelper.insertOpenDeclaration sourceText ctx ns let changedText, _ = OpenDeclarationHelper.insertOpenDeclaration sourceText ctx ns
return context.Document.WithText(changedText) return context.Document.WithText(changedText)
} |> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken)), } |> RoslynHelpers.StartAsyncAsTask(cancellationToken)),
displayText) displayText)
let getSuggestions (context: CodeFixContext) (candidates: (Entity * InsertContext) list) : unit = let getSuggestions (context: CodeFixContext) (candidates: (Entity * InsertContext) list) : unit =
...@@ -101,7 +101,7 @@ type internal FSharpAddOpenCodeFixProvider ...@@ -101,7 +101,7 @@ type internal FSharpAddOpenCodeFixProvider
let! symbol = let! symbol =
asyncMaybe { asyncMaybe {
let! lexerSymbol = CommonHelpers.getSymbolAtPosition(document.Id, sourceText, context.Span.End, document.FilePath, defines, SymbolLookupKind.Greedy) let! lexerSymbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, context.Span.End, document.FilePath, defines, Tokenizer.SymbolLookupKind.Greedy)
return! checkResults.GetSymbolUseAtLocation(Line.fromZ linePos.Line, lexerSymbol.Ident.idRange.EndColumn, line.ToString(), lexerSymbol.FullIsland) return! checkResults.GetSymbolUseAtLocation(Line.fromZ linePos.Line, lexerSymbol.Ident.idRange.EndColumn, line.ToString(), lexerSymbol.FullIsland)
} |> liftAsync } |> liftAsync
...@@ -145,5 +145,5 @@ type internal FSharpAddOpenCodeFixProvider ...@@ -145,5 +145,5 @@ type internal FSharpAddOpenCodeFixProvider
return entities |> Seq.map createEntity |> Seq.concat |> Seq.toList |> getSuggestions context return entities |> Seq.map createEntity |> Seq.concat |> Seq.toList |> getSuggestions context
} }
|> Async.Ignore |> Async.Ignore
|> CommonRoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken)
\ No newline at end of file
...@@ -24,7 +24,7 @@ type internal InterfaceState = ...@@ -24,7 +24,7 @@ type internal InterfaceState =
AppendBracketAt: int option AppendBracketAt: int option
Tokens: FSharpTokenInfo list } Tokens: FSharpTokenInfo list }
[<ExportCodeFixProvider(FSharpCommonConstants.FSharpLanguageName, Name = "ImplementInterface"); Shared>] [<ExportCodeFixProvider(FSharpConstants.FSharpLanguageName, Name = "ImplementInterface"); Shared>]
type internal FSharpImplementInterfaceCodeFixProvider type internal FSharpImplementInterfaceCodeFixProvider
[<ImportingConstructor>] [<ImportingConstructor>]
( (
...@@ -125,7 +125,7 @@ type internal FSharpImplementInterfaceCodeFixProvider ...@@ -125,7 +125,7 @@ type internal FSharpImplementInterfaceCodeFixProvider
InterfaceStubGenerator.getImplementedMemberSignatures getMemberByLocation displayContext state.InterfaceData InterfaceStubGenerator.getImplementedMemberSignatures getMemberByLocation displayContext state.InterfaceData
let newSourceText = applyImplementInterface sourceText state displayContext implementedMemberSignatures entity indentSize verboseMode let newSourceText = applyImplementInterface sourceText state displayContext implementedMemberSignatures entity indentSize verboseMode
return context.Document.WithText(newSourceText) return context.Document.WithText(newSourceText)
} |> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken)), } |> RoslynHelpers.StartAsyncAsTask(cancellationToken)),
title) title)
context.RegisterCodeFix(codeAction, diagnostics) context.RegisterCodeFix(codeAction, diagnostics)
...@@ -146,7 +146,7 @@ type internal FSharpImplementInterfaceCodeFixProvider ...@@ -146,7 +146,7 @@ type internal FSharpImplementInterfaceCodeFixProvider
let defines = CompilerEnvironment.GetCompilationDefinesForEditing(context.Document.FilePath, options.OtherOptions |> Seq.toList) let defines = CompilerEnvironment.GetCompilationDefinesForEditing(context.Document.FilePath, options.OtherOptions |> Seq.toList)
// Notice that context.Span doesn't return reliable ranges to find tokens at exact positions. // Notice that context.Span doesn't return reliable ranges to find tokens at exact positions.
// That's why we tokenize the line and try to find the last successive identifier token // That's why we tokenize the line and try to find the last successive identifier token
let tokens = CommonHelpers.tokenizeLine(context.Document.Id, sourceText, context.Span.Start, context.Document.FilePath, defines) let tokens = Tokenizer.tokenizeLine(context.Document.Id, sourceText, context.Span.Start, context.Document.FilePath, defines)
let startLeftColumn = context.Span.Start - textLine.Start let startLeftColumn = context.Span.Start - textLine.Start
let rec tryFindIdentifierToken acc tokens = let rec tryFindIdentifierToken acc tokens =
match tokens with match tokens with
...@@ -169,11 +169,11 @@ type internal FSharpImplementInterfaceCodeFixProvider ...@@ -169,11 +169,11 @@ type internal FSharpImplementInterfaceCodeFixProvider
| _ -> | _ ->
Some context.Span.End Some context.Span.End
let! interfaceState = queryInterfaceState appendBracketAt interfacePos tokens parsedInput let! interfaceState = queryInterfaceState appendBracketAt interfacePos tokens parsedInput
let! symbol = CommonHelpers.getSymbolAtPosition(context.Document.Id, sourceText, fixupPosition, context.Document.FilePath, defines, SymbolLookupKind.Greedy) let! symbol = Tokenizer.getSymbolAtPosition(context.Document.Id, sourceText, fixupPosition, context.Document.FilePath, defines, Tokenizer.SymbolLookupKind.Greedy)
let fcsTextLineNumber = textLine.LineNumber + 1 let fcsTextLineNumber = textLine.LineNumber + 1
let lineContents = textLine.ToString() let lineContents = textLine.ToString()
let! options = context.Document.GetOptionsAsync(cancellationToken) let! options = context.Document.GetOptionsAsync(cancellationToken)
let tabSize = options.GetOption(FormattingOptions.TabSize, FSharpCommonConstants.FSharpLanguageName) let tabSize = options.GetOption(FormattingOptions.TabSize, FSharpConstants.FSharpLanguageName)
let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, symbol.Ident.idRange.EndColumn, lineContents, symbol.FullIsland) let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, symbol.Ident.idRange.EndColumn, lineContents, symbol.FullIsland)
let! entity, displayContext = let! entity, displayContext =
match symbolUse.Symbol with match symbolUse.Symbol with
...@@ -185,4 +185,4 @@ type internal FSharpImplementInterfaceCodeFixProvider ...@@ -185,4 +185,4 @@ type internal FSharpImplementInterfaceCodeFixProvider
registerSuggestions (context, checkFileResults, interfaceState, displayContext, entity, tabSize) registerSuggestions (context, checkFileResults, interfaceState, displayContext, entity, tabSize)
} }
|> Async.Ignore |> Async.Ignore
|> CommonRoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken)
...@@ -13,7 +13,7 @@ open Microsoft.CodeAnalysis.CodeActions ...@@ -13,7 +13,7 @@ open Microsoft.CodeAnalysis.CodeActions
open Microsoft.FSharp.Compiler open Microsoft.FSharp.Compiler
[<ExportCodeFixProvider(FSharpCommonConstants.FSharpLanguageName, Name = "PrefixUnusedValueWithUnderscore"); Shared>] [<ExportCodeFixProvider(FSharpConstants.FSharpLanguageName, Name = "PrefixUnusedValueWithUnderscore"); Shared>]
type internal FSharpPrefixUnusedValueWithUnderscoreCodeFixProvider() = type internal FSharpPrefixUnusedValueWithUnderscoreCodeFixProvider() =
inherit CodeFixProvider() inherit CodeFixProvider()
let fixableDiagnosticIds = ["FS1182"] let fixableDiagnosticIds = ["FS1182"]
...@@ -25,7 +25,7 @@ type internal FSharpPrefixUnusedValueWithUnderscoreCodeFixProvider() = ...@@ -25,7 +25,7 @@ type internal FSharpPrefixUnusedValueWithUnderscoreCodeFixProvider() =
async { async {
let! sourceText = context.Document.GetTextAsync() let! sourceText = context.Document.GetTextAsync()
return context.Document.WithText(sourceText.WithChanges(textChange)) return context.Document.WithText(sourceText.WithChanges(textChange))
} |> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken)), } |> RoslynHelpers.StartAsyncAsTask(cancellationToken)),
title) title)
override __.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds override __.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds
...@@ -41,4 +41,4 @@ type internal FSharpPrefixUnusedValueWithUnderscoreCodeFixProvider() = ...@@ -41,4 +41,4 @@ type internal FSharpPrefixUnusedValueWithUnderscoreCodeFixProvider() =
let diagnostics = context.Diagnostics |> Seq.filter (fun x -> fixableDiagnosticIds |> List.contains x.Id) |> Seq.toImmutableArray let diagnostics = context.Diagnostics |> Seq.filter (fun x -> fixableDiagnosticIds |> List.contains x.Id) |> Seq.toImmutableArray
context.RegisterCodeFix(createCodeFix(SR.PrefixValueNameWithUnderscore.Value, context, TextChange(TextSpan(context.Span.Start, 0), "_")), diagnostics) context.RegisterCodeFix(createCodeFix(SR.PrefixValueNameWithUnderscore.Value, context, TextChange(TextSpan(context.Span.Start, 0), "_")), diagnostics)
context.RegisterCodeFix(createCodeFix(SR.RenameValueToUnderscore.Value, context, TextChange(context.Span, "_")), diagnostics) context.RegisterCodeFix(createCodeFix(SR.RenameValueToUnderscore.Value, context, TextChange(context.Span, "_")), diagnostics)
} |> CommonRoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) } |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken)
\ No newline at end of file \ No newline at end of file
...@@ -7,7 +7,7 @@ open System.Threading.Tasks ...@@ -7,7 +7,7 @@ open System.Threading.Tasks
open Microsoft.CodeAnalysis.CodeFixes open Microsoft.CodeAnalysis.CodeFixes
open Microsoft.CodeAnalysis.CodeActions open Microsoft.CodeAnalysis.CodeActions
[<ExportCodeFixProvider(FSharpCommonConstants.FSharpLanguageName, Name = "ProposeUpperCaseLabel"); Shared>] [<ExportCodeFixProvider(FSharpConstants.FSharpLanguageName, Name = "ProposeUpperCaseLabel"); Shared>]
type internal FSharpProposeUpperCaseLabelCodeFixProvider type internal FSharpProposeUpperCaseLabelCodeFixProvider
[<ImportingConstructor>] [<ImportingConstructor>]
( (
...@@ -27,4 +27,4 @@ type internal FSharpProposeUpperCaseLabelCodeFixProvider ...@@ -27,4 +27,4 @@ type internal FSharpProposeUpperCaseLabelCodeFixProvider
context.RegisterCodeFix( context.RegisterCodeFix(
CodeAction.Create(title, solutionChanger, title), CodeAction.Create(title, solutionChanger, title),
context.Diagnostics |> Seq.filter (fun x -> fixableDiagnosticIds |> List.contains x.Id) |> Seq.toImmutableArray) context.Diagnostics |> Seq.filter (fun x -> fixableDiagnosticIds |> List.contains x.Id) |> Seq.toImmutableArray)
} |> Async.Ignore |> CommonRoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) } |> Async.Ignore |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken)
\ No newline at end of file \ No newline at end of file
...@@ -14,7 +14,7 @@ open Microsoft.CodeAnalysis.CodeActions ...@@ -14,7 +14,7 @@ open Microsoft.CodeAnalysis.CodeActions
open Microsoft.FSharp.Compiler.Range open Microsoft.FSharp.Compiler.Range
[<ExportCodeFixProvider(FSharpCommonConstants.FSharpLanguageName, Name = "RemoveUnusedOpens"); Shared>] [<ExportCodeFixProvider(FSharpConstants.FSharpLanguageName, Name = "RemoveUnusedOpens"); Shared>]
type internal FSharpRemoveUnusedOpensCodeFixProvider type internal FSharpRemoveUnusedOpensCodeFixProvider
[<ImportingConstructor>] [<ImportingConstructor>]
( (
...@@ -44,7 +44,7 @@ type internal FSharpRemoveUnusedOpensCodeFixProvider ...@@ -44,7 +44,7 @@ type internal FSharpRemoveUnusedOpensCodeFixProvider
return document.WithText(sourceText.WithChanges(changes)) return document.WithText(sourceText.WithChanges(changes))
} }
|> Async.map (Option.defaultValue context.Document) |> Async.map (Option.defaultValue context.Document)
|> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken)), |> RoslynHelpers.StartAsyncAsTask(cancellationToken)),
title) title)
override __.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds override __.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds
...@@ -53,7 +53,7 @@ type internal FSharpRemoveUnusedOpensCodeFixProvider ...@@ -53,7 +53,7 @@ type internal FSharpRemoveUnusedOpensCodeFixProvider
async { async {
let diagnostics = context.Diagnostics |> Seq.filter (fun x -> fixableDiagnosticIds |> List.contains x.Id) |> Seq.toImmutableArray let diagnostics = context.Diagnostics |> Seq.filter (fun x -> fixableDiagnosticIds |> List.contains x.Id) |> Seq.toImmutableArray
context.RegisterCodeFix(createCodeFix(SR.RemoveUnusedOpens.Value, context), diagnostics) context.RegisterCodeFix(createCodeFix(SR.RemoveUnusedOpens.Value, context), diagnostics)
} |> CommonRoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) } |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken)
override __.GetFixAllProvider() = WellKnownFixAllProviders.BatchFixer override __.GetFixAllProvider() = WellKnownFixAllProviders.BatchFixer
\ No newline at end of file
...@@ -13,7 +13,7 @@ open Microsoft.CodeAnalysis.Text ...@@ -13,7 +13,7 @@ open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.CodeFixes open Microsoft.CodeAnalysis.CodeFixes
open Microsoft.CodeAnalysis.CodeActions open Microsoft.CodeAnalysis.CodeActions
[<ExportCodeFixProvider(FSharpCommonConstants.FSharpLanguageName, Name = "ReplaceWithSuggestion"); Shared>] [<ExportCodeFixProvider(FSharpConstants.FSharpLanguageName, Name = "ReplaceWithSuggestion"); Shared>]
type internal FSharpReplaceWithSuggestionCodeFixProvider() = type internal FSharpReplaceWithSuggestionCodeFixProvider() =
inherit CodeFixProvider() inherit CodeFixProvider()
let fixableDiagnosticIds = set ["FS0039"; "FS1129"; "FS0495"] let fixableDiagnosticIds = set ["FS0039"; "FS1129"; "FS0495"]
...@@ -26,7 +26,7 @@ type internal FSharpReplaceWithSuggestionCodeFixProvider() = ...@@ -26,7 +26,7 @@ type internal FSharpReplaceWithSuggestionCodeFixProvider() =
async { async {
let! sourceText = context.Document.GetTextAsync() let! sourceText = context.Document.GetTextAsync()
return context.Document.WithText(sourceText.WithChanges(textChange)) return context.Document.WithText(sourceText.WithChanges(textChange))
} |> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken)), } |> RoslynHelpers.StartAsyncAsTask(cancellationToken)),
title) title)
override __.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds override __.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds
...@@ -53,4 +53,4 @@ type internal FSharpReplaceWithSuggestionCodeFixProvider() = ...@@ -53,4 +53,4 @@ type internal FSharpReplaceWithSuggestionCodeFixProvider() =
context, context,
TextChange(context.Span, replacement)) TextChange(context.Span, replacement))
context.RegisterCodeFix(codefix, diagnostics)) context.RegisterCodeFix(codefix, diagnostics))
} |> CommonRoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) } |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken)
...@@ -13,7 +13,7 @@ open Microsoft.CodeAnalysis.Text ...@@ -13,7 +13,7 @@ open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.CodeFixes open Microsoft.CodeAnalysis.CodeFixes
open Microsoft.CodeAnalysis.CodeActions open Microsoft.CodeAnalysis.CodeActions
[<ExportCodeFixProvider(FSharpCommonConstants.FSharpLanguageName, Name = PredefinedCodeFixProviderNames.SimplifyNames); Shared>] [<ExportCodeFixProvider(FSharpConstants.FSharpLanguageName, Name = PredefinedCodeFixProviderNames.SimplifyNames); Shared>]
type internal FSharpSimplifyNameCodeFixProvider() = type internal FSharpSimplifyNameCodeFixProvider() =
inherit CodeFixProvider() inherit CodeFixProvider()
let fixableDiagnosticId = IDEDiagnosticIds.SimplifyNamesDiagnosticId let fixableDiagnosticId = IDEDiagnosticIds.SimplifyNamesDiagnosticId
...@@ -25,7 +25,7 @@ type internal FSharpSimplifyNameCodeFixProvider() = ...@@ -25,7 +25,7 @@ type internal FSharpSimplifyNameCodeFixProvider() =
async { async {
let! sourceText = context.Document.GetTextAsync() let! sourceText = context.Document.GetTextAsync()
return context.Document.WithText(sourceText.WithChanges(textChange)) return context.Document.WithText(sourceText.WithChanges(textChange))
} |> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken)), } |> RoslynHelpers.StartAsyncAsTask(cancellationToken)),
title) title)
override __.FixableDiagnosticIds = ImmutableArray.Create(fixableDiagnosticId) override __.FixableDiagnosticIds = ImmutableArray.Create(fixableDiagnosticId)
...@@ -42,4 +42,4 @@ type internal FSharpSimplifyNameCodeFixProvider() = ...@@ -42,4 +42,4 @@ type internal FSharpSimplifyNameCodeFixProvider() =
createCodeFix(title, context, TextChange(context.Span, "")), createCodeFix(title, context, TextChange(context.Span, "")),
ImmutableArray.Create(diagnostic)) ImmutableArray.Create(diagnostic))
} }
|> CommonRoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken)
\ No newline at end of file \ No newline at end of file
...@@ -73,7 +73,7 @@ type internal FsiCommandFilter(serviceProvider: System.IServiceProvider) = ...@@ -73,7 +73,7 @@ type internal FsiCommandFilter(serviceProvider: System.IServiceProvider) =
VSConstants.E_FAIL VSConstants.E_FAIL
[<Export(typeof<IWpfTextViewCreationListener>)>] [<Export(typeof<IWpfTextViewCreationListener>)>]
[<ContentType(FSharpCommonConstants.FSharpContentTypeName)>] [<ContentType(FSharpConstants.FSharpContentTypeName)>]
[<TextViewRole(PredefinedTextViewRoles.PrimaryDocument)>] [<TextViewRole(PredefinedTextViewRoles.PrimaryDocument)>]
type internal FsiCommandFilterProvider [<ImportingConstructor>] type internal FsiCommandFilterProvider [<ImportingConstructor>]
([<Import(typeof<SVsServiceProvider>)>] serviceProvider: System.IServiceProvider, ([<Import(typeof<SVsServiceProvider>)>] serviceProvider: System.IServiceProvider,
......
...@@ -14,7 +14,7 @@ open Microsoft.CodeAnalysis.Host.Mef ...@@ -14,7 +14,7 @@ open Microsoft.CodeAnalysis.Host.Mef
open Microsoft.FSharp.Compiler.Range open Microsoft.FSharp.Compiler.Range
[<Shared>] [<Shared>]
[<ExportLanguageService(typeof<IHelpContextService>, FSharpCommonConstants.FSharpLanguageName)>] [<ExportLanguageService(typeof<IHelpContextService>, FSharpConstants.FSharpLanguageName)>]
type internal FSharpHelpContextService type internal FSharpHelpContextService
[<ImportingConstructor>] [<ImportingConstructor>]
( (
...@@ -93,8 +93,8 @@ type internal FSharpHelpContextService ...@@ -93,8 +93,8 @@ type internal FSharpHelpContextService
} }
interface IHelpContextService with interface IHelpContextService with
member this.Language = FSharpCommonConstants.FSharpLanguageLongName member this.Language = FSharpConstants.FSharpLanguageLongName
member this.Product = FSharpCommonConstants.FSharpLanguageLongName member this.Product = FSharpConstants.FSharpLanguageLongName
member this.GetHelpTermAsync(document, textSpan, cancellationToken) = member this.GetHelpTermAsync(document, textSpan, cancellationToken) =
asyncMaybe { asyncMaybe {
...@@ -103,11 +103,11 @@ type internal FSharpHelpContextService ...@@ -103,11 +103,11 @@ type internal FSharpHelpContextService
let! textVersion = document.GetTextVersionAsync(cancellationToken) let! textVersion = document.GetTextVersionAsync(cancellationToken)
let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document)
let textLine = sourceText.Lines.GetLineFromPosition(textSpan.Start) let textLine = sourceText.Lines.GetLineFromPosition(textSpan.Start)
let tokens = CommonHelpers.getColorizationData(document.Id, sourceText, textLine.Span, Some document.Name, defines, cancellationToken) let tokens = Tokenizer.getColorizationData(document.Id, sourceText, textLine.Span, Some document.Name, defines, cancellationToken)
return! FSharpHelpContextService.GetHelpTerm(checkerProvider.Checker, sourceText, document.FilePath, options, textSpan, tokens, textVersion.GetHashCode()) return! FSharpHelpContextService.GetHelpTerm(checkerProvider.Checker, sourceText, document.FilePath, options, textSpan, tokens, textVersion.GetHashCode())
} }
|> Async.map (Option.defaultValue "") |> Async.map (Option.defaultValue "")
|> CommonRoslynHelpers.StartAsyncAsTask cancellationToken |> RoslynHelpers.StartAsyncAsTask cancellationToken
member this.FormatSymbol(_symbol) = Unchecked.defaultof<_> member this.FormatSymbol(_symbol) = Unchecked.defaultof<_>
...@@ -109,7 +109,7 @@ type internal XmlDocCommandFilter ...@@ -109,7 +109,7 @@ type internal XmlDocCommandFilter
VSConstants.E_FAIL VSConstants.E_FAIL
[<Export(typeof<IWpfTextViewCreationListener>)>] [<Export(typeof<IWpfTextViewCreationListener>)>]
[<ContentType(FSharpCommonConstants.FSharpContentTypeName)>] [<ContentType(FSharpConstants.FSharpContentTypeName)>]
[<TextViewRole(PredefinedTextViewRoles.PrimaryDocument)>] [<TextViewRole(PredefinedTextViewRoles.PrimaryDocument)>]
type internal XmlDocCommandFilterProvider type internal XmlDocCommandFilterProvider
[<ImportingConstructor>] [<ImportingConstructor>]
......
...@@ -8,7 +8,7 @@ open System.Diagnostics ...@@ -8,7 +8,7 @@ open System.Diagnostics
open Microsoft.CodeAnalysis.Classification open Microsoft.CodeAnalysis.Classification
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]
module internal FSharpCommonConstants = module internal FSharpConstants =
[<Literal>] [<Literal>]
/// "871D2A70-12A2-4e42-9440-425DD92A4116" /// "871D2A70-12A2-4e42-9440-425DD92A4116"
......
...@@ -9,19 +9,19 @@ open Microsoft.VisualStudio.Utilities ...@@ -9,19 +9,19 @@ open Microsoft.VisualStudio.Utilities
module FSharpStaticTypeDefinitions = module FSharpStaticTypeDefinitions =
[<Export>] [<Export>]
[<Name(FSharpCommonConstants.FSharpContentTypeName)>] [<Name(FSharpConstants.FSharpContentTypeName)>]
[<BaseDefinition(ContentTypeNames.RoslynContentType)>] [<BaseDefinition(ContentTypeNames.RoslynContentType)>]
let FSharpContentTypeDefinition = ContentTypeDefinition() let FSharpContentTypeDefinition = ContentTypeDefinition()
[<Export>] [<Export>]
[<Name(FSharpCommonConstants.FSharpSignatureHelpContentTypeName)>] [<Name(FSharpConstants.FSharpSignatureHelpContentTypeName)>]
[<BaseDefinition("sighelp")>] [<BaseDefinition("sighelp")>]
let FSharpSignatureHelpContentTypeDefinition = ContentTypeDefinition() let FSharpSignatureHelpContentTypeDefinition = ContentTypeDefinition()
[<ExportContentTypeLanguageService(FSharpCommonConstants.FSharpContentTypeName, FSharpCommonConstants.FSharpLanguageName)>] [<ExportContentTypeLanguageService(FSharpConstants.FSharpContentTypeName, FSharpConstants.FSharpLanguageName)>]
type FSharpContentType [<System.Composition.ImportingConstructor>](contentTypeRegistry : IContentTypeRegistryService) = type FSharpContentType [<System.Composition.ImportingConstructor>](contentTypeRegistry : IContentTypeRegistryService) =
member this.contentTypeRegistryService = contentTypeRegistry member this.contentTypeRegistryService = contentTypeRegistry
interface IContentTypeLanguageService with interface IContentTypeLanguageService with
member this.GetDefaultContentType() = member this.GetDefaultContentType() =
this.contentTypeRegistryService.GetContentType(FSharpCommonConstants.FSharpContentTypeName) this.contentTypeRegistryService.GetContentType(FSharpConstants.FSharpContentTypeName)
// 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.
[<AutoOpen>]
/// Type and Module Extensions
module internal Microsoft.VisualStudio.FSharp.Editor.Extensions
open System
open System.IO
open Microsoft.CodeAnalysis
open Microsoft.FSharp.Compiler.Ast
open Microsoft.FSharp.Compiler.SourceCodeServices
type Path with
static member GetFullPathSafe path =
try Path.GetFullPath path
with _ -> path
static member GetFileNameSafe path =
try Path.GetFileName path
with _ -> path
type System.IServiceProvider with
member x.GetService<'T>() = x.GetService(typeof<'T>) :?> 'T
member x.GetService<'S, 'T>() = x.GetService(typeof<'S>) :?> 'T
type FSharpNavigationDeclarationItem with
member x.RoslynGlyph : Glyph =
match x.Glyph with
| FSharpGlyph.Class
| FSharpGlyph.Typedef
| FSharpGlyph.Type
| FSharpGlyph.Exception ->
match x.Access with
| Some SynAccess.Private -> Glyph.ClassPrivate
| Some SynAccess.Internal -> Glyph.ClassInternal
| _ -> Glyph.ClassPublic
| FSharpGlyph.Constant ->
match x.Access with
| Some SynAccess.Private -> Glyph.ConstantPrivate
| Some SynAccess.Internal -> Glyph.ConstantInternal
| _ -> Glyph.ConstantPublic
| FSharpGlyph.Delegate ->
match x.Access with
| Some SynAccess.Private -> Glyph.DelegatePrivate
| Some SynAccess.Internal -> Glyph.DelegateInternal
| _ -> Glyph.DelegatePublic
| FSharpGlyph.Union
| FSharpGlyph.Enum ->
match x.Access with
| Some SynAccess.Private -> Glyph.EnumPrivate
| Some SynAccess.Internal -> Glyph.EnumInternal
| _ -> Glyph.EnumPublic
| FSharpGlyph.EnumMember
| FSharpGlyph.Variable
| FSharpGlyph.Field ->
match x.Access with
| Some SynAccess.Private -> Glyph.FieldPrivate
| Some SynAccess.Internal -> Glyph.FieldInternal
| _ -> Glyph.FieldPublic
| FSharpGlyph.Event ->
match x.Access with
| Some SynAccess.Private -> Glyph.EventPrivate
| Some SynAccess.Internal -> Glyph.EventInternal
| _ -> Glyph.EventPublic
| FSharpGlyph.Interface ->
match x.Access with
| Some SynAccess.Private -> Glyph.InterfacePrivate
| Some SynAccess.Internal -> Glyph.InterfaceInternal
| _ -> Glyph.InterfacePublic
| FSharpGlyph.Method
| FSharpGlyph.OverridenMethod ->
match x.Access with
| Some SynAccess.Private -> Glyph.MethodPrivate
| Some SynAccess.Internal -> Glyph.MethodInternal
| _ -> Glyph.MethodPublic
| FSharpGlyph.Module ->
match x.Access with
| Some SynAccess.Private -> Glyph.ModulePrivate
| Some SynAccess.Internal -> Glyph.ModuleInternal
| _ -> Glyph.ModulePublic
| FSharpGlyph.NameSpace -> Glyph.Namespace
| FSharpGlyph.Property ->
match x.Access with
| Some SynAccess.Private -> Glyph.PropertyPrivate
| Some SynAccess.Internal -> Glyph.PropertyInternal
| _ -> Glyph.PropertyPublic
| FSharpGlyph.Struct ->
match x.Access with
| Some SynAccess.Private -> Glyph.StructurePrivate
| Some SynAccess.Internal -> Glyph.StructureInternal
| _ -> Glyph.StructurePublic
| FSharpGlyph.ExtensionMethod ->
match x.Access with
| Some SynAccess.Private -> Glyph.ExtensionMethodPrivate
| Some SynAccess.Internal -> Glyph.ExtensionMethodInternal
| _ -> Glyph.ExtensionMethodPublic
| FSharpGlyph.Error -> Glyph.Error
[<RequireQualifiedAccess>]
module String =
let getLines (str: string) =
use reader = new StringReader(str)
[| let mutable line = reader.ReadLine()
while not (isNull line) do
yield line
line <- reader.ReadLine()
if str.EndsWith("\n") then
// last trailing space not returned
// http://stackoverflow.com/questions/19365404/stringreader-omits-trailing-linebreak
yield String.Empty
|]
[<RequireQualifiedAccess>]
module Option =
let guard (x: bool) : Option<unit> =
if x then Some() else None
let attempt (f: unit -> 'T) = try Some <| f() with _ -> None
let inline ofNull value =
if obj.ReferenceEquals(value, null) then None else Some value
/// Gets the option if Some x, otherwise try to get another value
let inline orTry f =
function
| Some x -> Some x
| None -> f()
/// Gets the value if Some x, otherwise try to get another value by calling a function
let inline getOrTry f =
function
| Some x -> x
| None -> f()
[<RequireQualifiedAccess>]
module List =
let foldi (folder : 'State -> int -> 'T -> 'State) (state : 'State) (xs : 'T list) =
let mutable state = state
let mutable i = 0
for x in xs do
state <- folder state i x
i <- i + 1
state
[<RequireQualifiedAccess>]
module Seq =
open System.Collections.Immutable
let toImmutableArray (xs: seq<'a>) : ImmutableArray<'a> = xs.ToImmutableArray()
[<RequireQualifiedAccess>]
module Array =
/// Optimized arrays equality. ~100x faster than `array1 = array2` on strings.
/// ~2x faster for floats
/// ~0.8x slower for ints
let areEqual (xs: 'T []) (ys: 'T []) =
match xs, ys with
| null, null -> true
| [||], [||] -> true
| null, _ | _, null -> false
| _ when xs.Length <> ys.Length -> false
| _ ->
let mutable break' = false
let mutable i = 0
let mutable result = true
while i < xs.Length && not break' do
if xs.[i] <> ys.[i] then
break' <- true
result <- false
i <- i + 1
result
/// check if subArray is found in the wholeArray starting
/// at the provided index
let isSubArray (subArray: 'T []) (wholeArray:'T []) index =
if isNull subArray || isNull wholeArray then false
elif subArray.Length = 0 then true
elif subArray.Length > wholeArray.Length then false
elif subArray.Length = wholeArray.Length then areEqual subArray wholeArray else
let rec loop subidx idx =
if subidx = subArray.Length then true
elif subArray.[subidx] = wholeArray.[idx] then loop (subidx+1) (idx+1)
else false
loop 0 index
/// Returns true if one array has another as its subset from index 0.
let startsWith (prefix: _ []) (whole: _ []) =
isSubArray prefix whole 0
/// Returns true if one array has trailing elements equal to another's.
let endsWith (suffix: _ []) (whole: _ []) =
isSubArray suffix whole (whole.Length-suffix.Length)
\ No newline at end of file
...@@ -3,7 +3,6 @@ module Microsoft.VisualStudio.FSharp.Editor.Pervasive ...@@ -3,7 +3,6 @@ module Microsoft.VisualStudio.FSharp.Editor.Pervasive
open System open System
open System.IO open System.IO
open System.Threading
open System.Threading.Tasks open System.Threading.Tasks
open System.Diagnostics open System.Diagnostics
...@@ -20,36 +19,8 @@ let isScriptFile (filePath:string) = ...@@ -20,36 +19,8 @@ let isScriptFile (filePath:string) =
/// Path combination operator /// Path combination operator
let (</>) path1 path2 = Path.Combine (path1, path2) let (</>) path1 path2 = Path.Combine (path1, path2)
type internal ISetThemeColors = abstract member SetColors: unit -> unit
type Path with
static member GetFullPathSafe path =
try Path.GetFullPath path
with _ -> path
static member GetFileNameSafe path =
try Path.GetFileName path
with _ -> path
[<RequireQualifiedAccess>]
module String =
let getLines (str: string) =
use reader = new StringReader(str)
[| let mutable line = reader.ReadLine()
while not (isNull line) do
yield line
line <- reader.ReadLine()
if str.EndsWith("\n") then
// last trailing space not returned
// http://stackoverflow.com/questions/19365404/stringreader-omits-trailing-linebreak
yield String.Empty
|]
type System.IServiceProvider with
member x.GetService<'T>() = x.GetService(typeof<'T>) :?> 'T
member x.GetService<'S, 'T>() = x.GetService(typeof<'S>) :?> 'T
[<Sealed>] [<Sealed>]
type MaybeBuilder () = type MaybeBuilder () =
...@@ -271,62 +242,3 @@ type AsyncBuilder with ...@@ -271,62 +242,3 @@ type AsyncBuilder with
member __.ReturnFrom(computation: System.Threading.Tasks.Task<'a>): Async<'a> = Async.AwaitTask computation member __.ReturnFrom(computation: System.Threading.Tasks.Task<'a>): Async<'a> = Async.AwaitTask computation
module Option =
let guard (x: bool) : Option<unit> =
if x then Some() else None
module List =
let foldi (folder : 'State -> int -> 'T -> 'State) (state : 'State) (xs : 'T list) =
let mutable state = state
let mutable i = 0
for x in xs do
state <- folder state i x
i <- i + 1
state
module Seq =
open System.Collections.Immutable
let toImmutableArray (xs: seq<'a>) : ImmutableArray<'a> = xs.ToImmutableArray()
module Array =
/// Optimized arrays equality. ~100x faster than `array1 = array2` on strings.
/// ~2x faster for floats
/// ~0.8x slower for ints
let areEqual (xs: 'T []) (ys: 'T []) =
match xs, ys with
| null, null -> true
| [||], [||] -> true
| null, _ | _, null -> false
| _ when xs.Length <> ys.Length -> false
| _ ->
let mutable break' = false
let mutable i = 0
let mutable result = true
while i < xs.Length && not break' do
if xs.[i] <> ys.[i] then
break' <- true
result <- false
i <- i + 1
result
/// check if subArray is found in the wholeArray starting
/// at the provided index
let isSubArray (subArray: 'T []) (wholeArray:'T []) index =
if isNull subArray || isNull wholeArray then false
elif subArray.Length = 0 then true
elif subArray.Length > wholeArray.Length then false
elif subArray.Length = wholeArray.Length then areEqual subArray wholeArray else
let rec loop subidx idx =
if subidx = subArray.Length then true
elif subArray.[subidx] = wholeArray.[idx] then loop (subidx+1) (idx+1)
else false
loop 0 index
/// Returns true if one array has another as its subset from index 0.
let startsWith (prefix: _ []) (whole: _ []) =
isSubArray prefix whole 0
/// Returns true if one array has trailing elements equal to another's.
let endsWith (suffix: _ []) (whole: _ []) =
isSubArray suffix whole (whole.Length-suffix.Length)
\ No newline at end of file
...@@ -13,9 +13,11 @@ open Microsoft.FSharp.Compiler ...@@ -13,9 +13,11 @@ open Microsoft.FSharp.Compiler
open Microsoft.FSharp.Compiler.Layout open Microsoft.FSharp.Compiler.Layout
open Microsoft.FSharp.Compiler.SourceCodeServices open Microsoft.FSharp.Compiler.SourceCodeServices
open Microsoft.FSharp.Compiler.Range open Microsoft.FSharp.Compiler.Range
open Microsoft.FSharp.Compiler.Ast
open Microsoft.FSharp.Compiler.SourceCodeServices
open Microsoft.VisualStudio.FSharp.LanguageService open Microsoft.VisualStudio.FSharp.LanguageService
module internal CommonRoslynHelpers = module internal RoslynHelpers =
let FSharpRangeToTextSpan(sourceText: SourceText, range: range) = let FSharpRangeToTextSpan(sourceText: SourceText, range: range) =
// Roslyn TextLineCollection is zero-based, F# range lines are one-based // Roslyn TextLineCollection is zero-based, F# range lines are one-based
...@@ -44,6 +46,8 @@ module internal CommonRoslynHelpers = ...@@ -44,6 +46,8 @@ module internal CommonRoslynHelpers =
Assert.Exception(task.Exception.GetBaseException()) Assert.Exception(task.Exception.GetBaseException())
raise(task.Exception.GetBaseException()) raise(task.Exception.GetBaseException())
/// maps from `LayoutTag` of the F# Compiler to Roslyn `TextTags` for use in tooltips /// maps from `LayoutTag` of the F# Compiler to Roslyn `TextTags` for use in tooltips
let roslynTag = function let roslynTag = function
| LayoutTag.ActivePatternCase | LayoutTag.ActivePatternCase
...@@ -113,202 +117,13 @@ module internal CommonRoslynHelpers = ...@@ -113,202 +117,13 @@ module internal CommonRoslynHelpers =
let descriptor = new DiagnosticDescriptor(id, emptyString, description, error.Subcategory, severity, true, emptyString, String.Empty, customTags) let descriptor = new DiagnosticDescriptor(id, emptyString, description, error.Subcategory, severity, true, emptyString, String.Empty, customTags)
Diagnostic.Create(descriptor, location) Diagnostic.Create(descriptor, location)
let inline (|Public|Internal|Protected|Private|) (a: FSharpAccessibility option) =
match a with
| None -> Public
| Some a ->
if a.IsPublic then Public
elif a.IsInternal then Internal
elif a.IsPrivate then Private
else Protected
let FSharpGlyphToRoslynGlyph (glyph: FSharpGlyph, accessibility: FSharpAccessibility option) =
match glyph with
| FSharpGlyph.Class
| FSharpGlyph.Exception
| FSharpGlyph.Typedef
| FSharpGlyph.Type ->
match accessibility with
| Public -> Glyph.ClassPublic
| Internal -> Glyph.ClassInternal
| Protected -> Glyph.ClassProtected
| Private -> Glyph.ClassPrivate
| FSharpGlyph.Constant ->
match accessibility with
| Public -> Glyph.ConstantPublic
| Internal -> Glyph.ConstantInternal
| Protected -> Glyph.ConstantProtected
| Private -> Glyph.ConstantPrivate
| FSharpGlyph.Delegate ->
match accessibility with
| Public -> Glyph.DelegatePublic
| Internal -> Glyph.DelegateInternal
| Protected -> Glyph.DelegateProtected
| Private -> Glyph.DelegatePrivate
| FSharpGlyph.Enum
| FSharpGlyph.Union ->
match accessibility with
| Public -> Glyph.EnumPublic
| Internal -> Glyph.EnumInternal
| Protected -> Glyph.EnumProtected
| Private -> Glyph.EnumPrivate
| FSharpGlyph.EnumMember -> Glyph.EnumMember
| FSharpGlyph.Event ->
match accessibility with
| Public -> Glyph.EventPublic
| Internal -> Glyph.EventInternal
| Protected -> Glyph.EventProtected
| Private -> Glyph.EventPrivate
| FSharpGlyph.Field ->
match accessibility with
| Public -> Glyph.FieldPublic
| Internal -> Glyph.FieldInternal
| Protected -> Glyph.FieldProtected
| Private -> Glyph.FieldPrivate
| FSharpGlyph.Interface ->
match accessibility with
| Public -> Glyph.InterfacePublic
| Internal -> Glyph.InterfaceInternal
| Protected -> Glyph.InterfaceProtected
| Private -> Glyph.InterfacePrivate
| FSharpGlyph.Method
| FSharpGlyph.OverridenMethod ->
match accessibility with
| Public -> Glyph.MethodPublic
| Internal -> Glyph.MethodInternal
| Protected -> Glyph.MethodProtected
| Private -> Glyph.MethodPrivate
| FSharpGlyph.ExtensionMethod ->
match accessibility with
| Public -> Glyph.ExtensionMethodPublic
| Internal -> Glyph.ExtensionMethodInternal
| Protected -> Glyph.ExtensionMethodProtected
| Private -> Glyph.ExtensionMethodPrivate
| FSharpGlyph.Module ->
match accessibility with
| Public -> Glyph.ModulePublic
| Internal -> Glyph.ModuleInternal
| Protected -> Glyph.ModuleProtected
| Private -> Glyph.ModulePrivate
| FSharpGlyph.NameSpace -> Glyph.Namespace
| FSharpGlyph.Property ->
match accessibility with
| Public -> Glyph.PropertyPublic
| Internal -> Glyph.PropertyInternal
| Protected -> Glyph.PropertyProtected
| Private -> Glyph.PropertyPrivate
| FSharpGlyph.Struct ->
match accessibility with
| Public -> Glyph.StructurePublic
| Internal -> Glyph.StructureInternal
| Protected -> Glyph.StructureProtected
| Private -> Glyph.StructurePrivate
| FSharpGlyph.Variable -> Glyph.Local
| FSharpGlyph.Error -> Glyph.Error
let GetGlyphForSymbol (symbol: FSharpSymbol, kind: LexerSymbolKind) =
match kind with
| LexerSymbolKind.Operator -> Glyph.Operator
| _ ->
match symbol with
| :? FSharpUnionCase as x ->
match Some x.Accessibility with
| Public -> Glyph.EnumPublic
| Internal -> Glyph.EnumInternal
| Protected -> Glyph.EnumProtected
| Private -> Glyph.EnumPrivate
| :? FSharpActivePatternCase -> Glyph.EnumPublic
| :? FSharpField as x ->
if x.IsLiteral then
match Some x.Accessibility with
| Public -> Glyph.ConstantPublic
| Internal -> Glyph.ConstantInternal
| Protected -> Glyph.ConstantProtected
| Private -> Glyph.ConstantPrivate
else
match Some x.Accessibility with
| Public -> Glyph.FieldPublic
| Internal -> Glyph.FieldInternal
| Protected -> Glyph.FieldProtected
| Private -> Glyph.FieldPrivate
| :? FSharpParameter -> Glyph.Parameter
| :? FSharpMemberOrFunctionOrValue as x ->
if x.LiteralValue.IsSome then
match Some x.Accessibility with
| Public -> Glyph.ConstantPublic
| Internal -> Glyph.ConstantInternal
| Protected -> Glyph.ConstantProtected
| Private -> Glyph.ConstantPrivate
elif x.IsExtensionMember then
match Some x.Accessibility with
| Public -> Glyph.ExtensionMethodPublic
| Internal -> Glyph.ExtensionMethodInternal
| Protected -> Glyph.ExtensionMethodProtected
| Private -> Glyph.ExtensionMethodPrivate
elif x.IsProperty || x.IsPropertyGetterMethod || x.IsPropertySetterMethod then
match Some x.Accessibility with
| Public -> Glyph.PropertyPublic
| Internal -> Glyph.PropertyInternal
| Protected -> Glyph.PropertyProtected
| Private -> Glyph.PropertyPrivate
elif x.IsEvent then
match Some x.Accessibility with
| Public -> Glyph.EventPublic
| Internal -> Glyph.EventInternal
| Protected -> Glyph.EventProtected
| Private -> Glyph.EventPrivate
else
match Some x.Accessibility with
| Public -> Glyph.MethodPublic
| Internal -> Glyph.MethodInternal
| Protected -> Glyph.MethodProtected
| Private -> Glyph.MethodPrivate
| :? FSharpEntity as x ->
if x.IsValueType then
match Some x.Accessibility with
| Public -> Glyph.StructurePublic
| Internal -> Glyph.StructureInternal
| Protected -> Glyph.StructureProtected
| Private -> Glyph.StructurePrivate
elif x.IsFSharpModule then
match Some x.Accessibility with
| Public -> Glyph.ModulePublic
| Internal -> Glyph.ModuleInternal
| Protected -> Glyph.ModuleProtected
| Private -> Glyph.ModulePrivate
elif x.IsEnum || x.IsFSharpUnion then
match Some x.Accessibility with
| Public -> Glyph.EnumPublic
| Internal -> Glyph.EnumInternal
| Protected -> Glyph.EnumProtected
| Private -> Glyph.EnumPrivate
elif x.IsInterface then
match Some x.Accessibility with
| Public -> Glyph.InterfacePublic
| Internal -> Glyph.InterfaceInternal
| Protected -> Glyph.InterfaceProtected
| Private -> Glyph.InterfacePrivate
elif x.IsDelegate then
match Some x.Accessibility with
| Public -> Glyph.DelegatePublic
| Internal -> Glyph.DelegateInternal
| Protected -> Glyph.DelegateProtected
| Private -> Glyph.DelegatePrivate
elif x.IsNamespace then
Glyph.Namespace
else
match Some x.Accessibility with
| Public -> Glyph.ClassPublic
| Internal -> Glyph.ClassInternal
| Protected -> Glyph.ClassProtected
| Private -> Glyph.ClassPrivate
| _ -> Glyph.None
let RangeToLocation (r: range, sourceText: SourceText, filePath: string) : Location = let RangeToLocation (r: range, sourceText: SourceText, filePath: string) : Location =
let linePositionSpan = LinePositionSpan(LinePosition(Line.toZ r.StartLine, r.StartColumn), LinePosition(Line.toZ r.EndLine, r.EndColumn)) let linePositionSpan = LinePositionSpan(LinePosition(Line.toZ r.StartLine, r.StartColumn), LinePosition(Line.toZ r.EndLine, r.EndColumn))
let textSpan = sourceText.Lines.GetTextSpan linePositionSpan let textSpan = sourceText.Lines.GetTextSpan linePositionSpan
Location.Create(filePath, textSpan, linePositionSpan) Location.Create(filePath, textSpan, linePositionSpan)
module internal OpenDeclarationHelper = module internal OpenDeclarationHelper =
/// <summary> /// <summary>
/// Inserts open declaration into `SourceText`. /// Inserts open declaration into `SourceText`.
......
...@@ -21,6 +21,8 @@ open Microsoft.VisualStudio.Shell.Interop ...@@ -21,6 +21,8 @@ open Microsoft.VisualStudio.Shell.Interop
open Microsoft.FSharp.Compiler open Microsoft.FSharp.Compiler
open Microsoft.FSharp.Compiler.Range open Microsoft.FSharp.Compiler.Range
open Microsoft.FSharp.Compiler.SourceCodeServices open Microsoft.FSharp.Compiler.SourceCodeServices
open Tokenizer
type internal FSharpCompletionProvider type internal FSharpCompletionProvider
( (
...@@ -140,7 +142,7 @@ type internal FSharpCompletionProvider ...@@ -140,7 +142,7 @@ type internal FSharpCompletionProvider
let maxHints = if mruItems.Values.Count = 0 then 0 else Seq.max mruItems.Values let maxHints = if mruItems.Values.Count = 0 then 0 else Seq.max mruItems.Values
sortedDeclItems |> Array.iteri (fun number declItem -> sortedDeclItems |> Array.iteri (fun number declItem ->
let glyph = CommonRoslynHelpers.FSharpGlyphToRoslynGlyph (declItem.Glyph, declItem.Accessibility) let glyph = FSharpGlyphToRoslynGlyph (declItem.Glyph, declItem.Accessibility)
let name = let name =
match entityKind, declItem.NamespaceToOpen with match entityKind, declItem.NamespaceToOpen with
| Some EntityKind.Attribute, _ when declItem.IsAttribute && declItem.Name.EndsWith "Attribute" -> | Some EntityKind.Attribute, _ when declItem.IsAttribute && declItem.Name.EndsWith "Attribute" ->
...@@ -226,7 +228,7 @@ type internal FSharpCompletionProvider ...@@ -226,7 +228,7 @@ type internal FSharpCompletionProvider
FSharpCompletionProvider.ProvideCompletionsAsyncAux(checkerProvider.Checker, sourceText, context.Position, options, FSharpCompletionProvider.ProvideCompletionsAsyncAux(checkerProvider.Checker, sourceText, context.Position, options,
document.FilePath, textVersion.GetHashCode(), getAllSymbols) document.FilePath, textVersion.GetHashCode(), getAllSymbols)
context.AddItems(results) context.AddItems(results)
} |> Async.Ignore |> CommonRoslynHelpers.StartAsyncUnitAsTask context.CancellationToken } |> Async.Ignore |> RoslynHelpers.StartAsyncUnitAsTask context.CancellationToken
override this.GetDescriptionAsync(_: Document, completionItem: Completion.CompletionItem, cancellationToken: CancellationToken): Task<CompletionDescription> = override this.GetDescriptionAsync(_: Document, completionItem: Completion.CompletionItem, cancellationToken: CancellationToken): Task<CompletionDescription> =
async { async {
...@@ -234,13 +236,13 @@ type internal FSharpCompletionProvider ...@@ -234,13 +236,13 @@ type internal FSharpCompletionProvider
if exists then if exists then
let! description = declarationItem.StructuredDescriptionTextAsync let! description = declarationItem.StructuredDescriptionTextAsync
let documentation = List() let documentation = List()
let collector = CommonRoslynHelpers.CollectTaggedText documentation let collector = RoslynHelpers.CollectTaggedText documentation
// mix main description and xmldoc by using one collector // mix main description and xmldoc by using one collector
XmlDocumentation.BuildDataTipText(documentationBuilder, collector, collector, description) XmlDocumentation.BuildDataTipText(documentationBuilder, collector, collector, description)
return CompletionDescription.Create(documentation.ToImmutableArray()) return CompletionDescription.Create(documentation.ToImmutableArray())
else else
return CompletionDescription.Empty return CompletionDescription.Empty
} |> CommonRoslynHelpers.StartAsyncAsTask cancellationToken } |> RoslynHelpers.StartAsyncAsTask cancellationToken
override this.GetChangeAsync(document, item, _, cancellationToken) : Task<CompletionChange> = override this.GetChangeAsync(document, item, _, cancellationToken) : Task<CompletionChange> =
async { async {
...@@ -285,4 +287,4 @@ type internal FSharpCompletionProvider ...@@ -285,4 +287,4 @@ type internal FSharpCompletionProvider
} }
|> Async.map (Option.defaultValue (CompletionChange.Create(TextChange(item.Span, nameInCode)))) |> Async.map (Option.defaultValue (CompletionChange.Create(TextChange(item.Span, nameInCode))))
} |> CommonRoslynHelpers.StartAsyncAsTask cancellationToken } |> RoslynHelpers.StartAsyncAsTask cancellationToken
\ No newline at end of file \ No newline at end of file
...@@ -36,12 +36,12 @@ type internal FSharpCompletionService ...@@ -36,12 +36,12 @@ type internal FSharpCompletionService
.WithDismissIfLastCharacterDeleted(true) .WithDismissIfLastCharacterDeleted(true)
.WithDefaultEnterKeyRule(EnterKeyRule.Never) .WithDefaultEnterKeyRule(EnterKeyRule.Never)
override this.Language = FSharpCommonConstants.FSharpLanguageName override this.Language = FSharpConstants.FSharpLanguageName
override this.GetBuiltInProviders() = builtInProviders override this.GetBuiltInProviders() = builtInProviders
override this.GetRules() = completionRules override this.GetRules() = completionRules
[<Shared>] [<Shared>]
[<ExportLanguageServiceFactory(typeof<CompletionService>, FSharpCommonConstants.FSharpLanguageName)>] [<ExportLanguageServiceFactory(typeof<CompletionService>, FSharpConstants.FSharpLanguageName)>]
type internal FSharpCompletionServiceFactory type internal FSharpCompletionServiceFactory
[<ImportingConstructor>] [<ImportingConstructor>]
( (
......
...@@ -85,7 +85,7 @@ module internal CompletionUtils = ...@@ -85,7 +85,7 @@ module internal CompletionUtils =
let shouldProvideCompletion (documentId: DocumentId, filePath: string, defines: string list, text: SourceText, position: int) : bool = let shouldProvideCompletion (documentId: DocumentId, filePath: string, defines: string list, text: SourceText, position: int) : bool =
let textLines = text.Lines let textLines = text.Lines
let triggerLine = textLines.GetLineFromPosition position let triggerLine = textLines.GetLineFromPosition position
let colorizationData = CommonHelpers.getColorizationData(documentId, text, triggerLine.Span, Some filePath, defines, CancellationToken.None) let colorizationData = Tokenizer.getColorizationData(documentId, text, triggerLine.Span, Some filePath, defines, CancellationToken.None)
colorizationData.Count = 0 || // we should provide completion at the start of empty line, where there are no tokens at all colorizationData.Count = 0 || // we should provide completion at the start of empty line, where there are no tokens at all
colorizationData.Exists (fun classifiedSpan -> colorizationData.Exists (fun classifiedSpan ->
classifiedSpan.TextSpan.IntersectsWith position && classifiedSpan.TextSpan.IntersectsWith position &&
......
...@@ -58,7 +58,7 @@ type internal HashDirectiveCompletionProvider(workspace: Workspace, projectInfoM ...@@ -58,7 +58,7 @@ type internal HashDirectiveCompletionProvider(workspace: Workspace, projectInfoM
let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document)
let textLines = text.Lines let textLines = text.Lines
let triggerLine = textLines.GetLineFromPosition(position) let triggerLine = textLines.GetLineFromPosition(position)
CommonHelpers.getColorizationData(documentId, text, triggerLine.Span, Some document.FilePath, defines, CancellationToken.None) Tokenizer.getColorizationData(documentId, text, triggerLine.Span, Some document.FilePath, defines, CancellationToken.None)
let isInStringLiteral(text: SourceText, position: int) : bool = let isInStringLiteral(text: SourceText, position: int) : bool =
getColorizationData(text, position) getColorizationData(text, position)
...@@ -143,7 +143,7 @@ type internal HashDirectiveCompletionProvider(workspace: Workspace, projectInfoM ...@@ -143,7 +143,7 @@ type internal HashDirectiveCompletionProvider(workspace: Workspace, projectInfoM
context.AddItems(helper.GetItems(pathThroughLastSlash, documentPath)) context.AddItems(helper.GetItems(pathThroughLastSlash, documentPath))
} }
|> Async.Ignore |> Async.Ignore
|> CommonRoslynHelpers.StartAsyncUnitAsTask context.CancellationToken |> RoslynHelpers.StartAsyncUnitAsTask context.CancellationToken
override __.IsInsertionTrigger(text, position, _) = override __.IsInsertionTrigger(text, position, _) =
// Bring up completion when the user types a quote (i.e.: #r "), or if they type a slash // Bring up completion when the user types a quote (i.e.: #r "), or if they type a slash
......
...@@ -20,7 +20,7 @@ open Microsoft.FSharp.Compiler.Range ...@@ -20,7 +20,7 @@ open Microsoft.FSharp.Compiler.Range
open Microsoft.FSharp.Compiler.SourceCodeServices open Microsoft.FSharp.Compiler.SourceCodeServices
[<Shared>] [<Shared>]
[<ExportSignatureHelpProvider("FSharpSignatureHelpProvider", FSharpCommonConstants.FSharpLanguageName)>] [<ExportSignatureHelpProvider("FSharpSignatureHelpProvider", FSharpConstants.FSharpLanguageName)>]
type internal FSharpSignatureHelpProvider type internal FSharpSignatureHelpProvider
[<ImportingConstructor>] [<ImportingConstructor>]
( (
...@@ -159,16 +159,16 @@ type internal FSharpSignatureHelpProvider ...@@ -159,16 +159,16 @@ type internal FSharpSignatureHelpProvider
// Create the documentation. Note, do this on the background thread, since doing it in the documentationBuild fails to build the XML index // Create the documentation. Note, do this on the background thread, since doing it in the documentationBuild fails to build the XML index
let mainDescription = List() let mainDescription = List()
let documentation = List() let documentation = List()
XmlDocumentation.BuildMethodOverloadTipText(documentationBuilder, CommonRoslynHelpers.CollectTaggedText mainDescription, CommonRoslynHelpers.CollectTaggedText documentation, method.StructuredDescription, false) XmlDocumentation.BuildMethodOverloadTipText(documentationBuilder, RoslynHelpers.CollectTaggedText mainDescription, RoslynHelpers.CollectTaggedText documentation, method.StructuredDescription, false)
let parameters = let parameters =
let parameters = if isStaticArgTip then method.StaticParameters else method.Parameters let parameters = if isStaticArgTip then method.StaticParameters else method.Parameters
[| for p in parameters do [| for p in parameters do
let doc = List() let doc = List()
// FSROSLYNTODO: compute the proper help text for parameters, c.f. AppendParameter in XmlDocumentation.fs // FSROSLYNTODO: compute the proper help text for parameters, c.f. AppendParameter in XmlDocumentation.fs
XmlDocumentation.BuildMethodParamText(documentationBuilder, CommonRoslynHelpers.CollectTaggedText doc, method.XmlDoc, p.ParameterName) XmlDocumentation.BuildMethodParamText(documentationBuilder, RoslynHelpers.CollectTaggedText doc, method.XmlDoc, p.ParameterName)
let parts = List() let parts = List()
renderL (taggedTextListR (CommonRoslynHelpers.CollectTaggedText parts)) p.StructuredDisplay |> ignore renderL (taggedTextListR (RoslynHelpers.CollectTaggedText parts)) p.StructuredDisplay |> ignore
yield (p.ParameterName, p.IsOptional, doc, parts) yield (p.ParameterName, p.IsOptional, doc, parts)
|] |]
...@@ -221,7 +221,7 @@ type internal FSharpSignatureHelpProvider ...@@ -221,7 +221,7 @@ type internal FSharpSignatureHelpProvider
return! None return! None
} }
|> Async.map Option.toObj |> Async.map Option.toObj
|> CommonRoslynHelpers.StartAsyncAsTask cancellationToken |> RoslynHelpers.StartAsyncAsTask cancellationToken
open System.ComponentModel.Composition open System.ComponentModel.Composition
open Microsoft.VisualStudio.Utilities open Microsoft.VisualStudio.Utilities
...@@ -232,7 +232,7 @@ open Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.SignatureHelp.Pre ...@@ -232,7 +232,7 @@ open Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.SignatureHelp.Pre
// Enable colorized signature help for F# buffers // Enable colorized signature help for F# buffers
[<Export(typeof<IClassifierProvider>)>] [<Export(typeof<IClassifierProvider>)>]
[<ContentType(FSharpCommonConstants.FSharpSignatureHelpContentTypeName)>] [<ContentType(FSharpConstants.FSharpSignatureHelpContentTypeName)>]
type internal FSharpSignatureHelpClassifierProvider [<ImportingConstructor>] (typeMap) = type internal FSharpSignatureHelpClassifierProvider [<ImportingConstructor>] (typeMap) =
interface IClassifierProvider with interface IClassifierProvider with
override __.GetClassifier (buffer: ITextBuffer) = override __.GetClassifier (buffer: ITextBuffer) =
......
...@@ -17,7 +17,7 @@ open Microsoft.FSharp.Compiler.SourceCodeServices ...@@ -17,7 +17,7 @@ open Microsoft.FSharp.Compiler.SourceCodeServices
open Microsoft.FSharp.Compiler.Range open Microsoft.FSharp.Compiler.Range
[<Shared>] [<Shared>]
[<ExportLanguageService(typeof<IBreakpointResolutionService>, FSharpCommonConstants.FSharpLanguageName)>] [<ExportLanguageService(typeof<IBreakpointResolutionService>, FSharpConstants.FSharpLanguageName)>]
type internal FSharpBreakpointResolutionService type internal FSharpBreakpointResolutionService
[<ImportingConstructor>] [<ImportingConstructor>]
( (
...@@ -45,10 +45,10 @@ type internal FSharpBreakpointResolutionService ...@@ -45,10 +45,10 @@ type internal FSharpBreakpointResolutionService
let! options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document) let! options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document)
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let! range = FSharpBreakpointResolutionService.GetBreakpointLocation(checkerProvider.Checker, sourceText, document.Name, textSpan, options) let! range = FSharpBreakpointResolutionService.GetBreakpointLocation(checkerProvider.Checker, sourceText, document.Name, textSpan, options)
return BreakpointResolutionResult.CreateSpanResult(document, CommonRoslynHelpers.FSharpRangeToTextSpan(sourceText, range)) return BreakpointResolutionResult.CreateSpanResult(document, RoslynHelpers.FSharpRangeToTextSpan(sourceText, range))
} }
|> Async.map Option.toObj |> Async.map Option.toObj
|> CommonRoslynHelpers.StartAsyncAsTask cancellationToken |> RoslynHelpers.StartAsyncAsTask cancellationToken
// FSROSLYNTODO: enable placing breakpoints by when user suplies fully-qualified function names // FSROSLYNTODO: enable placing breakpoints by when user suplies fully-qualified function names
member this.ResolveBreakpointsAsync(_, _, _): Task<IEnumerable<BreakpointResolutionResult>> = member this.ResolveBreakpointsAsync(_, _, _): Task<IEnumerable<BreakpointResolutionResult>> =
......
...@@ -17,7 +17,7 @@ open Microsoft.CodeAnalysis.Text ...@@ -17,7 +17,7 @@ open Microsoft.CodeAnalysis.Text
open Microsoft.VisualStudio.FSharp.LanguageService open Microsoft.VisualStudio.FSharp.LanguageService
[<Shared>] [<Shared>]
[<ExportLanguageService(typeof<ILanguageDebugInfoService>, FSharpCommonConstants.FSharpLanguageName)>] [<ExportLanguageService(typeof<ILanguageDebugInfoService>, FSharpConstants.FSharpLanguageName)>]
type internal FSharpLanguageDebugInfoService [<ImportingConstructor>](projectInfoManager: ProjectInfoManager) = type internal FSharpLanguageDebugInfoService [<ImportingConstructor>](projectInfoManager: ProjectInfoManager) =
static member GetDataTipInformation(sourceText: SourceText, position: int, tokens: List<ClassifiedSpan>): TextSpan option = static member GetDataTipInformation(sourceText: SourceText, position: int, tokens: List<ClassifiedSpan>): TextSpan option =
...@@ -55,13 +55,13 @@ type internal FSharpLanguageDebugInfoService [<ImportingConstructor>](projectInf ...@@ -55,13 +55,13 @@ type internal FSharpLanguageDebugInfoService [<ImportingConstructor>](projectInf
let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document)
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let textSpan = TextSpan.FromBounds(0, sourceText.Length) let textSpan = TextSpan.FromBounds(0, sourceText.Length)
let tokens = CommonHelpers.getColorizationData(document.Id, sourceText, textSpan, Some(document.Name), defines, cancellationToken) let tokens = Tokenizer.getColorizationData(document.Id, sourceText, textSpan, Some(document.Name), defines, cancellationToken)
let result = let result =
match FSharpLanguageDebugInfoService.GetDataTipInformation(sourceText, position, tokens) with match FSharpLanguageDebugInfoService.GetDataTipInformation(sourceText, position, tokens) with
| None -> DebugDataTipInfo() | None -> DebugDataTipInfo()
| Some textSpan -> DebugDataTipInfo(textSpan, sourceText.GetSubText(textSpan).ToString()) | Some textSpan -> DebugDataTipInfo(textSpan, sourceText.GetSubText(textSpan).ToString())
return result return result
} }
|> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken) |> RoslynHelpers.StartAsyncAsTask(cancellationToken)
\ No newline at end of file
...@@ -26,7 +26,7 @@ type internal DiagnosticsType = ...@@ -26,7 +26,7 @@ type internal DiagnosticsType =
| Syntax | Syntax
| Semantic | Semantic
[<DiagnosticAnalyzer(FSharpCommonConstants.FSharpLanguageName)>] [<DiagnosticAnalyzer(FSharpConstants.FSharpLanguageName)>]
type internal FSharpDocumentDiagnosticAnalyzer() = type internal FSharpDocumentDiagnosticAnalyzer() =
inherit DocumentDiagnosticAnalyzer() inherit DocumentDiagnosticAnalyzer()
...@@ -103,12 +103,12 @@ type internal FSharpDocumentDiagnosticAnalyzer() = ...@@ -103,12 +103,12 @@ type internal FSharpDocumentDiagnosticAnalyzer() =
TextSpan.FromBounds(start, sourceText.Length) TextSpan.FromBounds(start, sourceText.Length)
let location = Location.Create(filePath, correctedTextSpan , linePositionSpan) let location = Location.Create(filePath, correctedTextSpan , linePositionSpan)
Some(CommonRoslynHelpers.ConvertError(error, location))) Some(RoslynHelpers.ConvertError(error, location)))
|> Seq.toImmutableArray |> Seq.toImmutableArray
return results return results
} }
override this.SupportedDiagnostics = CommonRoslynHelpers.SupportedDiagnostics() override this.SupportedDiagnostics = RoslynHelpers.SupportedDiagnostics()
override this.AnalyzeSyntaxAsync(document: Document, cancellationToken: CancellationToken): Task<ImmutableArray<Diagnostic>> = override this.AnalyzeSyntaxAsync(document: Document, cancellationToken: CancellationToken): Task<ImmutableArray<Diagnostic>> =
let projectInfoManager = getProjectInfoManager document let projectInfoManager = getProjectInfoManager document
...@@ -121,7 +121,7 @@ type internal FSharpDocumentDiagnosticAnalyzer() = ...@@ -121,7 +121,7 @@ type internal FSharpDocumentDiagnosticAnalyzer() =
|> liftAsync |> liftAsync
} }
|> Async.map (Option.defaultValue ImmutableArray<Diagnostic>.Empty) |> Async.map (Option.defaultValue ImmutableArray<Diagnostic>.Empty)
|> CommonRoslynHelpers.StartAsyncAsTask cancellationToken |> RoslynHelpers.StartAsyncAsTask cancellationToken
override this.AnalyzeSemanticsAsync(document: Document, cancellationToken: CancellationToken): Task<ImmutableArray<Diagnostic>> = override this.AnalyzeSemanticsAsync(document: Document, cancellationToken: CancellationToken): Task<ImmutableArray<Diagnostic>> =
let projectInfoManager = getProjectInfoManager document let projectInfoManager = getProjectInfoManager document
...@@ -134,7 +134,7 @@ type internal FSharpDocumentDiagnosticAnalyzer() = ...@@ -134,7 +134,7 @@ type internal FSharpDocumentDiagnosticAnalyzer() =
|> liftAsync |> liftAsync
} }
|> Async.map (Option.defaultValue ImmutableArray<Diagnostic>.Empty) |> Async.map (Option.defaultValue ImmutableArray<Diagnostic>.Empty)
|> CommonRoslynHelpers.StartAsyncAsTask cancellationToken |> RoslynHelpers.StartAsyncAsTask cancellationToken
interface IBuiltInAnalyzer with interface IBuiltInAnalyzer with
member __.GetAnalyzerCategory() : DiagnosticAnalyzerCategory = DiagnosticAnalyzerCategory.SemanticDocumentAnalysis member __.GetAnalyzerCategory() : DiagnosticAnalyzerCategory = DiagnosticAnalyzerCategory.SemanticDocumentAnalysis
......
...@@ -108,7 +108,7 @@ type internal SimplifyNameDiagnosticAnalyzer() = ...@@ -108,7 +108,7 @@ type internal SimplifyNameDiagnosticAnalyzer() =
result.Add( result.Add(
Diagnostic.Create( Diagnostic.Create(
Descriptor, Descriptor,
CommonRoslynHelpers.RangeToLocation(unnecessaryRange, sourceText, document.FilePath), RoslynHelpers.RangeToLocation(unnecessaryRange, sourceText, document.FilePath),
properties = (dict [SimplifyNameDiagnosticAnalyzer.LongIdentPropertyKey, relativeName]).ToImmutableDictionary())) properties = (dict [SimplifyNameDiagnosticAnalyzer.LongIdentPropertyKey, relativeName]).ToImmutableDictionary()))
let diagnostics = result.ToImmutableArray() let diagnostics = result.ToImmutableArray()
...@@ -118,7 +118,7 @@ type internal SimplifyNameDiagnosticAnalyzer() = ...@@ -118,7 +118,7 @@ type internal SimplifyNameDiagnosticAnalyzer() =
finally guard.Release() |> ignore finally guard.Release() |> ignore
} }
|> Async.map (Option.defaultValue ImmutableArray.Empty) |> Async.map (Option.defaultValue ImmutableArray.Empty)
|> CommonRoslynHelpers.StartAsyncAsTask cancellationToken |> RoslynHelpers.StartAsyncAsTask cancellationToken
interface IBuiltInAnalyzer with interface IBuiltInAnalyzer with
member __.OpenFileOnly _ = true member __.OpenFileOnly _ = true
......
...@@ -8,14 +8,17 @@ open System.Threading ...@@ -8,14 +8,17 @@ open System.Threading
open System.Threading.Tasks open System.Threading.Tasks
open Microsoft.CodeAnalysis open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.Diagnostics open Microsoft.CodeAnalysis.Diagnostics
open Microsoft.FSharp.Compiler open Microsoft.FSharp.Compiler
open Microsoft.FSharp.Compiler.Ast open Microsoft.FSharp.Compiler.Ast
open Microsoft.FSharp.Compiler.Range open Microsoft.FSharp.Compiler.Range
open Microsoft.FSharp.Compiler.SourceCodeServices open Microsoft.FSharp.Compiler.SourceCodeServices
open Symbols
module private UnusedOpens = module private UnusedOpens =
open Microsoft.CodeAnalysis.Text
let rec visitSynModuleOrNamespaceDecls (parent: Ast.LongIdent) decls : (Set<string> * range) list = let rec visitSynModuleOrNamespaceDecls (parent: Ast.LongIdent) decls : (Set<string> * range) list =
[ for decl in decls do [ for decl in decls do
...@@ -70,7 +73,7 @@ module private UnusedOpens = ...@@ -70,7 +73,7 @@ module private UnusedOpens =
| None -> [] | None -> []
let symbolIsFullyQualified (sourceText: SourceText) (sym: FSharpSymbolUse) (fullName: string) = let symbolIsFullyQualified (sourceText: SourceText) (sym: FSharpSymbolUse) (fullName: string) =
match CommonRoslynHelpers.TryFSharpRangeToTextSpan(sourceText, sym.RangeAlternate) with match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, sym.RangeAlternate) with
| Some span // check that the symbol hasn't provided an invalid span | Some span // check that the symbol hasn't provided an invalid span
when sourceText.Length < span.Start when sourceText.Length < span.Start
|| sourceText.Length < span.End -> false || sourceText.Length < span.End -> false
...@@ -135,7 +138,7 @@ module private UnusedOpens = ...@@ -135,7 +138,7 @@ module private UnusedOpens =
let openStatements = getOpenStatements parsedInput let openStatements = getOpenStatements parsedInput
openStatements |> filter |> List.map snd openStatements |> filter |> List.map snd
[<DiagnosticAnalyzer(FSharpCommonConstants.FSharpLanguageName)>] [<DiagnosticAnalyzer(FSharpConstants.FSharpLanguageName)>]
type internal UnusedOpensDiagnosticAnalyzer() = type internal UnusedOpensDiagnosticAnalyzer() =
inherit DocumentDiagnosticAnalyzer() inherit DocumentDiagnosticAnalyzer()
...@@ -175,11 +178,11 @@ type internal UnusedOpensDiagnosticAnalyzer() = ...@@ -175,11 +178,11 @@ type internal UnusedOpensDiagnosticAnalyzer() =
|> List.map (fun m -> |> List.map (fun m ->
Diagnostic.Create( Diagnostic.Create(
Descriptor, Descriptor,
CommonRoslynHelpers.RangeToLocation(m, sourceText, document.FilePath))) RoslynHelpers.RangeToLocation(m, sourceText, document.FilePath)))
|> Seq.toImmutableArray |> Seq.toImmutableArray
} }
|> Async.map (Option.defaultValue ImmutableArray.Empty) |> Async.map (Option.defaultValue ImmutableArray.Empty)
|> CommonRoslynHelpers.StartAsyncAsTask cancellationToken |> RoslynHelpers.StartAsyncAsTask cancellationToken
interface IBuiltInAnalyzer with interface IBuiltInAnalyzer with
member __.OpenFileOnly _ = true member __.OpenFileOnly _ = true
......
...@@ -21,7 +21,7 @@ type internal FSharpHighlightSpan = ...@@ -21,7 +21,7 @@ type internal FSharpHighlightSpan =
override this.ToString() = sprintf "%+A" this override this.ToString() = sprintf "%+A" this
[<Shared>] [<Shared>]
[<ExportLanguageService(typeof<IDocumentHighlightsService>, FSharpCommonConstants.FSharpLanguageName)>] [<ExportLanguageService(typeof<IDocumentHighlightsService>, FSharpConstants.FSharpLanguageName)>]
type internal FSharpDocumentHighlightsService [<ImportingConstructor>] (checkerProvider: FSharpCheckerProvider, projectInfoManager: ProjectInfoManager) = type internal FSharpDocumentHighlightsService [<ImportingConstructor>] (checkerProvider: FSharpCheckerProvider, projectInfoManager: ProjectInfoManager) =
/// Fix invalid spans if they appear to have redundant suffix and prefix. /// Fix invalid spans if they appear to have redundant suffix and prefix.
...@@ -56,14 +56,14 @@ type internal FSharpDocumentHighlightsService [<ImportingConstructor>] (checkerP ...@@ -56,14 +56,14 @@ type internal FSharpDocumentHighlightsService [<ImportingConstructor>] (checkerP
let textLine = sourceText.Lines.GetLineFromPosition(position) let textLine = sourceText.Lines.GetLineFromPosition(position)
let textLinePos = sourceText.Lines.GetLinePosition(position) let textLinePos = sourceText.Lines.GetLinePosition(position)
let fcsTextLineNumber = Line.fromZ textLinePos.Line let fcsTextLineNumber = Line.fromZ textLinePos.Line
let! symbol = CommonHelpers.getSymbolAtPosition(documentKey, sourceText, position, filePath, defines, SymbolLookupKind.Greedy) let! symbol = Tokenizer.getSymbolAtPosition(documentKey, sourceText, position, filePath, defines, Tokenizer.SymbolLookupKind.Greedy)
let! _, _, checkFileResults = checker.ParseAndCheckDocument(filePath, textVersionHash, sourceText.ToString(), options, allowStaleResults = true) 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! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, symbol.Ident.idRange.EndColumn, textLine.ToString(), symbol.FullIsland)
let! symbolUses = checkFileResults.GetUsesOfSymbolInFile(symbolUse.Symbol) |> liftAsync let! symbolUses = checkFileResults.GetUsesOfSymbolInFile(symbolUse.Symbol) |> liftAsync
return return
[| for symbolUse in symbolUses do [| for symbolUse in symbolUses do
yield { IsDefinition = symbolUse.IsFromDefinition yield { IsDefinition = symbolUse.IsFromDefinition
TextSpan = CommonRoslynHelpers.FSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate) } |] TextSpan = RoslynHelpers.FSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate) } |]
|> fixInvalidSymbolSpans sourceText symbol.Ident.idText |> fixInvalidSymbolSpans sourceText symbol.Ident.idText
} }
...@@ -86,4 +86,4 @@ type internal FSharpDocumentHighlightsService [<ImportingConstructor>] (checkerP ...@@ -86,4 +86,4 @@ type internal FSharpDocumentHighlightsService [<ImportingConstructor>] (checkerP
return ImmutableArray.Create(DocumentHighlights(document, highlightSpans)) return ImmutableArray.Create(DocumentHighlights(document, highlightSpans))
} }
|> Async.map (Option.defaultValue ImmutableArray<DocumentHighlights>.Empty) |> Async.map (Option.defaultValue ImmutableArray<DocumentHighlights>.Empty)
|> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken) |> RoslynHelpers.StartAsyncAsTask(cancellationToken)
...@@ -33,15 +33,19 @@ ...@@ -33,15 +33,19 @@
<Compile Include="srFSharp.Editor.fs" /> <Compile Include="srFSharp.Editor.fs" />
<Compile Include="Common\AssemblyInfo.fs" /> <Compile Include="Common\AssemblyInfo.fs" />
<Compile Include="Common\Pervasive.fs" /> <Compile Include="Common\Pervasive.fs" />
<Compile Include="Common\CommonConstants.fs" /> <Compile Include="Common\Extensions.fs" />
<Compile Include="Common\Constants.fs" />
<Compile Include="Common\Logging.fs" /> <Compile Include="Common\Logging.fs" />
<Compile Include="Common\CommonHelpers.fs" /> <Compile Include="Common\RoslynHelpers.fs" />
<Compile Include="Common\CommonRoslynHelpers.fs" />
<Compile Include="Common\CodeAnalysisExtensions.fs" /> <Compile Include="Common\CodeAnalysisExtensions.fs" />
<Compile Include="Common\ContentType.fs" /> <Compile Include="Common\ContentType.fs" />
<Compile Include="Common\LanguageService.fs" /> <Compile Include="LanguageService\Tokenizer.fs" />
<Compile Include="Common\SymbolHelpers.fs" /> <Compile Include="LanguageService\Symbols.fs" />
<Compile Include="Common\AssemblyContentProvider.fs" /> <Compile Include="LanguageService\TypedAstUtils.fs" />
<Compile Include="LanguageService\FSharpCheckerExtensions.fs" />
<Compile Include="LanguageService\LanguageService.fs" />
<Compile Include="LanguageService\AssemblyContentProvider.fs" />
<Compile Include="LanguageService\SymbolHelpers.fs" />
<Compile Include="Properties\IntelliSensePropertyPage.fs" /> <Compile Include="Properties\IntelliSensePropertyPage.fs" />
<Compile Include="Classification\ClassificationDefinitions.fs" /> <Compile Include="Classification\ClassificationDefinitions.fs" />
<Compile Include="Classification\ColorizationService.fs" /> <Compile Include="Classification\ColorizationService.fs" />
...@@ -106,7 +110,6 @@ ...@@ -106,7 +110,6 @@
<Private>True</Private> <Private>True</Private>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="mscorlib" /> <Reference Include="mscorlib" />
<Reference Include="PresentationFramework" /> <Reference Include="PresentationFramework" />
...@@ -120,7 +123,6 @@ ...@@ -120,7 +123,6 @@
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="System.ComponentModel.Composition" /> <Reference Include="System.ComponentModel.Composition" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="EnvDTE"> <Reference Include="EnvDTE">
<HintPath>$(FSharpSourcesRoot)\..\packages\EnvDTE.8.0.1\lib\net10\EnvDTE.dll</HintPath> <HintPath>$(FSharpSourcesRoot)\..\packages\EnvDTE.8.0.1\lib\net10\EnvDTE.dll</HintPath>
......
...@@ -7,7 +7,7 @@ open System.ComponentModel.Composition ...@@ -7,7 +7,7 @@ open System.ComponentModel.Composition
open Microsoft.CodeAnalysis.Editor open Microsoft.CodeAnalysis.Editor
open Microsoft.FSharp.Compiler.SourceCodeServices open Microsoft.FSharp.Compiler.SourceCodeServices
[<ExportBraceMatcher(FSharpCommonConstants.FSharpLanguageName)>] [<ExportBraceMatcher(FSharpConstants.FSharpLanguageName)>]
type internal FSharpBraceMatchingService type internal FSharpBraceMatchingService
[<ImportingConstructor>] [<ImportingConstructor>]
( (
...@@ -18,7 +18,7 @@ type internal FSharpBraceMatchingService ...@@ -18,7 +18,7 @@ type internal FSharpBraceMatchingService
static member GetBraceMatchingResult(checker: FSharpChecker, sourceText, fileName, options, position: int) = static member GetBraceMatchingResult(checker: FSharpChecker, sourceText, fileName, options, position: int) =
async { async {
let! matchedBraces = checker.MatchBracesAlternate(fileName, sourceText.ToString(), options) let! matchedBraces = checker.MatchBracesAlternate(fileName, sourceText.ToString(), options)
let isPositionInRange range = CommonRoslynHelpers.FSharpRangeToTextSpan(sourceText, range).Contains(position) let isPositionInRange range = RoslynHelpers.FSharpRangeToTextSpan(sourceText, range).Contains(position)
return matchedBraces |> Array.tryFind(fun (left, right) -> isPositionInRange left || isPositionInRange right) return matchedBraces |> Array.tryFind(fun (left, right) -> isPositionInRange left || isPositionInRange right)
} }
...@@ -30,8 +30,8 @@ type internal FSharpBraceMatchingService ...@@ -30,8 +30,8 @@ type internal FSharpBraceMatchingService
let! (left, right) = FSharpBraceMatchingService.GetBraceMatchingResult(checkerProvider.Checker, sourceText, document.Name, options, position) let! (left, right) = FSharpBraceMatchingService.GetBraceMatchingResult(checkerProvider.Checker, sourceText, document.Name, options, position)
return return
BraceMatchingResult( BraceMatchingResult(
CommonRoslynHelpers.FSharpRangeToTextSpan(sourceText, left), RoslynHelpers.FSharpRangeToTextSpan(sourceText, left),
CommonRoslynHelpers.FSharpRangeToTextSpan(sourceText, right)) RoslynHelpers.FSharpRangeToTextSpan(sourceText, right))
} }
|> Async.map Option.toNullable |> Async.map Option.toNullable
|> CommonRoslynHelpers.StartAsyncAsTask cancellationToken |> RoslynHelpers.StartAsyncAsTask cancellationToken
...@@ -13,7 +13,7 @@ open Microsoft.CodeAnalysis.Host.Mef ...@@ -13,7 +13,7 @@ open Microsoft.CodeAnalysis.Host.Mef
open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.Text
[<Shared>] [<Shared>]
[<ExportLanguageService(typeof<ISynchronousIndentationService>, FSharpCommonConstants.FSharpLanguageName)>] [<ExportLanguageService(typeof<ISynchronousIndentationService>, FSharpConstants.FSharpLanguageName)>]
type internal FSharpIndentationService() = type internal FSharpIndentationService() =
static member GetDesiredIndentation(sourceText: SourceText, lineNumber: int, tabSize: int): Option<int> = static member GetDesiredIndentation(sourceText: SourceText, lineNumber: int, tabSize: int): Option<int> =
...@@ -47,7 +47,7 @@ type internal FSharpIndentationService() = ...@@ -47,7 +47,7 @@ type internal FSharpIndentationService() =
async { async {
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let! options = document.GetOptionsAsync(cancellationToken) let! options = document.GetOptionsAsync(cancellationToken)
let tabSize = options.GetOption(FormattingOptions.TabSize, FSharpCommonConstants.FSharpLanguageName) let tabSize = options.GetOption(FormattingOptions.TabSize, FSharpConstants.FSharpLanguageName)
return return
match FSharpIndentationService.GetDesiredIndentation(sourceText, lineNumber, tabSize) with match FSharpIndentationService.GetDesiredIndentation(sourceText, lineNumber, tabSize) with
......
...@@ -17,6 +17,9 @@ open Microsoft.CodeAnalysis.Text ...@@ -17,6 +17,9 @@ open Microsoft.CodeAnalysis.Text
open Microsoft.FSharp.Compiler open Microsoft.FSharp.Compiler
open Microsoft.FSharp.Compiler.Range open Microsoft.FSharp.Compiler.Range
open Microsoft.FSharp.Compiler.SourceCodeServices open Microsoft.FSharp.Compiler.SourceCodeServices
open Tokenizer
open Symbols
type internal FailureInlineRenameInfo private () = type internal FailureInlineRenameInfo private () =
interface IInlineRenameInfo with interface IInlineRenameInfo with
...@@ -63,11 +66,11 @@ type internal InlineRenameLocationSet(locationsByDocument: DocumentLocations [], ...@@ -63,11 +66,11 @@ type internal InlineRenameLocationSet(locationsByDocument: DocumentLocations [],
return return
{ new IInlineRenameReplacementInfo with { new IInlineRenameReplacementInfo with
member __.NewSolution = newSolution member __.NewSolution = newSolution
member __.ReplacementTextValid = CommonHelpers.isValidNameForSymbol(symbolKind, symbol, replacementText) member __.ReplacementTextValid = Tokenizer.isValidNameForSymbol(symbolKind, symbol, replacementText)
member __.DocumentIds = locationsByDocument |> Seq.map (fun doc -> doc.Document.Id) member __.DocumentIds = locationsByDocument |> Seq.map (fun doc -> doc.Document.Id)
member __.GetReplacements(documentId) = Seq.empty } member __.GetReplacements(documentId) = Seq.empty }
} }
|> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken) |> RoslynHelpers.StartAsyncAsTask(cancellationToken)
type internal InlineRenameInfo type internal InlineRenameInfo
( (
...@@ -87,8 +90,8 @@ type internal InlineRenameInfo ...@@ -87,8 +90,8 @@ type internal InlineRenameInfo
| _ -> document.GetTextAsync(cancellationToken).Result | _ -> document.GetTextAsync(cancellationToken).Result
let triggerSpan = let triggerSpan =
let span = CommonRoslynHelpers.FSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate) let span = RoslynHelpers.FSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate)
CommonHelpers.fixupSpan(sourceText, span) Tokenizer.fixupSpan(sourceText, span)
let symbolUses = let symbolUses =
SymbolHelpers.getSymbolUsesInSolution(symbolUse.Symbol, declLoc, checkFileResults, projectInfoManager, checker, document.Project.Solution) SymbolHelpers.getSymbolUsesInSolution(symbolUse.Symbol, declLoc, checkFileResults, projectInfoManager, checker, document.Project.Solution)
...@@ -107,7 +110,7 @@ type internal InlineRenameInfo ...@@ -107,7 +110,7 @@ type internal InlineRenameInfo
member __.GetReferenceEditSpan(location, cancellationToken) = member __.GetReferenceEditSpan(location, cancellationToken) =
let text = getDocumentText location.Document cancellationToken let text = getDocumentText location.Document cancellationToken
CommonHelpers.fixupSpan(text, location.TextSpan) Tokenizer.fixupSpan(text, location.TextSpan)
member __.GetConflictEditSpan(location, _replacementText, _cancellationToken) = Nullable(location.TextSpan) member __.GetConflictEditSpan(location, _replacementText, _cancellationToken) = Nullable(location.TextSpan)
...@@ -123,18 +126,18 @@ type internal InlineRenameInfo ...@@ -123,18 +126,18 @@ type internal InlineRenameInfo
let locations = let locations =
symbolUses symbolUses
|> Array.map (fun symbolUse -> |> Array.map (fun symbolUse ->
let textSpan = CommonHelpers.fixupSpan(sourceText, CommonRoslynHelpers.FSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate)) let textSpan = Tokenizer.fixupSpan(sourceText, RoslynHelpers.FSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate))
InlineRenameLocation(document, textSpan)) InlineRenameLocation(document, textSpan))
return { Document = document; Locations = locations } return { Document = document; Locations = locations }
}) })
|> Async.Parallel |> Async.Parallel
return InlineRenameLocationSet(locationsByDocument, document.Project.Solution, lexerSymbol.Kind, symbolUse.Symbol) :> IInlineRenameLocationSet return InlineRenameLocationSet(locationsByDocument, document.Project.Solution, lexerSymbol.Kind, symbolUse.Symbol) :> IInlineRenameLocationSet
} |> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken) } |> RoslynHelpers.StartAsyncAsTask(cancellationToken)
member __.TryOnBeforeGlobalSymbolRenamed(_workspace, _changedDocumentIDs, _replacementText) = true member __.TryOnBeforeGlobalSymbolRenamed(_workspace, _changedDocumentIDs, _replacementText) = true
member __.TryOnAfterGlobalSymbolRenamed(_workspace, _changedDocumentIDs, _replacementText) = true member __.TryOnAfterGlobalSymbolRenamed(_workspace, _changedDocumentIDs, _replacementText) = true
[<ExportLanguageService(typeof<IEditorInlineRenameService>, FSharpCommonConstants.FSharpLanguageName); Shared>] [<ExportLanguageService(typeof<IEditorInlineRenameService>, FSharpConstants.FSharpLanguageName); Shared>]
type internal InlineRenameService type internal InlineRenameService
[<ImportingConstructor>] [<ImportingConstructor>]
( (
...@@ -149,7 +152,7 @@ type internal InlineRenameService ...@@ -149,7 +152,7 @@ type internal InlineRenameService
let textLine = sourceText.Lines.GetLineFromPosition(position) let textLine = sourceText.Lines.GetLineFromPosition(position)
let textLinePos = sourceText.Lines.GetLinePosition(position) let textLinePos = sourceText.Lines.GetLinePosition(position)
let fcsTextLineNumber = Line.fromZ textLinePos.Line let fcsTextLineNumber = Line.fromZ textLinePos.Line
let! symbol = CommonHelpers.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy) let! symbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy)
let! _, _, checkFileResults = checker.ParseAndCheckDocument(document, options, allowStaleResults = true) let! _, _, checkFileResults = checker.ParseAndCheckDocument(document, options, allowStaleResults = true)
let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, symbol.Ident.idRange.EndColumn, textLine.Text.ToString(), symbol.FullIsland) let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, symbol.Ident.idRange.EndColumn, textLine.Text.ToString(), symbol.FullIsland)
let! declLoc = symbolUse.GetDeclarationLocation(document) let! declLoc = symbolUse.GetDeclarationLocation(document)
...@@ -165,4 +168,4 @@ type internal InlineRenameService ...@@ -165,4 +168,4 @@ type internal InlineRenameService
return! InlineRenameService.GetInlineRenameInfo(checkerProvider.Checker, projectInfoManager, document, sourceText, position, defines, options) return! InlineRenameService.GetInlineRenameInfo(checkerProvider.Checker, projectInfoManager, document, sourceText, position, defines, options)
} }
|> Async.map (Option.defaultValue FailureInlineRenameInfo.Instance) |> Async.map (Option.defaultValue FailureInlineRenameInfo.Instance)
|> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken) |> RoslynHelpers.StartAsyncAsTask(cancellationToken)
[<AutoOpen>]
module internal Microsoft.VisualStudio.FSharp.Editor.FSharpCheckerExtensions
open System
open System.Threading.Tasks
open Microsoft.CodeAnalysis
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) =
asyncMaybe {
let! fileParseResults = this.ParseFileInProject(document.FilePath, sourceText, options) |> liftAsync
return! fileParseResults.ParseTree
}
member this.ParseDocument(document: Document, options: FSharpProjectOptions, ?sourceText: SourceText) =
asyncMaybe {
let! sourceText =
match sourceText with
| Some x -> Task.FromResult x
| None -> document.GetTextAsync()
return! this.ParseDocument(document, options, sourceText.ToString())
}
member this.ParseAndCheckDocument(filePath: string, textVersionHash: int, sourceText: string, options: FSharpProjectOptions, allowStaleResults: bool) : Async<(FSharpParseFileResults * Ast.ParsedInput * FSharpCheckFileResults) option> =
let parseAndCheckFile =
async {
let! parseResults, checkFileAnswer = this.ParseAndCheckFileInProject(filePath, textVersionHash, sourceText, options)
return
match checkFileAnswer with
| FSharpCheckFileAnswer.Aborted ->
None
| FSharpCheckFileAnswer.Succeeded(checkFileResults) ->
Some (parseResults, checkFileResults)
}
let tryGetFreshResultsWithTimeout() : Async<CheckResults> =
async {
try
let! worker = Async.StartChild(parseAndCheckFile, 2000)
let! result = worker
return Ready result
with :? TimeoutException ->
return StillRunning parseAndCheckFile
}
let bindParsedInput(results: (FSharpParseFileResults * FSharpCheckFileResults) option) =
match results with
| Some(parseResults, checkResults) ->
match parseResults.ParseTree with
| Some parsedInput -> Some (parseResults, parsedInput, checkResults)
| None -> None
| None -> None
if allowStaleResults then
async {
let! freshResults = tryGetFreshResultsWithTimeout()
let! results =
match freshResults with
| Ready x -> async.Return x
| StillRunning worker ->
async {
match allowStaleResults, this.TryGetRecentCheckResultsForFile(filePath, options) with
| true, Some (parseResults, checkFileResults, _) ->
return Some (parseResults, checkFileResults)
| _ ->
return! worker
}
return bindParsedInput results
}
else parseAndCheckFile |> Async.map bindParsedInput
member this.ParseAndCheckDocument(document: Document, options: FSharpProjectOptions, allowStaleResults: bool, ?sourceText: SourceText) : Async<(FSharpParseFileResults * Ast.ParsedInput * FSharpCheckFileResults) option> =
async {
let! cancellationToken = Async.CancellationToken
let! sourceText =
match sourceText with
| Some x -> Task.FromResult x
| None -> document.GetTextAsync()
let! textVersion = document.GetTextVersionAsync(cancellationToken)
return! this.ParseAndCheckDocument(document.FilePath, textVersion.GetHashCode(), sourceText.ToString(), options, allowStaleResults)
}
member self.TryParseAndCheckFileInProject (projectOptions, fileName, source) = async {
let! (parseResults, checkAnswer) = self.ParseAndCheckFileInProject (fileName,0, source,projectOptions)
match checkAnswer with
| FSharpCheckFileAnswer.Aborted -> return None
| FSharpCheckFileAnswer.Succeeded checkResults -> return Some (parseResults,checkResults)
}
member self.GetAllUsesOfAllSymbolsInSourceString (projectOptions, fileName, source: string, checkForUnusedOpens) = async {
let! parseAndCheckResults = self.TryParseAndCheckFileInProject (projectOptions, fileName, source)
match parseAndCheckResults with
| None -> return [||]
| Some(_parseResults,checkResults) ->
let! fsharpSymbolsUses = checkResults.GetAllUsesOfAllSymbolsInFile()
let allSymbolsUses =
fsharpSymbolsUses
|> Array.map (fun symbolUse ->
let fullNames =
match symbolUse.Symbol with
// Make sure that unsafe manipulation isn't executed if unused opens are disabled
| _ when not checkForUnusedOpens -> None
| TypedAstPatterns.MemberFunctionOrValue func when func.IsExtensionMember ->
if func.IsProperty then
let fullNames =
[| if func.HasGetterMethod then
yield func.GetterMethod.EnclosingEntity.TryGetFullName()
if func.HasSetterMethod then
yield func.SetterMethod.EnclosingEntity.TryGetFullName()
|]
|> Array.choose id
match fullNames with
| [||] -> None
| _ -> Some fullNames
else
match func.EnclosingEntity with
// C# extension method
| TypedAstPatterns.FSharpEntity TypedAstPatterns.Class ->
let fullName = symbolUse.Symbol.FullName.Split '.'
if fullName.Length > 2 then
(* For C# extension methods FCS returns full name including the class name, like:
Namespace.StaticClass.ExtensionMethod
So, in order to properly detect that "open Namespace" actually opens ExtensionMethod,
we remove "StaticClass" part. This makes C# extension methods looks identically
with F# extension members.
*)
let fullNameWithoutClassName =
Array.append fullName.[0..fullName.Length - 3] fullName.[fullName.Length - 1..]
Some [|String.Join (".", fullNameWithoutClassName)|]
else None
| _ -> None
// Operators
| TypedAstPatterns.MemberFunctionOrValue func ->
match func with
| TypedAstPatterns.Constructor _ ->
// full name of a constructor looks like "UnusedSymbolClassifierTests.PrivateClass.( .ctor )"
// to make well formed full name parts we cut "( .ctor )" from the tail.
let fullName = func.FullName
let ctorSuffix = ".( .ctor )"
let fullName =
if fullName.EndsWith ctorSuffix then
fullName.[0..fullName.Length - ctorSuffix.Length - 1]
else fullName
Some [| fullName |]
| _ ->
Some [| yield func.FullName
match func.TryGetFullCompiledOperatorNameIdents() with
| Some idents -> yield String.concat "." idents
| None -> ()
|]
| TypedAstPatterns.FSharpEntity e ->
match e with
| e, TypedAstPatterns.Attribute, _ ->
e.TryGetFullName ()
|> Option.map (fun fullName ->
[| fullName; fullName.Substring(0, fullName.Length - "Attribute".Length) |])
| e, _, _ ->
e.TryGetFullName () |> Option.map (fun fullName -> [| fullName |])
| TypedAstPatterns.RecordField _
| TypedAstPatterns.UnionCase _ as symbol ->
Some [| let fullName = symbol.FullName
yield fullName
let idents = fullName.Split '.'
// Union cases/Record fields can be accessible without mentioning the enclosing type.
// So we add a FullName without having the type part.
if idents.Length > 1 then
yield String.Join (".", Array.append idents.[0..idents.Length - 3] idents.[idents.Length - 1..])
|]
| _ -> None
|> Option.defaultValue [|symbolUse.Symbol.FullName|]
|> Array.map (fun fullName -> fullName.Split '.')
{ SymbolUse = symbolUse
IsUsed = true
FullNames = fullNames
})
return allSymbolsUses
}
...@@ -33,7 +33,7 @@ open Microsoft.VisualStudio.ComponentModelHost ...@@ -33,7 +33,7 @@ open Microsoft.VisualStudio.ComponentModelHost
// Workaround to access non-public settings persistence type. // Workaround to access non-public settings persistence type.
// GetService( ) with this will work as long as the GUID matches the real type. // GetService( ) with this will work as long as the GUID matches the real type.
[<Guid(FSharpCommonConstants.svsSettingsPersistenceManagerGuidString)>] [<Guid(FSharpConstants.svsSettingsPersistenceManagerGuidString)>]
type internal SVsSettingsPersistenceManager = class end type internal SVsSettingsPersistenceManager = class end
// Exposes FSharpChecker as MEF export // Exposes FSharpChecker as MEF export
...@@ -176,7 +176,7 @@ type internal RoamingProfileStorageLocation(keyName: string) = ...@@ -176,7 +176,7 @@ type internal RoamingProfileStorageLocation(keyName: string) =
match languageName with match languageName with
| null -> unsubstitutedKeyName | null -> unsubstitutedKeyName
| _ -> | _ ->
let substituteLanguageName = if languageName = FSharpCommonConstants.FSharpLanguageName then "FSharp" else languageName let substituteLanguageName = if languageName = FSharpConstants.FSharpLanguageName then "FSharp" else languageName
unsubstitutedKeyName.Replace("%LANGUAGE%", substituteLanguageName) unsubstitutedKeyName.Replace("%LANGUAGE%", substituteLanguageName)
[<Composition.Shared>] [<Composition.Shared>]
...@@ -194,9 +194,9 @@ type internal FSharpCheckerWorkspaceServiceFactory ...@@ -194,9 +194,9 @@ type internal FSharpCheckerWorkspaceServiceFactory
member this.ProjectInfoManager = projectInfoManager } member this.ProjectInfoManager = projectInfoManager }
type type
[<Guid(FSharpCommonConstants.packageGuidString)>] [<Guid(FSharpConstants.packageGuidString)>]
[<ProvideLanguageService(languageService = typeof<FSharpLanguageService>, [<ProvideLanguageService(languageService = typeof<FSharpLanguageService>,
strLanguageName = FSharpCommonConstants.FSharpLanguageName, strLanguageName = FSharpConstants.FSharpLanguageName,
languageResourceID = 100, languageResourceID = 100,
MatchBraces = true, MatchBraces = true,
MatchBracesAtCaret = true, MatchBracesAtCaret = true,
...@@ -214,7 +214,7 @@ type ...@@ -214,7 +214,7 @@ type
internal FSharpPackage() = internal FSharpPackage() =
inherit AbstractPackage<FSharpPackage, FSharpLanguageService>() inherit AbstractPackage<FSharpPackage, FSharpLanguageService>()
override this.RoslynLanguageName = FSharpCommonConstants.FSharpLanguageName override this.RoslynLanguageName = FSharpConstants.FSharpLanguageName
override this.CreateWorkspace() = this.ComponentModel.GetService<VisualStudioWorkspaceImpl>() override this.CreateWorkspace() = this.ComponentModel.GetService<VisualStudioWorkspaceImpl>()
...@@ -226,19 +226,19 @@ type ...@@ -226,19 +226,19 @@ type
override this.RegisterMiscellaneousFilesWorkspaceInformation(_) = () override this.RegisterMiscellaneousFilesWorkspaceInformation(_) = ()
and and
[<Guid(FSharpCommonConstants.languageServiceGuidString)>] [<Guid(FSharpConstants.languageServiceGuidString)>]
[<ProvideLanguageExtension(typeof<FSharpLanguageService>, ".fs")>] [<ProvideLanguageExtension(typeof<FSharpLanguageService>, ".fs")>]
[<ProvideLanguageExtension(typeof<FSharpLanguageService>, ".fsi")>] [<ProvideLanguageExtension(typeof<FSharpLanguageService>, ".fsi")>]
[<ProvideLanguageExtension(typeof<FSharpLanguageService>, ".fsx")>] [<ProvideLanguageExtension(typeof<FSharpLanguageService>, ".fsx")>]
[<ProvideLanguageExtension(typeof<FSharpLanguageService>, ".fsscript")>] [<ProvideLanguageExtension(typeof<FSharpLanguageService>, ".fsscript")>]
[<ProvideLanguageExtension(typeof<FSharpLanguageService>, ".ml")>] [<ProvideLanguageExtension(typeof<FSharpLanguageService>, ".ml")>]
[<ProvideLanguageExtension(typeof<FSharpLanguageService>, ".mli")>] [<ProvideLanguageExtension(typeof<FSharpLanguageService>, ".mli")>]
[<ProvideEditorExtension(FSharpCommonConstants.editorFactoryGuidString, ".fs", 97)>] [<ProvideEditorExtension(FSharpConstants.editorFactoryGuidString, ".fs", 97)>]
[<ProvideEditorExtension(FSharpCommonConstants.editorFactoryGuidString, ".fsi", 97)>] [<ProvideEditorExtension(FSharpConstants.editorFactoryGuidString, ".fsi", 97)>]
[<ProvideEditorExtension(FSharpCommonConstants.editorFactoryGuidString, ".fsx", 97)>] [<ProvideEditorExtension(FSharpConstants.editorFactoryGuidString, ".fsx", 97)>]
[<ProvideEditorExtension(FSharpCommonConstants.editorFactoryGuidString, ".fsscript", 97)>] [<ProvideEditorExtension(FSharpConstants.editorFactoryGuidString, ".fsscript", 97)>]
[<ProvideEditorExtension(FSharpCommonConstants.editorFactoryGuidString, ".ml", 97)>] [<ProvideEditorExtension(FSharpConstants.editorFactoryGuidString, ".ml", 97)>]
[<ProvideEditorExtension(FSharpCommonConstants.editorFactoryGuidString, ".mli", 97)>] [<ProvideEditorExtension(FSharpConstants.editorFactoryGuidString, ".mli", 97)>]
internal FSharpLanguageService(package : FSharpPackage) = internal FSharpLanguageService(package : FSharpPackage) =
inherit AbstractLanguageService<FSharpPackage, FSharpLanguageService>(package) inherit AbstractLanguageService<FSharpPackage, FSharpLanguageService>(package)
...@@ -260,8 +260,8 @@ and ...@@ -260,8 +260,8 @@ and
override this.Initialize() = override this.Initialize() =
base.Initialize() base.Initialize()
this.Workspace.Options <- this.Workspace.Options.WithChangedOption(Completion.CompletionOptions.BlockForCompletionItems, FSharpCommonConstants.FSharpLanguageName, false) this.Workspace.Options <- this.Workspace.Options.WithChangedOption(Completion.CompletionOptions.BlockForCompletionItems, FSharpConstants.FSharpLanguageName, false)
this.Workspace.Options <- this.Workspace.Options.WithChangedOption(Shared.Options.ServiceFeatureOnOffOptions.ClosedFileDiagnostic, FSharpCommonConstants.FSharpLanguageName, Nullable false) this.Workspace.Options <- this.Workspace.Options.WithChangedOption(Shared.Options.ServiceFeatureOnOffOptions.ClosedFileDiagnostic, FSharpConstants.FSharpLanguageName, Nullable false)
this.Workspace.DocumentClosed.Add <| fun args -> this.Workspace.DocumentClosed.Add <| fun args ->
tryRemoveSingleFileProject args.Document.Project.Id tryRemoveSingleFileProject args.Document.Project.Id
...@@ -331,14 +331,14 @@ and ...@@ -331,14 +331,14 @@ and
let projectContext = let projectContext =
projectContextFactory.CreateProjectContext( projectContextFactory.CreateProjectContext(
FSharpCommonConstants.FSharpLanguageName, projectDisplayName, projectFileName, projectGuid, siteProvider, null, errorReporter) FSharpConstants.FSharpLanguageName, projectDisplayName, projectFileName, projectGuid, siteProvider, null, errorReporter)
let project = projectContext :?> AbstractProject let project = projectContext :?> AbstractProject
this.SyncProject(project, projectContext, site, forceUpdate=false) this.SyncProject(project, projectContext, site, forceUpdate=false)
site.AdviseProjectSiteChanges(FSharpCommonConstants.FSharpLanguageServiceCallbackName, site.AdviseProjectSiteChanges(FSharpConstants.FSharpLanguageServiceCallbackName,
AdviseProjectSiteChanges(fun () -> this.SyncProject(project, projectContext, site, forceUpdate=true))) AdviseProjectSiteChanges(fun () -> this.SyncProject(project, projectContext, site, forceUpdate=true)))
site.AdviseProjectSiteClosed(FSharpCommonConstants.FSharpLanguageServiceCallbackName, site.AdviseProjectSiteClosed(FSharpConstants.FSharpLanguageServiceCallbackName,
AdviseProjectSiteChanges(fun () -> AdviseProjectSiteChanges(fun () ->
projectInfoManager.ClearProjectInfo(project.Id) projectInfoManager.ClearProjectInfo(project.Id)
project.Disconnect())) project.Disconnect()))
...@@ -363,17 +363,17 @@ and ...@@ -363,17 +363,17 @@ and
let projectContextFactory = package.ComponentModel.GetService<IWorkspaceProjectContextFactory>(); let projectContextFactory = package.ComponentModel.GetService<IWorkspaceProjectContextFactory>();
let errorReporter = ProjectExternalErrorReporter(projectId, "FS", this.SystemServiceProvider) let errorReporter = ProjectExternalErrorReporter(projectId, "FS", this.SystemServiceProvider)
let projectContext = projectContextFactory.CreateProjectContext(FSharpCommonConstants.FSharpLanguageName, projectDisplayName, projectFileName, projectId.Id, hier, null, errorReporter) let projectContext = projectContextFactory.CreateProjectContext(FSharpConstants.FSharpLanguageName, projectDisplayName, projectFileName, projectId.Id, hier, null, errorReporter)
projectContext.AddSourceFile(fileName) projectContext.AddSourceFile(fileName)
let project = projectContext :?> AbstractProject let project = projectContext :?> AbstractProject
singleFileProjects.[projectId] <- project singleFileProjects.[projectId] <- project
override this.ContentTypeName = FSharpCommonConstants.FSharpContentTypeName override this.ContentTypeName = FSharpConstants.FSharpContentTypeName
override this.LanguageName = FSharpCommonConstants.FSharpLanguageName override this.LanguageName = FSharpConstants.FSharpLanguageName
override this.RoslynLanguageName = FSharpCommonConstants.FSharpLanguageName override this.RoslynLanguageName = FSharpConstants.FSharpLanguageName
override this.LanguageServiceId = new Guid(FSharpCommonConstants.languageServiceGuidString) override this.LanguageServiceId = new Guid(FSharpConstants.languageServiceGuidString)
override this.DebuggerLanguageId = DebuggerEnvironment.GetLanguageID() override this.DebuggerLanguageId = DebuggerEnvironment.GetLanguageID()
override this.CreateContext(_,_,_,_,_) = raise(System.NotImplementedException()) override this.CreateContext(_,_,_,_,_) = raise(System.NotImplementedException())
......
...@@ -11,6 +11,8 @@ open Microsoft.CodeAnalysis ...@@ -11,6 +11,8 @@ open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.Text
open Microsoft.FSharp.Compiler.SourceCodeServices open Microsoft.FSharp.Compiler.SourceCodeServices
open Symbols
module internal SymbolHelpers = module internal SymbolHelpers =
let getSymbolUsesInSolution (symbol: FSharpSymbol, declLoc: SymbolDeclarationLocation, checkFileResults: FSharpCheckFileResults, let getSymbolUsesInSolution (symbol: FSharpSymbol, declLoc: SymbolDeclarationLocation, checkFileResults: FSharpCheckFileResults,
...@@ -63,7 +65,7 @@ module internal SymbolHelpers = ...@@ -63,7 +65,7 @@ module internal SymbolHelpers =
do! Option.guard (originalText.Length > 0) do! Option.guard (originalText.Length > 0)
let! options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject document let! options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject document
let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, options.OtherOptions |> Seq.toList) let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, options.OtherOptions |> Seq.toList)
let! symbol = CommonHelpers.getSymbolAtPosition(document.Id, sourceText, symbolSpan.Start, document.FilePath, defines, SymbolLookupKind.Greedy) let! symbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, symbolSpan.Start, document.FilePath, defines, Tokenizer.SymbolLookupKind.Greedy)
let! _, _, checkFileResults = checker.ParseAndCheckDocument(document, options, allowStaleResults = true) let! _, _, checkFileResults = checker.ParseAndCheckDocument(document, options, allowStaleResults = true)
let textLine = sourceText.Lines.GetLineFromPosition(symbolSpan.Start) let textLine = sourceText.Lines.GetLineFromPosition(symbolSpan.Start)
let textLinePos = sourceText.Lines.GetLinePosition(symbolSpan.Start) let textLinePos = sourceText.Lines.GetLinePosition(symbolSpan.Start)
...@@ -85,10 +87,10 @@ module internal SymbolHelpers = ...@@ -85,10 +87,10 @@ module internal SymbolHelpers =
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let mutable sourceText = sourceText let mutable sourceText = sourceText
for symbolUse in symbolUses do for symbolUse in symbolUses do
let textSpan = CommonHelpers.fixupSpan(sourceText, CommonRoslynHelpers.FSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate)) let textSpan = Tokenizer.fixupSpan(sourceText, RoslynHelpers.FSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate))
sourceText <- sourceText.Replace(textSpan, newText) sourceText <- sourceText.Replace(textSpan, newText)
solution <- solution.WithDocumentText(documentId, sourceText) solution <- solution.WithDocumentText(documentId, sourceText)
return solution return solution
} |> CommonRoslynHelpers.StartAsyncAsTask cancellationToken), } |> RoslynHelpers.StartAsyncAsTask cancellationToken),
originalText originalText
} }
[<AutoOpen>]
module internal Microsoft.VisualStudio.FSharp.Editor.Symbols
open System
open System.Collections.Generic
open System.Threading
open System.Threading.Tasks
open System.Runtime.CompilerServices
open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.Classification
open Microsoft.CodeAnalysis.Text
open Microsoft.VisualStudio.FSharp.LanguageService
open Microsoft.FSharp.Compiler
open Microsoft.FSharp.Compiler.Ast
open Microsoft.FSharp.Compiler.SourceCodeServices
open System.IO
[<RequireQualifiedAccess; NoComparison>]
type SymbolDeclarationLocation =
| CurrentDocument
| Projects of Project list * isLocalForProject: bool
[<NoComparison>]
type SymbolUse =
{ SymbolUse: FSharpSymbolUse
IsUsed: bool
FullNames: Idents[] }
type FSharpSymbol with
member this.IsInternalToProject =
match this with
| :? FSharpParameter -> true
| :? FSharpMemberOrFunctionOrValue as m -> not m.IsModuleValueOrMember || not m.Accessibility.IsPublic
| :? FSharpEntity as m -> not m.Accessibility.IsPublic
| :? FSharpGenericParameter -> true
| :? FSharpUnionCase as m -> not m.Accessibility.IsPublic
| :? FSharpField as m -> not m.Accessibility.IsPublic
| _ -> false
type FSharpSymbolUse with
member this.GetDeclarationLocation (currentDocument: Document) : SymbolDeclarationLocation option =
if this.IsPrivateToFile then
Some SymbolDeclarationLocation.CurrentDocument
else
let isSymbolLocalForProject = this.Symbol.IsInternalToProject
let declarationLocation =
match this.Symbol.ImplementationLocation with
| Some x -> Some x
| None -> this.Symbol.DeclarationLocation
match declarationLocation with
| Some loc ->
let filePath = Path.GetFullPathSafe loc.FileName
let isScript = isScriptFile filePath
if isScript && filePath = currentDocument.FilePath then
Some SymbolDeclarationLocation.CurrentDocument
elif isScript then
// The standalone script might include other files via '#load'
// These files appear in project options and the standalone file
// should be treated as an individual project
Some (SymbolDeclarationLocation.Projects ([currentDocument.Project], isSymbolLocalForProject))
else
let projects =
currentDocument.Project.Solution.GetDocumentIdsWithFilePath(filePath)
|> Seq.map (fun x -> x.ProjectId)
|> Seq.distinct
|> Seq.map currentDocument.Project.Solution.GetProject
|> Seq.toList
match projects with
| [] -> None
| projects -> Some (SymbolDeclarationLocation.Projects (projects, isSymbolLocalForProject))
| None -> None
member this.IsPrivateToFile =
let isPrivate =
match this.Symbol with
| :? FSharpMemberOrFunctionOrValue as m -> not m.IsModuleValueOrMember || m.Accessibility.IsPrivate
| :? FSharpEntity as m -> m.Accessibility.IsPrivate
| :? FSharpGenericParameter -> true
| :? FSharpUnionCase as m -> m.Accessibility.IsPrivate
| :? FSharpField as m -> m.Accessibility.IsPrivate
| _ -> false
let declarationLocation =
match this.Symbol.SignatureLocation with
| Some x -> Some x
| _ ->
match this.Symbol.DeclarationLocation with
| Some x -> Some x
| _ -> this.Symbol.ImplementationLocation
let declaredInTheFile =
match declarationLocation with
| Some declRange -> declRange.FileName = this.RangeAlternate.FileName
| _ -> false
isPrivate && declaredInTheFile
type FSharpMemberOrFunctionOrValue with
member x.IsConstructor = x.CompiledName = ".ctor"
member x.IsOperatorOrActivePattern =
let name = x.DisplayName
if name.StartsWith "( " && name.EndsWith " )" && name.Length > 4
then name.Substring (2, name.Length - 4) |> String.forall (fun c -> c <> ' ')
else false
member x.EnclosingEntitySafe =
try
Some x.EnclosingEntity
with :? InvalidOperationException -> None
type FSharpEntity with
member x.AllBaseTypes =
let rec allBaseTypes (entity:FSharpEntity) =
[
match entity.TryFullName with
| Some _ ->
match entity.BaseType with
| Some bt ->
yield bt
if bt.HasTypeDefinition then
yield! allBaseTypes bt.TypeDefinition
| _ -> ()
| _ -> ()
]
allBaseTypes x
/// Active patterns over `FSharpSymbolUse`.
module SymbolUse =
let (|ActivePatternCase|_|) (symbol : FSharpSymbolUse) =
match symbol.Symbol with
| :? FSharpActivePatternCase as ap-> ActivePatternCase(ap) |> Some
| _ -> None
let private attributeSuffixLength = "Attribute".Length
let (|Entity|_|) (symbol : FSharpSymbolUse) : (FSharpEntity * (* cleanFullNames *) string list) option =
match symbol.Symbol with
| :? FSharpEntity as ent ->
// strip generic parameters count suffix (List`1 => List)
let cleanFullName =
// `TryFullName` for type aliases is always `None`, so we have to make one by our own
if ent.IsFSharpAbbreviation then
[ent.AccessPath + "." + ent.DisplayName]
else
ent.TryFullName
|> Option.toList
|> List.map (fun fullName ->
if ent.GenericParameters.Count > 0 && fullName.Length > 2 then
fullName.[0..fullName.Length - 3]
else fullName)
let cleanFullNames =
cleanFullName
|> List.collect (fun cleanFullName ->
if ent.IsAttributeType then
[cleanFullName; cleanFullName.[0..cleanFullName.Length - attributeSuffixLength - 1]]
else [cleanFullName]
)
Some (ent, cleanFullNames)
| _ -> None
let (|Field|_|) (symbol : FSharpSymbolUse) =
match symbol.Symbol with
| :? FSharpField as field-> Some field
| _ -> None
let (|GenericParameter|_|) (symbol: FSharpSymbolUse) =
match symbol.Symbol with
| :? FSharpGenericParameter as gp -> Some gp
| _ -> None
let (|MemberFunctionOrValue|_|) (symbol : FSharpSymbolUse) =
match symbol.Symbol with
| :? FSharpMemberOrFunctionOrValue as func -> Some func
| _ -> None
let (|ActivePattern|_|) = function
| MemberFunctionOrValue m when m.IsActivePattern -> Some m | _ -> None
let (|Parameter|_|) (symbol : FSharpSymbolUse) =
match symbol.Symbol with
| :? FSharpParameter as param -> Some param
| _ -> None
let (|StaticParameter|_|) (symbol : FSharpSymbolUse) =
match symbol.Symbol with
| :? FSharpStaticParameter as sp -> Some sp
| _ -> None
let (|UnionCase|_|) (symbol : FSharpSymbolUse) =
match symbol.Symbol with
| :? FSharpUnionCase as uc-> Some uc
| _ -> None
//let (|Constructor|_|) = function
// | MemberFunctionOrValue func when func.IsConstructor || func.IsImplicitConstructor -> Some func
// | _ -> None
let (|TypeAbbreviation|_|) = function
| Entity (entity, _) when entity.IsFSharpAbbreviation -> Some entity
| _ -> None
let (|Class|_|) = function
| Entity (entity, _) when entity.IsClass -> Some entity
| Entity (entity, _) when entity.IsFSharp &&
entity.IsOpaque &&
not entity.IsFSharpModule &&
not entity.IsNamespace &&
not entity.IsDelegate &&
not entity.IsFSharpUnion &&
not entity.IsFSharpRecord &&
not entity.IsInterface &&
not entity.IsValueType -> Some entity
| _ -> None
let (|Delegate|_|) = function
| Entity (entity, _) when entity.IsDelegate -> Some entity
| _ -> None
let (|Event|_|) = function
| MemberFunctionOrValue symbol when symbol.IsEvent -> Some symbol
| _ -> None
let (|Property|_|) = function
| MemberFunctionOrValue symbol when symbol.IsProperty || symbol.IsPropertyGetterMethod || symbol.IsPropertySetterMethod -> Some symbol
| _ -> None
let inline private notCtorOrProp (symbol:FSharpMemberOrFunctionOrValue) =
not symbol.IsConstructor && not symbol.IsPropertyGetterMethod && not symbol.IsPropertySetterMethod
let (|Method|_|) (symbolUse:FSharpSymbolUse) =
match symbolUse with
| MemberFunctionOrValue symbol when
symbol.IsModuleValueOrMember &&
not symbolUse.IsFromPattern &&
not symbol.IsOperatorOrActivePattern &&
not symbol.IsPropertyGetterMethod &&
not symbol.IsPropertySetterMethod -> Some symbol
| _ -> None
let (|Function|_|) (symbolUse:FSharpSymbolUse) =
match symbolUse with
| MemberFunctionOrValue symbol when
notCtorOrProp symbol &&
symbol.IsModuleValueOrMember &&
not symbol.IsOperatorOrActivePattern &&
not symbolUse.IsFromPattern ->
match symbol.FullTypeSafe with
| Some fullType when fullType.IsFunctionType -> Some symbol
| _ -> None
| _ -> None
let (|Operator|_|) (symbolUse:FSharpSymbolUse) =
match symbolUse with
| MemberFunctionOrValue symbol when
notCtorOrProp symbol &&
not symbolUse.IsFromPattern &&
not symbol.IsActivePattern &&
symbol.IsOperatorOrActivePattern ->
match symbol.FullTypeSafe with
| Some fullType when fullType.IsFunctionType -> Some symbol
| _ -> None
| _ -> None
let (|Pattern|_|) (symbolUse:FSharpSymbolUse) =
match symbolUse with
| MemberFunctionOrValue symbol when
notCtorOrProp symbol &&
not symbol.IsOperatorOrActivePattern &&
symbolUse.IsFromPattern ->
match symbol.FullTypeSafe with
| Some fullType when fullType.IsFunctionType ->Some symbol
| _ -> None
| _ -> None
let (|ClosureOrNestedFunction|_|) = function
| MemberFunctionOrValue symbol when
notCtorOrProp symbol &&
not symbol.IsOperatorOrActivePattern &&
not symbol.IsModuleValueOrMember ->
match symbol.FullTypeSafe with
| Some fullType when fullType.IsFunctionType -> Some symbol
| _ -> None
| _ -> None
let (|Val|_|) = function
| MemberFunctionOrValue symbol when notCtorOrProp symbol &&
not symbol.IsOperatorOrActivePattern ->
match symbol.FullTypeSafe with
| Some _fullType -> Some symbol
| _ -> None
| _ -> None
let (|Enum|_|) = function
| Entity (entity, _) when entity.IsEnum -> Some entity
| _ -> None
let (|Interface|_|) = function
| Entity (entity, _) when entity.IsInterface -> Some entity
| _ -> None
let (|Module|_|) = function
| Entity (entity, _) when entity.IsFSharpModule -> Some entity
| _ -> None
let (|Namespace|_|) = function
| Entity (entity, _) when entity.IsNamespace -> Some entity
| _ -> None
let (|Record|_|) = function
| Entity (entity, _) when entity.IsFSharpRecord -> Some entity
| _ -> None
let (|Union|_|) = function
| Entity (entity, _) when entity.IsFSharpUnion -> Some entity
| _ -> None
let (|ValueType|_|) = function
| Entity (entity, _) when entity.IsValueType && not entity.IsEnum -> Some entity
| _ -> None
let (|ComputationExpression|_|) (symbol:FSharpSymbolUse) =
if symbol.IsFromComputationExpression then Some symbol
else None
let (|Attribute|_|) = function
| Entity (entity, _) when entity.IsAttributeType -> Some entity
| _ -> None
\ No newline at end of file
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) =
// CompiledName throws exception on DataContractAttribute generated by SQLProvider
match Option.attempt (fun _ -> attribute.AttributeType.CompiledName) with
| Some name when name = typeof<'T>.Name -> true
| _ -> false
let tryGetAttribute<'T> (attributes: seq<FSharpAttribute>) =
attributes |> Seq.tryFind isAttribute<'T>
let hasModuleSuffixAttribute (entity: FSharpEntity) =
entity.Attributes
|> tryGetAttribute<CompilationRepresentationAttribute>
|> Option.bind (fun a ->
Option.attempt (fun _ -> a.ConstructorArguments)
|> Option.bind (fun args -> args |> Seq.tryPick (fun (_, arg) ->
let res =
match arg with
| :? int32 as arg when arg = int CompilationRepresentationFlags.ModuleSuffix ->
Some()
| :? CompilationRepresentationFlags as arg when arg = CompilationRepresentationFlags.ModuleSuffix ->
Some()
| _ ->
None
res)))
|> Option.isSome
let isOperator (name: string) =
name.StartsWith "( " && name.EndsWith " )" && name.Length > 4
&& name.Substring (2, name.Length - 4)
|> String.forall (fun c -> c <> ' ' && not (Char.IsLetter c))
let private UnnamedUnionFieldRegex = Regex("^Item(\d+)?$", RegexOptions.Compiled)
let isUnnamedUnionCaseField (field: FSharpField) = UnnamedUnionFieldRegex.IsMatch(field.Name)
module TypedAstPatterns =
let (|AbbreviatedType|_|) (entity: FSharpEntity) =
if entity.IsFSharpAbbreviation then Some entity.AbbreviatedType
else None
let (|TypeWithDefinition|_|) (ty: FSharpType) =
if ty.HasTypeDefinition then Some ty.TypeDefinition
else None
let rec getEntityAbbreviatedType (entity: FSharpEntity) =
if entity.IsFSharpAbbreviation then
match entity.AbbreviatedType with
| TypeWithDefinition def -> getEntityAbbreviatedType def
| abbreviatedType -> entity, Some abbreviatedType
else entity, None
let rec getAbbreviatedType (fsharpType: FSharpType) =
if fsharpType.IsAbbreviation then
getAbbreviatedType fsharpType.AbbreviatedType
else fsharpType
let (|Attribute|_|) (entity: FSharpEntity) =
let isAttribute (entity: FSharpEntity) =
let getBaseType (entity: FSharpEntity) =
try
match entity.BaseType with
| Some (TypeWithDefinition def) -> Some def
| _ -> None
with _ -> None
let rec isAttributeType (ty: FSharpEntity option) =
match ty with
| None -> false
| Some ty ->
match ty.TryGetFullName() with
| None -> false
| Some fullName ->
fullName = "System.Attribute" || isAttributeType (getBaseType ty)
isAttributeType (Some entity)
if isAttribute entity then Some() else None
let (|ValueType|_|) (e: FSharpEntity) =
if e.IsEnum || e.IsValueType || hasAttribute<MeasureAnnotatedAbbreviationAttribute> e.Attributes then Some()
else None
let (|Class|_|) (original: FSharpEntity, abbreviated: FSharpEntity, _) =
if abbreviated.IsClass
&& (not abbreviated.IsStaticInstantiation || original.IsFSharpAbbreviation) then Some()
else None
let (|Record|_|) (e: FSharpEntity) = if e.IsFSharpRecord then Some() else None
let (|UnionType|_|) (e: FSharpEntity) = if e.IsFSharpUnion then Some() else None
let (|Delegate|_|) (e: FSharpEntity) = if e.IsDelegate then Some() else None
let (|FSharpException|_|) (e: FSharpEntity) = if e.IsFSharpExceptionDeclaration then Some() else None
let (|Interface|_|) (e: FSharpEntity) = if e.IsInterface then Some() else None
let (|AbstractClass|_|) (e: FSharpEntity) =
if hasAttribute<AbstractClassAttribute> e.Attributes then Some() else None
let (|FSharpType|_|) (e: FSharpEntity) =
if e.IsDelegate || e.IsFSharpExceptionDeclaration || e.IsFSharpRecord || e.IsFSharpUnion
|| e.IsInterface || e.IsMeasure
|| (e.IsFSharp && e.IsOpaque && not e.IsFSharpModule && not e.IsNamespace) then Some()
else None
let (|ProvidedType|_|) (e: FSharpEntity) =
if (e.IsProvided || e.IsProvidedAndErased || e.IsProvidedAndGenerated) && e.CompiledName = e.DisplayName then
Some()
else None
let (|ByRef|_|) (e: FSharpEntity) = if e.IsByRef then Some() else None
let (|Array|_|) (e: FSharpEntity) = if e.IsArrayType then Some() else None
let (|FSharpModule|_|) (entity: FSharpEntity) = if entity.IsFSharpModule then Some() else None
let (|Namespace|_|) (entity: FSharpEntity) = if entity.IsNamespace then Some() else None
let (|ProvidedAndErasedType|_|) (entity: FSharpEntity) = if entity.IsProvidedAndErased then Some() else None
let (|Enum|_|) (entity: FSharpEntity) = if entity.IsEnum then Some() else None
let (|Tuple|_|) (ty: FSharpType option) =
ty |> Option.bind (fun ty -> if ty.IsTupleType then Some() else None)
let (|RefCell|_|) (ty: FSharpType) =
match getAbbreviatedType ty with
| TypeWithDefinition def when
def.IsFSharpRecord && def.FullName = "Microsoft.FSharp.Core.FSharpRef`1" -> Some()
| _ -> None
let (|FunctionType|_|) (ty: FSharpType) =
if ty.IsFunctionType then Some()
else None
let (|Pattern|_|) (symbol: FSharpSymbol) =
match symbol with
| :? FSharpUnionCase
| :? FSharpActivePatternCase -> Some()
| _ -> None
/// Field (field, fieldAbbreviatedType)
let (|Field|_|) (symbol: FSharpSymbol) =
match symbol with
| :? FSharpField as field -> Some (field, getAbbreviatedType field.FieldType)
| _ -> None
let (|MutableVar|_|) (symbol: FSharpSymbol) =
let isMutable =
match symbol with
| :? FSharpField as field -> field.IsMutable && not field.IsLiteral
| :? FSharpMemberOrFunctionOrValue as func -> func.IsMutable
| _ -> false
if isMutable then Some() else None
/// Entity (originalEntity, abbreviatedEntity, abbreviatedType)
let (|FSharpEntity|_|) (symbol: FSharpSymbol) =
match symbol with
| :? FSharpEntity as entity ->
let abbreviatedEntity, abbreviatedType = getEntityAbbreviatedType entity
Some (entity, abbreviatedEntity, abbreviatedType)
| _ -> None
let (|Parameter|_|) (symbol: FSharpSymbol) =
match symbol with
| :? FSharpParameter -> Some()
| _ -> None
let (|UnionCase|_|) (e: FSharpSymbol) =
match e with
| :? FSharpUnionCase as uc -> Some uc
| _ -> None
let (|RecordField|_|) (e: FSharpSymbol) =
match e with
| :? FSharpField as field ->
if field.DeclaringEntity.IsFSharpRecord then Some field else None
| _ -> None
let (|ActivePatternCase|_|) (symbol: FSharpSymbol) =
match symbol with
| :? FSharpActivePatternCase as case -> Some case
| _ -> None
/// Func (memberFunctionOrValue, fullType)
let (|MemberFunctionOrValue|_|) (symbol: FSharpSymbol) =
match symbol with
| :? FSharpMemberOrFunctionOrValue as func -> Some func
| _ -> None
/// Constructor (enclosingEntity)
let (|Constructor|_|) (func: FSharpMemberOrFunctionOrValue) =
match func.CompiledName with
| ".ctor" | ".cctor" -> Some func.EnclosingEntity
| _ -> None
let (|Function|_|) excluded (func: FSharpMemberOrFunctionOrValue) =
match func.FullTypeSafe |> Option.map getAbbreviatedType with
| Some typ when typ.IsFunctionType
&& not func.IsPropertyGetterMethod
&& not func.IsPropertySetterMethod
&& not excluded
&& not (isOperator func.DisplayName) -> Some()
| _ -> None
let (|ExtensionMember|_|) (func: FSharpMemberOrFunctionOrValue) =
if func.IsExtensionMember then Some() else None
let (|Event|_|) (func: FSharpMemberOrFunctionOrValue) =
if func.IsEvent then Some () else None
\ No newline at end of file
...@@ -15,7 +15,7 @@ open Microsoft.CodeAnalysis.FindUsages ...@@ -15,7 +15,7 @@ open Microsoft.CodeAnalysis.FindUsages
open Microsoft.FSharp.Compiler.Range open Microsoft.FSharp.Compiler.Range
open Microsoft.FSharp.Compiler.SourceCodeServices open Microsoft.FSharp.Compiler.SourceCodeServices
[<ExportLanguageService(typeof<IFindUsagesService>, FSharpCommonConstants.FSharpLanguageName); Shared>] [<ExportLanguageService(typeof<IFindUsagesService>, FSharpConstants.FSharpLanguageName); Shared>]
type internal FSharpFindUsagesService type internal FSharpFindUsagesService
[<ImportingConstructor>] [<ImportingConstructor>]
( (
...@@ -34,9 +34,9 @@ type internal FSharpFindUsagesService ...@@ -34,9 +34,9 @@ type internal FSharpFindUsagesService
async { async {
let doc = solution.GetDocument(documentId) let doc = solution.GetDocument(documentId)
let! sourceText = doc.GetTextAsync(cancellationToken) let! sourceText = doc.GetTextAsync(cancellationToken)
match CommonRoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range) with match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range) with
| Some span -> | Some span ->
let span = CommonHelpers.fixupSpan(sourceText, span) let span = Tokenizer.fixupSpan(sourceText, span)
return Some (DocumentSpan(doc, span)) return Some (DocumentSpan(doc, span))
| None -> return None | None -> return None
}) })
...@@ -54,10 +54,10 @@ type internal FSharpFindUsagesService ...@@ -54,10 +54,10 @@ type internal FSharpFindUsagesService
let lineNumber = sourceText.Lines.GetLinePosition(position).Line + 1 let lineNumber = sourceText.Lines.GetLinePosition(position).Line + 1
let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.FilePath, options.OtherOptions |> Seq.toList) let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.FilePath, options.OtherOptions |> Seq.toList)
let! symbol = CommonHelpers.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy) let! symbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, Tokenizer.SymbolLookupKind.Greedy)
let! symbolUse = checkFileResults.GetSymbolUseAtLocation(lineNumber, symbol.Ident.idRange.EndColumn, textLine, symbol.FullIsland) 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! declaration = checkFileResults.GetDeclarationLocationAlternate (lineNumber, symbol.Ident.idRange.EndColumn, textLine, symbol.FullIsland, false) |> liftAsync
let tags = GlyphTags.GetTags(CommonRoslynHelpers.GetGlyphForSymbol (symbolUse.Symbol, symbol.Kind)) let tags = GlyphTags.GetTags(Tokenizer.GetGlyphForSymbol (symbolUse.Symbol, symbol.Kind))
let declarationRange = let declarationRange =
match declaration with match declaration with
...@@ -142,8 +142,8 @@ type internal FSharpFindUsagesService ...@@ -142,8 +142,8 @@ type internal FSharpFindUsagesService
interface IFindUsagesService with interface IFindUsagesService with
member __.FindReferencesAsync(document, position, context) = member __.FindReferencesAsync(document, position, context) =
findReferencedSymbolsAsync(document, position, context, true) findReferencedSymbolsAsync(document, position, context, true)
|> CommonRoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken)
member __.FindImplementationsAsync(document, position, context) = member __.FindImplementationsAsync(document, position, context) =
findReferencedSymbolsAsync(document, position, context, false) findReferencedSymbolsAsync(document, position, context, false)
|> CommonRoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken)
\ No newline at end of file
...@@ -45,7 +45,7 @@ module internal FSharpGoToDefinition = ...@@ -45,7 +45,7 @@ module internal FSharpGoToDefinition =
let textLine = sourceText.Lines.GetLineFromPosition position let textLine = sourceText.Lines.GetLineFromPosition position
let textLinePos = sourceText.Lines.GetLinePosition position let textLinePos = sourceText.Lines.GetLinePosition position
let fcsTextLineNumber = Line.fromZ textLinePos.Line let fcsTextLineNumber = Line.fromZ textLinePos.Line
let! lexerSymbol = CommonHelpers.getSymbolAtPosition(documentKey, sourceText, position, filePath, defines, SymbolLookupKind.Greedy) let! lexerSymbol = Tokenizer.getSymbolAtPosition(documentKey, sourceText, position, filePath, defines, Tokenizer.SymbolLookupKind.Greedy)
let! _, _, checkFileResults = let! _, _, checkFileResults =
checker.ParseAndCheckDocument checker.ParseAndCheckDocument
(filePath, textVersionHash, sourceText.ToString(), options, allowStaleResults = preferSignature) (filePath, textVersionHash, sourceText.ToString(), options, allowStaleResults = preferSignature)
...@@ -71,7 +71,7 @@ module internal FSharpGoToDefinition = ...@@ -71,7 +71,7 @@ module internal FSharpGoToDefinition =
let refDocumentId = refDocumentIds.First() let refDocumentId = refDocumentIds.First()
let refDocument = document.Project.Solution.GetDocument refDocumentId let refDocument = document.Project.Solution.GetDocument refDocumentId
let! refSourceText = refDocument.GetTextAsync() let! refSourceText = refDocument.GetTextAsync()
let refTextSpan = CommonRoslynHelpers.FSharpRangeToTextSpan (refSourceText, range) let refTextSpan = RoslynHelpers.FSharpRangeToTextSpan (refSourceText, range)
return Some (FSharpNavigableItem (refDocument, refTextSpan)) return Some (FSharpNavigableItem (refDocument, refTextSpan))
else return None else return None
} }
...@@ -83,12 +83,12 @@ module internal FSharpGoToDefinition = ...@@ -83,12 +83,12 @@ module internal FSharpGoToDefinition =
let! projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject originDocument let! projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject originDocument
let defines = CompilerEnvironment.GetCompilationDefinesForEditing (originDocument.FilePath, projectOptions.OtherOptions |> Seq.toList) let defines = CompilerEnvironment.GetCompilationDefinesForEditing (originDocument.FilePath, projectOptions.OtherOptions |> Seq.toList)
let originTextSpan = CommonRoslynHelpers.FSharpRangeToTextSpan (sourceText, originRange) let originTextSpan = RoslynHelpers.FSharpRangeToTextSpan (sourceText, originRange)
let position = originTextSpan.Start let position = originTextSpan.Start
let! lexerSymbol = let! lexerSymbol =
CommonHelpers.getSymbolAtPosition Tokenizer.getSymbolAtPosition
(originDocument.Id, sourceText, position, originDocument.FilePath, defines, SymbolLookupKind.Greedy) (originDocument.Id, sourceText, position, originDocument.FilePath, defines, Tokenizer.SymbolLookupKind.Greedy)
let textLinePos = sourceText.Lines.GetLinePosition position let textLinePos = sourceText.Lines.GetLinePosition position
let fcsTextLineNumber = Line.fromZ textLinePos.Line let fcsTextLineNumber = Line.fromZ textLinePos.Line
...@@ -115,7 +115,7 @@ module internal FSharpGoToDefinition = ...@@ -115,7 +115,7 @@ module internal FSharpGoToDefinition =
let! symbolUses = checkFileResults.GetUsesOfSymbolInFile symbol |> liftAsync let! symbolUses = checkFileResults.GetUsesOfSymbolInFile symbol |> liftAsync
let! implSymbol = symbolUses |> Array.tryHead let! implSymbol = symbolUses |> Array.tryHead
let implTextSpan = CommonRoslynHelpers.FSharpRangeToTextSpan (implSourceText, implSymbol.RangeAlternate) let implTextSpan = RoslynHelpers.FSharpRangeToTextSpan (implSourceText, implSymbol.RangeAlternate)
return FSharpNavigableItem (implDoc, implTextSpan) return FSharpNavigableItem (implDoc, implTextSpan)
else else
let! targetDocument = originDocument.Project.Solution.TryGetDocumentFromFSharpRange fsSymbolUse.RangeAlternate let! targetDocument = originDocument.Project.Solution.TryGetDocumentFromFSharpRange fsSymbolUse.RangeAlternate
...@@ -152,7 +152,7 @@ module internal FSharpGoToDefinition = ...@@ -152,7 +152,7 @@ module internal FSharpGoToDefinition =
open FSharpGoToDefinition open FSharpGoToDefinition
[<Shared>] [<Shared>]
[<ExportLanguageService (typeof<IGoToDefinitionService>, FSharpCommonConstants.FSharpLanguageName)>] [<ExportLanguageService (typeof<IGoToDefinitionService>, FSharpConstants.FSharpLanguageName)>]
[<Export (typeof<FSharpGoToDefinitionService>)>] [<Export (typeof<FSharpGoToDefinitionService>)>]
type internal FSharpGoToDefinitionService [<ImportingConstructor>] type internal FSharpGoToDefinitionService [<ImportingConstructor>]
(checkerProvider: FSharpCheckerProvider, (checkerProvider: FSharpCheckerProvider,
...@@ -253,7 +253,7 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>] ...@@ -253,7 +253,7 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>]
let textLine = sourceText.Lines.GetLineFromPosition position let textLine = sourceText.Lines.GetLineFromPosition position
let textLinePos = sourceText.Lines.GetLinePosition position let textLinePos = sourceText.Lines.GetLinePosition position
let fcsTextLineNumber = Line.fromZ textLinePos.Line let fcsTextLineNumber = Line.fromZ textLinePos.Line
let! lexerSymbol = CommonHelpers.getSymbolAtPosition(documentKey, sourceText, position, filePath, defines, SymbolLookupKind.Greedy) let! lexerSymbol = Tokenizer.getSymbolAtPosition(documentKey, sourceText, position, filePath, defines, Tokenizer.SymbolLookupKind.Greedy)
let! _, _, checkFileResults = let! _, _, checkFileResults =
checker.ParseAndCheckDocument checker.ParseAndCheckDocument
(filePath, textVersionHash, sourceText.ToString(), options, allowStaleResults = true) |> Async.RunSynchronously (filePath, textVersionHash, sourceText.ToString(), options, allowStaleResults = true) |> Async.RunSynchronously
...@@ -287,8 +287,8 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>] ...@@ -287,8 +287,8 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>]
checkerProvider.Checker.ParseAndCheckDocument (originDocument, projectOptions, allowStaleResults=true, sourceText=sourceText) checkerProvider.Checker.ParseAndCheckDocument (originDocument, projectOptions, allowStaleResults=true, sourceText=sourceText)
let! lexerSymbol = let! lexerSymbol =
CommonHelpers.getSymbolAtPosition Tokenizer.getSymbolAtPosition
(originDocument.Id, sourceText, position,originDocument.FilePath, defines, SymbolLookupKind.Greedy) (originDocument.Id, sourceText, position,originDocument.FilePath, defines, Tokenizer.SymbolLookupKind.Greedy)
let idRange = lexerSymbol.Ident.idRange let idRange = lexerSymbol.Ident.idRange
let! declarations = let! declarations =
...@@ -314,7 +314,7 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>] ...@@ -314,7 +314,7 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>]
findSymbolDeclarationInFile findSymbolDeclarationInFile
(targetSymbolUse, implFilePath, implSourceText.ToString(), checkerProvider.Checker, projectOptions, implVersion.GetHashCode()) (targetSymbolUse, implFilePath, implSourceText.ToString(), checkerProvider.Checker, projectOptions, implVersion.GetHashCode())
let implTextSpan = CommonRoslynHelpers.FSharpRangeToTextSpan (implSourceText, targetRange) let implTextSpan = RoslynHelpers.FSharpRangeToTextSpan (implSourceText, targetRange)
let navItem = FSharpNavigableItem (implDocument, implTextSpan) let navItem = FSharpNavigableItem (implDocument, implTextSpan)
results.Add navItem results.Add navItem
return results.AsEnumerable() return results.AsEnumerable()
...@@ -327,7 +327,7 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>] ...@@ -327,7 +327,7 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>]
| FSharpFindDeclResult.DeclFound targetRange -> | FSharpFindDeclResult.DeclFound targetRange ->
let! sigDocument = originDocument.Project.Solution.TryGetDocumentFromPath targetRange.FileName let! sigDocument = originDocument.Project.Solution.TryGetDocumentFromPath targetRange.FileName
let! sigSourceText = sigDocument.GetTextAsync () |> liftTaskAsync let! sigSourceText = sigDocument.GetTextAsync () |> liftTaskAsync
let sigTextSpan = CommonRoslynHelpers.FSharpRangeToTextSpan (sigSourceText, targetRange) let sigTextSpan = RoslynHelpers.FSharpRangeToTextSpan (sigSourceText, targetRange)
let navItem = FSharpNavigableItem (sigDocument, sigTextSpan) let navItem = FSharpNavigableItem (sigDocument, sigTextSpan)
results.Add navItem results.Add navItem
return results.AsEnumerable() return results.AsEnumerable()
...@@ -338,7 +338,7 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>] ...@@ -338,7 +338,7 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>]
else else
let! sigDocument = originDocument.Project.Solution.TryGetDocumentFromPath targetRange.FileName let! sigDocument = originDocument.Project.Solution.TryGetDocumentFromPath targetRange.FileName
let! sigSourceText = sigDocument.GetTextAsync () |> liftTaskAsync let! sigSourceText = sigDocument.GetTextAsync () |> liftTaskAsync
let sigTextSpan = CommonRoslynHelpers.FSharpRangeToTextSpan (sigSourceText, targetRange) let sigTextSpan = RoslynHelpers.FSharpRangeToTextSpan (sigSourceText, targetRange)
// if the gotodef call originated from a signature and the returned target is a signature, navigate there // if the gotodef call originated from a signature and the returned target is a signature, navigate there
if isSignatureFile targetRange.FileName && preferSignature then if isSignatureFile targetRange.FileName && preferSignature then
let navItem = FSharpNavigableItem (sigDocument, sigTextSpan) let navItem = FSharpNavigableItem (sigDocument, sigTextSpan)
...@@ -354,13 +354,13 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>] ...@@ -354,13 +354,13 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>]
let! targetRange = let! targetRange =
findSymbolDeclarationInFile findSymbolDeclarationInFile
(targetSymbolUse, implFilePath, implSourceText.ToString(), checkerProvider.Checker, projectOptions, implVersion.GetHashCode()) (targetSymbolUse, implFilePath, implSourceText.ToString(), checkerProvider.Checker, projectOptions, implVersion.GetHashCode())
let implTextSpan = CommonRoslynHelpers.FSharpRangeToTextSpan (implSourceText, targetRange) let implTextSpan = RoslynHelpers.FSharpRangeToTextSpan (implSourceText, targetRange)
let navItem = FSharpNavigableItem (implDocument, implTextSpan) let navItem = FSharpNavigableItem (implDocument, implTextSpan)
results.Add navItem results.Add navItem
return results.AsEnumerable() return results.AsEnumerable()
| _ -> return! None | _ -> return! None
} |> Async.map (Option.defaultValue Seq.empty) } |> Async.map (Option.defaultValue Seq.empty)
|> CommonRoslynHelpers.StartAsyncAsTask cancellationToken |> RoslynHelpers.StartAsyncAsTask cancellationToken
interface IGoToDefinitionService with interface IGoToDefinitionService with
......
...@@ -177,7 +177,7 @@ module private Utils = ...@@ -177,7 +177,7 @@ module private Utils =
| _ -> container.Name | _ -> container.Name
typeAsString + name typeAsString + name
[<ExportLanguageService(typeof<INavigateToSearchService>, FSharpCommonConstants.FSharpLanguageName); Shared>] [<ExportLanguageService(typeof<INavigateToSearchService>, FSharpConstants.FSharpLanguageName); Shared>]
type internal FSharpNavigateToSearchService type internal FSharpNavigateToSearchService
[<ImportingConstructor>] [<ImportingConstructor>]
( (
...@@ -195,7 +195,7 @@ type internal FSharpNavigateToSearchService ...@@ -195,7 +195,7 @@ type internal FSharpNavigateToSearchService
match parseResults.ParseTree |> Option.map NavigateTo.getNavigableItems with match parseResults.ParseTree |> Option.map NavigateTo.getNavigableItems with
| Some items -> | Some items ->
[| for item in items do [| for item in items do
let sourceSpan = CommonRoslynHelpers.FSharpRangeToTextSpan(sourceText, item.Range) let sourceSpan = RoslynHelpers.FSharpRangeToTextSpan(sourceText, item.Range)
let glyph = Utils.navigateToItemKindToGlyph item.Kind let glyph = Utils.navigateToItemKindToGlyph item.Kind
let kind = Utils.navigateToItemKindToRoslynKind item.Kind let kind = Utils.navigateToItemKindToRoslynKind item.Kind
let additionalInfo = Utils.containerToString item.Container document.Project let additionalInfo = Utils.containerToString item.Container document.Project
...@@ -257,7 +257,7 @@ type internal FSharpNavigateToSearchService ...@@ -257,7 +257,7 @@ type internal FSharpNavigateToSearchService
} }
|> Async.map (Option.defaultValue [||]) |> Async.map (Option.defaultValue [||])
|> Async.map Seq.toImmutableArray |> Async.map Seq.toImmutableArray
|> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken) |> RoslynHelpers.StartAsyncAsTask(cancellationToken)
member __.SearchDocumentAsync(document, searchPattern, cancellationToken) : Task<ImmutableArray<INavigateToSearchResult>> = member __.SearchDocumentAsync(document, searchPattern, cancellationToken) : Task<ImmutableArray<INavigateToSearchResult>> =
asyncMaybe { asyncMaybe {
...@@ -267,4 +267,4 @@ type internal FSharpNavigateToSearchService ...@@ -267,4 +267,4 @@ type internal FSharpNavigateToSearchService
} }
|> Async.map (Option.defaultValue [||]) |> Async.map (Option.defaultValue [||])
|> Async.map Seq.toImmutableArray |> Async.map Seq.toImmutableArray
|> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken) |> RoslynHelpers.StartAsyncAsTask(cancellationToken)
\ No newline at end of file \ No newline at end of file
...@@ -18,7 +18,7 @@ open Microsoft.FSharp.Compiler.SourceCodeServices ...@@ -18,7 +18,7 @@ open Microsoft.FSharp.Compiler.SourceCodeServices
type internal NavigationBarSymbolItem(text, glyph, spans, childItems) = type internal NavigationBarSymbolItem(text, glyph, spans, childItems) =
inherit NavigationBarItem(text, glyph, spans, childItems) inherit NavigationBarItem(text, glyph, spans, childItems)
[<ExportLanguageService(typeof<INavigationBarItemService>, FSharpCommonConstants.FSharpLanguageName); Shared>] [<ExportLanguageService(typeof<INavigationBarItemService>, FSharpConstants.FSharpLanguageName); Shared>]
type internal FSharpNavigationBarItemService type internal FSharpNavigationBarItemService
[<ImportingConstructor>] [<ImportingConstructor>]
( (
...@@ -35,7 +35,7 @@ type internal FSharpNavigationBarItemService ...@@ -35,7 +35,7 @@ type internal FSharpNavigationBarItemService
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let! parsedInput = checkerProvider.Checker.ParseDocument(document, options, sourceText) let! parsedInput = checkerProvider.Checker.ParseDocument(document, options, sourceText)
let navItems = NavigationImpl.getNavigation parsedInput let navItems = NavigationImpl.getNavigation parsedInput
let rangeToTextSpan range = CommonRoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range) let rangeToTextSpan range = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range)
return return
navItems.Declarations navItems.Declarations
|> Array.choose (fun topLevelDecl -> |> Array.choose (fun topLevelDecl ->
...@@ -52,7 +52,7 @@ type internal FSharpNavigationBarItemService ...@@ -52,7 +52,7 @@ type internal FSharpNavigationBarItemService
:> NavigationBarItem)) :> IList<_> :> NavigationBarItem)) :> IList<_>
} }
|> Async.map (Option.defaultValue emptyResult) |> Async.map (Option.defaultValue emptyResult)
|> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken) |> RoslynHelpers.StartAsyncAsTask(cancellationToken)
member __.ShowItemGrayedIfNear (_item) : bool = false member __.ShowItemGrayedIfNear (_item) : bool = false
......
...@@ -19,6 +19,7 @@ open Microsoft.CodeAnalysis.Editor.Shared.Extensions ...@@ -19,6 +19,7 @@ open Microsoft.CodeAnalysis.Editor.Shared.Extensions
open Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.QuickInfo open Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.QuickInfo
open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.Text
open Microsoft.VisualStudio.FSharp.LanguageService open Microsoft.VisualStudio.FSharp.LanguageService
open Microsoft.VisualStudio.Shell open Microsoft.VisualStudio.Shell
open Microsoft.VisualStudio.Shell.Interop open Microsoft.VisualStudio.Shell.Interop
...@@ -30,8 +31,9 @@ open Microsoft.FSharp.Compiler.Range ...@@ -30,8 +31,9 @@ open Microsoft.FSharp.Compiler.Range
open Microsoft.FSharp.Compiler open Microsoft.FSharp.Compiler
open Internal.Utilities.StructuredFormat open Internal.Utilities.StructuredFormat
open CommonRoslynHelpers open Tokenizer
open System.Text open System.Text
open RoslynHelpers
module private SessionHandling = module private SessionHandling =
let mutable currentSession = None let mutable currentSession = None
...@@ -39,7 +41,7 @@ module private SessionHandling = ...@@ -39,7 +41,7 @@ module private SessionHandling =
[<Export (typeof<IQuickInfoSourceProvider>)>] [<Export (typeof<IQuickInfoSourceProvider>)>]
[<Name (FSharpProviderConstants.SessionCapturingProvider)>] [<Name (FSharpProviderConstants.SessionCapturingProvider)>]
[<Order (After = PredefinedQuickInfoProviderNames.Semantic)>] [<Order (After = PredefinedQuickInfoProviderNames.Semantic)>]
[<ContentType (FSharpCommonConstants.FSharpContentTypeName)>] [<ContentType (FSharpConstants.FSharpContentTypeName)>]
type SourceProviderForCapturingSession () = type SourceProviderForCapturingSession () =
interface IQuickInfoSourceProvider with interface IQuickInfoSourceProvider with
member x.TryCreateQuickInfoSource _ = member x.TryCreateQuickInfoSource _ =
...@@ -99,7 +101,7 @@ module private FSharpQuickInfo = ...@@ -99,7 +101,7 @@ module private FSharpQuickInfo =
let extDocument = solution.GetProject(extDocId.ProjectId).GetDocument extDocId let extDocument = solution.GetProject(extDocId.ProjectId).GetDocument extDocId
let! extSourceText = extDocument.GetTextAsync cancellationToken let! extSourceText = extDocument.GetTextAsync cancellationToken
let extSpan = CommonRoslynHelpers.FSharpRangeToTextSpan (extSourceText, declRange) let extSpan = RoslynHelpers.FSharpRangeToTextSpan (extSourceText, declRange)
let extLineText = (extSourceText.Lines.GetLineFromPosition extSpan.Start).ToString() let extLineText = (extSourceText.Lines.GetLineFromPosition extSpan.Start).ToString()
// project options need to be retrieved because the signature file could be in another project // project options need to be retrieved because the signature file could be in another project
...@@ -109,7 +111,7 @@ module private FSharpQuickInfo = ...@@ -109,7 +111,7 @@ module private FSharpQuickInfo =
(extDocument.FilePath, extProjectOptions.OtherOptions |> Seq.toList) (extDocument.FilePath, extProjectOptions.OtherOptions |> Seq.toList)
let! extLexerSymbol = let! extLexerSymbol =
CommonHelpers.getSymbolAtPosition Tokenizer.getSymbolAtPosition
(extDocId, extSourceText, extSpan.Start, declRange.FileName, extDefines, SymbolLookupKind.Greedy) (extDocId, extSourceText, extSpan.Start, declRange.FileName, extDefines, SymbolLookupKind.Greedy)
let! _, _, extCheckFileResults = let! _, _, extCheckFileResults =
...@@ -127,14 +129,14 @@ module private FSharpQuickInfo = ...@@ -127,14 +129,14 @@ module private FSharpQuickInfo =
let! extSymbolUse = let! extSymbolUse =
extCheckFileResults.GetSymbolUseAtLocation(declRange.StartLine, extLexerSymbol.Ident.idRange.EndColumn, extLineText, extLexerSymbol.FullIsland) extCheckFileResults.GetSymbolUseAtLocation(declRange.StartLine, extLexerSymbol.Ident.idRange.EndColumn, extLineText, extLexerSymbol.FullIsland)
let extTextSpan = CommonRoslynHelpers.FSharpRangeToTextSpan (extSourceText, extLexerSymbol.Range) let extTextSpan = RoslynHelpers.FSharpRangeToTextSpan (extSourceText, extLexerSymbol.Range)
return! Some (extTooltipText, extTextSpan, extSymbolUse, extLexerSymbol.Kind) return! Some (extTooltipText, extTextSpan, extSymbolUse, extLexerSymbol.Kind)
} }
let! sourceText = document.GetTextAsync cancellationToken let! sourceText = document.GetTextAsync cancellationToken
let! projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject document let! projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject document
let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.FilePath, projectOptions.OtherOptions |> Seq.toList) let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.FilePath, projectOptions.OtherOptions |> Seq.toList)
let! lexerSymbol = CommonHelpers.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy) let! lexerSymbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy)
let idRange = lexerSymbol.Ident.idRange let idRange = lexerSymbol.Ident.idRange
let! _, _, checkFileResults = checker.ParseAndCheckDocument(document, projectOptions, allowStaleResults = true, sourceText=sourceText) let! _, _, checkFileResults = checker.ParseAndCheckDocument(document, projectOptions, allowStaleResults = true, sourceText=sourceText)
let textLinePos = sourceText.Lines.GetLinePosition position let textLinePos = sourceText.Lines.GetLinePosition position
...@@ -153,7 +155,7 @@ module private FSharpQuickInfo = ...@@ -153,7 +155,7 @@ module private FSharpQuickInfo =
| FSharpToolTipText [FSharpStructuredToolTipElement.None] -> return! None | FSharpToolTipText [FSharpStructuredToolTipElement.None] -> return! None
| _ -> | _ ->
let! symbolUse = checkFileResults.GetSymbolUseAtLocation (fcsTextLineNumber, idRange.EndColumn, lineText, lexerSymbol.FullIsland) let! symbolUse = checkFileResults.GetSymbolUseAtLocation (fcsTextLineNumber, idRange.EndColumn, lineText, lexerSymbol.FullIsland)
let targetTextSpan = CommonRoslynHelpers.FSharpRangeToTextSpan (sourceText, lexerSymbol.Range) let targetTextSpan = RoslynHelpers.FSharpRangeToTextSpan (sourceText, lexerSymbol.Range)
return! Some (targetTooltip, targetTextSpan, symbolUse, lexerSymbol.Kind) return! Some (targetTooltip, targetTextSpan, symbolUse, lexerSymbol.Kind)
} }
...@@ -194,7 +196,7 @@ module private FSharpQuickInfo = ...@@ -194,7 +196,7 @@ module private FSharpQuickInfo =
return (None, Some backupTooltipInfo) return (None, Some backupTooltipInfo)
} }
[<ExportQuickInfoProvider(PredefinedQuickInfoProviderNames.Semantic, FSharpCommonConstants.FSharpLanguageName)>] [<ExportQuickInfoProvider(PredefinedQuickInfoProviderNames.Semantic, FSharpConstants.FSharpLanguageName)>]
type internal FSharpQuickInfoProvider type internal FSharpQuickInfoProvider
[<System.ComponentModel.Composition.ImportingConstructor>] [<System.ComponentModel.Composition.ImportingConstructor>]
( (
...@@ -219,7 +221,7 @@ type internal FSharpQuickInfoProvider ...@@ -219,7 +221,7 @@ type internal FSharpQuickInfoProvider
let targetPath = range.FileName let targetPath = range.FileName
let! targetDoc = solution.TryGetDocumentFromFSharpRange (range,initialDoc.Project.Id) let! targetDoc = solution.TryGetDocumentFromFSharpRange (range,initialDoc.Project.Id)
let! targetSource = targetDoc.GetTextAsync() let! targetSource = targetDoc.GetTextAsync()
let! targetTextSpan = CommonRoslynHelpers.TryFSharpRangeToTextSpan (targetSource, range) let! targetTextSpan = RoslynHelpers.TryFSharpRangeToTextSpan (targetSource, range)
// to ensure proper navigation decsions we need to check the type of document the navigation call // to ensure proper navigation decsions we need to check the type of document the navigation call
// is originating from and the target we're provided by default // is originating from and the target we're provided by default
// - signature files (.fsi) should navigate to other signature files // - signature files (.fsi) should navigate to other signature files
...@@ -284,14 +286,14 @@ type internal FSharpQuickInfoProvider ...@@ -284,14 +286,14 @@ type internal FSharpQuickInfoProvider
let textLine = sourceText.Lines.GetLineFromPosition position let textLine = sourceText.Lines.GetLineFromPosition position
let textLineNumber = textLine.LineNumber + 1 // Roslyn line numbers are zero-based let textLineNumber = textLine.LineNumber + 1 // Roslyn line numbers are zero-based
let defines = CompilerEnvironment.GetCompilationDefinesForEditing (filePath, options.OtherOptions |> Seq.toList) let defines = CompilerEnvironment.GetCompilationDefinesForEditing (filePath, options.OtherOptions |> Seq.toList)
let! symbol = CommonHelpers.getSymbolAtPosition (documentId, sourceText, position, filePath, defines, SymbolLookupKind.Precise) let! symbol = Tokenizer.getSymbolAtPosition (documentId, sourceText, position, filePath, defines, SymbolLookupKind.Precise)
let! res = checkFileResults.GetStructuredToolTipTextAlternate (textLineNumber, symbol.Ident.idRange.EndColumn, textLine.ToString(), symbol.FullIsland, FSharpTokenTag.IDENT) |> liftAsync let! res = checkFileResults.GetStructuredToolTipTextAlternate (textLineNumber, symbol.Ident.idRange.EndColumn, textLine.ToString(), symbol.FullIsland, FSharpTokenTag.IDENT) |> liftAsync
match res with match res with
| FSharpToolTipText [] | FSharpToolTipText []
| FSharpToolTipText [FSharpStructuredToolTipElement.None] -> return! None | FSharpToolTipText [FSharpStructuredToolTipElement.None] -> return! None
| _ -> | _ ->
let! symbolUse = checkFileResults.GetSymbolUseAtLocation (textLineNumber, symbol.Ident.idRange.EndColumn, textLine.ToString(), symbol.FullIsland) let! symbolUse = checkFileResults.GetSymbolUseAtLocation (textLineNumber, symbol.Ident.idRange.EndColumn, textLine.ToString(), symbol.FullIsland)
return! Some (res, CommonRoslynHelpers.FSharpRangeToTextSpan (sourceText, symbol.Range), symbolUse.Symbol, symbol.Kind) return! Some (res, RoslynHelpers.FSharpRangeToTextSpan (sourceText, symbol.Range), symbolUse.Symbol, symbol.Kind)
} }
interface IQuickInfoProvider with interface IQuickInfoProvider with
...@@ -309,7 +311,7 @@ type internal FSharpQuickInfoProvider ...@@ -309,7 +311,7 @@ type internal FSharpQuickInfoProvider
XmlDocumentation.BuildDataTipText(documentationBuilder, mainDescription.Add, documentation.Add, toolTipElement) XmlDocumentation.BuildDataTipText(documentationBuilder, mainDescription.Add, documentation.Add, toolTipElement)
let content = let content =
FSharpQuickInfo.tooltip FSharpQuickInfo.tooltip
(SymbolGlyphDeferredContent(CommonRoslynHelpers.GetGlyphForSymbol(symbolUse.Symbol, symbolKind), glyphService), (SymbolGlyphDeferredContent(GetGlyphForSymbol(symbolUse.Symbol, symbolKind), glyphService),
fragment (mainDescription, typeMap, document, symbolUse.RangeAlternate), fragment (mainDescription, typeMap, document, symbolUse.RangeAlternate),
fragment (documentation, typeMap, document, symbolUse.RangeAlternate)) fragment (documentation, typeMap, document, symbolUse.RangeAlternate))
return QuickInfoItem (textSpan, content) return QuickInfoItem (textSpan, content)
...@@ -352,10 +354,10 @@ type internal FSharpQuickInfoProvider ...@@ -352,10 +354,10 @@ type internal FSharpQuickInfoProvider
let content = let content =
FSharpQuickInfo.tooltip FSharpQuickInfo.tooltip
(SymbolGlyphDeferredContent (CommonRoslynHelpers.GetGlyphForSymbol (targetSymbolUse.Symbol, targetSymbolKind), glyphService), (SymbolGlyphDeferredContent (GetGlyphForSymbol (targetSymbolUse.Symbol, targetSymbolKind), glyphService),
fragment (description, typeMap, document, targetSymbolUse.RangeAlternate), fragment (description, typeMap, document, targetSymbolUse.RangeAlternate),
fragment (documentation, typeMap, document, targetSymbolUse.RangeAlternate)) fragment (documentation, typeMap, document, targetSymbolUse.RangeAlternate))
return QuickInfoItem (targetTextSpan, content) return QuickInfoItem (targetTextSpan, content)
} |> Async.map Option.toObj } |> Async.map Option.toObj
|> CommonRoslynHelpers.StartAsyncAsTask cancellationToken |> RoslynHelpers.StartAsyncAsTask cancellationToken
...@@ -73,9 +73,9 @@ module internal BlockStructure = ...@@ -73,9 +73,9 @@ module internal BlockStructure =
|> Seq.distinctBy (fun x -> x.Range.StartLine) |> Seq.distinctBy (fun x -> x.Range.StartLine)
|> Seq.choose (fun scopeRange -> |> Seq.choose (fun scopeRange ->
// the range of text to collapse // the range of text to collapse
let textSpan = CommonRoslynHelpers.TryFSharpRangeToTextSpan(sourceText, scopeRange.CollapseRange) let textSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, scopeRange.CollapseRange)
// the range of the entire expression // the range of the entire expression
let hintSpan = CommonRoslynHelpers.TryFSharpRangeToTextSpan(sourceText, scopeRange.Range) let hintSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, scopeRange.Range)
match textSpan,hintSpan with match textSpan,hintSpan with
| Some textSpan, Some hintSpan -> | Some textSpan, Some hintSpan ->
let line = sourceText.Lines.GetLineFromPosition textSpan.Start let line = sourceText.Lines.GetLineFromPosition textSpan.Start
...@@ -93,7 +93,7 @@ open BlockStructure ...@@ -93,7 +93,7 @@ open BlockStructure
type internal FSharpBlockStructureService(checker: FSharpChecker, projectInfoManager: ProjectInfoManager) = type internal FSharpBlockStructureService(checker: FSharpChecker, projectInfoManager: ProjectInfoManager) =
inherit BlockStructureService() inherit BlockStructureService()
override __.Language = FSharpCommonConstants.FSharpLanguageName override __.Language = FSharpConstants.FSharpLanguageName
override __.GetBlockStructureAsync(document, cancellationToken) : Task<BlockStructure> = override __.GetBlockStructureAsync(document, cancellationToken) : Task<BlockStructure> =
asyncMaybe { asyncMaybe {
...@@ -104,9 +104,9 @@ type internal FSharpBlockStructureService(checker: FSharpChecker, projectInfoMan ...@@ -104,9 +104,9 @@ type internal FSharpBlockStructureService(checker: FSharpChecker, projectInfoMan
} }
|> Async.map (Option.defaultValue ImmutableArray<_>.Empty) |> Async.map (Option.defaultValue ImmutableArray<_>.Empty)
|> Async.map BlockStructure |> Async.map BlockStructure
|> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken) |> RoslynHelpers.StartAsyncAsTask(cancellationToken)
[<ExportLanguageServiceFactory(typeof<BlockStructureService>, FSharpCommonConstants.FSharpLanguageName); Shared>] [<ExportLanguageServiceFactory(typeof<BlockStructureService>, FSharpConstants.FSharpLanguageName); Shared>]
type internal FSharpBlockStructureServiceFactory [<ImportingConstructor>](checkerProvider: FSharpCheckerProvider, projectInfoManager: ProjectInfoManager) = type internal FSharpBlockStructureServiceFactory [<ImportingConstructor>](checkerProvider: FSharpCheckerProvider, projectInfoManager: ProjectInfoManager) =
interface ILanguageServiceFactory with interface ILanguageServiceFactory with
member __.CreateLanguageService(_languageServices) = member __.CreateLanguageService(_languageServices) =
......
...@@ -731,7 +731,7 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem ...@@ -731,7 +731,7 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
override x.GetGuidProperty(propid:int, guid:byref<Guid> ) = override x.GetGuidProperty(propid:int, guid:byref<Guid> ) =
if (enum propid = __VSHPROPID.VSHPROPID_PreferredLanguageSID) then if (enum propid = __VSHPROPID.VSHPROPID_PreferredLanguageSID) then
guid <- new Guid(FSharpCommonConstants.languageServiceGuidString) guid <- new Guid(FSharpConstants.languageServiceGuidString)
VSConstants.S_OK VSConstants.S_OK
// below is how VS decide 'which templates' to associate with an 'add new item' call in this project // below is how VS decide 'which templates' to associate with an 'add new item' call in this project
elif (enum propid = __VSHPROPID2.VSHPROPID_AddItemTemplatesGuid) then elif (enum propid = __VSHPROPID2.VSHPROPID_AddItemTemplatesGuid) then
...@@ -1611,7 +1611,7 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem ...@@ -1611,7 +1611,7 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
// in the registry hive so that more editors can be added without changing this part of the // in the registry hive so that more editors can be added without changing this part of the
// code. FSharp only makes usage of one Editor Factory and therefore we will return // code. FSharp only makes usage of one Editor Factory and therefore we will return
// that guid // that guid
guidEditorType <- new Guid(FSharpCommonConstants.editorFactoryGuidString) guidEditorType <- new Guid(FSharpConstants.editorFactoryGuidString)
VSConstants.S_OK VSConstants.S_OK
interface IVsProjectSpecificEditorMap2 with interface IVsProjectSpecificEditorMap2 with
...@@ -1625,7 +1625,7 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem ...@@ -1625,7 +1625,7 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
// in the registry hive so that more editors can be added without changing this part of the // in the registry hive so that more editors can be added without changing this part of the
// code. FSharp only makes usage of one Editor Factory and therefore we will return // code. FSharp only makes usage of one Editor Factory and therefore we will return
// that guid // that guid
guidEditorType <- new Guid(FSharpCommonConstants.editorFactoryGuidString) guidEditorType <- new Guid(FSharpConstants.editorFactoryGuidString)
VSConstants.S_OK VSConstants.S_OK
member x.GetSpecificLanguageService(_mkDocument:string, guidLanguageService:byref<Guid> ) = member x.GetSpecificLanguageService(_mkDocument:string, guidLanguageService:byref<Guid> ) =
......
...@@ -147,9 +147,9 @@ type internal FSharpLanguageServiceTestable() as this = ...@@ -147,9 +147,9 @@ type internal FSharpLanguageServiceTestable() as this =
match hier with match hier with
| :? IProvideProjectSite as siteProvider -> | :? IProvideProjectSite as siteProvider ->
let site = siteProvider.GetProjectSite() let site = siteProvider.GetProjectSite()
site.AdviseProjectSiteChanges(FSharpCommonConstants.FSharpLanguageServiceCallbackName, site.AdviseProjectSiteChanges(FSharpConstants.FSharpLanguageServiceCallbackName,
new AdviseProjectSiteChanges(fun () -> this.OnProjectSettingsChanged(site))) new AdviseProjectSiteChanges(fun () -> this.OnProjectSettingsChanged(site)))
site.AdviseProjectSiteCleaned(FSharpCommonConstants.FSharpLanguageServiceCallbackName, site.AdviseProjectSiteCleaned(FSharpConstants.FSharpLanguageServiceCallbackName,
new AdviseProjectSiteChanges(fun () -> this.OnProjectCleaned(site))) new AdviseProjectSiteChanges(fun () -> this.OnProjectCleaned(site)))
| _ -> | _ ->
// This can happen when the file is in a solution folder or in, say, a C# project. // This can happen when the file is in a solution folder or in, say, a C# project.
......
...@@ -50,7 +50,7 @@ type BraceMatchingServiceTests() = ...@@ -50,7 +50,7 @@ type BraceMatchingServiceTests() =
| None -> Assert.Fail("Didn't find a match for start brace at position '{0}", startMarkerPosition) | None -> Assert.Fail("Didn't find a match for start brace at position '{0}", startMarkerPosition)
| Some(left, right) -> | Some(left, right) ->
let endPositionInRange(range) = let endPositionInRange(range) =
let span = CommonRoslynHelpers.FSharpRangeToTextSpan(sourceText, range) let span = RoslynHelpers.FSharpRangeToTextSpan(sourceText, range)
span.Start <= endMarkerPosition && endMarkerPosition <= span.End span.Start <= endMarkerPosition && endMarkerPosition <= span.End
Assert.IsTrue(endPositionInRange(left) || endPositionInRange(right), "Found end match at incorrect position") Assert.IsTrue(endPositionInRange(left) || endPositionInRange(right), "Found end match at incorrect position")
......
...@@ -76,7 +76,7 @@ let main argv = ...@@ -76,7 +76,7 @@ let main argv =
match actualResolutionOption with match actualResolutionOption with
| None -> Assert.IsTrue(expectedResolution.IsNone, "BreakpointResolutionService failed to resolve breakpoint position") | None -> Assert.IsTrue(expectedResolution.IsNone, "BreakpointResolutionService failed to resolve breakpoint position")
| Some(actualResolutionRange) -> | Some(actualResolutionRange) ->
let actualResolution = sourceText.GetSubText(CommonRoslynHelpers.FSharpRangeToTextSpan(sourceText, actualResolutionRange)).ToString() let actualResolution = sourceText.GetSubText(RoslynHelpers.FSharpRangeToTextSpan(sourceText, actualResolutionRange)).ToString()
Assert.IsTrue(expectedResolution.IsSome, "BreakpointResolutionService resolved a breakpoint while it shouldn't at: {0}", actualResolution) Assert.IsTrue(expectedResolution.IsSome, "BreakpointResolutionService resolved a breakpoint while it shouldn't at: {0}", actualResolution)
Assert.AreEqual(expectedResolution.Value, actualResolution, "Expected and actual resolutions should match") Assert.AreEqual(expectedResolution.Value, actualResolution, "Expected and actual resolutions should match")
\ No newline at end of file
...@@ -10,6 +10,7 @@ open Microsoft.CodeAnalysis.Classification ...@@ -10,6 +10,7 @@ open Microsoft.CodeAnalysis.Classification
open Microsoft.CodeAnalysis open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.Text
open Microsoft.VisualStudio.FSharp.Editor open Microsoft.VisualStudio.FSharp.Editor
open RoslynHelpers
[<TestFixture>][<Category "Roslyn Services">] [<TestFixture>][<Category "Roslyn Services">]
type ColorizationServiceTests() = type ColorizationServiceTests() =
...@@ -18,7 +19,7 @@ type ColorizationServiceTests() = ...@@ -18,7 +19,7 @@ type ColorizationServiceTests() =
let textSpan = TextSpan(0, fileContents.Length) let textSpan = TextSpan(0, fileContents.Length)
let fileName = if isScriptFile.IsSome && isScriptFile.Value then "test.fsx" else "test.fs" let fileName = if isScriptFile.IsSome && isScriptFile.Value then "test.fsx" else "test.fs"
let documentId = DocumentId.CreateNewId(ProjectId.CreateNewId()) let documentId = DocumentId.CreateNewId(ProjectId.CreateNewId())
let tokens = CommonHelpers.getColorizationData(documentId, SourceText.From(fileContents), textSpan, Some(fileName), defines, CancellationToken.None) let tokens = Tokenizer.getColorizationData(documentId, SourceText.From(fileContents), textSpan, Some(fileName), defines, CancellationToken.None)
let markerPosition = fileContents.IndexOf(marker) let markerPosition = fileContents.IndexOf(marker)
Assert.IsTrue(markerPosition >= 0, "Cannot find marker '{0}' in file contents", marker) Assert.IsTrue(markerPosition >= 0, "Cannot find marker '{0}' in file contents", marker)
(tokens, markerPosition) (tokens, markerPosition)
......
...@@ -58,7 +58,7 @@ let private getSpans (sourceText: SourceText) (caretPosition: int) = ...@@ -58,7 +58,7 @@ let private getSpans (sourceText: SourceText) (caretPosition: int) =
let private span sourceText isDefinition (startLine, startCol) (endLine, endCol) = let private span sourceText isDefinition (startLine, startCol) (endLine, endCol) =
let range = Range.mkRange filePath (Range.mkPos startLine startCol) (Range.mkPos endLine endCol) let range = Range.mkRange filePath (Range.mkPos startLine startCol) (Range.mkPos endLine endCol)
{ IsDefinition = isDefinition { IsDefinition = isDefinition
TextSpan = CommonRoslynHelpers.FSharpRangeToTextSpan(sourceText, range) } TextSpan = RoslynHelpers.FSharpRangeToTextSpan(sourceText, range) }
[<Test>] [<Test>]
let ShouldHighlightAllSimpleLocalSymbolReferences() = let ShouldHighlightAllSimpleLocalSymbolReferences() =
......
...@@ -58,7 +58,7 @@ type HelpContextServiceTests() = ...@@ -58,7 +58,7 @@ type HelpContextServiceTests() =
let span = TextSpan(marker, 0) let span = TextSpan(marker, 0)
let textLine = sourceText.Lines.GetLineFromPosition(marker) let textLine = sourceText.Lines.GetLineFromPosition(marker)
let documentId = DocumentId.CreateNewId(ProjectId.CreateNewId()) let documentId = DocumentId.CreateNewId(ProjectId.CreateNewId())
let tokens = CommonHelpers.getColorizationData(documentId, sourceText, textLine.Span, Some "test.fs", [], CancellationToken.None) let tokens = Tokenizer.getColorizationData(documentId, sourceText, textLine.Span, Some "test.fs", [], CancellationToken.None)
yield FSharpHelpContextService.GetHelpTerm(FSharpChecker.Instance, sourceText, fileName, newOptions, span, tokens, version) yield FSharpHelpContextService.GetHelpTerm(FSharpChecker.Instance, sourceText, fileName, newOptions, span, tokens, version)
|> Async.RunSynchronously |> Async.RunSynchronously
......
...@@ -54,7 +54,7 @@ let main argv = ...@@ -54,7 +54,7 @@ let main argv =
let sourceText = SourceText.From(code) let sourceText = SourceText.From(code)
let documentId = DocumentId.CreateNewId(ProjectId.CreateNewId()) let documentId = DocumentId.CreateNewId(ProjectId.CreateNewId())
let tokens = CommonHelpers.getColorizationData(documentId, sourceText, TextSpan.FromBounds(0, sourceText.Length), Some(fileName), defines, CancellationToken.None) let tokens = Tokenizer.getColorizationData(documentId, sourceText, TextSpan.FromBounds(0, sourceText.Length), Some(fileName), defines, CancellationToken.None)
let actualDataTipSpanOption = FSharpLanguageDebugInfoService.GetDataTipInformation(sourceText, searchPosition, tokens) let actualDataTipSpanOption = FSharpLanguageDebugInfoService.GetDataTipInformation(sourceText, searchPosition, tokens)
match actualDataTipSpanOption with match actualDataTipSpanOption with
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册