Skip to content

Add decorator-requires-scope validation for @convenientAPI and @clientOption - #5119

Open
iscai-msft wants to merge 12 commits into
mainfrom
iscai-msft-add-convenient-api-scope-linter-rule
Open

Add decorator-requires-scope validation for @convenientAPI and @clientOption#5119
iscai-msft wants to merge 12 commits into
mainfrom
iscai-msft-add-convenient-api-scope-linter-rule

Conversation

@iscai-msft

@iscai-msft iscai-msft commented Jul 30, 2026

Copy link
Copy Markdown
Member

Summary

Adds a new onValidate-phase validation (decorator-requires-scope) that warns when TCGC decorators that require a language scope are used without one or with an invalid scope.

Decorators checked:

  • @convenientAPI — must be scoped to "java" and/or "csharp" (the only emitters that use this information)
  • @clientOption — must be scoped to any specific language

This subsumes the previous inline client-option-requires-scope diagnostic with a centralized validation approach that runs during the $onValidate phase.

Changes:

  • New src/validations/decorators.ts with validateDecoratorScopes() function
  • New decorator-requires-scope paramMessage diagnostic in lib.ts
  • Removed old inline scope check from $clientOption decorator
  • Updated all tests to use proper "java" scope for @convenientAPI
  • Updated all references from client-option-requires-scope to decorator-requires-scope

Fixes #3751

Related specs prs:
https://github.com/Azure/azure-rest-api-specs-pr/pull/29828
Azure/azure-rest-api-specs#45196

@microsoft-github-policy-service microsoft-github-policy-service Bot added int:azure-specs Run integration tests against azure-rest-api-specs lib:tcgc Issues for @azure-tools/typespec-client-generator-core library meta:website TypeSpec.io updates linter Issues related to linter rules labels Jul 30, 2026
@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

❌ There is undocummented changes. Run chronus add to add a changeset or click here.

The following packages have changes but are not documented.

  • @azure-tools/azure-http-specs
  • @azure-tools/typespec-java

The following packages have already been documented:

  • @azure-tools/typespec-client-generator-core
Show changes

@azure-tools/typespec-client-generator-core - feature ✏️

Add decorator-requires-scope validation that warns when @convenientAPI is used without a "java" or "csharp" scope, and when @clientOption is used without any scope. This subsumes the previous client-option-requires-scope diagnostic.

@pkg-pr-new

pkg-pr-new Bot commented Jul 30, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@azure-tools/azure-http-specs@5119
npm i https://pkg.pr.new/@azure-tools/typespec-client-generator-core@5119
npm i https://pkg.pr.new/@azure-tools/typespec-java@5119

commit: b884b18

@azure-sdk-automation

Copy link
Copy Markdown
Contributor

You can try these changes here

🛝 Playground 🌐 Website

@iscai-msft
iscai-msft force-pushed the iscai-msft-add-convenient-api-scope-linter-rule branch from 2ebc06d to 2d82c69 Compare July 30, 2026 18:26
@iscai-msft iscai-msft changed the title Add require-convenient-api-scope linter rule Add convenient-api-requires-scope diagnostic warning Jul 30, 2026
@iscai-msft iscai-msft changed the title Add convenient-api-requires-scope diagnostic warning Add decorator-requires-scope validation for @convenientAPI and @clientOption Jul 30, 2026
@microsoft-github-policy-service microsoft-github-policy-service Bot added the lib:azure-http-specs For issues/prs related to the @azure-tools/typespec-azure-http-specs package label Jul 31, 2026

@tadelesh Chenjie Shi (tadelesh) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems a big breaking. Could you please check if any spec or spector test need to apply this breaking?

@iscai-msft

Copy link
Copy Markdown
Member Author

Seems a big breaking. Could you please check if any spec or spector test need to apply this breaking?

It's not very breaking, went through the specs and these are the only changes
Azure/azure-rest-api-specs#45196
https://github.com/Azure/azure-rest-api-specs-pr/pull/29828

iscai-msft and others added 4 commits August 3, 2026 15:03
Emit a warning when @convenientAPI is used without a language scope
parameter. The decorator should always be scoped to a specific language
(e.g., "java", "csharp") since convenience API behavior is typically
language-specific.

Uses the same pattern as the existing client-option-requires-scope
diagnostic — the warning fires directly in the decorator implementation.

Also updates existing tests to use scoped @convenientAPI calls.

Closes #3751

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 600858eb-38c5-4725-a32c-5b62b51c3b44
…toption

Adds a new onValidate-phase validation that warns when:
- @convenientAPI is used without a "java" or "csharp" scope
- @clientoption is used without any language scope

This subsumes the previous inline client-option-requires-scope diagnostic
with a centralized validation approach.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 600858eb-38c5-4725-a32c-5b62b51c3b44
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 600858eb-38c5-4725-a32c-5b62b51c3b44
Only @convenientAPI(true) requires java/csharp scope. Opting out with
@convenientAPI(false) is safe for any language and doesn't need scope.

Revert azure-http-specs change since those use @convenientAPI(false).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 600858eb-38c5-4725-a32c-5b62b51c3b44
iscai-msft and others added 4 commits August 3, 2026 15:03
Keep scope only on tests that specifically test cross-emitter scoping
behavior. Tests that just use @convenientAPI(false) to opt out don't
need a scope since the validation now skips false values.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 600858eb-38c5-4725-a32c-5b62b51c3b44
…API and emitter option check

- @convenientAPI and @protocolAPI both require java/csharp scope (true or false)
- Add @protocolAPI to decorator scope validation
- Add unnecessary-emitter-option diagnostic for non-java/csharp emitters
  using generate-convenience-methods or generate-protocol-methods
- Scope all test/spec usages appropriately

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 600858eb-38c5-4725-a32c-5b62b51c3b44
…lidation

Replace namespace-walking validation in $onValidate with the compiler's
DecoratorValidatorCallbacks pattern. Each decorator (,
, ) now returns { onTargetFinish } to report
scope diagnostics directly, which is the preferred approach per the
compiler's validation hooks.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 600858eb-38c5-4725-a32c-5b62b51c3b44
Validate generate-convenience-methods/generate-protocol-methods at SDK
context creation time instead of in $onValidate. This is more streamlined
since the emitter name and options are already available in that context.

Removes the now-empty validations/decorators.ts file.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 600858eb-38c5-4725-a32c-5b62b51c3b44
@iscai-msft
iscai-msft force-pushed the iscai-msft-add-convenient-api-scope-linter-rule branch from 8a0b515 to cd21a19 Compare August 3, 2026 19:05
…tor-requires-scope.md

Co-authored-by: Chenjie Shi <tadelesh.shi@live.cn>

@tadelesh Chenjie Shi (tadelesh) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Please help to fix the ci before merge.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new validation has two substring-matching gaps that let JavaScript bypass the intended checks, and the diagnostic documentation contradicts the implemented behavior.

.split(",")
.map((s) => s.trim().toLowerCase());
const hasValidScope = parsedScopes.some((s) =>
VALID_SCOPES.some((allowed) => s.includes(allowed)),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scope matching is too permissive. includes accepts scopes such as "javascript", "notjava", and "java, python". The last case applies the decorator to Python too, but no diagnostic is emitted because one token contains java. Negation patterns such as "!(python, csharp)" are also misclassified. Please parse the scope with the existing scope parser and require every effective positive scope to be exactly java or csharp.


// Warn if non-java/csharp emitter sets convenience/protocol options
const resolvedEmitterName = (emitterName ?? context.options["emitter-name"] ?? "").toLowerCase();
const isJavaOrCsharp = ["java", "csharp"].some((lang) => resolvedEmitterName.includes(lang));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JavaScript is classified as Java here. The real emitter name @azure-tools/typespec-javascript contains the substring java, so isJavaOrCsharp becomes true and the new unnecessary-emitter-option warning is skipped for JavaScript. Please compare the parsed emitter language exactly rather than searching the package name by substring.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great catch, thanks so much! i've added tests for this


- **Area:** Language-scoped decorator behavior. The decorator may apply globally or to unintended emitters without a proper scope.
- **Decorators checked:**
- `@convenientAPI(true)` — must be scoped to `"java"` and/or `"csharp"`. `@convenientAPI(false)` is always allowed without scope since opting out of convenience methods is safe for any language.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documented exception does not exist in the implementation. validateJavaCsharpScope warns whenever scope is undefined, regardless of the decorator value, and the added test explicitly expects a warning for @convenientAPI(false). This page also repeats the invalid unscoped example below. Please either implement the exception or update the documentation to match the chosen behavior.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh thanks! that was from a previous implementation, i didn't clean it up well enough

iscai-msft and others added 3 commits August 7, 2026 12:27
- Use exact scope matching (VALID_SCOPES.includes) instead of substring
  matching to prevent 'javascript' from matching 'java'
- Use parseEmitterName() for emitter language detection instead of
  substring search on package name
- Update docs to reflect that both true and false values of
  @convenientAPI/@protocolAPI require a scope

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 600858eb-38c5-4725-a32c-5b62b51c3b44
- Verify 'javascript' scope is not accepted (not confused with 'java')
- Verify javascript emitter gets unnecessary-emitter-option warning
- Verify java emitter does NOT get the warning

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 600858eb-38c5-4725-a32c-5b62b51c3b44
Use the existing parseScopes() utility instead of manual string splitting,
properly handling negation patterns like '!(python)' and '!(java, csharp)'.

New tests:
- 'notjava' scope is rejected (not confused with 'java')
- '!(python)' negation is accepted (implicitly includes java/csharp)
- '!(java, csharp)' negation is rejected (excludes all valid scopes)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 600858eb-38c5-4725-a32c-5b62b51c3b44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:java Issues for @azure-tools/typespec-java emitter int:azure-specs Run integration tests against azure-rest-api-specs lib:azure-http-specs For issues/prs related to the @azure-tools/typespec-azure-http-specs package lib:tcgc Issues for @azure-tools/typespec-client-generator-core library linter Issues related to linter rules meta:website TypeSpec.io updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[tcgc] add linter warning if @convenientApi decorator isn't scoped to java or sharp

3 participants