Add decorator-requires-scope validation for @convenientAPI and @clientOption - #5119
Add decorator-requires-scope validation for @convenientAPI and @clientOption#5119iscai-msft wants to merge 12 commits into
decorator-requires-scope validation for @convenientAPI and @clientOption#5119Conversation
|
❌ There is undocummented changes. Run The following packages have changes but are not documented.
The following packages have already been documented:
Show changes
|
commit: |
|
You can try these changes here
|
2ebc06d to
2d82c69
Compare
require-convenient-api-scope linter ruleconvenient-api-requires-scope diagnostic warning
convenient-api-requires-scope diagnostic warningdecorator-requires-scope validation for @convenientAPI and @clientOption
Chenjie Shi (tadelesh)
left a comment
There was a problem hiding this comment.
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 |
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
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
8a0b515 to
cd21a19
Compare
…tor-requires-scope.md Co-authored-by: Chenjie Shi <tadelesh.shi@live.cn>
Weidong Xu (weidongxu-microsoft)
left a comment
There was a problem hiding this comment.
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)), |
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
oh thanks! that was from a previous implementation, i didn't clean it up well enough
- 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
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 languageThis subsumes the previous inline
client-option-requires-scopediagnostic with a centralized validation approach that runs during the$onValidatephase.Changes:
src/validations/decorators.tswithvalidateDecoratorScopes()functiondecorator-requires-scopeparamMessage diagnostic inlib.ts$clientOptiondecorator"java"scope for@convenientAPIclient-option-requires-scopetodecorator-requires-scopeFixes #3751
Related specs prs:
https://github.com/Azure/azure-rest-api-specs-pr/pull/29828
Azure/azure-rest-api-specs#45196