Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/System.Management.Automation/engine/parser/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2411,6 +2411,16 @@ private StatementAst IfStatementRule(Token ifToken)

clauses.Add(new IfClause(condition, body));

// Save a restore point here. In case there is no 'elseif' or 'else' following,
// we should resync back here to preserve the possible new lines. The new lines
// could be important for the following parsing. For example, in case we are in
// a HashExpression, a new line might be needed for parsing the key-value that
// is following the if statement:
// @{
// a = if (1) {}
// b = 10
// }
int restorePoint = _ungotToken == null ? _tokenizer.GetRestorePoint() : _ungotToken.Extent.StartOffset;
SkipNewlines();
keyword = PeekToken();

Expand All @@ -2419,8 +2429,7 @@ private StatementAst IfStatementRule(Token ifToken)
SkipToken();
continue;
}

if (keyword.Kind == TokenKind.Else)
else if (keyword.Kind == TokenKind.Else)
{
SkipToken();
SkipNewlines();
Expand All @@ -2436,6 +2445,11 @@ private StatementAst IfStatementRule(Token ifToken)
return new ErrorStatementAst(ExtentOf(ifToken, keyword), componentAsts);
}
}
else
{
// There is no 'elseif' or 'else' following, so resync back to the possible new lines.
Resync(restorePoint);
}
break;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,94 @@ Describe "Members of System.Type" -Tags "CI" {
[MyType].ImplementedInterfaces | Should -Be System.Collections.IEnumerable
}
}

Describe "Hash expression with if statement as value" -Tags "CI" {
BeforeAll {
# With no extra new lines after if-statement
$hash1 = @{
a = if (1) {'a'}
b = 'b'
c = if (0) {2} elseif (1) {'c'}
d = 'd'
e = if (0) {2} elseif (0) {2} else {'e'}
f = 'f'
g = if (0) {2} else {'g'}
h = 'h'
}

# With extra new lines after if-statement
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.

Perhaps the comment should be more stringent
Caution!!! Don't remove extra new lines after if-statement!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think when looking at the BeforeAll block, it's clear enough that the format of those hashtable expressions shouldn't be changed.

$hash2 = @{
a = if (1) {'a'}

b = 'b'
c = if (0) {2} elseif (1) {'c'}

d = 'd'
e = if (0) {2} elseif (0) {2} else {'e'}

f = 'f'
g = if (0) {2} else {'g'}

h = 'h'
}

# With expanded if-statement
$hash3 = @{
a = if (1)
{
'a'
}
b = 'b'
c = if (0)
{
2
}
elseif (1)
{
'c'
}
d = 'd'
e = if (0)
{
2
}
elseif (0)
{
2
}
else
{
'e'
}
f = 'f'
g = if (0)
{
2
}
else
{
'g'
}
h = 'h'
}

$testCases = @(
@{ name = "No extra new lines"; hash = $hash1 }
@{ name = "With extra new lines"; hash = $hash2 }
@{ name = "With expanded if-statement"; hash = $hash3 }
)
}

It "Key-value pairs after an if-statement-value in a HashExpression should continue to be parsed - <name>" -TestCases $testCases {
param($hash)

$hash['a'] | Should -BeExactly 'a'
$hash['b'] | Should -BeExactly 'b'
$hash['c'] | Should -BeExactly 'c'
$hash['d'] | Should -BeExactly 'd'
$hash['e'] | Should -BeExactly 'e'
$hash['f'] | Should -BeExactly 'f'
$hash['g'] | Should -BeExactly 'g'
$hash['h'] | Should -BeExactly 'h'
}
}