Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge main to release/dev17.6 #14983

Merged
merged 3 commits into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Compiler/Service/ServiceDeclarationLists.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,7 @@ type DeclarationListInfo(declarations: DeclarationListItem[], isForType: bool, i
// Make a 'Declarations' object for a set of selected items
static member Create(infoReader:InfoReader, ad, m: range, denv, getAccessibility: Item -> FSharpAccessibility, items: CompletionItem list, currentNamespace: string[] option, isAttributeApplicationContext: bool) =
let g = infoReader.g
let isForType = items |> List.exists (fun x -> x.Type.IsSome)
let isForType = items |> List.exists (fun x -> x.Type.IsSome || (x.Item |> function Item.AnonRecdField _ -> true | _ -> false))
let items = items |> RemoveExplicitlySuppressedCompletionItems g

let tyconRefOptEq tref1 tref2 =
Expand Down
14 changes: 14 additions & 0 deletions tests/service/CompletionTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ let assertHasItemWithNames names (completionInfo: DeclarationListInfo) =
for name in names do
Assert.That(Set.contains name itemNames, name)

let assertHasExactlyNamesAndNothingElse names (completionInfo: DeclarationListInfo) =
let itemNames = getCompletionItemNames completionInfo |> set
let expectedNames = Set.ofList names

Assert.That(itemNames, Is.EqualTo expectedNames)


[<Test>]
let ``Expr - record - field 01 - anon module`` () =
Expand Down Expand Up @@ -57,3 +63,11 @@ let record = { Field = 1 }
{ }
"""
assertHasItemWithNames ["Field"; "record"] info

[<Test>]
let ``Expr - array of anonymous records`` () =
let info = getCompletionInfo "x[0]." (3, 6) """
let x = [ {| Name = "foo" |} ]
x[0].
"""
assertHasExactlyNamesAndNothingElse ["Name"; "Equals"; "GetHashCode"; "GetType"; "ToString"] info
5 changes: 4 additions & 1 deletion vsintegration/src/FSharp.Editor/FSharp.Editor.resx
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,10 @@ Always add new line on enter;</value>
<value>QuickInfo</value>
</data>
<data name="QuickInfoPageKeywords" xml:space="preserve">
<value>Navigation links;
<value>Formatting;
Preferred description width in characters;
Format signature to the given width by adding line breaks conforming with F# syntax rules;
Navigation links;
Show navigation links as;
Solid underline;
Dot underline;
Expand Down
26 changes: 21 additions & 5 deletions vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,13 @@ module internal FSharpQuickInfo =
// when a construct has been declared in a signature file the documentation comments that are
// written in that file are the ones that go into the generated xml when the project is compiled
// therefore we should include these doccoms in our design time quick info
let getQuickInfoFromRange (document: Document, declRange: range, cancellationToken: CancellationToken) : Async<FSharpQuickInfo option> =
let getQuickInfoFromRange
(
document: Document,
declRange: range,
width: int option,
cancellationToken: CancellationToken
) : Async<FSharpQuickInfo option> =

asyncMaybe {
let userOpName = "getQuickInfoFromRange"
Expand All @@ -593,7 +599,8 @@ module internal FSharpQuickInfo =
extLexerSymbol.Ident.idRange.EndColumn,
extLineText,
extLexerSymbol.FullIsland,
FSharpTokenTag.IDENT
FSharpTokenTag.IDENT,
?width = width
)

match extQuickInfoText with
Expand Down Expand Up @@ -624,6 +631,7 @@ module internal FSharpQuickInfo =
(
document: Document,
position: int,
width: int option,
cancellationToken: CancellationToken
) : Async<(range * FSharpQuickInfo option * FSharpQuickInfo option) option> =

Expand All @@ -643,7 +651,15 @@ module internal FSharpQuickInfo =
let targetQuickInfo =
match lexerSymbol.Kind with
| LexerSymbolKind.Keyword -> checkFileResults.GetKeywordTooltip(lexerSymbol.FullIsland)
| _ -> checkFileResults.GetToolTip(fcsTextLineNumber, idRange.EndColumn, lineText, lexerSymbol.FullIsland, tag)
| _ ->
checkFileResults.GetToolTip(
fcsTextLineNumber,
idRange.EndColumn,
lineText,
lexerSymbol.FullIsland,
tag,
?width = width
)

match targetQuickInfo with
| ToolTipText []
Expand Down Expand Up @@ -693,7 +709,7 @@ module internal FSharpQuickInfo =
match findSigDeclarationResult with
| FindDeclResult.DeclFound declRange when isSignatureFile declRange.FileName ->
asyncMaybe {
let! sigQuickInfo = getQuickInfoFromRange (document, declRange, cancellationToken)
let! sigQuickInfo = getQuickInfoFromRange (document, declRange, width, cancellationToken)

// if the target was declared in a signature file, and the current file
// is not the corresponding module implementation file for that signature,
Expand All @@ -712,7 +728,7 @@ module internal FSharpQuickInfo =
| FindDeclResult.DeclNotFound _
| FindDeclResult.ExternalDecl _ -> return symbolUse.Range, Some sigQuickInfo, None
| FindDeclResult.DeclFound declRange ->
let! implQuickInfo = getQuickInfoFromRange (document, declRange, cancellationToken)
let! implQuickInfo = getQuickInfoFromRange (document, declRange, width, cancellationToken)

return
symbolUse.Range,
Expand Down
3 changes: 3 additions & 0 deletions vsintegration/src/FSharp.Editor/Options/EditorOptions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,14 @@ type QuickInfoOptions =
{
DisplayLinks: bool
UnderlineStyle: QuickInfoUnderlineStyle
DescriptionWidth: int option
}

static member Default =
{
DisplayLinks = true
UnderlineStyle = QuickInfoUnderlineStyle.Solid
DescriptionWidth = None
}

[<CLIMutable>]
Expand Down Expand Up @@ -180,6 +182,7 @@ module internal OptionsUI =
bindRadioButton view.dot path QuickInfoUnderlineStyle.Dot
bindRadioButton view.dash path QuickInfoUnderlineStyle.Dash
bindCheckBox view.displayLinks (nameof QuickInfoOptions.Default.DisplayLinks)
bindDescriptionWidthTextBox view.descriptionWidth (nameof QuickInfoOptions.Default.DescriptionWidth)
upcast view

[<Guid(Guids.codeFixesOptionPageIdString)>]
Expand Down
44 changes: 42 additions & 2 deletions vsintegration/src/FSharp.Editor/Options/UIHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ open Microsoft.VisualStudio.Shell
open Microsoft.VisualStudio.ComponentModelHost

module internal OptionsUIHelpers =
open System

[<AbstractClass>]
type AbstractOptionPage<'options>() as this =
Expand Down Expand Up @@ -64,9 +65,9 @@ module internal OptionsUIHelpers =
//data binding helpers
let radioButtonCoverter =
{ new IValueConverter with
member this.Convert(value, _, parameter, _) = upcast value.Equals(parameter)
member _.Convert(value, _, parameter, _) = upcast value.Equals(parameter)

member this.ConvertBack(value, _, parameter, _) =
member _.ConvertBack(value, _, parameter, _) =
if value.Equals(true) then parameter else Binding.DoNothing
}

Expand All @@ -78,3 +79,42 @@ module internal OptionsUIHelpers =

let bindCheckBox (checkBox: CheckBox) (path: string) =
checkBox.SetBinding(CheckBox.IsCheckedProperty, path) |> ignore

let bindDescriptionWidthTextBox (tb: TextBox) path =
let intOptionConverter =
{ new IValueConverter with
member _.Convert(value, _, _, _) =
try
value :?> int option
|> Option.map Convert.ToString
|> Option.defaultValue ""
|> box
with _ ->
Binding.DoNothing

member _.ConvertBack(value, _, _, _) =
try
Convert.ToInt32(value) |> Some |> box
with _ ->
None
}

let binding =
Binding(path, Converter = intOptionConverter, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged)

binding.ValidationRules.Add(
{ new ValidationRule() with
member _.Validate(value, _) =
try
if String.IsNullOrWhiteSpace(downcast value) then
ValidationResult.ValidResult
else
match Convert.ToInt32(value) with
| n when n >= 20 -> ValidationResult.ValidResult
| _ -> ValidationResult(false, "")
with _ ->
ValidationResult(false, "")
}
)

tb.SetBinding(TextBox.TextProperty, binding) |> ignore
18 changes: 12 additions & 6 deletions vsintegration/src/FSharp.Editor/QuickInfo/QuickInfoProvider.fs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ type internal FSharpAsyncQuickInfoSource
statusBar: StatusBar,
xmlMemberIndexService: IVsXMLMemberIndexService,
metadataAsSource: FSharpMetadataAsSourceService,
textBuffer: ITextBuffer
textBuffer: ITextBuffer,
editorOptions: EditorOptions
) =

// test helper
static member ProvideQuickInfo(document: Document, position: int) =
static member ProvideQuickInfo(document: Document, position: int, ?width: int) =
asyncMaybe {
let! _, sigQuickInfo, targetQuickInfo = FSharpQuickInfo.getQuickInfo (document, position, CancellationToken.None)
let! _, sigQuickInfo, targetQuickInfo = FSharpQuickInfo.getQuickInfo (document, position, width, CancellationToken.None)
return! sigQuickInfo |> Option.orElse targetQuickInfo
}

Expand Down Expand Up @@ -69,12 +70,14 @@ type internal FSharpAsyncQuickInfoSource
| true ->
let triggerPoint = triggerPoint.GetValueOrDefault()

let width = editorOptions.QuickInfo.DescriptionWidth

asyncMaybe {
let document =
textBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges()

let! symbolUseRange, sigQuickInfo, targetQuickInfo =
FSharpQuickInfo.getQuickInfo (document, triggerPoint.Position, cancellationToken)
FSharpQuickInfo.getQuickInfo (document, triggerPoint.Position, width, cancellationToken)

let getTooltip filePath =
let solutionDir = Path.GetDirectoryName(document.Project.Solution.FilePath)
Expand Down Expand Up @@ -195,7 +198,8 @@ type internal FSharpAsyncQuickInfoSource
type internal FSharpAsyncQuickInfoSourceProvider [<ImportingConstructor>]
(
[<Import(typeof<SVsServiceProvider>)>] serviceProvider: IServiceProvider,
metadataAsSource: FSharpMetadataAsSourceService
metadataAsSource: FSharpMetadataAsSourceService,
editorOptions: EditorOptions
) =

interface IAsyncQuickInfoSourceProvider with
Expand All @@ -204,4 +208,6 @@ type internal FSharpAsyncQuickInfoSourceProvider [<ImportingConstructor>]
// It is safe to do it here (see #4713)
let statusBar = StatusBar(serviceProvider.GetService<SVsStatusbar, IVsStatusbar>())
let xmlMemberIndexService = serviceProvider.XMLMemberIndexService
new FSharpAsyncQuickInfoSource(statusBar, xmlMemberIndexService, metadataAsSource, textBuffer) :> IAsyncQuickInfoSource

new FSharpAsyncQuickInfoSource(statusBar, xmlMemberIndexService, metadataAsSource, textBuffer, editorOptions)
:> IAsyncQuickInfoSource
16 changes: 10 additions & 6 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -181,16 +181,20 @@ Cache parsing results (experimental)</target>
<note />
</trans-unit>
<trans-unit id="QuickInfoPageKeywords">
<source>Navigation links;
<source>Formatting;
Maximum description width in characters;
Navigation links;
Show navigation links as;
Solid underline;
Dot underline;
Dash underline;</source>
<target state="translated">Navigační odkazy;
Zobrazit navigační odkazy jako;
Plné podtržení;
Podtržení tečkami;
Přerušované podtržení;</target>
<target state="new">Formatting;
Maximum description width in characters;
Navigation links;
Show navigation links as;
Solid underline;
Dot underline;
Dash underline;</target>
<note />
</trans-unit>
<trans-unit id="RemoveReturn">
Expand Down
16 changes: 10 additions & 6 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -181,16 +181,20 @@ Cache parsing results (experimental)</target>
<note />
</trans-unit>
<trans-unit id="QuickInfoPageKeywords">
<source>Navigation links;
<source>Formatting;
Maximum description width in characters;
Navigation links;
Show navigation links as;
Solid underline;
Dot underline;
Dash underline;</source>
<target state="translated">Navigationslinks;
Navigationslinks anzeigen als;
Durchgehende Unterstreichung;
Gepunktete Unterstreichung;
Gestrichelte Unterstreichung;</target>
<target state="new">Formatting;
Maximum description width in characters;
Navigation links;
Show navigation links as;
Solid underline;
Dot underline;
Dash underline;</target>
<note />
</trans-unit>
<trans-unit id="RemoveReturn">
Expand Down
16 changes: 10 additions & 6 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -181,16 +181,20 @@ Cache parsing results (experimental)</target>
<note />
</trans-unit>
<trans-unit id="QuickInfoPageKeywords">
<source>Navigation links;
<source>Formatting;
Maximum description width in characters;
Navigation links;
Show navigation links as;
Solid underline;
Dot underline;
Dash underline;</source>
<target state="translated">Vínculos de navegación;
Mostrar vínculos de navegación como;
Subrayado sólido;
Subrayado de punto;
Subrayado de guion;</target>
<target state="new">Formatting;
Maximum description width in characters;
Navigation links;
Show navigation links as;
Solid underline;
Dot underline;
Dash underline;</target>
<note />
</trans-unit>
<trans-unit id="RemoveReturn">
Expand Down
16 changes: 10 additions & 6 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -181,16 +181,20 @@ Cache parsing results (experimental)</target>
<note />
</trans-unit>
<trans-unit id="QuickInfoPageKeywords">
<source>Navigation links;
<source>Formatting;
Maximum description width in characters;
Navigation links;
Show navigation links as;
Solid underline;
Dot underline;
Dash underline;</source>
<target state="translated">Liens de navigation ;
Afficher les liens de navigation en tant que ;
Soulignement uni ;
Soulignement pointé ;
Soulignement en tirets ;</target>
<target state="new">Formatting;
Maximum description width in characters;
Navigation links;
Show navigation links as;
Solid underline;
Dot underline;
Dash underline;</target>
<note />
</trans-unit>
<trans-unit id="RemoveReturn">
Expand Down
16 changes: 10 additions & 6 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -181,16 +181,20 @@ Cache parsing results (experimental)</target>
<note />
</trans-unit>
<trans-unit id="QuickInfoPageKeywords">
<source>Navigation links;
<source>Formatting;
Maximum description width in characters;
Navigation links;
Show navigation links as;
Solid underline;
Dot underline;
Dash underline;</source>
<target state="translated">Collegamenti di spostamento;
Mostra collegamenti di spostamento come;
Sottolineatura a tinta unita;
Sottolineatura punto;
Trattino sottolineato;</target>
<target state="new">Formatting;
Maximum description width in characters;
Navigation links;
Show navigation links as;
Solid underline;
Dot underline;
Dash underline;</target>
<note />
</trans-unit>
<trans-unit id="RemoveReturn">
Expand Down
Loading