Repository: PowerShell/PowerShell
File: src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs (C#)

Code before:
            var helper = new PowerShellExecutionHelper(PowerShell.Create(RunspaceMode.CurrentRunspace));
            var executionContext = helper.CurrentPowerShell.Runspace.ExecutionContext;
            return CompleteVariable(new CompletionContext { WordToComplete = variableName, Helper = helper, ExecutionContext = executionContext });
        }

        private static readonly string[] s_variableScopes = new string[] { "Global:", "Local:", "Script:", "Private:" };

        private static readonly char[] s_charactersRequiringQuotes = new char[] {
            '-', '`', '&', '@', '\'', '"', '#', '{', '}', '(', ')', '$', ',', ';', '|', '<', '>', ' ', '.', '\\', '/', '\t', '^',
        };

        internal static List<CompletionResult> CompleteVariable(CompletionContext context)
        {
            HashSet<string> hashedResults = new(StringComparer.OrdinalIgnoreCase);
            List<CompletionResult> results = new();
            List<CompletionResult> tempResults = new();

            var wordToComplete = context.WordToComplete;
            var colon = wordToComplete.IndexOf(':');

            var lastAst = context.RelatedAsts?[^1];
            var variableAst = lastAst as VariableExpressionAst;
            if (lastAst is PropertyMemberAst ||
                (lastAst is not null && lastAst.Parent is ParameterAst parameter && (parameter.DefaultValue is null || parameter.DefaultValue != lastAst)))
            {
                // User is adding a new parameter, variable tab completion is not useful.
                return results;
            }
            var prefix = variableAst != null && variableAst.Splatted ? "@" : "$";
            bool tokenAtCursorUsedBraces = context.TokenAtCursor is not null && context.TokenAtCursor.Text.StartsWith("${");

            // Look for variables in the input (e.g. parameters, etc.) before checking session state - these
            // variables might not exist in session state yet.
            var wildcardPattern = WildcardPattern.Get(wordToComplete + "*", WildcardOptions.IgnoreCase);
            if (lastAst is not null)
            {
                Ast parent = lastAst.Parent;
                var findVariablesVisitor = new FindVariablesVisitor
                {
                    CompletionVariableAst = lastAst,
                    StopSearchOffset = lastAst.Extent.StartOffset,
                    Context = context.TypeInferenceContext
                };
                while (parent != null)
                {
                    if (parent is IParameterMetadataProvider)
                    {
                        findVariablesVisitor.Top = parent;
                        parent.Visit(findVariablesVisitor);
                    }


Review comment (suggestion):
```suggestion
                // User is adding a new parameter or a class member, variable tab completion is not useful.
```

Code after:
            var helper = new PowerShellExecutionHelper(PowerShell.Create(RunspaceMode.CurrentRunspace));
            var executionContext = helper.CurrentPowerShell.Runspace.ExecutionContext;
            return CompleteVariable(new CompletionContext { WordToComplete = variableName, Helper = helper, ExecutionContext = executionContext });
        }

        private static readonly string[] s_variableScopes = new string[] { "Global:", "Local:", "Script:", "Private:" };

        private static readonly char[] s_charactersRequiringQuotes = new char[] {
            '-', '`', '&', '@', '\'', '"', '#', '{', '}', '(', ')', '$', ',', ';', '|', '<', '>', ' ', '.', '\\', '/', '\t', '^',
        };

        internal static List<CompletionResult> CompleteVariable(CompletionContext context)
        {
            HashSet<string> hashedResults = new(StringComparer.OrdinalIgnoreCase);
            List<CompletionResult> results = new();
            List<CompletionResult> tempResults = new();

            var wordToComplete = context.WordToComplete;
            var colon = wordToComplete.IndexOf(':');

            var lastAst = context.RelatedAsts?[^1];
            var variableAst = lastAst as VariableExpressionAst;
            if (lastAst is PropertyMemberAst ||
                (lastAst is not null && lastAst.Parent is ParameterAst parameter && parameter.DefaultValue != lastAst))
            {
                // User is adding a new parameter or a class member, variable tab completion is not useful.
                return results;
            }
            var prefix = variableAst != null && variableAst.Splatted ? "@" : "$";
            bool tokenAtCursorUsedBraces = context.TokenAtCursor is not null && context.TokenAtCursor.Text.StartsWith("${");

            // Look for variables in the input (e.g. parameters, etc.) before checking session state - these
            // variables might not exist in session state yet.
            var wildcardPattern = WildcardPattern.Get(wordToComplete + "*", WildcardOptions.IgnoreCase);
            if (lastAst is not null)
            {
                Ast parent = lastAst.Parent;
                var findVariablesVisitor = new FindVariablesVisitor
                {
                    CompletionVariableAst = lastAst,
                    StopSearchOffset = lastAst.Extent.StartOffset,
                    Context = context.TypeInferenceContext
                };
                while (parent != null)
                {
                    if (parent is IParameterMetadataProvider)
                    {
                        findVariablesVisitor.Top = parent;
                        parent.Visit(findVariablesVisitor);
                    }