Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fix tab completions for a hash table#6839

Merged
iSazonov merged 3 commits intoPowerShell:masterfrom
iSazonov:fix-tabcompletion
May 21, 2018
Merged

Fix tab completions for a hash table#6839
iSazonov merged 3 commits intoPowerShell:masterfrom
iSazonov:fix-tabcompletion

Conversation

@iSazonov
Copy link
Collaborator

@iSazonov iSazonov commented May 8, 2018

PR Summary

Fix #5322.

Now working:

  • Get-Date | Sort-Object @{Expression=<tab>
  • Get-Date | Sort-Object @{Expression=...;<tab>

PR Checklist

@iSazonov iSazonov self-assigned this May 8, 2018
@iSazonov iSazonov requested review from SteveL-MSFT and lzybkr May 8, 2018 15:02
replacementLength = 0;
break;

case TokenKind.Semi:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does adding this case affect get-something; e<TAB> - in other words, no hashtable, just simple command completion?

Copy link
Collaborator Author

@iSazonov iSazonov May 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I don't see the side affect.
Maybe add the test?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I re-check get-something; e<Tab> - in Windows PowerShell 5.1 and in PowerShell Core 6.0 simple command completion works - nothing new added in the PR.

@iSazonov
Copy link
Collaborator Author

@SteveL-MSFT @daxian-dbw Could you please review too?


case TokenKind.Semi:
// Handle scenarios such as 'gci | Format-Table @{Label=...;<tab>'
result = GetResultForHashtable(completionContext);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get-something;<tab> does go through this path. It's better to check if (lastAst is HashtableAst) before calling GetResultForHashtable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

}
// Handle scenarios such as 'gci | Format-Table @{Label=<tab>'
return null;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This duplicates the call to GetResultForEnumPropertyValueOfDSCResource.
How about changing to this:

case TokenKind.LParen:
    {
        if (lastAst is AttributeAst)
        {
            ...
        }
        else if (lastAst.Parent is DynamicKeywordStatementAst)  // <-- change here
        {
            ...
        }
        else if (lastAst is HashtableAst hashTableAst && CheckForPendingAssignment(hashTableAst)) // <-- change here
        {
            return result;
        }
        break;
    }

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Second condition doesn't work for configuration foo { File ab { Attributes =( test - really lastAst.Parent is CommandExpressionAst.

Fixed.

$result.CompletionMatches.Count | Should -Be 3
$result.CompletionMatches[0].CompletionText | Should -Be 'Expression'
$result.CompletionMatches[1].CompletionText | Should -Be 'Ascending'
$result.CompletionMatches[2].CompletionText | Should -Be 'Descending'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test succeeds even without changes in this PR. You need to check ReplacementIndex and ReplacementLength, as they were -1 previously and changes in this PR should fix them.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

{
//
// Handle auto completion for enum/dependson property of DSC resource,
// 1. Handle scenarios such as 'configuration foo { File ab { Attributes ='
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handle auto completion for enum/dependson property of DSC resource

The example configuration foo { File ab { Attributes = is a completion for enum property, so it should not be marked as 1..

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
}
else
else if (lastAst.Parent is DynamicKeywordStatementAst || lastAst.Parent is CommandExpressionAst)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are making two special checks here. Maybe we should only have one special check, like the following. What do you think?

if (lastAst is AttributeAst)
{
    // the original attribute handling
}
else if (lastAst is HashtableAst hashTableAst &&
         !(lastAst.Parent is DynamicKeywordStatementAst) &&
         CheckForPendingAssignment(hashTableAst))
{
    return null;
}
else
{
    // the original else block
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Thanks!

Fixed.

$cmd = "Get-Date | Sort-Object @{Expression=...;"
$result = TabExpansion2 -inputScript $cmd -cursorColumn $cmd.Length
$result.CurrentMatchIndex | Should -Be -1
$result.ReplacementIndex | Should -Be 40
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And ReplacementLength?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

$result.CompletionMatches[2].CompletionText | Should -Be 'Descending'
$result.CompletionMatches[0].CompletionText | Should -Be 'Expression'
$result.CompletionMatches[1].CompletionText | Should -Be 'Ascending'
$result.CompletionMatches[2].CompletionText | Should -Be 'Descending'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$result.CompletionMatches[2].CompletionText is checked twice.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was for ReplacementLength :-)

Fixed.

@iSazonov
Copy link
Collaborator Author

The while code is very tricky and sensetive 😕 and crush PowerShell if something wrong. Maybe we should make it more robust.

Copy link
Member

@daxian-dbw daxian-dbw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.
@iSazonov What while code were you referring to?

@iSazonov
Copy link
Collaborator Author

I means our Completion code - if I return wrong index PowerShell is crashed. Asts can be combined in many ways. Can we be sure that we tested all their? The code is complex and tricky - can we create simple algorithm? Using visitors?

@iSazonov
Copy link
Collaborator Author

@lzybkr @SteveL-MSFT Do you have any comments?

@iSazonov iSazonov merged commit 626a83b into PowerShell:master May 21, 2018
@iSazonov iSazonov deleted the fix-tabcompletion branch May 21, 2018 04:06
@daxian-dbw
Copy link
Member

@iSazonov Sorry for the late reply. I agree the tab completion code is a bit hard to organize now. Many changes have been made that are very specific to the scenarios they try to solve, so you can see checks in CompletionAnalysis that are tied to one particular scenario which is hard to understand just by reading the code.

However, the crash is possibly not related to tab completion, but the code rending results to console. If you mess up the index, the rendering code might do weird bad things. I don't think a visitor can help much here, as many checks need to inspect ancestors of an ast.

@iSazonov
Copy link
Collaborator Author

@daxian-dbw Thanks for great comment!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Completion of hash table key has invalid replacement index/length

3 participants