Repository: vscode
Issue: Upcoming when clause context parser
Labels: under-discussion,context-keys

<!-- ⚠️⚠️ Do Not Delete This! feature_request_template ⚠️⚠️ -->
<!-- Please read our Rules of Conduct: https://opensource.microsoft.com/codeofconduct/ -->
<!-- Please search existing issues to avoid creating duplicates. -->

<!-- Describe the feature you'd like. -->

## What's a when clause? 

[When clauses](https://code.visualstudio.com/api/references/when-clause-contexts) allow to selectively enable and disable various extension contributions such as commands and UI elements (e.g., menus or views). When clauses are simple expressions that are put in an extension’s manifest (i.e., `package.json`). 

## New parser 

The next VS Code release is planned to include a new parser of when clauses. The new parser will come with new features, more precise but stricter parsing rules, and a linter to see incorrect when clauses right away in `package.json` files.

Below we outline new features, breakages, and a way to make sure your extension works as intended. Please, subscribe to this issue to stay up-to-date with other changes that may happen before the next VS Code release 1.77.

### New features

1. Support for parentheses
    
    (requested in https://github.com/microsoft/vscode/issues/91473) 
    
    ~~Note: Negation of expressions such as `!(editorTextFocus && debugState == 'running')` is still work-in-progress. A comment will be posted to this issue, when it’s ready. Currently, one can only negate a context key, e.g., `!editorTextFocus`.~~

   Negation of expressions (e.g., `!(editorTextFocus && debugState == 'running')`) is also now supported.
    
2. Support for more regular expression flags
    
    [Key-value when clause operator](https://code.visualstudio.com/api/references/when-clause-contexts#keyvalue-when-clause-operator) `=~` currently supports the `i` flag for case-insensitive regular expression search, but the new parser will support the following flags are supported: `i`, `s`, `m`, `u`. VS Code will not throw an error if `g` and `y` flags are put in the regular expression but will not use them. 

3. Support operators `===` and `!==`

     The new parser allows `===` and `!==` operators, but they behave the same as `==` and `!=`. We noticed that there are already extensions that use these operators, assuming that they are supported, so we designed the new parser to be more flexible and support such operators. 
    

### Breakages

We tried our best to keep old parser’s behavior on most when clauses so that existing when clauses work as they did before. There are three cases to keep in mind, however, for a when clause to work as intended: 

1. When used with key-value when clause operator, a regular expression needs to be put between slash characters `/` just as in JavaScript, e.g., `view =~ /[a-z]+/`.  
    
    Also important to note that a slash character within a regular expression needs to be escaped with two backslash characters, e.g., `"when": "workspacePath =~ /my\\/path\//"` . The first backslash is to escape the second backslash in the JSON string within `package.json` and the second backslash is to escape the slash character. 
    
2. A string value containing whitespace must be quoted, e.g., 
    
    `"when": "myContextKey == 'two words'"`

   Note: only single quotes are currently supported.
    
3. Comparison operators need to be separated by whitespace from its operands, i.e., 
    
    correct: `count < 2`
    
    incorrect: `count<2`
    

## Migration

[VS Code Insiders](https://code.visualstudio.com/insiders/) comes with a linter for when clauses when an extension manifest file `package.json` is open. See no errors are reported for your extension’s `package.json`. 

<img width="771" alt="image" src="https://user-images.githubusercontent.com/16353531/222198862-5bf68d3a-f6bc-45a9-9e85-24697b134636.png">

VS Code Insiders will also run the new parser by default to see how extensions work with the new parser -- a comment will be posted when this happens as a notification to check out how your extension works with it.

## Latest parsing grammar

In [EBNF](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form). 

```ebnf
expression ::= or

or ::= and { '||' and }*

and ::= term { '&&' term }*

term ::=
	| '!' (KEY | true | false | parenthesized)
	| primary

primary ::=
	| 'true'
	| 'false'
	| parenthesized
	| KEY '=~' REGEX
	| KEY [ ('==' | '!=' | '<' | '<=' | '>' | '>=' | 'not' 'in' | 'in') value ]

parenthesized ::=
	| '(' expression ')'

value ::=
	| 'true'
	| 'false'
	| 'in'      	
	| VALUE 
	| SINGLE_QUOTED_STR
	| EMPTY_STR  	
```

Please, let me know if you have any feedback! :-)