Skip to content

UseConsistentWhitespace - Create option to ignore assignment operator inside hash table - #1566

Merged
James Truher (JamesWTruher) merged 9 commits into
PowerShell:masterfrom
daviesj:master
Jan 5, 2021
Merged

UseConsistentWhitespace - Create option to ignore assignment operator inside hash table#1566
James Truher (JamesWTruher) merged 9 commits into
PowerShell:masterfrom
daviesj:master

Conversation

@daviesj

@daviesjJoel Davies (daviesj) commented Aug 7, 2020

Copy link
Copy Markdown
Contributor

PR Summary

Fix#769 instead of creating a workaround. This creates an option on the UseConsistentWhitespace rule to ignore the assignment operator inside a multi-line hash table, making it compatible with the AlignAssignmentStatement rule. Also this enables the new option in the code formatting settings presets since they all enable the AlignAssignmentStatement rule. If I were a bit smarter, I would also automatically enable this option if AlignAssignmentStatement is enabled but I do not see how to do that.

PR Checklist`

@ghost

Deleted user (ghost) commented Aug 7, 2020

Copy link
Copy Markdown

CLA assistant check
All CLA requirements met.

Comment threadEngine/Settings/CodeFormatting.psd1 Outdated
Comment threadRules/UseConsistentWhitespace.cs Outdated
Comment threadRules/UseConsistentWhitespace.cs Outdated
Comment threadRules/UseConsistentWhitespace.cs Outdated
Comment threadRules/UseConsistentWhitespace.cs
@daviesjJoel Davies (daviesj) changed the title UseConsistentWhitespace - Create option to ignore assignment operator inside hash tableWIP: UseConsistentWhitespace - Create option to ignore assignment operator inside hash tableAug 11, 2020
Comment threadEngine/TokenOperations.cs Outdated
Comment threadEngine/TokenOperations.cs Outdated
Comment on lines +290 to +313
public override AstVisitAction VisitScriptBlock(ScriptBlockAst scriptBlockAst)
{
return Visit(scriptBlockAst);
}

public override AstVisitAction VisitNamedBlock(NamedBlockAst namedBlockAst)
{
return Visit(namedBlockAst);
}

public override AstVisitAction VisitAssignmentStatement(AssignmentStatementAst assignmentStatementAst)
{
return Visit(assignmentStatementAst);
}

public override AstVisitAction VisitCommandExpression(CommandExpressionAst commandExpressionAst)
{
return Visit(commandExpressionAst);
}

public override AstVisitAction VisitHashtable(HashtableAst hashtableAst)
{
return Visit(hashtableAst);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Given its general name, this visitor should probably have overrides for all AST types so that it will reliably work for all position visits. The alternative is to implement this class as a private nested class for the relevant rule.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fully intend to implement all overrides. Just didn't want to produce that much code before I knew I was barking up the right tree. It flummoxed me a bit when I first decided to work on this that there is no good way to search a PowerShell AST based on script position without writing 200+ lines of code. That is why I had tried the simpler solution first (that I agree with you was not ideal by a long shot).

@rjmholtRob Holt (rjmholt)Aug 11, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Well there is another way, which is to use FindAll() instead:

IEnumerable<Ast>astsContainingToken=scriptAst.FindAll(foundAst =>ContainsTokenExtent(token,foundAst),/* search through nested ASTs -- I can't remember the correct parameter name */true);// Find the containing AST with the smallest extentAstsmallestContainingAst=astsContainingToken.First();foreach(AstcontainingAstinastsContainingToken){if(HasSmallerExtent(smallestContainingAst,containingAst)){smallestContainingAst=containingAst;}}

Naturally you'd need to write the methods I've used there, but they basically contain logic you've already written

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I did try something like that but ran into a problem because apparently Ast's can contain another of exactly the same size so there isn't always a smallest. At that point I figured as many issues as I have run into so far trying to use FindAll(), it would be better just to go the visitor route.

@rjmholt
Rob Holt (rjmholt) marked this pull request as draft August 12, 2020 00:13
@daviesj

Copy link
Copy Markdown
ContributorAuthor

Not sure if I have the preprocessor version directives just right in FindAstPositionVisitor.cs. I was puzzled that there isn't a PSV5 constant and building for PowerShell 4 sets both PSV3 and PSV4.

@daviesjJoel Davies (daviesj) changed the title WIP: UseConsistentWhitespace - Create option to ignore assignment operator inside hash tableUseConsistentWhitespace - Create option to ignore assignment operator inside hash tableSep 16, 2020
@daviesj
Joel Davies (daviesj) marked this pull request as ready for review September 16, 2020 16:22

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for your efforts. Only a minor suggestion from my side but I am happy with it from a code and test perspective, also tested it locally. Having the IgnoreAssignmentOperatorInsideHashTable setting will allow us to introduce this new functionality first as 'off by default, i.e. one has to opt-in' in VS-Code and once proven robust, I am even thinking of removing that setting in future versions and enabling it by default or do you think there are still use cases to keep the setting long term Joel Davies (@daviesj) ?
Rob Holt (@rjmholt) Can you re-review please?

Comment threadEngine/FindAstPositionVisitor.cs Outdated
Comment threadEngine/FindAstPositionVisitor.cs Outdated
Comment on lines +33 to +47
/// <summary>
/// Traverses the AST based on offests to find the leaf node which contains the provided <see cref="IScriptPosition"/>.
/// This method implements the entire functionality of this visitor. All <see cref="AstVisitor2"/> methods are overridden to simply invoke this one.
/// </summary>
/// <param name="ast">Current AST node to process.</param>
/// <returns>An <see cref="AstVisitAction"/> indicating whether to visit children of the current node.</returns>
private AstVisitAction Visit(Ast ast)
{
if (ast.Extent.StartOffset > searchPosition.Offset || ast.Extent.EndOffset <= searchPosition.Offset)
{
return AstVisitAction.SkipChildren;
}
AstPosition = ast;
return AstVisitAction.Continue;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

As a private method, I would put this one below all the others

Sign up for freeto 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.

Unable to use both AlignAssignmentStatement and UseConsistentWhitespace rules

4 participants

@daviesj@rjmholt@bergmeister@JamesWTruher