Report linter diagnostics on library template members the user gave a type to - #11862
Conversation
commit: |
|
All changed packages have been documented.
Show changes
|
|
You can try these changes here
|
Narrow the fix so a library-declared member is reported only when its declared type depends on a template parameter the user passed an argument for, and retarget the diagnostic to that argument node in the user's project.
A member the parameter merely appears inside, such as `value: T[]` in `Page<T>`, is the library's own declaration: a diagnostic about it is the library's to fix no matter which item type the user passed. Reported against azure-rest-api-specs this removes the `missing-x-ms-identifiers` findings on `Page<X>` while keeping `no-unknown` on `ArmResponse<unknown>` and `missing-x-ms-identifiers` where the user passed the array itself.
Fixes #11861
A linter rule can never report on a type that only exists because the user instantiated a library template. Given a library that declares:
and a spec that writes
...ResourceNameParameter<Employee, Type = Azure.Core.uuid>, a rule such asno-uuidsees thenameproperty and reports on it — and the linter silently throws the diagnostic away, becausename's source location resolves to the library declaration. This was found while adding ano-uuidrule in Azure/typespec-azure#5336, where it hid 9 offending resource-name declarations across 6 projects (35 Swagger findings).The coarse "is it in the user's project?" filter exists for a good reason — a rule must not blame a user for library-internal code they cannot change. But the type a user themselves passed is something they control.
So the filter now asks a sharper question: was this member declared as a template parameter the user supplied an argument for? If so, report it — on the argument, in the user's own file:
Everything else a library template declares stays filtered.
The same PR also makes
#suppressat an instantiation site apply to diagnostics raised inside the template — previously a diagnostic located in a library was unsuppressable from the spec that triggered it.Getting the scope right
Every broader design was tried and rejected on evidence from the Azure ARM libraries and
azure-rest-api-specs:compiler/lib/intrinsics.tsp, four levels of library templates deepop is ArmXxx<T>That last narrowing matters.
Azure.Core.Page<T>declaresvalue: T[], somissing-x-ms-identifiersfired on everyPage<X>inazure-rest-api-specs— but the array is the library's own declaration, and@identifiersbelongs on it, not on anything the user wrote. A member declared asbody: Requestis the opposite case: its type is what the user passed. Measured onspecification/web/.../AppService:Whole instantiated models and operations are excluded too —
op delete is ArmResourceDeleteWithoutOkAsync<Employee>produces two operation types, so reporting on both duplicates every ARM operation diagnostic. And arguments left to their default are excluded, since the user never wrote them.Known follow-up
documentation-requiredstill reports at the template argument when the real cause is an augment such as@@doc(Replica.properties, "")elsewhere in the spec. The finding is correct — the spec really is blanking the doc — but the location is indirect. Preferring the user's augment node was tried and does not work generically: the linter has no way to know which decorator a rule cares about, so it lands on an unrelated@@clientNameor@@flattenPropertyjust as often. The right fix is in the rule, which does know: report on the@docapplication when there is one.