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
|
||||
: (paramBlockAst != null) ? paramBlockAst.Extent : null;
|
||||
IScriptExtent endExtent = null;
|
||||
IScriptExtent extent;
|
||||
IScriptExtent extent = null;
|
||||
IScriptExtent scriptBlockExtent = null;
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
@ -1628,7 +1629,28 @@ namespace System.Management.Automation.Language
|
|||
switch (blockNameToken.Kind)
|
||||
{
|
||||
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);
|
||||
extent = ExtentOf(startExtent, endExtent);
|
||||
goto finished_named_block_list;
|
||||
|
||||
case TokenKind.Dynamicparam:
|
||||
|
@ -1687,11 +1709,9 @@ namespace System.Management.Automation.Language
|
|||
SkipNewlinesAndSemicolons();
|
||||
}
|
||||
finished_named_block_list:
|
||||
|
||||
IScriptExtent scriptBlockExtent;
|
||||
extent = ExtentOf(startExtent, endExtent);
|
||||
CompleteScriptBlockBody(lCurly, ref extent, out scriptBlockExtent);
|
||||
|
||||
return_script_block_ast:
|
||||
return new ScriptBlockAst(scriptBlockExtent, usingStatements, paramBlockAst, beginBlock, processBlock, endBlock,
|
||||
dynamicParamBlock);
|
||||
}
|
||||
|
|
|
@ -493,6 +493,9 @@ The correct form is: foreach ($a in $b) {...}</value>
|
|||
<data name="DuplicateScriptCommandClause" xml:space="preserve">
|
||||
<value>Script command clause '{0}' has already been defined.</value>
|
||||
</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">
|
||||
<value>Missing closing '}' in statement block or type definition.</value>
|
||||
</data>
|
||||
|
|
|
@ -915,4 +915,20 @@ foo``u{2195}abc
|
|||
# Issue #2780
|
||||
{ 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