[semantic] Add a `parameter` semantic token modifier
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
I am working on a theme that styles parameters in italics and functions in pink.
For a regular parameter, this works as expected:
```ts
function f(a: string) {
console.log(a);
}
```
The semantic token classifications are `parameter.declaration` at declaration, and `parameter` at usage.
The issue appears with a function-valued parameter:
```ts
function f(a: string, cb: () => string) {
cb();
}
```
In this case, `cb` is classified as `function.declaration` at declaration, and `function` at usage.
That classification is understandable because `cb` denotes a callable value. However, `cb` is also a parameter accepted by `f`. It is therefore incomplete for theming purposes because the parameter role is lost. Semantic tokens require the provider to choose one standard token type, so themes cannot express both styling intentions.
I would like `cb` to receive parameter styling (italic) and function styling (pink), but there is no selector that can apply italics specifically to function-valued parameters without also affecting unrelated function declarations or usages.
Proposed solution: add a standard `parameter` semantic token modifier.
Existing classifications remain unchanged while gaining the modifier:
Regular parameter declaration: `parameter.declaration.parameter`
Regular parameter usage: `parameter.parameter`
Function-valued parameter declaration: `function.declaration.parameter`
Function-valued parameter usage: `function.parameter`
This would allow themes to style every parameter using:
```json
"*.parameter": {
"fontStyle": "italic"
}
```
Function-valued parameters would still match existing `function` rules and receive their function color:
```json
"function": {
"foreground": "#ff69b4"
}
```
For tokens whose standard type is already `parameter`, the modifier can be emitted for consistency (`parameter.parameter`), or omitted as redundant. Either representation would be compatible with existing themes, although the former would require themes to style both `parameter` and `*.parameter`.
The proposal is additive:
* existing themes continue matching `parameter` and `function`
* existing providers remain valid
* providers can add the new modifier incrementally
* newer themes can use `*.parameter`
* no current primary token type needs to be renamed or reinterpreted
The desired classifications would be (with modifier `parameter` provided for standard `parameter`):
a at declaration: `parameter.declaration.parameter`
a at usage: `parameter.parameter`
cb at declaration: `function.declaration.parameter`
cb at usage: `function.parameter`
`parameter` becomes usable as an orthogonal fact: "This symbol is accepted as an input by the surrounding declaration.". That applies regardless of whether the standard type is `parameter`, `function`, or another future token type.
The open questions are
- whether `parameter` is suitable as a standard modifier,
- whether it should apply to standard `parameter` as well.
- whether `typeParameter` should also recieve the `parameter` modifier, or the feature should remain intended for runtime parameter constructs.
Contributor guide
Assessment
This issue has not been assessed yet.