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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion RoslynPackageVersion.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.1.0-beta3-19222-02
3.2.0
1 change: 1 addition & 0 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
https://vside.myget.org/F/vs-impl/api/v3/index.json;
https://myget.org/F/roslyn_concord/api/v3/index.json;
https://vside.myget.org/F/devcore/api/v3/index.json;
C:\roslyn\artifacts\packages\Debug\Release;
</RestoreSources>
<!-- version numbers from files -->
<RoslynPackageVersion>$([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)..\RoslynPackageVersion.txt').Trim())</RoslynPackageVersion>
Expand Down
20 changes: 0 additions & 20 deletions vsintegration/src/FSharp.Editor/Common/ContentType.fs

This file was deleted.

8 changes: 0 additions & 8 deletions vsintegration/src/FSharp.Editor/Common/RoslynHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,6 @@ module internal RoslynHelpers =
let StartAsyncUnitAsTask cancellationToken (computation:Async<unit>) =
StartAsyncAsTask cancellationToken computation :> Task

let private TheSupportedDiagnostics =
// We are constructing our own descriptors at run-time. Compiler service is already doing error formatting and localization.
let dummyDescriptors =
[| for i in 0 .. 10000 -> DiagnosticDescriptor(sprintf "FS%04d" i, String.Empty, String.Empty, String.Empty, DiagnosticSeverity.Error, true, null, null) |]
ImmutableArray.Create<DiagnosticDescriptor>(dummyDescriptors)

let SupportedDiagnostics() = TheSupportedDiagnostics

let ConvertError(error: FSharpErrorInfo, location: Location) =
// Normalize the error message into the same format that we will receive it from the compiler.
// This ensures that IntelliSense and Compiler errors in the 'Error List' are de-duplicated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.Completion
open Microsoft.CodeAnalysis.Options
open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Completion

open Microsoft.VisualStudio.Shell
open Microsoft.VisualStudio.Shell.Interop
Expand Down Expand Up @@ -52,7 +53,7 @@ type internal FSharpCompletionProvider
|> List.filter (fun (keyword, _) -> not (PrettyNaming.IsOperatorName keyword))
|> List.sortBy (fun (keyword, _) -> keyword)
|> List.mapi (fun n (keyword, description) ->
CommonCompletionItem.Create(keyword, null, CompletionItemRules.Default, Nullable Glyph.Keyword, sortText = sprintf "%06d" (1000000 + n))
FSharpCommonCompletionItem.Create(keyword, null, CompletionItemRules.Default, Nullable Glyph.Keyword, sortText = sprintf "%06d" (1000000 + n))
.AddProperty("description", description)
.AddProperty(IsKeywordPropName, ""))

Expand All @@ -77,7 +78,7 @@ type internal FSharpCompletionProvider
// * let xs = [1..10] <<---- Don't commit autocomplete! (same for arrays)
let noCommitChars = [|' '; '='; ','; '.'; '<'; '>'; '('; ')'; '!'; ':'; '['; ']'; '|'|].ToImmutableArray()

CompletionItemRules.Default.WithCommitCharacterRule(CharacterSetModificationRule.Create(CharacterSetModificationKind.Remove, noCommitChars))
CompletionItemRules.Default.WithCommitCharacterRules(ImmutableArray.Create (CharacterSetModificationRule.Create(CharacterSetModificationKind.Remove, noCommitChars)))

static let getRules showAfterCharIsTyped = if showAfterCharIsTyped then noCommitOnSpaceRules else CompletionItemRules.Default

Expand Down Expand Up @@ -156,7 +157,7 @@ type internal FSharpCompletionProvider
| _, idents -> Array.last idents

let completionItem =
CommonCompletionItem.Create(name, null, rules = getRules intellisenseOptions.ShowAfterCharIsTyped, glyph = Nullable (Microsoft.CodeAnalysis.ExternalAccess.FSharp.FSharpGlyphHelpersObsolete.Convert(glyph)), filterText = filterText)
FSharpCommonCompletionItem.Create(name, null, rules = getRules intellisenseOptions.ShowAfterCharIsTyped, glyph = Nullable glyph, filterText = filterText)
.AddProperty(FullNamePropName, declarationItem.FullName)

let completionItem =
Expand Down Expand Up @@ -202,7 +203,7 @@ type internal FSharpCompletionProvider
}

override this.ShouldTriggerCompletion(sourceText: SourceText, caretPosition: int, trigger: CompletionTrigger, _: OptionSet) =
use _logBlock = Logger.LogBlockMessage this.Name LogEditorFunctionId.Completion_ShouldTrigger
use _logBlock = Logger.LogBlock LogEditorFunctionId.Completion_ShouldTrigger

let getInfo() =
let documentId = workspace.GetDocumentIdInCurrentContext(sourceText.Container)
Expand Down
10 changes: 6 additions & 4 deletions vsintegration/src/FSharp.Editor/Completion/CompletionService.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.Completion
open Microsoft.CodeAnalysis.Host
open Microsoft.CodeAnalysis.Host.Mef
open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Completion

open Microsoft.VisualStudio.Shell

Expand All @@ -26,10 +27,11 @@ type internal FSharpCompletionService
let builtInProviders =
ImmutableArray.Create<CompletionProvider>(
FSharpCompletionProvider(workspace, serviceProvider, checkerProvider, projectInfoManager, assemblyContentProvider),
HashDirectiveCompletionProvider(workspace, projectInfoManager,
[ Completion.Create("""\s*#load\s+(@?"*(?<literal>"[^"]*"?))""", [".fs"; ".fsx"], useIncludeDirectives = true)
Completion.Create("""\s*#r\s+(@?"*(?<literal>"[^"]*"?))""", [".dll"; ".exe"], useIncludeDirectives = true)
Completion.Create("""\s*#I\s+(@?"*(?<literal>"[^"]*"?))""", ["\x00"], useIncludeDirectives = false) ]))
FSharpCommonCompletionProvider.Create(
HashDirectiveCompletionProvider(workspace, projectInfoManager,
[ Completion.Create("""\s*#load\s+(@?"*(?<literal>"[^"]*"?))""", [".fs"; ".fsx"], useIncludeDirectives = true)
Completion.Create("""\s*#r\s+(@?"*(?<literal>"[^"]*"?))""", [".dll"; ".exe"], useIncludeDirectives = true)
Completion.Create("""\s*#I\s+(@?"*(?<literal>"[^"]*"?))""", ["\x00"], useIncludeDirectives = false) ])))

override this.Language = FSharpConstants.FSharpLanguageName
override this.GetBuiltInProviders() = builtInProviders
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.Classification
open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.Completion
open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Completion
open System.Globalization
open FSharp.Compiler.SourceCodeServices

Expand Down Expand Up @@ -81,7 +82,7 @@ module internal CompletionUtils =
| _ -> false

let isStartingNewWord (sourceText, position) =
CommonCompletionUtilities.IsStartingNewWord(sourceText, position, (fun ch -> isIdentifierStartCharacter ch), (fun ch -> isIdentifierPartCharacter ch))
FSharpCommonCompletionUtilities.IsStartingNewWord(sourceText, position, (fun ch -> isIdentifierStartCharacter ch), (fun ch -> isIdentifierPartCharacter ch))

let shouldProvideCompletion (documentId: DocumentId, filePath: string, defines: string list, sourceText: SourceText, triggerPosition: int) : bool =
let textLines = sourceText.Lines
Expand Down
138 changes: 70 additions & 68 deletions vsintegration/src/FSharp.Editor/Completion/FileSystemCompletion.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.Completion
open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.Classification
open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Completion

type internal Completion =
{ DirectiveRegex: Regex
Expand All @@ -23,7 +24,6 @@ type internal Completion =
UseIncludeDirectives = useIncludeDirectives }

type internal HashDirectiveCompletionProvider(workspace: Workspace, projectInfoManager: FSharpProjectOptionsManager, completions: Completion list) =
inherit CommonCompletionProvider()

let [<Literal>] NetworkPath = "\\\\"
let commitRules = ImmutableArray.Create(CharacterSetModificationRule.Create(CharacterSetModificationKind.Replace, '"', '\\', ',', '/'))
Expand Down Expand Up @@ -82,75 +82,77 @@ type internal HashDirectiveCompletionProvider(workspace: Workspace, projectInfoM
)
|> Seq.toList

override this.ProvideCompletionsAsync(context) =
asyncMaybe {
let document = context.Document
let position = context.Position
do! let extension = Path.GetExtension document.FilePath
Option.guard (extension = ".fsx" || extension = ".fsscript")

let! ct = liftAsync Async.CancellationToken
let! text = document.GetTextAsync(ct)
do! Option.guard (isInStringLiteral(text, position))
let line = text.Lines.GetLineFromPosition(position)
let lineText = text.ToString(TextSpan.FromBounds(line.Start, position))
interface IFSharpCommonCompletionProvider with

member this.ProvideCompletionsAsync(context) =
asyncMaybe {
let document = context.Document
let position = context.Position
do! let extension = Path.GetExtension document.FilePath
Option.guard (extension = ".fsx" || extension = ".fsscript")

let! ct = liftAsync Async.CancellationToken
let! text = document.GetTextAsync(ct)
do! Option.guard (isInStringLiteral(text, position))
let line = text.Lines.GetLineFromPosition(position)
let lineText = text.ToString(TextSpan.FromBounds(line.Start, position))

let! completion, quotedPathGroup =
completions |> List.tryPick (fun completion ->
match completion.DirectiveRegex.Match lineText with
| m when m.Success ->
let quotedPathGroup = m.Groups.["literal"]
let endsWithQuote = PathCompletionUtilities.EndsWithQuote(quotedPathGroup.Value)
if endsWithQuote && (position >= line.Start + m.Length) then
None
else
Some (completion, quotedPathGroup)
| _ -> None)

let snapshot = text.FindCorrespondingEditorTextSnapshot()
let! completion, quotedPathGroup =
completions |> List.tryPick (fun completion ->
match completion.DirectiveRegex.Match lineText with
| m when m.Success ->
let quotedPathGroup = m.Groups.["literal"]
let endsWithQuote = PathCompletionUtilities.EndsWithQuote(quotedPathGroup.Value)
if endsWithQuote && (position >= line.Start + m.Length) then
None
else
Some (completion, quotedPathGroup)
| _ -> None)

let snapshot = text.FindCorrespondingEditorTextSnapshot()

do! Option.guard (not (isNull snapshot))

let extraSearchPaths =
if completion.UseIncludeDirectives then
getIncludeDirectives (text, position)
else []

let defaultSearchPath = Path.GetDirectoryName document.FilePath
let searchPaths = defaultSearchPath :: extraSearchPaths

let helper =
FileSystemCompletionHelper(
Glyph.OpenFolder,
completion.AllowableExtensions |> List.tryPick getFileGlyph |> Option.defaultValue Glyph.None,
Seq.toImmutableArray searchPaths,
null,
completion.AllowableExtensions |> Seq.toImmutableArray,
rules)
do! Option.guard (not (isNull snapshot))

let extraSearchPaths =
if completion.UseIncludeDirectives then
getIncludeDirectives (text, position)
else []

let defaultSearchPath = Path.GetDirectoryName document.FilePath
let searchPaths = defaultSearchPath :: extraSearchPaths

let helper =
FSharpFileSystemCompletionHelper(
Glyph.OpenFolder,
completion.AllowableExtensions |> List.tryPick getFileGlyph |> Option.defaultValue Glyph.None,
Seq.toImmutableArray searchPaths,
null,
completion.AllowableExtensions |> Seq.toImmutableArray,
rules)

let pathThroughLastSlash = getPathThroughLastSlash(text, position, quotedPathGroup)
let! items = helper.GetItemsAsync(pathThroughLastSlash, ct) |> Async.AwaitTask |> liftAsync
context.AddItems(items)
}
|> Async.Ignore
|> RoslynHelpers.StartAsyncUnitAsTask context.CancellationToken
let pathThroughLastSlash = getPathThroughLastSlash(text, position, quotedPathGroup)
let! items = helper.GetItemsAsync(pathThroughLastSlash, ct) |> Async.AwaitTask |> liftAsync
context.AddItems(items)
}
|> Async.Ignore
|> RoslynHelpers.StartAsyncUnitAsTask context.CancellationToken

override __.IsInsertionTrigger(text, position, _) =
// Bring up completion when the user types a quote (i.e.: #r "), or if they type a slash
// path separator character, or if they type a comma (#r "foo,version...").
// Also, if they're starting a word. i.e. #r "c:\W
let ch = text.[position]
let isTriggerChar =
ch = '"' || ch = '\\' || ch = ',' || ch = '/' ||
CommonCompletionUtilities.IsStartingNewWord(text, position, (fun x -> Char.IsLetter x), (fun x -> Char.IsLetterOrDigit x))
isTriggerChar && isInStringLiteral(text, position)
member __.IsInsertionTrigger(text, position, _) =
// Bring up completion when the user types a quote (i.e.: #r "), or if they type a slash
// path separator character, or if they type a comma (#r "foo,version...").
// Also, if they're starting a word. i.e. #r "c:\W
let ch = text.[position]
let isTriggerChar =
ch = '"' || ch = '\\' || ch = ',' || ch = '/' ||
FSharpCommonCompletionUtilities.IsStartingNewWord(text, position, (fun x -> Char.IsLetter x), (fun x -> Char.IsLetterOrDigit x))
isTriggerChar && isInStringLiteral(text, position)

override __.GetTextChangeAsync(selectedItem, ch, cancellationToken) =
// When we commit "\\" when the user types \ we have to adjust for the fact that the
// controller will automatically append \ after we commit. Because of that, we don't
// want to actually commit "\\" as we'll end up with "\\\". So instead we just commit
// "\" and know that controller will append "\" and give us "\\".
if selectedItem.DisplayText = NetworkPath && ch = Nullable '\\' then
Task.FromResult(Nullable(TextChange(selectedItem.Span, "\\")))
else
base.GetTextChangeAsync(selectedItem, ch, cancellationToken)
member __.GetTextChangeAsync(baseGetTextChangeAsync, selectedItem, ch, cancellationToken) =
// When we commit "\\" when the user types \ we have to adjust for the fact that the
// controller will automatically append \ after we commit. Because of that, we don't
// want to actually commit "\\" as we'll end up with "\\\". So instead we just commit
// "\" and know that controller will append "\" and give us "\\".
if selectedItem.DisplayText = NetworkPath && ch = Nullable '\\' then
Task.FromResult(Nullable(TextChange(selectedItem.Span, "\\")))
else
baseGetTextChangeAsync.Invoke(selectedItem, ch, cancellationToken)
Loading