From 20f646a55c27d2545d303cacc07fee181ea0929b Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Tue, 16 May 2023 12:25:48 +0200 Subject: [PATCH] =?UTF-8?q?A=20na=C3=AFve=20telemetry=20duration=20impleme?= =?UTF-8?q?ntation=20(#15219)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .fantomasignore | 7 +- .../Classification/ClassificationService.fs | 56 ++++++- .../FSharp.Editor/CodeFix/CodeFixHelpers.fs | 22 ++- .../Completion/CompletionProvider.fs | 12 ++ .../Diagnostics/DocumentDiagnosticAnalyzer.fs | 15 ++ .../src/FSharp.Editor/FSharp.Editor.fsproj | 2 +- .../src/FSharp.Editor/Hints/RoslynAdapter.fs | 2 +- .../LanguageService/LanguageService.fs | 11 +- .../LanguageService/SymbolHelpers.fs | 8 +- .../FSharp.Editor/Options/EditorOptions.fs | 2 + .../Telemetry/TelemetryReporter.fs | 145 ++++++++++++++++-- .../AdvancedOptionsControl.xaml | 4 + .../FSharp.UIResources/Strings.Designer.cs | 18 +++ .../src/FSharp.UIResources/Strings.resx | 6 + .../src/FSharp.UIResources/xlf/Strings.cs.xlf | 10 ++ .../src/FSharp.UIResources/xlf/Strings.de.xlf | 10 ++ .../src/FSharp.UIResources/xlf/Strings.es.xlf | 10 ++ .../src/FSharp.UIResources/xlf/Strings.fr.xlf | 10 ++ .../src/FSharp.UIResources/xlf/Strings.it.xlf | 10 ++ .../src/FSharp.UIResources/xlf/Strings.ja.xlf | 10 ++ .../src/FSharp.UIResources/xlf/Strings.ko.xlf | 10 ++ .../src/FSharp.UIResources/xlf/Strings.pl.xlf | 10 ++ .../FSharp.UIResources/xlf/Strings.pt-BR.xlf | 10 ++ .../src/FSharp.UIResources/xlf/Strings.ru.xlf | 10 ++ .../src/FSharp.UIResources/xlf/Strings.tr.xlf | 10 ++ .../xlf/Strings.zh-Hans.xlf | 10 ++ .../xlf/Strings.zh-Hant.xlf | 10 ++ 27 files changed, 404 insertions(+), 36 deletions(-) diff --git a/.fantomasignore b/.fantomasignore index d2f57d7fc7..45eb387fa1 100644 --- a/.fantomasignore +++ b/.fantomasignore @@ -12,7 +12,11 @@ vsintegration/* !vsintegration/tests/FSharp.Editor.Tests artifacts/ -# Explicitly unformatted implementation +# For some reason, it tries to format files from remotes (Processing .\.git\refs\remotes\\FSComp.fsi) +.git/ + + +# Explicitly unformatted implementation src/Compiler/Checking/AccessibilityLogic.fs src/Compiler/Checking/AttributeChecking.fs src/Compiler/Checking/AugmentWithHashCompare.fs @@ -113,4 +117,3 @@ src/FSharp.Core/list.fsi src/FSharp.Core/Query.fsi src/FSharp.Core/resumable.fsi src/FSharp.Core/async.fsi - diff --git a/vsintegration/src/FSharp.Editor/Classification/ClassificationService.fs b/vsintegration/src/FSharp.Editor/Classification/ClassificationService.fs index 43673355ab..31d69db735 100644 --- a/vsintegration/src/FSharp.Editor/Classification/ClassificationService.fs +++ b/vsintegration/src/FSharp.Editor/Classification/ClassificationService.fs @@ -20,6 +20,7 @@ open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Classification open FSharp.Compiler.CodeAnalysis open FSharp.Compiler.EditorServices open FSharp.Compiler.Tokenization +open Microsoft.VisualStudio.FSharp.Editor.Telemetry // IEditorClassificationService is marked as Obsolete, but is still supported. The replacement (IClassificationService) // is internal to Microsoft.CodeAnalysis.Workspaces which we don't have internals visible to. Rather than add yet another @@ -183,7 +184,20 @@ type internal FSharpClassificationService [] () = // For closed documents, only get classification for the text within the span. // This may be inaccurate for multi-line tokens such as string literals, but this is ok for now // as it's better than having to tokenize a big part of a file which in return will allocate a lot and hurt find all references performance. - if not (document.Project.Solution.Workspace.IsDocumentOpen document.Id) then + let isOpenDocument = document.Project.Solution.Workspace.IsDocumentOpen document.Id + + let eventProps: (string * obj) array = + [| + "context.document.project.id", document.Project.Id.Id.ToString() + "context.document.id", document.Id.Id.ToString() + "isOpenDocument", isOpenDocument + "textSpanLength", textSpan.Length + |] + + use _eventDuration = + TelemetryReporter.ReportSingleEventWithDuration(TelemetryEvents.AddSyntacticCalssifications, eventProps) + + if not isOpenDocument then result.AddRange(getLexicalClassifications (document.FilePath, defines, sourceText, textSpan, cancellationToken)) else result.AddRange( @@ -200,7 +214,7 @@ type internal FSharpClassificationService [] () = } |> RoslynHelpers.StartAsyncUnitAsTask cancellationToken - member this.AddSemanticClassificationsAsync + member _.AddSemanticClassificationsAsync ( document: Document, textSpan: TextSpan, @@ -215,16 +229,52 @@ type internal FSharpClassificationService [] () = // If we are trying to get semantic classification for a document that is not open, get the results from the background and cache it. // We do this for find all references when it is populating results. // We cache it temporarily so we do not have to continously call into the checker and perform a background operation. - if not (document.Project.Solution.Workspace.IsDocumentOpen document.Id) then + let isOpenDocument = document.Project.Solution.Workspace.IsDocumentOpen document.Id + + if not isOpenDocument then match! semanticClassificationCache.TryGetValueAsync document with | ValueSome classificationDataLookup -> + let eventProps: (string * obj) array = + [| + "context.document.project.id", document.Project.Id.Id.ToString() + "context.document.id", document.Id.Id.ToString() + "isOpenDocument", isOpenDocument + "textSpanLength", textSpan.Length + "cacheHit", true + |] + + use _eventDuration = + TelemetryReporter.ReportSingleEventWithDuration(TelemetryEvents.AddSemanticCalssifications, eventProps) + addSemanticClassificationByLookup sourceText textSpan classificationDataLookup result | _ -> + let eventProps = + [| + "isOpenDocument", isOpenDocument :> obj + "textSpanLength", textSpan.Length + "cacheHit", false + |] + + use _eventDuration = + TelemetryReporter.ReportSingleEventWithDuration(TelemetryEvents.AddSemanticCalssifications, eventProps) + let! classificationData = document.GetFSharpSemanticClassificationAsync(nameof (FSharpClassificationService)) let classificationDataLookup = toSemanticClassificationLookup classificationData do! semanticClassificationCache.SetAsync(document, classificationDataLookup) addSemanticClassificationByLookup sourceText textSpan classificationDataLookup result else + let eventProps: (string * obj) array = + [| + "context.document.project.id", document.Project.Id.Id.ToString() + "context.document.id", document.Id.Id.ToString() + "isOpenDocument", isOpenDocument + "textSpanLength", textSpan.Length + "cacheHit", false + |] + + use _eventDuration = + TelemetryReporter.ReportSingleEventWithDuration(TelemetryEvents.AddSemanticCalssifications, eventProps) + let! _, checkResults = document.GetFSharpParseAndCheckResultsAsync(nameof (IFSharpClassificationService)) let targetRange = diff --git a/vsintegration/src/FSharp.Editor/CodeFix/CodeFixHelpers.fs b/vsintegration/src/FSharp.Editor/CodeFix/CodeFixHelpers.fs index e8af59ad67..924bf6d38f 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/CodeFixHelpers.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/CodeFixHelpers.fs @@ -17,21 +17,27 @@ open Microsoft.VisualStudio.FSharp.Editor.Telemetry [] module internal CodeFixHelpers = - let private reportCodeFixTelemetry (diagnostics: ImmutableArray) (doc: Document) (staticName: string) (additionalProps) = + let private reportCodeFixTelemetry + (diagnostics: ImmutableArray) + (doc: Document) + (staticName: string) + (additionalProps: (string * obj) array) + = let ids = diagnostics |> Seq.map (fun d -> d.Id) |> Seq.distinct |> String.concat "," - let props: (string * obj) list = - additionalProps - @ [ + let defaultProps: (string * obj) array = + [| "name", staticName "ids", ids "context.document.project.id", doc.Project.Id.Id.ToString() "context.document.id", doc.Id.Id.ToString() "context.diagnostics.count", diagnostics.Length - ] + |] - TelemetryReporter.reportEvent "codefixactivated" props + let props: (string * obj) array = Array.concat [ additionalProps; defaultProps ] + + TelemetryReporter.ReportSingleEvent(TelemetryEvents.CodefixActivated, props) let createFixAllProvider name getChanges = FixAllProvider.Create(fun fixAllCtx doc allDiagnostics -> @@ -46,7 +52,7 @@ module internal CodeFixHelpers = allDiagnostics doc name - [ "scope", fixAllCtx.Scope.ToString(); "elapsedMs", sw.ElapsedMilliseconds ] + [| "scope", fixAllCtx.Scope.ToString(); "elapsedMs", sw.ElapsedMilliseconds |] return doc }) @@ -58,7 +64,7 @@ module internal CodeFixHelpers = backgroundTask { let! sourceText = context.Document.GetTextAsync(cancellationToken) let doc = context.Document.WithText(sourceText.WithChanges(changes)) - reportCodeFixTelemetry context.Diagnostics context.Document name [] + reportCodeFixTelemetry context.Diagnostics context.Document name [||] return doc }), name diff --git a/vsintegration/src/FSharp.Editor/Completion/CompletionProvider.fs b/vsintegration/src/FSharp.Editor/Completion/CompletionProvider.fs index 963997eb80..baac85294f 100644 --- a/vsintegration/src/FSharp.Editor/Completion/CompletionProvider.fs +++ b/vsintegration/src/FSharp.Editor/Completion/CompletionProvider.fs @@ -13,6 +13,7 @@ open Microsoft.CodeAnalysis.Completion open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Completion +open Microsoft.VisualStudio.FSharp.Editor.Telemetry open Microsoft.VisualStudio.Shell open FSharp.Compiler.CodeAnalysis @@ -142,6 +143,7 @@ type internal FSharpCompletionProvider ) = asyncMaybe { + let! parseResults, checkFileResults = document.GetFSharpParseAndCheckResultsAsync("ProvideCompletionsAsyncAux") |> liftAsync @@ -298,6 +300,16 @@ type internal FSharpCompletionProvider Logger.LogBlockMessage context.Document.Name LogEditorFunctionId.Completion_ProvideCompletionsAsync let document = context.Document + + let eventProps: (string * obj) array = + [| + "context.document.project.id", document.Project.Id.Id.ToString() + "context.document.id", document.Id.Id.ToString() + |] + + use _eventDuration = + TelemetryReporter.ReportSingleEventWithDuration(TelemetryEvents.ProvideCompletions, eventProps) + let! sourceText = context.Document.GetTextAsync(context.CancellationToken) let defines, langVersion = document.GetFSharpQuickDefinesAndLangVersion() diff --git a/vsintegration/src/FSharp.Editor/Diagnostics/DocumentDiagnosticAnalyzer.fs b/vsintegration/src/FSharp.Editor/Diagnostics/DocumentDiagnosticAnalyzer.fs index 9607840abf..249a9bb25f 100644 --- a/vsintegration/src/FSharp.Editor/Diagnostics/DocumentDiagnosticAnalyzer.fs +++ b/vsintegration/src/FSharp.Editor/Diagnostics/DocumentDiagnosticAnalyzer.fs @@ -15,6 +15,7 @@ open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Diagnostics open FSharp.Compiler.CodeAnalysis open FSharp.Compiler.Diagnostics +open Microsoft.VisualStudio.FSharp.Editor.Telemetry [] type internal DiagnosticsType = @@ -53,6 +54,20 @@ type internal FSharpDocumentDiagnosticAnalyzer [] () = static member GetDiagnostics(document: Document, diagnosticType: DiagnosticsType) = async { + + let eventProps: (string * obj) array = + [| + "context.document.project.id", document.Project.Id.Id.ToString() + "context.document.id", document.Id.Id.ToString() + "context.diagnostics.type", + match diagnosticType with + | DiagnosticsType.Syntax -> "syntax" + | DiagnosticsType.Semantic -> "semantic" + |] + + use _eventDuration = + TelemetryReporter.ReportSingleEventWithDuration(TelemetryEvents.GetDiagnosticsForDocument, eventProps) + let! ct = Async.CancellationToken let! parseResults = document.GetFSharpParseResultsAsync("GetDiagnostics") diff --git a/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj b/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj index 6ba152f923..fb9f60c065 100644 --- a/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj +++ b/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj @@ -28,7 +28,6 @@ - @@ -44,6 +43,7 @@ + diff --git a/vsintegration/src/FSharp.Editor/Hints/RoslynAdapter.fs b/vsintegration/src/FSharp.Editor/Hints/RoslynAdapter.fs index 53820400d9..e24562031a 100644 --- a/vsintegration/src/FSharp.Editor/Hints/RoslynAdapter.fs +++ b/vsintegration/src/FSharp.Editor/Hints/RoslynAdapter.fs @@ -27,7 +27,7 @@ type internal RoslynAdapter [] (settings: EditorOptions) = return ImmutableArray.Empty else let hintKindsSerialized = hintKinds |> Set.map Hints.serialize |> String.concat "," - TelemetryReporter.reportEvent "hints" [ ("hints.kinds", hintKindsSerialized) ] + TelemetryReporter.ReportSingleEvent(TelemetryEvents.Hints, [| ("hints.kinds", hintKindsSerialized) |]) let! sourceText = document.GetTextAsync cancellationToken |> Async.AwaitTask let! nativeHints = HintService.getHintsForDocument sourceText document hintKinds userOpName cancellationToken diff --git a/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs b/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs index c9b25aad44..c1544bf78c 100644 --- a/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs +++ b/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs @@ -118,7 +118,7 @@ type internal FSharpWorkspaceServiceFactory [ let checker = lazy - TelemetryReporter.reportEvent "languageservicestarted" [] + TelemetryReporter.ReportSingleEvent(TelemetryEvents.LanguageServiceStarted, [||]) let editorOptions = workspace.Services.GetService() @@ -162,9 +162,9 @@ type internal FSharpWorkspaceServiceFactory [ diff --git a/vsintegration/src/FSharp.Editor/LanguageService/SymbolHelpers.fs b/vsintegration/src/FSharp.Editor/LanguageService/SymbolHelpers.fs index 1fcf662bdc..f84c2bec55 100644 --- a/vsintegration/src/FSharp.Editor/LanguageService/SymbolHelpers.fs +++ b/vsintegration/src/FSharp.Editor/LanguageService/SymbolHelpers.fs @@ -72,11 +72,13 @@ module internal SymbolHelpers = | firstProject :: _ -> let isFastFindReferencesEnabled = firstProject.IsFastFindReferencesEnabled + // TODO: this needs to use already boxed boolean instead of boxing it every time. let props = - [ nameof isFastFindReferencesEnabled, isFastFindReferencesEnabled :> obj ] + [| nameof isFastFindReferencesEnabled, isFastFindReferencesEnabled :> obj |] backgroundTask { - TelemetryReporter.reportEvent "getSymbolUsesInProjectsStarted" props + // TODO: this needs to be a single event with a duration + TelemetryReporter.ReportSingleEvent(TelemetryEvents.GetSymbolUsesInProjectsStarted, props) do! projects @@ -84,7 +86,7 @@ module internal SymbolHelpers = Task.Run(fun () -> project.FindFSharpReferencesAsync(symbol, onFound, "getSymbolUsesInProjects", ct))) |> Task.WhenAll - TelemetryReporter.reportEvent "getSymbolUsesInProjectsFinished" props + TelemetryReporter.ReportSingleEvent(TelemetryEvents.GetSymbolUsesInProjectsFinished, props) } let findSymbolUses (symbolUse: FSharpSymbolUse) (currentDocument: Document) (checkFileResults: FSharpCheckFileResults) onFound = diff --git a/vsintegration/src/FSharp.Editor/Options/EditorOptions.fs b/vsintegration/src/FSharp.Editor/Options/EditorOptions.fs index 9ecda0ff39..137bcce687 100644 --- a/vsintegration/src/FSharp.Editor/Options/EditorOptions.fs +++ b/vsintegration/src/FSharp.Editor/Options/EditorOptions.fs @@ -105,6 +105,7 @@ type AdvancedOptions = IsInlineParameterNameHintsEnabled: bool IsInlineReturnTypeHintsEnabled: bool IsLiveBuffersEnabled: bool + SendAdditionalTelemetry: bool } static member Default = @@ -115,6 +116,7 @@ type AdvancedOptions = IsInlineParameterNameHintsEnabled = false IsInlineReturnTypeHintsEnabled = false IsLiveBuffersEnabled = FSharpExperimentalFeaturesEnabledAutomatically + SendAdditionalTelemetry = FSharpExperimentalFeaturesEnabledAutomatically } [] diff --git a/vsintegration/src/FSharp.Editor/Telemetry/TelemetryReporter.fs b/vsintegration/src/FSharp.Editor/Telemetry/TelemetryReporter.fs index 1cfe1c42d6..04832c8471 100644 --- a/vsintegration/src/FSharp.Editor/Telemetry/TelemetryReporter.fs +++ b/vsintegration/src/FSharp.Editor/Telemetry/TelemetryReporter.fs @@ -3,25 +3,144 @@ namespace Microsoft.VisualStudio.FSharp.Editor.Telemetry open Microsoft.VisualStudio.Telemetry +open System +open System.Diagnostics +open System.Collections.Concurrent +open Microsoft.VisualStudio.Shell +open Microsoft.VisualStudio +open Microsoft.VisualStudio.LanguageServices +open Microsoft.VisualStudio.FSharp.Editor +#nowarn "3220" // Ignore warning about direct tuple items access. + +[] +module TelemetryEvents = + [] + let CodefixActivated = "codefixactivated" + + [] + let Hints = "hints" + + [] + let LanguageServiceStarted = "languageservicestarted" + + [] + let GetSymbolUsesInProjectsStarted = "getSymbolUsesInProjectsStarted" + + [] + let GetSymbolUsesInProjectsFinished = "getSymbolUsesInProjectsFinished" + + [] + let AddSyntacticCalssifications = "addsyntacticclassifications" + + [] + let AddSemanticCalssifications = "addsemanticclassifications" + + [] + let GetDiagnosticsForDocument = "getdiagnosticsfordocument" + + [] + let ProvideCompletions = "providecompletions" + +// TODO: needs to be something more sophisticated in future +[] +type TelemetryThrottlingStrategy = + | NoThrottling + | Throttle of {| Timeout: TimeSpan |} + // At most, send one event per 5 seconds. + static member Default = + Throttle + {| + Timeout = TimeSpan.FromSeconds(5.0) + |} + +[] module TelemetryReporter = + let internal noopDisposable = + { new IDisposable with + member _.Dispose() = () + } - let private eventPrefix = "dotnet/fsharp/" - let private propPrefix = "dotnet.fsharp." + let internal lastTriggeredEvents = ConcurrentDictionary() - let private getFullEventName name = eventPrefix + name - let private getFullPropName name = propPrefix + name + [] + let eventPrefix = "dotnet/fsharp/" - let private createEvent name (props: (string * obj) list) = - let event = TelemetryEvent(getFullEventName name) + [] + let propPrefix = "dotnet.fsharp." - props - |> List.map (fun (k, v) -> getFullPropName k, v) - |> List.iter event.Properties.Add + // This should always be inlined. + let inline createEvent name (props: (string * obj) array) = + let eventName = eventPrefix + name + let event = TelemetryEvent(eventName, TelemetrySeverity.Normal) + + // TODO: + // We need to utilize TelemetryEvent's Correlation id, so we can track (for example) events on one document in the project. + + // TODO: need to carefully review the code, since it will be a hot path when we are sending telemetry + // This particular approach is here to avoid alocations for properties, which is likely the case if we destructing them. + for prop in props do + event.Properties.Add(propPrefix + prop.Item1, prop.Item2) event - let reportEvent name props = - let session = TelemetryService.DefaultSession - let event = createEvent name props - session.PostEvent event +[] +type TelemetryReporter private (name: string, props: (string * obj) array, stopwatch: Stopwatch) = + + static member val private SendAdditionalTelemetry = + lazy + (let componentModel = + Package.GetGlobalService(typeof) :?> ComponentModelHost.IComponentModel + + if componentModel = null then + TelemetryService.DefaultSession.IsUserMicrosoftInternal + else + let workspace = componentModel.GetService() + workspace.Services.GetService().Advanced.SendAdditionalTelemetry) + + static member ReportSingleEvent(name, props) = + let event = TelemetryReporter.createEvent name props + TelemetryService.DefaultSession.PostEvent event + + // A naïve implementation using stopwatch and returning an IDisposable + // TODO: needs a careful review, since it will be a hot path when we are sending telemetry + static member ReportSingleEventWithDuration(name, props, ?throttlingStrategy) : IDisposable = + + let additionalTelemetryEnabled = not TelemetryReporter.SendAdditionalTelemetry.Value + + let isUserMicrosoftInternal = + TelemetryService.DefaultSession.IsUserMicrosoftInternal + + if additionalTelemetryEnabled || isUserMicrosoftInternal then + let throttlingStrategy = + defaultArg throttlingStrategy TelemetryThrottlingStrategy.Default + + match throttlingStrategy with + | TelemetryThrottlingStrategy.NoThrottling -> + let stopwatch = Stopwatch() + stopwatch.Start() + new TelemetryReporter(name, props, stopwatch) + | TelemetryThrottlingStrategy.Throttle s -> + // This is not "atomic" for now, theoretically multiple threads can send the event as for now. + match TelemetryReporter.lastTriggeredEvents.TryGetValue(name) with + | false, lastTriggered + | true, lastTriggered when lastTriggered + s.Timeout < DateTime.UtcNow -> + let stopwatch = Stopwatch() + stopwatch.Start() + // Whenever we create an event, we update the time. + TelemetryReporter.lastTriggeredEvents.AddOrUpdate(name, DateTime.UtcNow, (fun _ _ -> DateTime.UtcNow)) + |> ignore + + new TelemetryReporter(name, props, stopwatch) + | _ -> TelemetryReporter.noopDisposable + else + TelemetryReporter.noopDisposable + + interface IDisposable with + member _.Dispose() = + stopwatch.Stop() + + let event = + TelemetryReporter.createEvent name (Array.concat [ props; [| "vs_event_duration_ms", stopwatch.ElapsedMilliseconds |] ]) + + TelemetryService.DefaultSession.PostEvent event diff --git a/vsintegration/src/FSharp.UIResources/AdvancedOptionsControl.xaml b/vsintegration/src/FSharp.UIResources/AdvancedOptionsControl.xaml index 78afe373f8..d9388204b6 100644 --- a/vsintegration/src/FSharp.UIResources/AdvancedOptionsControl.xaml +++ b/vsintegration/src/FSharp.UIResources/AdvancedOptionsControl.xaml @@ -38,6 +38,10 @@ + + + diff --git a/vsintegration/src/FSharp.UIResources/Strings.Designer.cs b/vsintegration/src/FSharp.UIResources/Strings.Designer.cs index 05c26ae57a..1ce713052f 100644 --- a/vsintegration/src/FSharp.UIResources/Strings.Designer.cs +++ b/vsintegration/src/FSharp.UIResources/Strings.Designer.cs @@ -60,6 +60,15 @@ namespace Microsoft.VisualStudio.FSharp.UIResources { } } + /// + /// Looks up a localized string similar to Additional performance telemetry (experimental). + /// + public static string AdditionalTelemetry { + get { + return ResourceManager.GetString("AdditionalTelemetry", resourceCulture); + } + } + /// /// Looks up a localized string similar to Always place open statements at the top level. /// @@ -312,6 +321,15 @@ namespace Microsoft.VisualStudio.FSharp.UIResources { } } + /// + /// Looks up a localized string similar to Send additional performance telemetry. + /// + public static string Send_Additional_Telemetry { + get { + return ResourceManager.GetString("Send_Additional_Telemetry", resourceCulture); + } + } + /// /// Looks up a localized string similar to Show s_ymbols in unopened namespaces. /// diff --git a/vsintegration/src/FSharp.UIResources/Strings.resx b/vsintegration/src/FSharp.UIResources/Strings.resx index 98d089b053..12f2ce0f94 100644 --- a/vsintegration/src/FSharp.UIResources/Strings.resx +++ b/vsintegration/src/FSharp.UIResources/Strings.resx @@ -237,6 +237,12 @@ Live Buffers (experimental) + + Additional performance telemetry (experimental) + + + Send additional performance telemetry + Cache parsing results (experimental) diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.cs.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.cs.xlf index 8d56d2adbd..1d431306de 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.cs.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.cs.xlf @@ -2,6 +2,11 @@ + + Additional performance telemetry (experimental) + Additional performance telemetry (experimental) + + Always place open statements at the top level Vždy umístit otevřené příkazy na nejvyšší úroveň @@ -92,6 +97,11 @@ Upřednostňovaná šířka popisu ve znacích + + Send additional performance telemetry + Send additional performance telemetry + + Display inline parameter name hints (preview) Zobrazit nápovědy k názvům vložených parametrů (preview) diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf index ea47f390c0..0b4a44eaa3 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf @@ -2,6 +2,11 @@ + + Additional performance telemetry (experimental) + Additional performance telemetry (experimental) + + Always place open statements at the top level open-Anweisungen immer an oberster Ebene platzieren @@ -92,6 +97,11 @@ Bevorzugte Beschreibungsbreite in Zeichen + + Send additional performance telemetry + Send additional performance telemetry + + Display inline parameter name hints (preview) Hinweise zu Inlineparameternamen anzeigen (Vorschau) diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf index d58237d68b..b3b7158342 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf @@ -2,6 +2,11 @@ + + Additional performance telemetry (experimental) + Additional performance telemetry (experimental) + + Always place open statements at the top level Colocar siempre las instrucciones open en el nivel superior @@ -92,6 +97,11 @@ Anchura preferida de la descripción en caracteres + + Send additional performance telemetry + Send additional performance telemetry + + Display inline parameter name hints (preview) Mostrar sugerencias de nombres de parámetros en línea (vista previa) diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf index 30ee652da6..5970e89584 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf @@ -2,6 +2,11 @@ + + Additional performance telemetry (experimental) + Additional performance telemetry (experimental) + + Always place open statements at the top level Placer toujours les instructions open au niveau supérieur @@ -92,6 +97,11 @@ Largeur de description préférée en caractères + + Send additional performance telemetry + Send additional performance telemetry + + Display inline parameter name hints (preview) Afficher les conseils de nom de paramètre en ligne (préversion) diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf index 6b4009249b..c7f7d17d24 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf @@ -2,6 +2,11 @@ + + Additional performance telemetry (experimental) + Additional performance telemetry (experimental) + + Always place open statements at the top level Inserisci sempre le istruzioni OPEN al primo livello @@ -92,6 +97,11 @@ Larghezza descrizione preferita in caratteri + + Send additional performance telemetry + Send additional performance telemetry + + Display inline parameter name hints (preview) Visualizza suggerimenti per i nomi di parametro inline (anteprima) diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf index 074852e1f7..d699a836bc 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf @@ -2,6 +2,11 @@ + + Additional performance telemetry (experimental) + Additional performance telemetry (experimental) + + Always place open statements at the top level Open ステートメントを常に最上位に配置する @@ -92,6 +97,11 @@ 優先する説明の文字幅 + + Send additional performance telemetry + Send additional performance telemetry + + Display inline parameter name hints (preview) インライン パラメーター名のヒントを表示する (プレビュー) diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf index 369dc3d81c..c603eb3270 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf @@ -2,6 +2,11 @@ + + Additional performance telemetry (experimental) + Additional performance telemetry (experimental) + + Always place open statements at the top level 항상 최상위에 open 문 배치 @@ -92,6 +97,11 @@ 기본 설정 설명 너비(문자) + + Send additional performance telemetry + Send additional performance telemetry + + Display inline parameter name hints (preview) 인라인 매개 변수 이름 힌트 표시(미리 보기) diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf index 8f85bfb4f6..798997dddf 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf @@ -2,6 +2,11 @@ + + Additional performance telemetry (experimental) + Additional performance telemetry (experimental) + + Always place open statements at the top level Zawsze umieszczaj otwarte instrukcje na najwyższym poziomie @@ -92,6 +97,11 @@ Preferowana szerokość opisu w znakach + + Send additional performance telemetry + Send additional performance telemetry + + Display inline parameter name hints (preview) Wyświetl wskazówki w tekście dotyczące nazw parametrów (wersja zapoznawcza) diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf index 257b0f3f57..110cdc0ee8 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf @@ -2,6 +2,11 @@ + + Additional performance telemetry (experimental) + Additional performance telemetry (experimental) + + Always place open statements at the top level Sempre coloque as instruções abertas no nível superior @@ -92,6 +97,11 @@ Largura de descrição preferencial em caracteres + + Send additional performance telemetry + Send additional performance telemetry + + Display inline parameter name hints (preview) Exibir dicas de nome de parâmetro embutido (versão prévia) diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf index ed978ec293..fabb6126be 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf @@ -2,6 +2,11 @@ + + Additional performance telemetry (experimental) + Additional performance telemetry (experimental) + + Always place open statements at the top level Всегда располагайте открытые операторы на верхнем уровне @@ -92,6 +97,11 @@ Предпочитаемая ширина описания в символах + + Send additional performance telemetry + Send additional performance telemetry + + Display inline parameter name hints (preview) Отображение подсказок для имен встроенных параметров (предварительная версия) diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf index 181076a632..892af3ca3e 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf @@ -2,6 +2,11 @@ + + Additional performance telemetry (experimental) + Additional performance telemetry (experimental) + + Always place open statements at the top level Açık deyimleri her zaman en üst düzeye yerleştir @@ -92,6 +97,11 @@ Karakter olarak tercih edilen açıklama genişliği + + Send additional performance telemetry + Send additional performance telemetry + + Display inline parameter name hints (preview) Satır içi parametre adı ipuçlarını görüntüle (önizleme) diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf index 4fc3ff63c9..6e0ff2e91d 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf @@ -2,6 +2,11 @@ + + Additional performance telemetry (experimental) + Additional performance telemetry (experimental) + + Always place open statements at the top level 始终在顶层放置 open 语句 @@ -92,6 +97,11 @@ 以字符为单位的首选说明宽度 + + Send additional performance telemetry + Send additional performance telemetry + + Display inline parameter name hints (preview) 显示内联参数名称提示(预览版) diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf index 1b0248ea00..1ed09d1f28 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf @@ -2,6 +2,11 @@ + + Additional performance telemetry (experimental) + Additional performance telemetry (experimental) + + Always place open statements at the top level 一律將 open 陳述式放在最上層 @@ -92,6 +97,11 @@ 慣用説明寬度 (以字元為單位) + + Send additional performance telemetry + Send additional performance telemetry + + Display inline parameter name hints (preview) 顯示內嵌參數名稱提示 (預覽)