| File: Linker.Steps\ValidateVirtualMethodAnnotationsStep.cs | Web Access |
| Project: src\runtime\src\tools\illink\src\linker\Mono.Linker.csproj (illink) |
// Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Diagnostics.CodeAnalysis; using ILLink.Shared; using Mono.Cecil; namespace Mono.Linker.Steps { public class ValidateVirtualMethodAnnotationsStep : BaseStep { protected override void Process() { var annotations = Context.Annotations; foreach (var method in annotations.VirtualMethodsWithAnnotationsToValidate) { var baseOverrideInformations = annotations.GetBaseMethods(method); if (baseOverrideInformations != null) { foreach (var baseOv in baseOverrideInformations) { annotations.FlowAnnotations.ValidateMethodAnnotationsAreSame(baseOv); ValidateMethodRequiresUnreferencedCodeAreSame(baseOv); } } var overrides = annotations.GetOverrides(method); if (overrides != null) { foreach (var overrideInformation in overrides) { // Skip validation for cases where both base and override are in the list, we will validate the edge // when validating the override from the list. // This avoids validating the edge twice (it would produce the same warning twice) if (annotations.VirtualMethodsWithAnnotationsToValidate.Contains(overrideInformation.Override)) continue; annotations.FlowAnnotations.ValidateMethodAnnotationsAreSame(overrideInformation); ValidateMethodRequiresUnreferencedCodeAreSame(overrideInformation); } } } } void ValidateMethodRequiresUnreferencedCodeAreSame(OverrideInformation ov) { var method = ov.Override; var baseMethod = ov.Base; var annotations = Context.Annotations; bool methodSatisfies = annotations.IsInRequiresUnreferencedCodeScope(method, out _); bool baseRequires = annotations.DoesMethodRequireUnreferencedCode(baseMethod, out _); if ((baseRequires && !methodSatisfies) || (!baseRequires && annotations.DoesMethodRequireUnreferencedCode(method, out _))) { string message = MessageFormat.FormatRequiresAttributeMismatch( methodSatisfies, baseMethod.DeclaringType.IsInterface, nameof(RequiresUnreferencedCodeAttribute), method.GetDisplayName(), baseMethod.GetDisplayName()); IMemberDefinition origin = (ov.IsOverrideOfInterfaceMember && ov.InterfaceImplementor.Implementor != method.DeclaringType) ? ov.InterfaceImplementor.Implementor : method; Context.LogWarning(origin, DiagnosticId.RequiresUnreferencedCodeAttributeMismatch, message); } } } }