diff --git a/src/System.Management.Automation/engine/AutomationEngine.cs b/src/System.Management.Automation/engine/AutomationEngine.cs
index 279bab545ab..58e490759a6 100644
--- a/src/System.Management.Automation/engine/AutomationEngine.cs
+++ b/src/System.Management.Automation/engine/AutomationEngine.cs
@@ -62,19 +62,19 @@ internal string Expand(string s)
/// Compile a piece of text into a parse tree for later execution.
///
/// The text to parse
- ///
+ /// true iff the scriptblock will be added to history
/// The parse text as a parsetree node.
- internal ScriptBlock ParseScriptBlock(string script, bool interactiveCommand)
+ internal ScriptBlock ParseScriptBlock(string script, bool addToHistory)
{
- return ParseScriptBlock(script, null, interactiveCommand);
+ return ParseScriptBlock(script, null, addToHistory);
}
- internal ScriptBlock ParseScriptBlock(string script, string fileName, bool interactiveCommand)
+ internal ScriptBlock ParseScriptBlock(string script, string fileName, bool addToHistory)
{
ParseError[] errors;
var ast = EngineParser.Parse(fileName, script, null, out errors, ParseMode.Default);
- if (interactiveCommand)
+ if (addToHistory)
{
EngineParser.SetPreviousFirstLastToken(Context);
}
diff --git a/src/System.Management.Automation/engine/parser/tokenizer.cs b/src/System.Management.Automation/engine/parser/tokenizer.cs
index 1a1045afc5a..b5d73758a33 100644
--- a/src/System.Management.Automation/engine/parser/tokenizer.cs
+++ b/src/System.Management.Automation/engine/parser/tokenizer.cs
@@ -492,6 +492,7 @@ internal class TokenizerState
internal string Script;
internal int TokenStart;
internal int CurrentIndex;
+ internal Token FirstToken;
internal Token LastToken;
internal BitArray SkippedCharOffsets;
internal List TokenList;
@@ -687,6 +688,7 @@ internal TokenizerState StartNestedScan(UnscannedSubExprToken nestedText)
NestedTokensAdjustment = _nestedTokensAdjustment,
Script = _script,
TokenStart = _tokenStart,
+ FirstToken = FirstToken,
LastToken = LastToken,
SkippedCharOffsets = _skippedCharOffsets,
TokenList = TokenList,
@@ -708,6 +710,7 @@ internal void FinishNestedScan(TokenizerState ts)
_nestedTokensAdjustment = ts.NestedTokensAdjustment;
_script = ts.Script;
_tokenStart = ts.TokenStart;
+ FirstToken = ts.FirstToken;
LastToken = ts.LastToken;
_skippedCharOffsets = ts.SkippedCharOffsets;
TokenList = ts.TokenList;
diff --git a/test/powershell/Language/Parser/Parser.Tests.ps1 b/test/powershell/Language/Parser/Parser.Tests.ps1
index 0edc62fda66..6307fa5c99a 100644
--- a/test/powershell/Language/Parser/Parser.Tests.ps1
+++ b/test/powershell/Language/Parser/Parser.Tests.ps1
@@ -915,4 +915,39 @@ foo``u{2195}abc
# Issue #2780
{ ExecuteCommand "`$herestr=@`"`n'`"'`n`"@" } | Should Not Throw
}
+
+ Context "#requires nested scan tokenizer tests" {
+ BeforeAll {
+ $settings = [System.Management.Automation.PSInvocationSettings]::new()
+ $settings.AddToHistory = $true
+
+ $ps = [powershell]::Create()
+ }
+
+ AfterAll {
+ $ps.Dispose()
+ }
+
+ AfterEach {
+ $ps.Commands.Clear()
+ }
+
+ $testCases = @(
+ @{ script = "#requires"; firstToken = $null; lastToken = $null },
+ @{ script = "#requires -Version 5.0`n10"; firstToken = "10"; lastToken = "10" },
+ @{ script = "Write-Host 'Hello'`n#requires -Version 5.0`n7"; firstToken = "Write-Host"; lastToken = "7" },
+ @{ script = "Write-Host 'Hello'`n#requires -Version 5.0"; firstToken = "Write-Host"; lastToken = "Hello"}
+ )
+
+ It "Correctly resets the first and last tokens in the tokenizer after nested scan in script" -TestCases $testCases {
+ param($script, $firstToken, $lastToken)
+
+ $ps.AddScript($script)
+ $ps.AddScript("(`$^,`$`$)")
+ $tokens = $ps.Invoke(@(), $settings)
+
+ $tokens[0] | Should -BeExactly $firstToken
+ $tokens[1] | Should -BeExactly $lastToken
+ }
+ }
}
diff --git a/test/powershell/Language/Scripting/Requires.Tests.ps1 b/test/powershell/Language/Scripting/Requires.Tests.ps1
index d4a25d04a70..4354dba3cc6 100644
--- a/test/powershell/Language/Scripting/Requires.Tests.ps1
+++ b/test/powershell/Language/Scripting/Requires.Tests.ps1
@@ -27,4 +27,21 @@ Describe "Requires tests" -Tags "CI" {
}
}
-}
\ No newline at end of file
+ Context "Interactive requires" {
+
+ BeforeAll {
+ $ps = [powershell]::Create()
+ }
+
+ AfterAll {
+ $ps.Dispose()
+ }
+
+ It "Successfully does nothing when given '#requires' interactively" {
+ $settings = [System.Management.Automation.PSInvocationSettings]::new()
+ $settings.AddToHistory = $true
+
+ { $ps.AddScript("#requires").Invoke(@(), $settings) } | Should -Not -Throw
+ }
+ }
+}