microsoft / microsoft/typespec
Align @experimental emitterScope with the standard scope convention
- Dominant language
- Java
- Stars
- 5.9k
- Forks
- 394
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 104
Description
## Problem
`TypeSpec.HttpClient.@experimental` uses `options.emitterScope` to control which emitters receive its lifecycle metadata:
```typespec
@experimental(#{ emitterScope: "@typespec/http-client-csharp" })
op test(): void;
```
This differs from the established client-generator decorator convention, which uses a top-level optional argument named `scope`:
```typespec
extern dec clientName(
target: unknown,
rename: valueof string,
scope?: valueof string
);
```
`@experimental` and `ClientDecoratorOptions.emitterScope` were introduced together in #11094 with a package-specific scope parser.
## Impact
TCGC's generic decorator handling automatically filters decorators by `decoratorInfo.arguments.scope`. It cannot recognize the nested `decoratorInfo.arguments.options.emitterScope` value used by `@experimental`.
As a result, emitters consuming `@experimental` through TCGC's generic decorator metadata must implement a second scope parser and filtering path. This creates duplicated behavior and makes the two scoping conventions easier to interpret differently over time.
## Proposed compatibility path
Align `@experimental` with the standard top-level `scope` convention without immediately breaking existing TypeSpec:
1. Add an optional top-level `scope` argument to `@experimental`.
2. Continue accepting `options.emitterScope` as a deprecated compatibility alias.
3. Use `scope` when provided; otherwise fall back to `options.emitterScope`.
4. Report a diagnostic if both values are supplied.
5. Update examples and documentation to use `scope`.
6. Remove `emitterScope` only in a future breaking release.
Possible shape:
```typespec
@experimental(
#{ diagnosticId: "C", dependsOn: #["A", "B"] },
"@typespec/http-client-csharp"
)
op test(): void;
```
## Acceptance criteria
- [ ] New usage follows the standard top-level `scope` convention.
- [ ] Existing `options.emitterScope` usage continues to compile during the compatibility period.
- [ ] TCGC automatically filters the decorator without emitter-specific scope parsing.
- [ ] Supplying both scope forms produces a clear diagnostic.
- [ ] Existing include/exclude behavior remains unchanged.
- [ ] Documentation describes the migration and deprecation.
## Related work
- Original implementation: #11094
- Experimental metadata enhancement: #11684
- C# emitter integration: #11685
- Experimental diagnostic design: #11690
Contributor guide
Research direction
Start at the @experimental definition and ClientDecoratorOptions.emitterScope introduced in #11094, then trace TCGC's generic decorator handling and its scope filtering. Add the top-level scope compatibility path, diagnostic, and migration documentation while preserving existing include/exclude behavior; verify the acceptance criteria with the relevant decorator and emitter tests.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers, documentation
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100