| File: Analyzers\ComHostingDoesNotSupportGeneratedComInterfaceAnalyzer.cs | Web Access |
| Project: src\runtime\src\libraries\System.Runtime.InteropServices\gen\ComInterfaceGenerator\ComInterfaceGenerator.csproj (Microsoft.Interop.ComInterfaceGenerator) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Immutable; using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.DotnetRuntime.Extensions; using Microsoft.CodeAnalysis.Operations; using static Microsoft.Interop.Analyzers.AnalyzerDiagnostics; namespace Microsoft.Interop.Analyzers { [DiagnosticAnalyzer(LanguageNames.CSharp)] public class ComHostingDoesNotSupportGeneratedComInterfaceAnalyzer : DiagnosticAnalyzer { public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(ComHostingDoesNotSupportGeneratedComInterface); public override void Initialize(AnalysisContext context) { context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); context.EnableConcurrentExecution(); context.RegisterCompilationStartAction(context => { if (!context.Options.AnalyzerConfigOptionsProvider.GlobalOptions.TryGetValue("build_property.EnableComHosting", out string? enableComHosting) || !bool.TryParse(enableComHosting, out bool enableComHostingValue) || !enableComHostingValue) { return; } INamedTypeSymbol? generatedComClassAttribute = context.Compilation.GetBestTypeByMetadataName(TypeNames.GeneratedComClassAttribute); INamedTypeSymbol? generatedComInterfaceAttribute = context.Compilation.GetBestTypeByMetadataName(TypeNames.GeneratedComInterfaceAttribute); INamedTypeSymbol? comVisibleAttribute = context.Compilation.GetBestTypeByMetadataName(TypeNames.System_Runtime_InteropServices_ComVisibleAttribute)!; if (generatedComClassAttribute is null || generatedComInterfaceAttribute is null || comVisibleAttribute is null) { return; } context.RegisterOperationAction(context => { IAttributeOperation attr = (IAttributeOperation)context.Operation; if (attr.Operation is not IObjectCreationOperation ctor || !comVisibleAttribute.Equals(ctor.Type, SymbolEqualityComparer.Default) || ctor.Arguments[0].Value.ConstantValue.Value is not true) { return; } INamedTypeSymbol containingType = (INamedTypeSymbol)context.ContainingSymbol; if (containingType.GetAttributes().Any(attr => generatedComClassAttribute.Equals(attr.AttributeClass, SymbolEqualityComparer.Default))) { context.ReportDiagnostic(context.ContainingSymbol.CreateDiagnostic(ComHostingDoesNotSupportGeneratedComInterface, context.ContainingSymbol.Name)); return; } foreach (var iface in containingType.AllInterfaces) { if (iface.GetAttributes().Any(attr => generatedComInterfaceAttribute.Equals(attr.AttributeClass, SymbolEqualityComparer.Default))) { context.ReportDiagnostic(context.ContainingSymbol.CreateDiagnostic(ComHostingDoesNotSupportGeneratedComInterface, context.ContainingSymbol.Name)); return; } } }, OperationKind.Attribute); }); } } }