Update tree-sitter-wasm (#278399)

* Update tree-sitter-wasm

* Update test results

* Update pwsh && tests, fix prompt

Fixes #274548

---------

Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com>
This commit is contained in:
Alex Ross
2025-11-20 10:49:33 +01:00
committed by GitHub
parent 5e1893f284
commit c8547e5708
10 changed files with 116 additions and 40 deletions

View File

@@ -125,6 +125,20 @@
"light_modern": "string: #A31515" "light_modern": "string: #A31515"
} }
}, },
{
"c": "mystyle.css",
"t": "string.quoted.double.css",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
"hc_black": "string: #CE9178",
"dark_modern": "string: #CE9178",
"hc_light": "string: #0F4A85",
"light_modern": "string: #A31515"
}
},
{ {
"c": "\"", "c": "\"",
"t": "string.quoted.double.css", "t": "string.quoted.double.css",
@@ -209,6 +223,20 @@
"light_modern": "string: #A31515" "light_modern": "string: #A31515"
} }
}, },
{
"c": "mystyle.css",
"t": "string.quoted.double.css",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
"hc_black": "string: #CE9178",
"dark_modern": "string: #CE9178",
"hc_light": "string: #0F4A85",
"light_modern": "string: #A31515"
}
},
{ {
"c": "\"", "c": "\"",
"t": "string.quoted.double.css", "t": "string.quoted.double.css",
@@ -307,6 +335,20 @@
"light_modern": "string: #A31515" "light_modern": "string: #A31515"
} }
}, },
{
"c": "bluish.css",
"t": "string.quoted.double.css",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
"hc_black": "string: #CE9178",
"dark_modern": "string: #CE9178",
"hc_light": "string: #0F4A85",
"light_modern": "string: #A31515"
}
},
{ {
"c": "\"", "c": "\"",
"t": "string.quoted.double.css", "t": "string.quoted.double.css",
@@ -3387,6 +3429,20 @@
"light_modern": "string: #A31515" "light_modern": "string: #A31515"
} }
}, },
{
"c": "<angle>",
"t": "string.quoted.single.css",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
"hc_black": "string: #CE9178",
"dark_modern": "string: #CE9178",
"hc_light": "string: #0F4A85",
"light_modern": "string: #A31515"
}
},
{ {
"c": "'", "c": "'",
"t": "string.quoted.single.css", "t": "string.quoted.single.css",
@@ -7307,6 +7363,20 @@
"light_modern": "string: #A31515" "light_modern": "string: #A31515"
} }
}, },
{
"c": "#B3AE94",
"t": "string.quoted.single.css",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
"hc_black": "string: #CE9178",
"dark_modern": "string: #CE9178",
"hc_light": "string: #0F4A85",
"light_modern": "string: #A31515"
}
},
{ {
"c": "'", "c": "'",
"t": "string.quoted.single.css", "t": "string.quoted.single.css",
@@ -8413,6 +8483,20 @@
"light_modern": "string: #A31515" "light_modern": "string: #A31515"
} }
}, },
{
"c": "codicon-",
"t": "meta.selector.css string.quoted.single.css",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
"hc_black": "string: #CE9178",
"dark_modern": "string: #CE9178",
"hc_light": "string: #0F4A85",
"light_modern": "string: #A31515"
}
},
{ {
"c": "'", "c": "'",
"t": "meta.selector.css string.quoted.single.css", "t": "meta.selector.css string.quoted.single.css",

8
package-lock.json generated
View File

@@ -22,7 +22,7 @@
"@vscode/spdlog": "^0.15.2", "@vscode/spdlog": "^0.15.2",
"@vscode/sqlite3": "5.1.8-vscode", "@vscode/sqlite3": "5.1.8-vscode",
"@vscode/sudo-prompt": "9.3.1", "@vscode/sudo-prompt": "9.3.1",
"@vscode/tree-sitter-wasm": "^0.2.0", "@vscode/tree-sitter-wasm": "^0.3.0",
"@vscode/vscode-languagedetection": "1.0.21", "@vscode/vscode-languagedetection": "1.0.21",
"@vscode/windows-mutex": "^0.5.0", "@vscode/windows-mutex": "^0.5.0",
"@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-process-tree": "^0.6.0",
@@ -3325,9 +3325,9 @@
} }
}, },
"node_modules/@vscode/tree-sitter-wasm": { "node_modules/@vscode/tree-sitter-wasm": {
"version": "0.2.0", "version": "0.3.0",
"resolved": "https://registry.npmjs.org/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.2.0.tgz", "resolved": "https://registry.npmjs.org/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.3.0.tgz",
"integrity": "sha512-abvLfKwmriqgdS4WrIzFK7mzdPUVqIIW1UWarp2lA8lpOZ1EDPL1snRBKe7g+5R5ri173mNJEuPLnG/NlpMp4w==", "integrity": "sha512-4kjB1jgLyG9VimGfyJb1F8/GFdrx55atsBCH/9r2D/iZHAUDCvZ5zhWXB7sRQ2z2WkkuNYm/0pgQtUm1jhdf7A==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@vscode/v8-heap-parser": { "node_modules/@vscode/v8-heap-parser": {

View File

@@ -84,7 +84,7 @@
"@vscode/spdlog": "^0.15.2", "@vscode/spdlog": "^0.15.2",
"@vscode/sqlite3": "5.1.8-vscode", "@vscode/sqlite3": "5.1.8-vscode",
"@vscode/sudo-prompt": "9.3.1", "@vscode/sudo-prompt": "9.3.1",
"@vscode/tree-sitter-wasm": "^0.2.0", "@vscode/tree-sitter-wasm": "^0.3.0",
"@vscode/vscode-languagedetection": "1.0.21", "@vscode/vscode-languagedetection": "1.0.21",
"@vscode/windows-mutex": "^0.5.0", "@vscode/windows-mutex": "^0.5.0",
"@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-process-tree": "^0.6.0",

View File

@@ -16,7 +16,7 @@
"@vscode/proxy-agent": "^0.36.0", "@vscode/proxy-agent": "^0.36.0",
"@vscode/ripgrep": "^1.15.13", "@vscode/ripgrep": "^1.15.13",
"@vscode/spdlog": "^0.15.2", "@vscode/spdlog": "^0.15.2",
"@vscode/tree-sitter-wasm": "^0.2.0", "@vscode/tree-sitter-wasm": "^0.3.0",
"@vscode/vscode-languagedetection": "1.0.21", "@vscode/vscode-languagedetection": "1.0.21",
"@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-process-tree": "^0.6.0",
"@vscode/windows-registry": "^1.1.0", "@vscode/windows-registry": "^1.1.0",
@@ -188,9 +188,9 @@
} }
}, },
"node_modules/@vscode/tree-sitter-wasm": { "node_modules/@vscode/tree-sitter-wasm": {
"version": "0.2.0", "version": "0.3.0",
"resolved": "https://registry.npmjs.org/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.2.0.tgz", "resolved": "https://registry.npmjs.org/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.3.0.tgz",
"integrity": "sha512-abvLfKwmriqgdS4WrIzFK7mzdPUVqIIW1UWarp2lA8lpOZ1EDPL1snRBKe7g+5R5ri173mNJEuPLnG/NlpMp4w==", "integrity": "sha512-4kjB1jgLyG9VimGfyJb1F8/GFdrx55atsBCH/9r2D/iZHAUDCvZ5zhWXB7sRQ2z2WkkuNYm/0pgQtUm1jhdf7A==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@vscode/vscode-languagedetection": { "node_modules/@vscode/vscode-languagedetection": {

View File

@@ -11,7 +11,7 @@
"@vscode/proxy-agent": "^0.36.0", "@vscode/proxy-agent": "^0.36.0",
"@vscode/ripgrep": "^1.15.13", "@vscode/ripgrep": "^1.15.13",
"@vscode/spdlog": "^0.15.2", "@vscode/spdlog": "^0.15.2",
"@vscode/tree-sitter-wasm": "^0.2.0", "@vscode/tree-sitter-wasm": "^0.3.0",
"@vscode/vscode-languagedetection": "1.0.21", "@vscode/vscode-languagedetection": "1.0.21",
"@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-process-tree": "^0.6.0",
"@vscode/windows-registry": "^1.1.0", "@vscode/windows-registry": "^1.1.0",

View File

@@ -11,7 +11,7 @@
"@microsoft/1ds-core-js": "^3.2.13", "@microsoft/1ds-core-js": "^3.2.13",
"@microsoft/1ds-post-js": "^3.2.13", "@microsoft/1ds-post-js": "^3.2.13",
"@vscode/iconv-lite-umd": "0.7.1", "@vscode/iconv-lite-umd": "0.7.1",
"@vscode/tree-sitter-wasm": "^0.2.0", "@vscode/tree-sitter-wasm": "^0.3.0",
"@vscode/vscode-languagedetection": "1.0.21", "@vscode/vscode-languagedetection": "1.0.21",
"@xterm/addon-clipboard": "^0.2.0-beta.119", "@xterm/addon-clipboard": "^0.2.0-beta.119",
"@xterm/addon-image": "^0.9.0-beta.136", "@xterm/addon-image": "^0.9.0-beta.136",
@@ -78,9 +78,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@vscode/tree-sitter-wasm": { "node_modules/@vscode/tree-sitter-wasm": {
"version": "0.2.0", "version": "0.3.0",
"resolved": "https://registry.npmjs.org/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.2.0.tgz", "resolved": "https://registry.npmjs.org/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.3.0.tgz",
"integrity": "sha512-abvLfKwmriqgdS4WrIzFK7mzdPUVqIIW1UWarp2lA8lpOZ1EDPL1snRBKe7g+5R5ri173mNJEuPLnG/NlpMp4w==", "integrity": "sha512-4kjB1jgLyG9VimGfyJb1F8/GFdrx55atsBCH/9r2D/iZHAUDCvZ5zhWXB7sRQ2z2WkkuNYm/0pgQtUm1jhdf7A==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@vscode/vscode-languagedetection": { "node_modules/@vscode/vscode-languagedetection": {

View File

@@ -6,7 +6,7 @@
"@microsoft/1ds-core-js": "^3.2.13", "@microsoft/1ds-core-js": "^3.2.13",
"@microsoft/1ds-post-js": "^3.2.13", "@microsoft/1ds-post-js": "^3.2.13",
"@vscode/iconv-lite-umd": "0.7.1", "@vscode/iconv-lite-umd": "0.7.1",
"@vscode/tree-sitter-wasm": "^0.2.0", "@vscode/tree-sitter-wasm": "^0.3.0",
"@vscode/vscode-languagedetection": "1.0.21", "@vscode/vscode-languagedetection": "1.0.21",
"@xterm/addon-clipboard": "^0.2.0-beta.119", "@xterm/addon-clipboard": "^0.2.0-beta.119",
"@xterm/addon-image": "^0.9.0-beta.136", "@xterm/addon-image": "^0.9.0-beta.136",

View File

@@ -65,10 +65,9 @@ function createPowerShellModelDescription(shell: string): string {
`This tool allows you to execute ${isWinPwsh ? 'Windows PowerShell 5.1' : 'PowerShell'} commands in a persistent terminal session, preserving environment variables, working directory, and other context across multiple commands.`, `This tool allows you to execute ${isWinPwsh ? 'Windows PowerShell 5.1' : 'PowerShell'} commands in a persistent terminal session, preserving environment variables, working directory, and other context across multiple commands.`,
'', '',
'Command Execution:', 'Command Execution:',
// TODO: Even for pwsh 7+ we want to use `;` to chain commands since the tree sitter grammar // IMPORTANT: PowerShell 5 does not support `&&` so always re-write them to `;`. Note that
// doesn't parse `&&`. We want to change this to avoid `&&` only in Windows PowerShell when // the behavior of `&&` differs a little from `;` but in general it's fine
// the grammar supports it https://github.com/airbus-cert/tree-sitter-powershell/issues/27 isWinPwsh ? '- Use semicolons ; to chain commands on one line, NEVER use && even when asked explicitly' : '- Prefer ; when chaining commands on one line',
'- Use semicolons ; to chain commands on one line, NEVER use && even when asked explicitly',
'- Prefer pipelines | for object-based data flow', '- Prefer pipelines | for object-based data flow',
'- Never create a sub-shell (eg. powershell -c "command") unless explicitly asked', '- Never create a sub-shell (eg. powershell -c "command") unless explicitly asked',
'', '',

View File

@@ -34,10 +34,8 @@ export class TreeSitterCommandParser extends Disposable {
async extractPwshDoubleAmpersandChainOperators(commandLine: string): Promise<QueryCapture[]> { async extractPwshDoubleAmpersandChainOperators(commandLine: string): Promise<QueryCapture[]> {
const captures = await this._queryTree(TreeSitterCommandParserLanguage.PowerShell, commandLine, [ const captures = await this._queryTree(TreeSitterCommandParserLanguage.PowerShell, commandLine, [
'(', '(',
' (command', ' (pipeline',
' (command_elements', ' (pipeline_chain_tail) @double.ampersand)',
' (generic_token) @double.ampersand',
' (#eq? @double.ampersand "&&")))',
')', ')',
].join('\n')); ].join('\n'));
return captures; return captures;

View File

@@ -212,15 +212,14 @@ suite('TreeSitterCommandParser', () => {
test('&& with complex commands', () => t('Get-ChildItem -Path C:\\ && Set-Location C:\\Users', ['&&'])); test('&& with complex commands', () => t('Get-ChildItem -Path C:\\ && Set-Location C:\\Users', ['&&']));
test('&& with parameters', () => t('Get-Process -Name notepad && Stop-Process -Name notepad', ['&&'])); test('&& with parameters', () => t('Get-Process -Name notepad && Stop-Process -Name notepad', ['&&']));
test('&& with pipeline inside', () => t('Get-Process | Where-Object {$_.Name -eq "notepad"} && Write-Host "Found"', ['&&'])); test('&& with pipeline inside', () => t('Get-Process | Where-Object {$_.Name -eq "notepad"} && Write-Host "Found"', ['&&']));
// TODO: A lot of these tests are skipped until proper parsing of && is supported in https://github.com/airbus-cert/tree-sitter-powershell/issues/27 test('nested && in script blocks', () => t('if ($true) { echo hello && echo world }', ['&&']));
test.skip('nested && in script blocks', () => t('if ($true) { echo hello && echo world } && echo done', ['&&', '&&'])); test('&& with method calls', () => t('"hello".ToUpper() && "world".ToLower()', ['&&']));
test.skip('&& with method calls', () => t('"hello".ToUpper() && "world".ToLower()', ['&&'])); test('&& with array operations', () => t('@(1,2,3) | ForEach-Object { $_ } && Write-Host "done"', ['&&']));
test.skip('&& with array operations', () => t('@(1,2,3) | ForEach-Object { $_ } && Write-Host "done"', ['&&'])); test('&& with hashtable', () => t('@{key="value"} && Write-Host "created"', ['&&']));
test.skip('&& with hashtable', () => t('@{key="value"} && Write-Host "created"', ['&&'])); test('&& with type casting', () => t('[int]"123" && [string]456', ['&&']));
test.skip('&& with type casting', () => t('[int]"123" && [string]456', ['&&'])); test('&& with comparison operators', () => t('5 -gt 3 && "hello" -like "h*"', ['&&']));
test.skip('&& with comparison operators', () => t('5 -gt 3 && "hello" -like "h*"', ['&&'])); test('&& with variable assignment', () => t('$var = "test" && Write-Host $var', ['&&']));
test.skip('&& with variable assignment', () => t('$var = "test" && Write-Host $var', ['&&'])); test('&& with expandable strings', () => t('$name="World" && "Hello $name"', ['&&']));
test.skip('&& with expandable strings', () => t('$name="World" && "Hello $name"', ['&&']));
test('&& with subexpressions', () => t('Write-Host $(Get-Date) && Get-Location', ['&&'])); test('&& with subexpressions', () => t('Write-Host $(Get-Date) && Get-Location', ['&&']));
test('&& with here-strings', () => t('Write-Host @"\nhello\nworld\n"@ && Get-Date', ['&&'])); test('&& with here-strings', () => t('Write-Host @"\nhello\nworld\n"@ && Get-Date', ['&&']));
test('&& with splatting', () => t('$params = @{Path="C:\\"}; Get-ChildItem @params && Write-Host "done"', ['&&'])); test('&& with splatting', () => t('$params = @{Path="C:\\"}; Get-ChildItem @params && Write-Host "done"', ['&&']));
@@ -230,7 +229,7 @@ suite('TreeSitterCommandParser', () => {
test('&& with error handling', () => t('try { Get-Content "file.txt" && Write-Host "success" } catch { Write-Error "failed" }', ['&&'])); test('&& with error handling', () => t('try { Get-Content "file.txt" && Write-Host "success" } catch { Write-Error "failed" }', ['&&']));
test('&& inside foreach', () => t('ForEach-Object { Write-Host $_.Name && Write-Host $_.Length }', ['&&'])); test('&& inside foreach', () => t('ForEach-Object { Write-Host $_.Name && Write-Host $_.Length }', ['&&']));
test('&& with conditional logic', () => t('if (Test-Path "file.txt") { Get-Content "file.txt" && Write-Host "read" }', ['&&'])); test('&& with conditional logic', () => t('if (Test-Path "file.txt") { Get-Content "file.txt" && Write-Host "read" }', ['&&']));
test.skip('&& with switch statement', () => t('switch ($var) { 1 { "one" && "first" } 2 { "two" && "second" } }', ['&&', '&&'])); test('&& with switch statement', () => t('switch ($var) { 1 { "one" && "first" } 2 { "two" && "second" } }', ['&&', '&&']));
test('&& in do-while', () => t('do { Write-Host $i && $i++ } while ($i -lt 5)', ['&&'])); test('&& in do-while', () => t('do { Write-Host $i && $i++ } while ($i -lt 5)', ['&&']));
test('&& in for loop', () => t('for ($i=0; $i -lt 5; $i++) { Write-Host $i && Start-Sleep 1 }', ['&&'])); test('&& in for loop', () => t('for ($i=0; $i -lt 5; $i++) { Write-Host $i && Start-Sleep 1 }', ['&&']));
test('&& with parallel processing', () => t('1..10 | ForEach-Object -Parallel { Write-Host $_ && Start-Sleep 1 }', ['&&'])); test('&& with parallel processing', () => t('1..10 | ForEach-Object -Parallel { Write-Host $_ && Start-Sleep 1 }', ['&&']));
@@ -239,22 +238,18 @@ suite('TreeSitterCommandParser', () => {
suite('edge cases', () => { suite('edge cases', () => {
test('empty string', () => t('', [])); test('empty string', () => t('', []));
test('whitespace only', () => t(' \n\t ', [])); test('whitespace only', () => t(' \n\t ', []));
test('single &', () => t('Get-Date & Get-Location', [])); test('triple &&&', () => t('echo hello &&& echo world', ['&&']));
test.skip('triple &&&', () => t('echo hello &&& echo world', ['&&']));
test.skip('&& at beginning', () => t('&& echo hello', ['&&']));
test('&& at end', () => t('echo hello &&', ['&&']));
test('spaced && operators', () => t('echo hello & & echo world', [])); test('spaced && operators', () => t('echo hello & & echo world', []));
test('&& with unicode', () => t('Write-Host "测试" && Write-Host "🚀"', ['&&'])); test('&& with unicode', () => t('Write-Host "测试" && Write-Host "🚀"', ['&&']));
test('very long command with &&', () => t('Write-Host "' + 'a'.repeat(1000) + '" && Get-Date', ['&&'])); test('very long command with &&', () => t('Write-Host "' + 'a'.repeat(1000) + '" && Get-Date', ['&&']));
test('deeply nested with &&', () => t('if ($true) { if ($true) { if ($true) { echo nested && echo deep } } }', ['&&'])); test('deeply nested with &&', () => t('if ($true) { if ($true) { if ($true) { echo nested && echo deep } } }', ['&&']));
test('&& with escaped characters', () => t('Write-Host "hello`"world" && Get-Date', ['&&'])); test('&& with escaped characters', () => t('Write-Host "hello`"world" && Get-Date', ['&&']));
test.skip('&& with backticks', () => t('Write-Host `hello && Get-Date', ['&&'])); test('&& with backticks', () => t('Write-Host `hello && Get-Date', ['&&']));
test.skip('malformed syntax with &&', () => t('echo "unclosed && Get-Date', ['&&']));
}); });
suite('real-world scenarios', () => { suite('real-world scenarios', () => {
test('git workflow', () => t('git add . && git commit -m "message" && git push', ['&&', '&&'])); test('git workflow', () => t('git add . && git commit -m "message" && git push', ['&&', '&&']));
test.skip('build and test', () => t('dotnet build && dotnet test && dotnet publish', ['&&', '&&'])); test('build and test', () => t('dotnet build && dotnet test && dotnet publish', ['&&', '&&']));
test('file operations', () => t('New-Item -Type File "test.txt" && Add-Content "test.txt" "hello" && Get-Content "test.txt"', ['&&', '&&'])); test('file operations', () => t('New-Item -Type File "test.txt" && Add-Content "test.txt" "hello" && Get-Content "test.txt"', ['&&', '&&']));
test('service management', () => t('Stop-Service spooler && Set-Service spooler -StartupType Manual && Start-Service spooler', ['&&', '&&'])); test('service management', () => t('Stop-Service spooler && Set-Service spooler -StartupType Manual && Start-Service spooler', ['&&', '&&']));
test('registry operations', () => t('New-Item -Path "HKCU:\\Software\\Test" && Set-ItemProperty -Path "HKCU:\\Software\\Test" -Name "Value" -Value "Data"', ['&&'])); test('registry operations', () => t('New-Item -Path "HKCU:\\Software\\Test" && Set-ItemProperty -Path "HKCU:\\Software\\Test" -Name "Value" -Value "Data"', ['&&']));