From 353ba8ba011365ddc5280b31d3c362d82aa56f60 Mon Sep 17 00:00:00 2001 From: HeeJae Chang Date: Mon, 17 Jun 2019 18:31:02 -0700 Subject: [PATCH] added basic completion statement telemetry --- .../CompleteStatementCommandHandler.cs | 43 +++++++++++-------- .../Core/Portable/Log/FunctionId.cs | 1 + 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/EditorFeatures/CSharp/CompleteStatement/CompleteStatementCommandHandler.cs b/src/EditorFeatures/CSharp/CompleteStatement/CompleteStatementCommandHandler.cs index f31541e6750b4..0ee7717278243 100644 --- a/src/EditorFeatures/CSharp/CompleteStatement/CompleteStatementCommandHandler.cs +++ b/src/EditorFeatures/CSharp/CompleteStatement/CompleteStatementCommandHandler.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.Editor.Implementation.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Internal.Log; using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; @@ -18,7 +19,6 @@ using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor.Commanding.Commands; using Microsoft.VisualStudio.Utilities; -using Roslyn.Utilities; using VSCommanding = Microsoft.VisualStudio.Commanding; namespace Microsoft.CodeAnalysis.Editor.CSharp.CompleteStatement @@ -173,22 +173,33 @@ private static void MoveCaretToFinalPositionInStatement(SyntaxNode statementNode return; } + if (TryGetCaretPositionToMove(statementNode, caret, isInsideDelimiters, out var targetPosition)) + { + Logger.Log(FunctionId.CommandHandler_CompleteStatement, KeyValueLogMessage.Create(LogType.UserAction, m => + { + m[nameof(isInsideDelimiters)] = isInsideDelimiters; + m[nameof(statementNode)] = statementNode.Kind(); + })); + + args.TextView.TryMoveCaretToAndEnsureVisible(targetPosition); + } + } + + private static bool TryGetCaretPositionToMove(SyntaxNode statementNode, SnapshotPoint caret, bool isInsideDelimiters, out SnapshotPoint targetPosition) + { + targetPosition = default; + switch (statementNode.Kind()) { case SyntaxKind.DoStatement: // Move caret after the do statment's closing paren. - var doStatementCaret = args.SubjectBuffer.CurrentSnapshot.GetPoint(((DoStatementSyntax)statementNode).CloseParenToken.Span.End); - args.TextView.TryMoveCaretToAndEnsureVisible(doStatementCaret); - return; + targetPosition = caret.Snapshot.GetPoint(((DoStatementSyntax)statementNode).CloseParenToken.Span.End); + return true; case SyntaxKind.ForStatement: // `For` statements can have semicolon after initializer/declaration or after condition. // If caret is in initialer/declaration or condition, AND is inside other delimiters, complete statement // Otherwise, return without moving the caret. - if (TryGetForStatementCaret(caret, (ForStatementSyntax)statementNode, args, out var forStatementCaret) && isInsideDelimiters) - { - args.TextView.TryMoveCaretToAndEnsureVisible(forStatementCaret); - } - return; + return isInsideDelimiters && TryGetForStatementCaret(caret, (ForStatementSyntax)statementNode, out targetPosition); case SyntaxKind.ExpressionStatement: case SyntaxKind.GotoCaseStatement: case SyntaxKind.LocalDeclarationStatement: @@ -198,18 +209,15 @@ private static void MoveCaretToFinalPositionInStatement(SyntaxNode statementNode case SyntaxKind.DelegateDeclaration: // These statement types end in a semicolon. // if the original caret was inside any delimiters, `caret` will be after the outermost delimiter - if (isInsideDelimiters) - { - args.TextView.TryMoveCaretToAndEnsureVisible(args.SubjectBuffer.CurrentSnapshot.GetPoint(caret)); - } - return; + targetPosition = caret; + return isInsideDelimiters; default: // For all other statement types, don't complete statement. Return without moving the caret. - return; + return false; } } - private static bool TryGetForStatementCaret(SnapshotPoint originalCaret, ForStatementSyntax forStatement, TypeCharCommandArgs args, out SnapshotPoint forStatementCaret) + private static bool TryGetForStatementCaret(SnapshotPoint originalCaret, ForStatementSyntax forStatement, out SnapshotPoint forStatementCaret) { if (CaretIsInForStatementCondition(originalCaret, forStatement)) { @@ -232,8 +240,7 @@ private static bool TryGetForStatementCaret(SnapshotPoint originalCaret, ForStat return (forStatementCaret != default); // Locals - SnapshotPoint GetCaretAtPosition(int position) - => args.SubjectBuffer.CurrentSnapshot.GetPoint(position); + SnapshotPoint GetCaretAtPosition(int position) => originalCaret.Snapshot.GetPoint(position); } private static bool CaretIsInForStatementCondition(int caretPosition, ForStatementSyntax forStatementSyntax) diff --git a/src/Workspaces/Core/Portable/Log/FunctionId.cs b/src/Workspaces/Core/Portable/Log/FunctionId.cs index 1d90e52924cd8..7115fecda5f2b 100644 --- a/src/Workspaces/Core/Portable/Log/FunctionId.cs +++ b/src/Workspaces/Core/Portable/Log/FunctionId.cs @@ -61,6 +61,7 @@ internal enum FunctionId CommandHandler_GetCommandState, CommandHandler_ExecuteHandlers, CommandHandler_FormatCommand, + CommandHandler_CompleteStatement, Workspace_SourceText_GetChangeRanges, Workspace_Recoverable_RecoverRootAsync,