feat: Add SDK anti-pattern diagnostics (#44)#81
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new Roslyn-based diagnostic validator to the LSP server to detect common Azure Connectors SDK usage anti-patterns, expanding the existing diagnostics suite.
Changes:
- Introduces
SdkAntiPatternValidatoremitting diagnostics CSDK401–CSDK405 (with CSDK406–CSDK407 reserved). - Registers the new validator in server DI so it participates in diagnostic publishing.
- Adds unit tests covering positive/negative cases and edge conditions for the new diagnostics.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| Server/Program.cs | Registers the new SdkAntiPatternValidator in DI so it runs with other validators. |
| Server/Diagnostics/Validators/SdkAntiPatternValidator.cs | Implements syntax + semantic checks for CSDK401–CSDK405. |
| Server/Diagnostics/DiagnosticCodes.cs | Adds new diagnostic code constants CSDK401–CSDK407. |
| Server.Tests/SdkAntiPatternValidatorTests.cs | Adds test coverage for the new validator behaviors. |
- CSDK401: connector-scoped validation + positional arg range placement - CSDK402: unwrap nullable/qualified types before Input/Output check - CSDK403: handle conditional access (ex?.StatusCode) - CSDK405: use semantic model for CancellationToken parameter detection Co-authored-by: Dobby <dobby@microsoft.com>
…pace check - Thread cancellationToken into syntax-only helpers (CSDK401-403) - Unwrap chained invocations for CSDK404 (e.g. .ConfigureAwait()) - Add System.Threading namespace check for CancellationToken in CSDK405 Co-authored-by: Dobby <dobby@microsoft.com>
…, chained invocation tests - CSDK402: break after first awaited initializer to avoid duplicate diagnostics - Fix ConfigureAwait comments to use named parameter convention - Add tests for chained ConfigureAwait fire-and-forget detection (CSDK404) Co-authored-by: Dobby <dobby@microsoft.com>
- CSDK403: scan catch filter expression (when clause) for StatusCode - CSDK405: add ThrowIfCancellationRequested in inner invocation loop - New test for catch filter pattern Co-authored-by: Dobby <dobby@microsoft.com>
…-qualified catch type - CSDK401: resolve constant-style ConnectorName (FieldName) to canonical value via ConnectorNameConstants - CSDK403: use ExtractRightmostIdentifier for alias-qualified types (global::) - New tests for both patterns Co-authored-by: Dobby <dobby@microsoft.com>
- Skip CSDK401 when ConnectorName is present (AttributeValidator CSDK009 handles it) - CSDK401 now only fires when ConnectorName is absent (unique value-add) - Updated tests to match new behavior Co-authored-by: Dobby <dobby@microsoft.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (1)
Server/Diagnostics/Validators/SdkAntiPatternValidator.cs:141
- In CSDK401, ConnectorName is mapped via sdkIndex.ConnectorNameConstants (lines 127–141), but the value is never used for any validation because the code immediately skips whenever ConnectorName is non-null. This makes the mapping logic and its associated comments/tests misleading; consider either using the resolved ConnectorName to drive connector-scoped validation / resolution checks, or removing this unused resolution block if CSDK401 intentionally never runs when ConnectorName is provided.
// Try connector-scoped validation first when ConnectorName is present.
string? connectorName = SdkAntiPatternValidator.GetConnectorNameFromAttribute(attribute);
// Resolve constant-style ConnectorName (e.g., "Office365" from
// ConnectorNames.Office365) to the canonical value ("office365")
// using the SDK index's ConnectorNameConstants.
if (connectorName is not null)
{
SdkConstant? matchedConnector = sdkIndex.ConnectorNameConstants
.FirstOrDefault(connector =>
string.Equals(connector.FieldName, connectorName, StringComparison.OrdinalIgnoreCase) ||
string.Equals(connector.Value, connectorName, StringComparison.OrdinalIgnoreCase));
if (matchedConnector is not null)
{
connectorName = matchedConnector.Value;
}
}
- CSDK401 doc: clarify defers to AttributeValidator when ConnectorName present - CSDK402 doc: remove 'or vice versa' (only Input->Output direction implemented) - Update test comment for constant-reference case Co-authored-by: Dobby <dobby@microsoft.com>
…oken check - Remove dead ConnectorName normalization code (unconditionally skipped) - CSDK405: use semantic GetTypeInfo for CancellationToken argument detection instead of identifier text matching (handles cts.Token, default, etc.) - Update PR description to clarify CSDK401 scope Co-authored-by: Dobby <dobby@microsoft.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extends the LSP server with five new SDK usage anti-pattern diagnostics (CSDK401-CSDK405), with codes CSDK406-CSDK407 reserved for future use.
Diagnostics Added
Implementation
Testing
Closes #44