diff --git a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/AZC0001Tests.cs b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/AZC0001Tests.cs deleted file mode 100644 index 575ccfce44c..00000000000 --- a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/AZC0001Tests.cs +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System.Threading.Tasks; -using Xunit; -using Verifier = Azure.ClientSdk.Analyzers.Tests.AzureAnalyzerVerifier; - -namespace Azure.ClientSdk.Analyzers.Tests -{ - public class AZC0001Tests - { - private readonly string message = "Namespace '{0}' shouldn't contain public types." - + " Use one of the following pre-approved namespace groups (https://azure.github.io/azure-sdk/registered_namespaces.html):" - + " Azure.AI, Azure.Analytics, Azure.Communication, Azure.Compute, Azure.Containers, Azure.Core.Expressions, Azure.Data, Azure.Developer," - + " Azure.DigitalTwins, Azure.Health, Azure.Identity, Azure.IoT, Azure.Maps, Azure.Media, Azure.Messaging, Azure.MixedReality," - + " Azure.Monitor, Azure.ResourceManager, Azure.Search, Azure.Security, Azure.Storage, Azure.Verticals," - + " Microsoft.Extensions.Azure"; - - [Fact] - public async Task AZC0001ProducedForInvalidNamespaces() - { - const string code = @" -namespace RandomNamespace -{ - public class Program { } -}"; - - var diagnostic = Verifier.Diagnostic("AZC0001") - .WithMessage(string.Format(this.message, "RandomNamespace")) - .WithSpan(2, 11, 2, 26); - - await Verifier.VerifyAnalyzerAsync(code, diagnostic); - } - - [Fact] - public async Task AZC0001ProducedForInvalidNamespaceWithValidRoot() - { - const string code = @" -namespace Azure.StorageBadNamespace -{ - public class Program { } -}"; - - var diagnostic = Verifier.Diagnostic("AZC0001") - .WithMessage(string.Format(this.message, "Azure.StorageBadNamespace")) - .WithSpan(2, 17, 2, 36); - - await Verifier.VerifyAnalyzerAsync(code, diagnostic); - } - - [Fact] - public async Task AZC0001ProducedForInvalidSubNamespaceWithValidRoot() - { - const string code = @" -namespace Azure.StorageBadNamespace.Child -{ - public class Program { } -}"; - - var diagnostic = Verifier.Diagnostic("AZC0001") - .WithMessage(string.Format(this.message, "Azure.StorageBadNamespace.Child")) - .WithSpan(2, 37, 2, 42); - - await Verifier.VerifyAnalyzerAsync(code, diagnostic); - } - - [Fact] - public async Task AZC0001ProducedOneErrorPerNamespaceDefinition() - { - const string code = @" -namespace {|AZC0001:RandomNamespace|} -{ - public class Program { } -} - -namespace {|AZC0001:RandomNamespace|} -{ - public class Program2 { } -}"; - await Verifier.VerifyAnalyzerAsync(code); - } - - [Fact] - public async Task AZC0001NotProducedForNamespacesWithPrivateMembersOnly() - { - const string code = @" -namespace RandomNamespace -{ - internal class Program { } -}"; - await Verifier.VerifyAnalyzerAsync(code); - } - - [Fact] - public async Task AZC0001NotProducedForAllowedNamespaces() - { - const string code = @" -namespace Azure.Storage -{ - public class Program { } -}"; - await Verifier.VerifyAnalyzerAsync(code); - } - - [Fact] - public async Task AZC0001NotProducedForAllowedSubNamespaces() - { - const string code = @" -namespace Azure.Storage.Hello -{ - public class Program { } -}"; - await Verifier.VerifyAnalyzerAsync(code); - } - - [Fact] - public async Task AZC0001NotProducedForAzureCoreExpressions() - { - const string code = @" -namespace Azure.Core.Expressions -{ - public class Program { } -}"; - - await Verifier.VerifyAnalyzerAsync(code); - } - - [Fact] - public async Task AZC0001NotProducedForAzureCoreExpressionsSubNamespace() - { - const string code = @" -namespace Azure.Core.Expressions.Foobar -{ - public class Program { } -}"; - - await Verifier.VerifyAnalyzerAsync(code); - } - - [Fact] - public async Task AZC0001NotProducedForSubNamespacesOfAzureTemplate() - { - const string code = @" -namespace Azure.Template.RandomNamespace -{ - public class Program { } -}"; - - await Verifier.VerifyAnalyzerAsync(code); - } - - [Fact] - public async Task AZC0001NotProducedForAzureTemplateRoot() - { - const string code = @" -namespace Azure.Template -{ - public class Program { } -}"; - - await Verifier.VerifyAnalyzerAsync(code); - } - - [Fact] - public async Task AZC0001NotProducedForAzureTemplateSubNamespace() - { - const string code = @" -namespace Azure.Template.Models -{ - public class Program { } -}"; - - await Verifier.VerifyAnalyzerAsync(code); - } - } -} diff --git a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ClientAssemblyNamespaceAnalyzer.cs b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ClientAssemblyNamespaceAnalyzer.cs deleted file mode 100644 index 866774063f8..00000000000 --- a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ClientAssemblyNamespaceAnalyzer.cs +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System.Collections.Immutable; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Diagnostics; - -namespace Azure.ClientSdk.Analyzers -{ - [DiagnosticAnalyzer(LanguageNames.CSharp)] - public class ClientAssemblyNamespaceAnalyzer : SymbolAnalyzerBase - { - internal static readonly string[] AllowedNamespacePrefix = new[] - { - "Azure.AI", - "Azure.Analytics", - "Azure.Communication", - "Azure.Compute", - "Azure.Containers", - "Azure.Core.Expressions", - "Azure.Data", - "Azure.Developer", - "Azure.DigitalTwins", - "Azure.Health", - "Azure.Identity", - "Azure.IoT", - "Azure.Maps", - "Azure.Media", - "Azure.Messaging", - "Azure.MixedReality", - "Azure.Monitor", - "Azure.ResourceManager", - "Azure.Search", - "Azure.Security", - "Azure.Storage", - "Azure.Verticals", - "Microsoft.Extensions.Azure" - }; - - public ClientAssemblyNamespaceAnalyzer() - { - SupportedDiagnostics = ImmutableArray.Create(new[] - { - Descriptors.AZC0001 - }); - } - - public override ImmutableArray SupportedDiagnostics { get; } - - public override SymbolKind[] SymbolKinds { get; } = new[] { SymbolKind.Namespace }; - - public override void Analyze(ISymbolAnalysisContext context) - { - var namespaceSymbol = (INamespaceSymbol)context.Symbol; - bool hasPublicTypes = false; - foreach (var member in namespaceSymbol.GetMembers()) - { - if (member.IsType && member.DeclaredAccessibility == Accessibility.Public) - { - hasPublicTypes = true; - break; - } - } - - if (!hasPublicTypes) - { - return; - } - - var displayString = namespaceSymbol.ToDisplayString(); - foreach (var prefix in AllowedNamespacePrefix) - { - // Both the namespace itself or a sub-namespace are valid. - if (displayString == prefix || displayString.StartsWith(prefix + ".")) - { - return; - } - - // "Azure.Template" is not an approved namespace prefix, but we have a project template by that name - // to help customers get started. We do not want our template to include a suppression for this - // descriptor out of the box, so we need to treat it as a special case. - if (displayString == "Azure.Template" || displayString.StartsWith("Azure.Template.")) - { - return; - } - } - - foreach (var namespaceSymbolLocation in namespaceSymbol.Locations) - { - context.ReportDiagnostic(Diagnostic.Create(Descriptors.AZC0001, namespaceSymbolLocation, displayString), namespaceSymbol); - } - } - } -} diff --git a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/Descriptors.cs b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/Descriptors.cs index a3db298b73b..c6b6a2009ae 100644 --- a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/Descriptors.cs +++ b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/Descriptors.cs @@ -7,13 +7,7 @@ namespace Azure.ClientSdk.Analyzers { internal class Descriptors { - private static readonly string AZC0001Title = "Use one of the following pre-approved namespace groups (https://azure.github.io/azure-sdk/registered_namespaces.html): " + string.Join(", ", ClientAssemblyNamespaceAnalyzer.AllowedNamespacePrefix); - #region Guidelines - public static DiagnosticDescriptor AZC0001 = new DiagnosticDescriptor( - nameof(AZC0001), AZC0001Title, - "Namespace '{0}' shouldn't contain public types. " + AZC0001Title, DiagnosticCategory.Usage, DiagnosticSeverity.Warning, true); - public static DiagnosticDescriptor AZC0002 = new DiagnosticDescriptor( nameof(AZC0002), "DO ensure all service methods, both asynchronous and synchronous, take an optional CancellationToken parameter called 'cancellationToken' or a RequestContext parameter called 'context'.",