microsoft / microsoft/vscode

[semantic] Add a `parameter` semantic token modifier

Open
#327,506 2 comments 2 reactions 1 assignee Claimed by @aeschli View on GitHub
feature-request
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.