Throw better parsing error when statements should be put in named block (#6434)
This commit is contained in:
parent
41b3161830
commit
9df8ea58e9
|
@ -1620,7 +1620,8 @@ namespace System.Management.Automation.Language
|
||||||
? lCurly.Extent
|
? lCurly.Extent
|
||||||
: (paramBlockAst != null) ? paramBlockAst.Extent : null;
|
: (paramBlockAst != null) ? paramBlockAst.Extent : null;
|
||||||
IScriptExtent endExtent = null;
|
IScriptExtent endExtent = null;
|
||||||
IScriptExtent extent;
|
IScriptExtent extent = null;
|
||||||
|
IScriptExtent scriptBlockExtent = null;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -1628,7 +1629,28 @@ namespace System.Management.Automation.Language
|
||||||
switch (blockNameToken.Kind)
|
switch (blockNameToken.Kind)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
|
// Next token is unexpected.
|
||||||
|
// ErrorRecovery: if 'lCurly' is present, pretend we saw a closing curly; otherwise, eat the unexpected token.
|
||||||
|
if (lCurly != null)
|
||||||
|
{
|
||||||
|
UngetToken(blockNameToken);
|
||||||
|
scriptBlockExtent = ExtentOf(startExtent, endExtent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If "lCurly == null", then it's a ps1/psm1 file, and thus the extent is the whole file.
|
||||||
|
scriptBlockExtent = _tokenizer.GetScriptExtent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Report error about the unexpected token.
|
||||||
|
ReportError(blockNameToken.Extent, () => ParserStrings.MissingNamedBlocks, blockNameToken.Text);
|
||||||
|
goto return_script_block_ast;
|
||||||
|
|
||||||
|
case TokenKind.RCurly:
|
||||||
|
case TokenKind.EndOfInput:
|
||||||
|
// If the next token is RCurly or <eof>, handle it in 'CompleteScriptBlockBody'.
|
||||||
UngetToken(blockNameToken);
|
UngetToken(blockNameToken);
|
||||||
|
extent = ExtentOf(startExtent, endExtent);
|
||||||
goto finished_named_block_list;
|
goto finished_named_block_list;
|
||||||
|
|
||||||
case TokenKind.Dynamicparam:
|
case TokenKind.Dynamicparam:
|
||||||
|
@ -1687,11 +1709,9 @@ namespace System.Management.Automation.Language
|
||||||
SkipNewlinesAndSemicolons();
|
SkipNewlinesAndSemicolons();
|
||||||
}
|
}
|
||||||
finished_named_block_list:
|
finished_named_block_list:
|
||||||
|
|
||||||
IScriptExtent scriptBlockExtent;
|
|
||||||
extent = ExtentOf(startExtent, endExtent);
|
|
||||||
CompleteScriptBlockBody(lCurly, ref extent, out scriptBlockExtent);
|
CompleteScriptBlockBody(lCurly, ref extent, out scriptBlockExtent);
|
||||||
|
|
||||||
|
return_script_block_ast:
|
||||||
return new ScriptBlockAst(scriptBlockExtent, usingStatements, paramBlockAst, beginBlock, processBlock, endBlock,
|
return new ScriptBlockAst(scriptBlockExtent, usingStatements, paramBlockAst, beginBlock, processBlock, endBlock,
|
||||||
dynamicParamBlock);
|
dynamicParamBlock);
|
||||||
}
|
}
|
||||||
|
|
|
@ -493,6 +493,9 @@ The correct form is: foreach ($a in $b) {...}</value>
|
||||||
<data name="DuplicateScriptCommandClause" xml:space="preserve">
|
<data name="DuplicateScriptCommandClause" xml:space="preserve">
|
||||||
<value>Script command clause '{0}' has already been defined.</value>
|
<value>Script command clause '{0}' has already been defined.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="MissingNamedBlocks" xml:space="preserve">
|
||||||
|
<value>unexpected token '{0}', expected 'begin', 'process', 'end', or 'dynamicparam'.</value>
|
||||||
|
</data>
|
||||||
<data name="MissingEndCurlyBrace" xml:space="preserve">
|
<data name="MissingEndCurlyBrace" xml:space="preserve">
|
||||||
<value>Missing closing '}' in statement block or type definition.</value>
|
<value>Missing closing '}' in statement block or type definition.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
@ -915,4 +915,20 @@ foo``u{2195}abc
|
||||||
# Issue #2780
|
# Issue #2780
|
||||||
{ ExecuteCommand "`$herestr=@`"`n'`"'`n`"@" } | Should -Not -Throw
|
{ ExecuteCommand "`$herestr=@`"`n'`"'`n`"@" } | Should -Not -Throw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
It "Throw better error when statement should be put in named blocks - <name>" -TestCases @(
|
||||||
|
@{ script = "Function foo { [CmdletBinding()] param() DynamicParam {} Hi"; name = "function" }
|
||||||
|
@{ script = "{ begin {} Hi"; name = "script-block" }
|
||||||
|
@{ script = "begin {} Hi"; name = "script-file" }
|
||||||
|
) {
|
||||||
|
param($script)
|
||||||
|
|
||||||
|
$err = { ExecuteCommand $script } | Should -Throw -ErrorId "ParseException" -PassThru
|
||||||
|
$err.Exception.InnerException.ErrorRecord.FullyQualifiedErrorId | Should -BeExactly "MissingNamedBlocks"
|
||||||
|
}
|
||||||
|
|
||||||
|
It "IncompleteParseException should be thrown when only ending curly is missing" {
|
||||||
|
$err = { ExecuteCommand "Function foo { [CmdletBinding()] param() DynamicParam {} " } | Should -Throw -ErrorId "IncompleteParseException" -PassThru
|
||||||
|
$err.Exception.InnerException.ErrorRecord.FullyQualifiedErrorId | Should -BeExactly "MissingEndCurlyBrace"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue