Add ILLink.Shared project to Native AOT (#63230)
authorTlakaelel Axayakatl Ceja <tlakaelel.ceja@microsoft.com>
Fri, 31 Dec 2021 02:54:35 +0000 (18:54 -0800)
committerGitHub <noreply@github.com>
Fri, 31 Dec 2021 02:54:35 +0000 (18:54 -0800)
Change diagnostics to use ILLink.Shared utilities
Update ReferenceSource folder
Add method to obtain Requires attribute named argument URL

20 files changed:
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/DiagnosticUtilities.cs
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReferenceSource/DiagnosticUtilities.cs [new file with mode: 0644]
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReferenceSource/DynamicallyAccessedMembersBinder.cs
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReferenceSource/FlowAnnotations.cs
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReferenceSource/MethodBodyScanner.cs
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReferenceSource/README.md
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReferenceSource/ReflectionMethodBodyScanner.cs
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReferenceSource/ReflectionPatternContext.cs
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReferenceSource/ScannerExtensions.cs
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReferenceSource/ValueNode.cs
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs
src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj
src/coreclr/tools/aot/ILLink.Shared/DiagnosticCategory.cs [new file with mode: 0644]
src/coreclr/tools/aot/ILLink.Shared/DiagnosticId.cs [new file with mode: 0644]
src/coreclr/tools/aot/ILLink.Shared/DiagnosticString.cs [new file with mode: 0644]
src/coreclr/tools/aot/ILLink.Shared/ILLink.Shared.projitems [new file with mode: 0644]
src/coreclr/tools/aot/ILLink.Shared/ILLink.Shared.shproj [new file with mode: 0644]
src/coreclr/tools/aot/ILLink.Shared/MessageFormat.cs [new file with mode: 0644]
src/coreclr/tools/aot/ILLink.Shared/SharedStrings.resx [new file with mode: 0644]
src/coreclr/tools/aot/ilc.sln

index 895c343..219c7ed 100644 (file)
@@ -44,13 +44,13 @@ namespace ILCompiler.Dataflow
                 return ((TypeDesc)parent).GetDisplayName();
         }
 
-        internal static string GetRequiresUnreferencedCodeAttributeMessage(MethodDesc method)
+        internal static string GetRequiresAttributeMessage(MethodDesc method, string requiresAttributeName)
         {
             var ecmaMethod = method.GetTypicalMethodDefinition() as EcmaMethod;
             if (ecmaMethod == null)
                 return null;
 
-            var decoded = ecmaMethod.GetDecodedCustomAttribute("System.Diagnostics.CodeAnalysis", "RequiresUnreferencedCodeAttribute");
+            var decoded = ecmaMethod.GetDecodedCustomAttribute("System.Diagnostics.CodeAnalysis", requiresAttributeName);
             if (decoded == null)
                 return null;
 
@@ -62,20 +62,20 @@ namespace ILCompiler.Dataflow
             return null;
         }
 
-        internal static string GetRequiresDynamicCodeAttributeMessage(MethodDesc method)
+        internal static string GetRequiresAttributeUrl(MethodDesc method, string requiresAttributeName)
         {
             var ecmaMethod = method.GetTypicalMethodDefinition() as EcmaMethod;
             if (ecmaMethod == null)
                 return null;
 
-            var decoded = ecmaMethod.GetDecodedCustomAttribute("System.Diagnostics.CodeAnalysis", "RequiresDynamicCodeAttribute");
+            var decoded = ecmaMethod.GetDecodedCustomAttribute("System.Diagnostics.CodeAnalysis", requiresAttributeName);
             if (decoded == null)
                 return null;
 
             var decodedValue = decoded.Value;
 
-            if (decodedValue.FixedArguments.Length != 0)
-                return (string)decodedValue.FixedArguments[0].Value;
+            if (decodedValue.NamedArguments.Length != 0 && decodedValue.NamedArguments[0].Name == "Url")
+                return (string)decodedValue.NamedArguments[0].Value;
 
             return null;
         }
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReferenceSource/DiagnosticUtilities.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReferenceSource/DiagnosticUtilities.cs
new file mode 100644 (file)
index 0000000..9aef3fd
--- /dev/null
@@ -0,0 +1,39 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using Mono.Cecil;
+
+namespace Mono.Linker.Dataflow
+{
+       static class DiagnosticUtilities
+       {
+               internal static IMetadataTokenProvider GetMethodParameterFromIndex (MethodDefinition method, int parameterIndex)
+               {
+                       int declaredParameterIndex;
+                       if (method.HasImplicitThis ()) {
+                               if (parameterIndex == 0)
+                                       return method;
+
+                               declaredParameterIndex = parameterIndex - 1;
+                       } else
+                               declaredParameterIndex = parameterIndex;
+
+                       if (declaredParameterIndex >= 0 && declaredParameterIndex < method.Parameters.Count)
+                               return method.Parameters[declaredParameterIndex];
+
+                       throw new InvalidOperationException ();
+               }
+
+               internal static string GetParameterNameForErrorMessage (ParameterDefinition parameterDefinition) =>
+                       string.IsNullOrEmpty (parameterDefinition.Name) ? $"#{parameterDefinition.Index}" : parameterDefinition.Name;
+
+               internal static string GetGenericParameterDeclaringMemberDisplayName (GenericParameter genericParameter) =>
+                       genericParameter.DeclaringMethod != null ?
+                               genericParameter.DeclaringMethod.GetDisplayName () :
+                               genericParameter.DeclaringType.GetDisplayName ();
+
+               internal static string GetMethodSignatureDisplayName (IMethodSignature methodSignature) =>
+                       (methodSignature is MethodReference method) ? method.GetDisplayName () : (methodSignature.ToString () ?? string.Empty);
+       }
+}
index 3f92f05..b44dd1c 100644 (file)
@@ -1,6 +1,5 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
 
 using System;
 using System.Collections.Generic;
@@ -8,8 +7,6 @@ using System.Diagnostics.CodeAnalysis;
 using System.Reflection;
 using Mono.Cecil;
 
-#nullable enable
-
 namespace Mono.Linker
 {
        // Temporary workaround - should be removed once linker can be upgraded to build against
index 5a7af5a..4f4a50d 100644 (file)
@@ -1,6 +1,5 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
 
 using System;
 using System.Collections.Generic;
@@ -9,8 +8,6 @@ using System.Diagnostics.CodeAnalysis;
 using Mono.Cecil;
 using Mono.Cecil.Cil;
 
-#nullable enable
-
 namespace Mono.Linker.Dataflow
 {
        class FlowAnnotations
@@ -589,15 +586,15 @@ namespace Mono.Linker.Dataflow
                {
                        readonly TypeDefinition _type;
                        readonly DynamicallyAccessedMemberTypes _typeAnnotation;
-                       readonly MethodAnnotations[] _annotatedMethods;
-                       readonly FieldAnnotation[] _annotatedFields;
+                       readonly MethodAnnotations[]? _annotatedMethods;
+                       readonly FieldAnnotation[]? _annotatedFields;
                        readonly DynamicallyAccessedMemberTypes[]? _genericParameterAnnotations;
 
                        public TypeAnnotations (
                                TypeDefinition type,
                                DynamicallyAccessedMemberTypes typeAnnotation,
-                               MethodAnnotations[] annotatedMethods,
-                               FieldAnnotation[] annotatedFields,
+                               MethodAnnotations[]? annotatedMethods,
+                               FieldAnnotation[]? annotatedFields,
                                DynamicallyAccessedMemberTypes[]? genericParameterAnnotations)
                                => (_type, _typeAnnotation, _annotatedMethods, _annotatedFields, _genericParameterAnnotations)
                                 = (type, typeAnnotation, annotatedMethods, annotatedFields, genericParameterAnnotations);
index 6fc44bc..f3cce6d 100644 (file)
@@ -1,6 +1,5 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
 
 using System;
 using System.Collections.Generic;
@@ -9,8 +8,6 @@ using Mono.Cecil;
 using Mono.Cecil.Cil;
 using Mono.Collections.Generic;
 
-#nullable enable
-
 namespace Mono.Linker.Dataflow
 {
        /// <summary>
index bc461d7..693097e 100644 (file)
@@ -1 +1 @@
-Sources taken from https://github.com/dotnet/linker/tree/640878adf1e27cb79bea0a894033f85a84db208d/src/linker/Linker.Dataflow.
+Sources taken from https://github.com/dotnet/linker/tree/9996319f2a619c2911b02c164b4d6b1d20e29a39/src/linker/Linker.Dataflow.
index c25f404..67ce51f 100644 (file)
@@ -1,6 +1,5 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
 
 using System;
 using System.Collections.Generic;
@@ -14,8 +13,6 @@ using Mono.Linker.Steps;
 
 using BindingFlags = System.Reflection.BindingFlags;
 
-#nullable enable
-
 namespace Mono.Linker.Dataflow
 {
        class ReflectionMethodBodyScanner : MethodBodyScanner
@@ -894,8 +891,7 @@ namespace Mono.Linker.Dataflow
                                                                // We have one of the accessors for the property. The Expression.Property will in this case search
                                                                // for the matching PropertyInfo and store that. So to be perfectly correct we need to mark the
                                                                // respective PropertyInfo as "accessed via reflection".
-                                                               var propertyDefinition = methodBaseValue.MethodRepresented.GetProperty ();
-                                                               if (propertyDefinition != null) {
+                                                               if (methodBaseValue.MethodRepresented.TryGetProperty (out PropertyDefinition? propertyDefinition)) {
                                                                        MarkProperty (ref reflectionContext, propertyDefinition);
                                                                        continue;
                                                                }
@@ -1051,15 +1047,14 @@ namespace Mono.Linker.Dataflow
                                                }
                                                foreach (var typeNameValue in methodParams[0].UniqueValues ()) {
                                                        if (typeNameValue is KnownStringValue knownStringValue) {
-                                                               TypeReference foundTypeRef = _context.TypeNameResolver.ResolveTypeName (knownStringValue.Contents, callingMethodDefinition, out AssemblyDefinition typeAssembly, false);
-                                                               TypeDefinition? foundType = ResolveToTypeDefinition (foundTypeRef);
-                                                               if (foundType == null) {
+                                                               if (!_context.TypeNameResolver.TryResolveTypeName (knownStringValue.Contents, callingMethodDefinition, out TypeReference? foundTypeRef, out AssemblyDefinition? typeAssembly, false)
+                                                                       || ResolveToTypeDefinition (foundTypeRef) is not TypeDefinition foundType) {
                                                                        // Intentionally ignore - it's not wrong for code to call Type.GetType on non-existing name, the code might expect null/exception back.
                                                                        reflectionContext.RecordHandledPattern ();
                                                                } else {
                                                                        reflectionContext.RecordRecognizedPattern (foundType, () => _markStep.MarkTypeVisibleToReflection (foundTypeRef, foundType, new DependencyInfo (DependencyKind.AccessedViaReflection, callingMethodDefinition)));
                                                                        methodReturnValue = MergePointValue.MergeValues (methodReturnValue, new SystemTypeValue (foundType));
-                                                                       _context.MarkingHelpers.MarkMatchingExportedType (foundType, typeAssembly, new DependencyInfo (DependencyKind.AccessedViaReflection, foundType));
+                                                                       _context.MarkingHelpers.MarkMatchingExportedType (foundType, typeAssembly, new DependencyInfo (DependencyKind.AccessedViaReflection, foundType), reflectionContext.Origin);
                                                                }
                                                        } else if (typeNameValue == NullValue.Instance) {
                                                                reflectionContext.RecordHandledPattern ();
@@ -1200,7 +1195,7 @@ namespace Mono.Linker.Dataflow
                                                                                        // We have chosen not to populate the methodReturnValue for now
                                                                                        RequireDynamicallyAccessedMembers (ref reflectionContext, DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes, value, calledMethodDefinition);
                                                                                else {
-                                                                                       TypeDefinition[] matchingNestedTypes = MarkNestedTypesOnType (ref reflectionContext, systemTypeValue.TypeRepresented, m => m.Name == stringValue.Contents, bindingFlags);
+                                                                                       TypeDefinition[]? matchingNestedTypes = MarkNestedTypesOnType (ref reflectionContext, systemTypeValue.TypeRepresented, m => m.Name == stringValue.Contents, bindingFlags);
 
                                                                                        if (matchingNestedTypes != null) {
                                                                                                for (int i = 0; i < matchingNestedTypes.Length; i++)
@@ -1936,9 +1931,9 @@ namespace Mono.Linker.Dataflow
                                                                continue;
                                                        }
 
-                                                       var typeRef = _context.TypeNameResolver.ResolveTypeName (resolvedAssembly, typeNameStringValue.Contents);
-                                                       var resolvedType = _context.TryResolve (typeRef);
-                                                       if (resolvedType == null || typeRef is ArrayType) {
+                                                       if (!_context.TypeNameResolver.TryResolveTypeName (resolvedAssembly, typeNameStringValue.Contents, out TypeReference? typeRef)
+                                                               || _context.TryResolve (typeRef) is not TypeDefinition resolvedType
+                                                               || typeRef is ArrayType) {
                                                                // It's not wrong to have a reference to non-existing type - the code may well expect to get an exception in this case
                                                                // Note that we did find the assembly, so it's not a linker config problem, it's either intentional, or wrong versions of assemblies
                                                                // but linker can't know that. In case a user tries to create an array using System.Activator we should simply ignore it, the user
@@ -2232,15 +2227,14 @@ namespace Mono.Linker.Dataflow
                                } else if (uniqueValue is SystemTypeValue systemTypeValue) {
                                        MarkTypeForDynamicallyAccessedMembers (ref reflectionContext, systemTypeValue.TypeRepresented, requiredMemberTypes, DependencyKind.DynamicallyAccessedMember);
                                } else if (uniqueValue is KnownStringValue knownStringValue) {
-                                       TypeReference typeRef = _context.TypeNameResolver.ResolveTypeName (knownStringValue.Contents, reflectionContext.Source, out AssemblyDefinition typeAssembly);
-                                       TypeDefinition? foundType = ResolveToTypeDefinition (typeRef);
-                                       if (foundType == null) {
+                                       if (!_context.TypeNameResolver.TryResolveTypeName (knownStringValue.Contents, reflectionContext.Source, out TypeReference? typeRef, out AssemblyDefinition? typeAssembly)
+                                               || ResolveToTypeDefinition (typeRef) is not TypeDefinition foundType) {
                                                // Intentionally ignore - it's not wrong for code to call Type.GetType on non-existing name, the code might expect null/exception back.
                                                reflectionContext.RecordHandledPattern ();
                                        } else {
                                                MarkType (ref reflectionContext, typeRef);
                                                MarkTypeForDynamicallyAccessedMembers (ref reflectionContext, foundType, requiredMemberTypes, DependencyKind.DynamicallyAccessedMember);
-                                               _context.MarkingHelpers.MarkMatchingExportedType (foundType, typeAssembly, new DependencyInfo (DependencyKind.DynamicallyAccessedMember, foundType));
+                                               _context.MarkingHelpers.MarkMatchingExportedType (foundType, typeAssembly, new DependencyInfo (DependencyKind.DynamicallyAccessedMember, foundType), reflectionContext.Origin);
                                        }
                                } else if (uniqueValue == NullValue.Instance) {
                                        // Ignore - probably unreachable path as it would fail at runtime anyway.
@@ -2387,7 +2381,7 @@ namespace Mono.Linker.Dataflow
                                MarkField (ref reflectionContext, field);
                }
 
-               TypeDefinition[] MarkNestedTypesOnType (ref ReflectionPatternContext reflectionContext, TypeDefinition type, Func<TypeDefinition, bool> filter, BindingFlags? bindingFlags = BindingFlags.Default)
+               TypeDefinition[]? MarkNestedTypesOnType (ref ReflectionPatternContext reflectionContext, TypeDefinition type, Func<TypeDefinition, bool> filter, BindingFlags? bindingFlags = BindingFlags.Default)
                {
                        var result = new ArrayBuilder<TypeDefinition> ();
 
index 870a302..1cd64ce 100644 (file)
@@ -1,6 +1,5 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
 
 using System;
 using System.Diagnostics;
@@ -26,9 +25,9 @@ namespace Mono.Linker.Dataflow
 #endif
 
                public MessageOrigin Origin { get; init; }
-               public ICustomAttributeProvider Source { get => Origin.Provider; }
+               public ICustomAttributeProvider? Source { get => Origin.Provider; }
                public IMetadataTokenProvider MemberWithRequirements { get; init; }
-               public Instruction Instruction { get; init; }
+               public Instruction? Instruction { get; init; }
                public bool ReportingEnabled { get; init; }
 
                public ReflectionPatternContext (
@@ -36,7 +35,7 @@ namespace Mono.Linker.Dataflow
                        bool reportingEnabled,
                        in MessageOrigin origin,
                        IMetadataTokenProvider memberWithRequirements,
-                       Instruction instruction = null)
+                       Instruction? instruction = null)
                {
                        _context = context;
                        ReportingEnabled = reportingEnabled;
index aa7b3f0..0b7a2af 100644 (file)
@@ -1,6 +1,5 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
 
 using System;
 using System.Collections.Generic;
index 0afda81..5e3349d 100644 (file)
@@ -1,6 +1,5 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
 
 using System;
 using System.Collections.Generic;
@@ -13,8 +12,6 @@ using FieldDefinition = Mono.Cecil.FieldDefinition;
 using GenericParameter = Mono.Cecil.GenericParameter;
 using TypeDefinition = Mono.Cecil.TypeDefinition;
 
-#nullable enable
-
 namespace Mono.Linker.Dataflow
 {
        public enum ValueNodeKind
index 5f4e52e..9819837 100644 (file)
@@ -7,6 +7,7 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
 using System.Linq;
+using ILLink.Shared;
 
 using Internal.IL;
 using Internal.TypeSystem;
@@ -897,9 +898,8 @@ namespace ILCompiler.Dataflow
                                         if (hasUncheckedAnnotation)
                                         {
                                             reflectionContext.RecordUnrecognizedPattern(
-                                                    2055,
-                                                    $"Call to '{calledMethod.GetDisplayName()}' can not be statically analyzed. " +
-                                                    $"It's not possible to guarantee the availability of requirements of the generic type.");
+                                                    (int)DiagnosticId.MakeGenericType,
+                                                    new DiagnosticString(DiagnosticId.MakeGenericType).GetMessage(calledMethod.GetDisplayName()));
                                         }
                                     }
 
@@ -912,9 +912,8 @@ namespace ILCompiler.Dataflow
                                 {
                                     // We have no way to "include more" to fix this if we don't know, so we have to warn
                                     reflectionContext.RecordUnrecognizedPattern(
-                                        2055,
-                                        $"Call to '{calledMethod.GetDisplayName()}' can not be statically analyzed. " +
-                                        $"It's not possible to guarantee the availability of requirements of the generic type.");
+                                        (int)DiagnosticId.MakeGenericType,
+                                        new DiagnosticString(DiagnosticId.MakeGenericType).GetMessage(calledMethod.GetDisplayName()));
                                 }
                             }
 
@@ -1030,8 +1029,8 @@ namespace ILCompiler.Dataflow
                                                 // We don't know what method the `MakeGenericMethod` was called on, so we have to assume
                                                 // that the method may have requirements which we can't fullfil -> warn.
                                                 reflectionContext.RecordUnrecognizedPattern(
-                                                    2060, string.Format(Resources.Strings.IL2060,
-                                                        DiagnosticUtilities.GetMethodSignatureDisplayName(calledMethod)));
+                                                    (int)DiagnosticId.MakeGenericMethodCannotBeStaticallyAnalyzed,
+                                                    new DiagnosticString(DiagnosticId.MakeGenericMethodCannotBeStaticallyAnalyzed).GetMessage(DiagnosticUtilities.GetMethodSignatureDisplayName(calledMethod)));
                                             }
 
                                             RequireDynamicallyAccessedMembers(
@@ -1049,8 +1048,8 @@ namespace ILCompiler.Dataflow
                                         // We don't know what method the `MakeGenericMethod` was called on, so we have to assume
                                         // that the method may have requirements which we can't fullfil -> warn.
                                         reflectionContext.RecordUnrecognizedPattern(
-                                            2060, string.Format(Resources.Strings.IL2060,
-                                                DiagnosticUtilities.GetMethodSignatureDisplayName(calledMethod)));
+                                            (int)DiagnosticId.MakeGenericMethodCannotBeStaticallyAnalyzed,
+                                            new DiagnosticString(DiagnosticId.MakeGenericMethodCannotBeStaticallyAnalyzed).GetMessage(DiagnosticUtilities.GetMethodSignatureDisplayName(calledMethod)));
                                     }
 
                                     RequireDynamicallyAccessedMembers(
@@ -1093,7 +1092,8 @@ namespace ILCompiler.Dataflow
                                 // In all other cases we may not even know which type this is about, so there's nothing we can do
                                 // report it as a warning.
                                 reflectionContext.RecordUnrecognizedPattern(
-                                    2103, string.Format(Resources.Strings.IL2103,
+                                    (int)DiagnosticId.PropertyAccessorParameterInLinqExpressionsCannotBeStaticallyDetermined,
+                                    new DiagnosticString(DiagnosticId.PropertyAccessorParameterInLinqExpressionsCannotBeStaticallyDetermined).GetMessage(
                                         DiagnosticUtilities.GetParameterNameForErrorMessage(new ParameterOrigin(calledMethod, 1)),
                                         DiagnosticUtilities.GetMethodSignatureDisplayName(calledMethod)));
                             }
@@ -2162,7 +2162,8 @@ namespace ILCompiler.Dataflow
                                     // We don't know what method the `MakeGenericMethod` was called on, so we have to assume
                                     // that the method may have requirements which we can't fullfil -> warn.
                                     reflectionContext.RecordUnrecognizedPattern(
-                                        2060, string.Format(Resources.Strings.IL2060,
+                                        (int)DiagnosticId.MakeGenericMethodCannotBeStaticallyAnalyzed,
+                                        new DiagnosticString(DiagnosticId.MakeGenericMethodCannotBeStaticallyAnalyzed).GetMessage(
                                             DiagnosticUtilities.GetMethodSignatureDisplayName(calledMethod)));
                                 }
                             }
@@ -2221,25 +2222,14 @@ namespace ILCompiler.Dataflow
                         if (shouldEnableReflectionWarnings &&
                             calledMethod.HasCustomAttribute("System.Diagnostics.CodeAnalysis", "RequiresUnreferencedCodeAttribute"))
                         {
-                            string attributeMessage = DiagnosticUtilities.GetRequiresUnreferencedCodeAttributeMessage(calledMethod);
+                            string arg1 = MessageFormat.FormatRequiresAttributeMessageArg(DiagnosticUtilities.GetRequiresAttributeMessage(calledMethod, "RequiresUnreferencedCodeAttribute"));
+                            string arg2 = MessageFormat.FormatRequiresAttributeUrlArg(DiagnosticUtilities.GetRequiresAttributeUrl(calledMethod, "RequiresUnreferencedCodeAttribute"));
+                            string message = new DiagnosticString(DiagnosticId.RequiresUnreferencedCode).GetMessage(calledMethod.GetDisplayName(), arg1, arg2);
 
-                            if (attributeMessage != null && attributeMessage.Length > 0 && !attributeMessage.EndsWith('.'))
-                                attributeMessage += '.';
-
-                            string message =
-                                $"Using method '{calledMethod.GetDisplayName()}' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. {attributeMessage}";
-
-                            //if (requiresUnreferencedCode.Url != null)
-                            //{
-                            //    message += " " + requiresUnreferencedCode.Url;
-                            //}
-
-                            _logger.LogWarning(message, 2026, callingMethodBody, offset, MessageSubCategory.TrimAnalysis);
+                            _logger.LogWarning(message, (int)DiagnosticId.RequiresUnreferencedCode, callingMethodBody, offset, MessageSubCategory.TrimAnalysis);
                         }
 
-                        
-
-                        if (shouldEnableAotWarnings &&                            
+                        if (shouldEnableAotWarnings &&
                             calledMethod.HasCustomAttribute("System.Diagnostics.CodeAnalysis", "RequiresDynamicCodeAttribute"))
                         {
                             LogDynamicCodeWarning(_logger, callingMethodBody, offset, calledMethod);
@@ -2247,19 +2237,11 @@ namespace ILCompiler.Dataflow
 
                         static void LogDynamicCodeWarning(Logger logger, MethodIL callingMethodBody, int offset, MethodDesc calledMethod)
                         {
-                            string attributeMessage = DiagnosticUtilities.GetRequiresDynamicCodeAttributeMessage(calledMethod);
-
-                            if (attributeMessage != null && attributeMessage.Length > 0 && !attributeMessage.EndsWith('.'))
-                                attributeMessage += '.';
-
-                            string message = $"{String.Format(Resources.Strings.IL3050, calledMethod.GetDisplayName())} {attributeMessage}";
+                            string arg1 = MessageFormat.FormatRequiresAttributeMessageArg(DiagnosticUtilities.GetRequiresAttributeMessage(calledMethod, "RequiresDynamicCodeAttribute"));
+                            string arg2 = MessageFormat.FormatRequiresAttributeUrlArg(DiagnosticUtilities.GetRequiresAttributeUrl(calledMethod, "RequiresDynamicCodeAttribute"));
+                            string message = new DiagnosticString(DiagnosticId.RequiresDynamicCode).GetMessage(calledMethod.GetDisplayName(), arg1, arg2);
 
-                            //if (requiresUnreferencedCode.Url != null)
-                            //{
-                            //    message += " " + requiresUnreferencedCode.Url;
-                            //}
-
-                            logger.LogWarning(message, 3050, callingMethodBody, offset, MessageSubCategory.AotAnalysis);
+                            logger.LogWarning(message, (int)DiagnosticId.RequiresDynamicCode, callingMethodBody, offset, MessageSubCategory.AotAnalysis);
                         }
 
                         // To get good reporting of errors we need to track the origin of the value for all method calls
@@ -2591,7 +2573,8 @@ namespace ILCompiler.Dataflow
                         switch ((valueWithDynamicallyAccessedMember.SourceContext, targetContext))
                         {
                             case (ParameterOrigin sourceParameter, ParameterOrigin targetParameter):
-                                reflectionContext.RecordUnrecognizedPattern(2067, string.Format(Resources.Strings.IL2067,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsParameter,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsParameter).GetMessage(
                                     DiagnosticUtilities.GetParameterNameForErrorMessage(targetParameter),
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(targetParameter.Method),
                                     DiagnosticUtilities.GetParameterNameForErrorMessage(sourceParameter),
@@ -2599,21 +2582,24 @@ namespace ILCompiler.Dataflow
                                     missingMemberTypes));
                                 break;
                             case (ParameterOrigin sourceParameter, MethodReturnOrigin targetMethodReturnType):
-                                reflectionContext.RecordUnrecognizedPattern(2068, string.Format(Resources.Strings.IL2068,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsMethodReturnType,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsMethodReturnType).GetMessage(
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(targetMethodReturnType.Method),
                                     DiagnosticUtilities.GetParameterNameForErrorMessage(sourceParameter),
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(sourceParameter.Method),
                                     missingMemberTypes));
                                 break;
                             case (ParameterOrigin sourceParameter, FieldOrigin targetField):
-                                reflectionContext.RecordUnrecognizedPattern(2069, string.Format(Resources.Strings.IL2069,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsField,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsField).GetMessage(
                                     targetField.GetDisplayName(),
                                     DiagnosticUtilities.GetParameterNameForErrorMessage(sourceParameter),
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(sourceParameter.Method),
                                     missingMemberTypes));
                                 break;
                             case (ParameterOrigin sourceParameter, MethodOrigin targetMethod):
-                                reflectionContext.RecordUnrecognizedPattern(2070, string.Format(Resources.Strings.IL2070,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsThisParameter,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsThisParameter).GetMessage(
                                     targetMethod.GetDisplayName(),
                                     DiagnosticUtilities.GetParameterNameForErrorMessage(sourceParameter),
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(sourceParameter.Method),
@@ -2621,7 +2607,8 @@ namespace ILCompiler.Dataflow
                                 break;
                             case (ParameterOrigin sourceParameter, GenericParameterOrigin targetGenericParameter):
                                 // Currently this is never generated, once ILLink supports full analysis of MakeGenericType/MakeGenericMethod this will be used
-                                reflectionContext.RecordUnrecognizedPattern(2071, string.Format(Resources.Strings.IL2071,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsGenericParameter,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsGenericParameter).GetMessage(
                                     targetGenericParameter.Name,
                                     DiagnosticUtilities.GetGenericParameterDeclaringMemberDisplayName(targetGenericParameter),
                                     DiagnosticUtilities.GetParameterNameForErrorMessage(sourceParameter),
@@ -2630,33 +2617,38 @@ namespace ILCompiler.Dataflow
                                 break;
 
                             case (MethodReturnOrigin sourceMethodReturnType, ParameterOrigin targetParameter):
-                                reflectionContext.RecordUnrecognizedPattern(2072, string.Format(Resources.Strings.IL2072,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter).GetMessage(
                                     DiagnosticUtilities.GetParameterNameForErrorMessage(targetParameter),
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(targetParameter.Method),
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(sourceMethodReturnType.Method),
                                     missingMemberTypes));
                                 break;
                             case (MethodReturnOrigin sourceMethodReturnType, MethodReturnOrigin targetMethodReturnType):
-                                reflectionContext.RecordUnrecognizedPattern(2073, string.Format(Resources.Strings.IL2073,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsMethodReturnType,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsMethodReturnType).GetMessage(
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(targetMethodReturnType.Method),
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(sourceMethodReturnType.Method),
                                     missingMemberTypes));
                                 break;
                             case (MethodReturnOrigin sourceMethodReturnType, FieldOrigin targetField):
-                                reflectionContext.RecordUnrecognizedPattern(2074, string.Format(Resources.Strings.IL2074,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsField,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsField).GetMessage(
                                     targetField.GetDisplayName(),
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(sourceMethodReturnType.Method),
                                     missingMemberTypes));
                                 break;
                             case (MethodReturnOrigin sourceMethodReturnType, MethodOrigin targetMethod):
-                                reflectionContext.RecordUnrecognizedPattern(2075, string.Format(Resources.Strings.IL2075,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter).GetMessage(
                                     targetMethod.GetDisplayName(),
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(sourceMethodReturnType.Method),
                                     missingMemberTypes));
                                 break;
                             case (MethodReturnOrigin sourceMethodReturnType, GenericParameterOrigin targetGenericParameter):
                                 // Currently this is never generated, once ILLink supports full analysis of MakeGenericType/MakeGenericMethod this will be used
-                                reflectionContext.RecordUnrecognizedPattern(2076, string.Format(Resources.Strings.IL2076,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsGenericParameter,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsGenericParameter).GetMessage(
                                     targetGenericParameter.Name,
                                     DiagnosticUtilities.GetGenericParameterDeclaringMemberDisplayName(targetGenericParameter),
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(sourceMethodReturnType.Method),
@@ -2664,33 +2656,38 @@ namespace ILCompiler.Dataflow
                                 break;
 
                             case (FieldOrigin sourceField, ParameterOrigin targetParameter):
-                                reflectionContext.RecordUnrecognizedPattern(2077, string.Format(Resources.Strings.IL2077,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsParameter,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsParameter).GetMessage(
                                     DiagnosticUtilities.GetParameterNameForErrorMessage(targetParameter),
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(targetParameter.Method),
                                     sourceField.GetDisplayName(),
                                     missingMemberTypes));
                                 break;
                             case (FieldOrigin sourceField, MethodReturnOrigin targetMethodReturnType):
-                                reflectionContext.RecordUnrecognizedPattern(2078, string.Format(Resources.Strings.IL2078,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsMethodReturnType,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsMethodReturnType).GetMessage(
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(targetMethodReturnType.Method),
                                     sourceField.GetDisplayName(),
                                     missingMemberTypes));
                                 break;
                             case (FieldOrigin sourceField, FieldOrigin targetField):
-                                reflectionContext.RecordUnrecognizedPattern(2079, string.Format(Resources.Strings.IL2079,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsField,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsField).GetMessage(
                                     targetField.GetDisplayName(),
                                     sourceField.GetDisplayName(),
                                     missingMemberTypes));
                                 break;
                             case (FieldOrigin sourceField, MethodOrigin targetMethod):
-                                reflectionContext.RecordUnrecognizedPattern(2080, string.Format(Resources.Strings.IL2080,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsThisParameter,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsThisParameter).GetMessage(
                                     targetMethod.GetDisplayName(),
                                     sourceField.GetDisplayName(),
                                     missingMemberTypes));
                                 break;
                             case (FieldOrigin sourceField, GenericParameterOrigin targetGenericParameter):
                                 // Currently this is never generated, once ILLink supports full analysis of MakeGenericType/MakeGenericMethod this will be used
-                                reflectionContext.RecordUnrecognizedPattern(2081, string.Format(Resources.Strings.IL2081,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsGenericParameter,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsGenericParameter).GetMessage(
                                     targetGenericParameter.Name,
                                     DiagnosticUtilities.GetGenericParameterDeclaringMemberDisplayName(targetGenericParameter),
                                     sourceField.GetDisplayName(),
@@ -2698,33 +2695,38 @@ namespace ILCompiler.Dataflow
                                 break;
 
                             case (MethodOrigin sourceMethod, ParameterOrigin targetParameter):
-                                reflectionContext.RecordUnrecognizedPattern(2082, string.Format(Resources.Strings.IL2082,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsParameter,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsParameter).GetMessage(
                                     DiagnosticUtilities.GetParameterNameForErrorMessage(targetParameter),
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(targetParameter.Method),
                                     sourceMethod.GetDisplayName(),
                                     missingMemberTypes));
                                 break;
                             case (MethodOrigin sourceMethod, MethodReturnOrigin targetMethodReturnType):
-                                reflectionContext.RecordUnrecognizedPattern(2083, string.Format(Resources.Strings.IL2083,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsMethodReturnType,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsMethodReturnType).GetMessage(
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(targetMethodReturnType.Method),
                                     sourceMethod.GetDisplayName(),
                                     missingMemberTypes));
                                 break;
                             case (MethodOrigin sourceMethod, FieldOrigin targetField):
-                                reflectionContext.RecordUnrecognizedPattern(2084, string.Format(Resources.Strings.IL2084,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsField,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsField).GetMessage(
                                     targetField.GetDisplayName(),
                                     sourceMethod.GetDisplayName(),
                                     missingMemberTypes));
                                 break;
                             case (MethodOrigin sourceMethod, MethodOrigin targetMethod):
-                                reflectionContext.RecordUnrecognizedPattern(2085, string.Format(Resources.Strings.IL2085,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsThisParameter,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsThisParameter).GetMessage(
                                     targetMethod.GetDisplayName(),
                                     sourceMethod.GetDisplayName(),
                                     missingMemberTypes));
                                 break;
                             case (MethodOrigin sourceMethod, GenericParameterOrigin targetGenericParameter):
                                 // Currently this is never generated, once ILLink supports full analysis of MakeGenericType/MakeGenericMethod this will be used
-                                reflectionContext.RecordUnrecognizedPattern(2086, string.Format(Resources.Strings.IL2086,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsGenericParameter,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsGenericParameter).GetMessage(
                                     targetGenericParameter.Name,
                                     DiagnosticUtilities.GetGenericParameterDeclaringMemberDisplayName(targetGenericParameter),
                                     sourceMethod.GetDisplayName(),
@@ -2732,7 +2734,8 @@ namespace ILCompiler.Dataflow
                                 break;
 
                             case (GenericParameterOrigin sourceGenericParameter, ParameterOrigin targetParameter):
-                                reflectionContext.RecordUnrecognizedPattern(2087, string.Format(Resources.Strings.IL2087,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsParameter,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsParameter).GetMessage(
                                     DiagnosticUtilities.GetParameterNameForErrorMessage(targetParameter),
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(targetParameter.Method),
                                     sourceGenericParameter.Name,
@@ -2740,14 +2743,16 @@ namespace ILCompiler.Dataflow
                                     missingMemberTypes));
                                 break;
                             case (GenericParameterOrigin sourceGenericParameter, MethodReturnOrigin targetMethodReturnType):
-                                reflectionContext.RecordUnrecognizedPattern(2088, string.Format(Resources.Strings.IL2088,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsMethodReturnType,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsMethodReturnType).GetMessage(
                                     DiagnosticUtilities.GetMethodSignatureDisplayName(targetMethodReturnType.Method),
                                     sourceGenericParameter.Name,
                                     DiagnosticUtilities.GetGenericParameterDeclaringMemberDisplayName(sourceGenericParameter),
                                     missingMemberTypes));
                                 break;
                             case (GenericParameterOrigin sourceGenericParameter, FieldOrigin targetField):
-                                reflectionContext.RecordUnrecognizedPattern(2089, string.Format(Resources.Strings.IL2089,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsField,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsField).GetMessage(
                                     targetField.GetDisplayName(),
                                     sourceGenericParameter.Name,
                                     DiagnosticUtilities.GetGenericParameterDeclaringMemberDisplayName(sourceGenericParameter),
@@ -2761,14 +2766,16 @@ namespace ILCompiler.Dataflow
                                 //    // This passes the T as the "this" parameter to Type.GetMethods()
                                 //    typeof(Type).GetMethod("GetMethods").Invoke(typeof(T), new object[] {});
                                 // }
-                                reflectionContext.RecordUnrecognizedPattern(2090, string.Format(Resources.Strings.IL2090,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsThisParameter,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsThisParameter).GetMessage(
                                     targetMethod.GetDisplayName(),
                                     sourceGenericParameter.Name,
                                     DiagnosticUtilities.GetGenericParameterDeclaringMemberDisplayName(sourceGenericParameter),
                                     missingMemberTypes));
                                 break;
                             case (GenericParameterOrigin sourceGenericParameter, GenericParameterOrigin targetGenericParameter):
-                                reflectionContext.RecordUnrecognizedPattern(2091, string.Format(Resources.Strings.IL2091,
+                                reflectionContext.RecordUnrecognizedPattern((int)DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsGenericParameter,
+                                    new DiagnosticString(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsGenericParameter).GetMessage(
                                     targetGenericParameter.Name,
                                     DiagnosticUtilities.GetGenericParameterDeclaringMemberDisplayName(targetGenericParameter),
                                     sourceGenericParameter.Name,
@@ -3057,8 +3064,8 @@ namespace ILCompiler.Dataflow
             if (!AnalyzeGenericInstantiationTypeArray(genericParametersArray, ref reflectionContext, reflectionMethod, genericMethod.GetMethodDefinition().Instantiation))
             {
                 reflectionContext.RecordUnrecognizedPattern(
-                    2060,
-                    string.Format(Resources.Strings.IL2060, DiagnosticUtilities.GetMethodSignatureDisplayName(reflectionMethod)));
+                    (int)DiagnosticId.MakeGenericMethodCannotBeStaticallyAnalyzed,
+                    new DiagnosticString(DiagnosticId.MakeGenericMethodCannotBeStaticallyAnalyzed).GetMessage(DiagnosticUtilities.GetMethodSignatureDisplayName(reflectionMethod)));
             }
             else
             {
@@ -3103,49 +3110,5 @@ namespace ILCompiler.Dataflow
             GetDynamicallyAccessedMemberTypesFromBindingFlagsForMethods(bindingFlags) |
             GetDynamicallyAccessedMemberTypesFromBindingFlagsForProperties(bindingFlags) |
             GetDynamicallyAccessedMemberTypesFromBindingFlagsForNestedTypes(bindingFlags);
-
-        private static class Resources
-        {
-            public static class Strings
-            {
-                public const string IL2060 = "Call to '{0}' can not be statically analyzed. It's not possible to guarantee the availability of requirements of the generic method.";
-                public const string IL2067 = "'{0}' argument does not satisfy {4} in call to '{1}'. The parameter '{2}' of method '{3}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2068 = "'{0}' method return value does not satisfy {3} requirements. The parameter '{1}' of method '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2069 = "value stored in field '{0}' does not satisfy {3} requirements. The parameter '{1}' of method '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2070 = "'this' argument does not satisfy {3} in call to '{0}'. The parameter '{1}' of method '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2071 = "'{0}' generic argument does not satisfy {4} in '{1}'. The parameter '{2}' of method '{3}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2072 = "'{0}' argument does not satisfy {3} in call to '{1}'. The return value of method '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2073 = "'{0}' method return value does not satisfy {2} requirements. The return value of method '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2074 = "value stored in field '{0}' does not satisfy {2} requirements. The return value of method '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2075 = "'this' argument does not satisfy {2} in call to '{0}'. The return value of method '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2076 = "'{0}' generic argument does not satisfy {3} in '{1}'. The return value of method '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2077 = "'{0}' argument does not satisfy {3} in call to '{1}'. The field '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2078 = "'{0}' method return value does not satisfy {2} requirements. The field '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2079 = "value stored in field '{0}' does not satisfy {2} requirements. The field '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2080 = "'this' argument does not satisfy {2} in call to '{0}'. The field '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2081 = "'{0}' generic argument does not satisfy {3} in '{1}'. The field '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2082 = "'{0}' argument does not satisfy {3} in call to '{1}'. The implicit 'this' argument of method '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2083 = "'{0}' method return value does not satisfy {2} requirements. The implicit 'this' argument of method '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2084 = "value stored in field '{0}' does not satisfy {2} requirements. The implicit 'this' argument of method '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2085 = "'this' argument does not satisfy {2} in call to '{0}'. The implicit 'this' argument of method '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2086 = "'{0}' generic argument does not satisfy {3} in '{1}'. The implicit 'this' argument of method '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2087 = "'{0}' argument does not satisfy {4} in call to '{1}'. The generic parameter '{2}' of '{3}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2088 = "'{0}' method return value does not satisfy {3} requirements. The generic parameter '{1}' of '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2089 = "value stored in field '{0}' does not satisfy {3} requirements. The generic parameter '{1}' of '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2090 = "'this' argument does not satisfy {3} in call to '{0}'. The generic parameter '{1}' of '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2091 = "'{0}' generic argument does not satisfy {4} in '{1}'. The generic parameter '{2}' of '{3}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.";
-                public const string IL2103 = "Value passed to the '{0}' parameter of method '{1}' cannot be statically determined as a property accessor.";
-
-                // Error codes > 6000 are reserved for custom steps and illink doesn't claim ownership of them
-
-
-                public const string IL3050 = "Using member '{0}' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling.";
-                // IL3051 - mismatched RequiresDynamicCode on virtuals
-                // TODO: these are all unique to NativeAOT - mono/linker repo is not aware this error code is used.
-                // IL3052 - COM
-                // IL3053 - AOT analysis warnings
-                // IL3054 - Generic cycle
-            }
-        }
     }
 }
index c37b562..3273d2c 100644 (file)
     <Compile Include="Compiler\DependencyAnalysis\CallingConventionConverterKey.cs" />
     <Compile Include="Compiler\DependencyAnalysis\CodeBasedDependencyAlgorithm.cs" />
     <Compile Include="Compiler\DependencyAnalysis\DelegateMarshallingStubMapNode.cs" />
-    <Compile Include="Compiler\DependencyAnalysis\StructMarshallingStubMapNode.cs" />    
+    <Compile Include="Compiler\DependencyAnalysis\StructMarshallingStubMapNode.cs" />
     <Compile Include="Compiler\DependencyAnalysis\GenericVirtualMethodTableNode.cs" />
     <Compile Include="Compiler\DependencyAnalysis\InterfaceGenericVirtualMethodTableNode.cs" />
     <Compile Include="Compiler\DependencyAnalysis\IObjectDumper.cs" />
       <Link>Pgo\PgoFormat.cs</Link>
     </Compile>
   </ItemGroup>
+
+  <ItemGroup>
+    <Compile Update="Resources\Strings.Designer.cs">
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Strings.resx</DependentUpon>
+    </Compile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <EmbeddedResource Update="Resources\Strings.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Strings.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+  </ItemGroup>
+
+  <Import Project="..\ILLink.Shared\ILLink.Shared.projitems" Label="Shared" />
 </Project>
diff --git a/src/coreclr/tools/aot/ILLink.Shared/DiagnosticCategory.cs b/src/coreclr/tools/aot/ILLink.Shared/DiagnosticCategory.cs
new file mode 100644 (file)
index 0000000..427c7fa
--- /dev/null
@@ -0,0 +1,12 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace ILLink.Shared
+{
+    internal static class DiagnosticCategory
+    {
+        public const string SingleFile = nameof(SingleFile);
+        public const string Trimming = nameof(Trimming);
+        public const string AOT = nameof(AOT);
+    }
+}
diff --git a/src/coreclr/tools/aot/ILLink.Shared/DiagnosticId.cs b/src/coreclr/tools/aot/ILLink.Shared/DiagnosticId.cs
new file mode 100644 (file)
index 0000000..429644f
--- /dev/null
@@ -0,0 +1,65 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace ILLink.Shared
+{
+    public enum DiagnosticId
+    {
+        // Linker diagnostic ids.
+        RequiresUnreferencedCode = 2026,
+        RequiresUnreferencedCodeAttributeMismatch = 2046,
+        CorrectnessOfCOMCannotBeGuaranteed = 2050,
+        MakeGenericType = 2055,
+        MakeGenericMethod = 2060,
+        RequiresOnBaseClass = 2109,
+        RequiresUnreferencedCodeOnStaticConstructor = 2116,
+
+        // Dynamically Accessed Members attribute mismatch.
+        MakeGenericMethodCannotBeStaticallyAnalyzed = 2060,
+        DynamicallyAccessedMembersMismatchParameterTargetsParameter = 2067,
+        DynamicallyAccessedMembersMismatchParameterTargetsMethodReturnType = 2068,
+        DynamicallyAccessedMembersMismatchParameterTargetsField = 2069,
+        DynamicallyAccessedMembersMismatchParameterTargetsThisParameter = 2070,
+        DynamicallyAccessedMembersMismatchParameterTargetsGenericParameter = 2071,
+        DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter = 2072,
+        DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsMethodReturnType = 2073,
+        DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsField = 2074,
+        DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter = 2075,
+        DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsGenericParameter = 2076,
+        DynamicallyAccessedMembersMismatchFieldTargetsParameter = 2077,
+        DynamicallyAccessedMembersMismatchFieldTargetsMethodReturnType = 2078,
+        DynamicallyAccessedMembersMismatchFieldTargetsField = 2079,
+        DynamicallyAccessedMembersMismatchFieldTargetsThisParameter = 2080,
+        DynamicallyAccessedMembersMismatchFieldTargetsGenericParameter = 2081,
+        DynamicallyAccessedMembersMismatchThisParameterTargetsParameter = 2082,
+        DynamicallyAccessedMembersMismatchThisParameterTargetsMethodReturnType = 2083,
+        DynamicallyAccessedMembersMismatchThisParameterTargetsField = 2084,
+        DynamicallyAccessedMembersMismatchThisParameterTargetsThisParameter = 2085,
+        DynamicallyAccessedMembersMismatchThisParameterTargetsGenericParameter = 2086,
+        DynamicallyAccessedMembersMismatchTypeArgumentTargetsParameter = 2087,
+        DynamicallyAccessedMembersMismatchTypeArgumentTargetsMethodReturnType = 2088,
+        DynamicallyAccessedMembersMismatchTypeArgumentTargetsField = 2089,
+        DynamicallyAccessedMembersMismatchTypeArgumentTargetsThisParameter = 2090,
+        DynamicallyAccessedMembersMismatchTypeArgumentTargetsGenericParameter = 2091,
+        PropertyAccessorParameterInLinqExpressionsCannotBeStaticallyDetermined = 2103,
+
+        // Single-file diagnostic ids.
+        AvoidAssemblyLocationInSingleFile = 3000,
+        AvoidAssemblyGetFilesInSingleFile = 3001,
+        RequiresAssemblyFiles = 3002,
+        RequiresAssemblyFilesAttributeMismatch = 3003,
+
+        // Dynamic code diagnostic ids.
+        RequiresDynamicCode = 3050,
+        RequiresDynamicCodeAttributeMismatch = 3051
+        // TODO: these are all unique to NativeAOT - mono/linker repo is not aware these error codes usage.
+        // IL3052 - COM
+        // IL3053 - AOT analysis warnings
+        // IL3054 - Generic cycle
+    }
+
+    public static class DiagnosticIdExtensions
+    {
+        public static string AsString(this DiagnosticId diagnosticId) => $"IL{(int)diagnosticId}";
+    }
+}
diff --git a/src/coreclr/tools/aot/ILLink.Shared/DiagnosticString.cs b/src/coreclr/tools/aot/ILLink.Shared/DiagnosticString.cs
new file mode 100644 (file)
index 0000000..103b93e
--- /dev/null
@@ -0,0 +1,35 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace ILLink.Shared
+{
+    public readonly struct DiagnosticString
+    {
+        readonly string _titleFormat;
+        readonly string _messageFormat;
+
+        public DiagnosticString(DiagnosticId diagnosticId)
+        {
+            var resourceManager = SharedStrings.ResourceManager;
+            _titleFormat = resourceManager.GetString($"{diagnosticId}Title") ?? string.Empty;
+            _messageFormat = resourceManager.GetString($"{diagnosticId}Message") ?? string.Empty;
+        }
+
+        public DiagnosticString(string diagnosticResourceStringName)
+        {
+            var resourceManager = SharedStrings.ResourceManager;
+            _titleFormat = resourceManager.GetString($"{diagnosticResourceStringName}Title") ?? string.Empty;
+            _messageFormat = resourceManager.GetString($"{diagnosticResourceStringName}Message") ?? string.Empty;
+        }
+
+        public string GetMessage(params string[] args) =>
+            string.Format(_messageFormat, args);
+
+        public string GetMessageFormat() => _messageFormat;
+
+        public string GetTitle(params string[] args) =>
+            string.Format(_titleFormat, args);
+
+        public string GetTitleFormat() => _titleFormat;
+    }
+}
diff --git a/src/coreclr/tools/aot/ILLink.Shared/ILLink.Shared.projitems b/src/coreclr/tools/aot/ILLink.Shared/ILLink.Shared.projitems
new file mode 100644 (file)
index 0000000..0a61390
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
+    <HasSharedItems>true</HasSharedItems>
+    <SharedGUID>ff598e93-8e9e-4091-9f50-61a7572663ae</SharedGUID>
+  </PropertyGroup>
+  <PropertyGroup Label="Configuration">
+    <Import_RootNamespace>ILLink.Shared</Import_RootNamespace>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="$(MSBuildThisFileDirectory)DiagnosticCategory.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)DiagnosticId.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)DiagnosticString.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)MessageFormat.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="$(MSBuildThisFileDirectory)SharedStrings.resx">
+      <GenerateSource>true</GenerateSource>
+      <Namespace>ILLink.Shared</Namespace>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/src/coreclr/tools/aot/ILLink.Shared/ILLink.Shared.shproj b/src/coreclr/tools/aot/ILLink.Shared/ILLink.Shared.shproj
new file mode 100644 (file)
index 0000000..d632a98
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>ff598e93-8e9e-4091-9f50-61a7572663ae</ProjectGuid>
+    <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
+  </PropertyGroup>
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
+  <PropertyGroup />
+  <Import Project="ILLink.Shared.projitems" Label="Shared" />
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
+</Project>
diff --git a/src/coreclr/tools/aot/ILLink.Shared/MessageFormat.cs b/src/coreclr/tools/aot/ILLink.Shared/MessageFormat.cs
new file mode 100644 (file)
index 0000000..755279e
--- /dev/null
@@ -0,0 +1,39 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#nullable enable
+
+namespace ILLink.Shared
+{
+    internal static class MessageFormat
+    {
+        public static string FormatRequiresAttributeMessageArg(string? message)
+        {
+            if (!string.IsNullOrEmpty(message))
+                return $" {message}{(message!.TrimEnd().EndsWith(".") ? "" : ".")}";
+
+            return string.Empty;
+        }
+
+        public static string FormatRequiresAttributeUrlArg(string? url)
+        {
+            if (!string.IsNullOrEmpty(url))
+                return $" {url}";
+
+            return string.Empty;
+        }
+
+        public static string FormatRequiresAttributeMismatch(bool memberHasAttribute, bool isInterface, params object[] args)
+        {
+            string format = (memberHasAttribute, isInterface) switch
+            {
+                (false, true) => SharedStrings.InterfaceRequiresMismatchMessage,
+                (true, true) => SharedStrings.ImplementationRequiresMismatchMessage,
+                (false, false) => SharedStrings.BaseRequiresMismatchMessage,
+                (true, false) => SharedStrings.DerivedRequiresMismatchMessage
+            };
+
+            return string.Format(format, args);
+        }
+    }
+}
diff --git a/src/coreclr/tools/aot/ILLink.Shared/SharedStrings.resx b/src/coreclr/tools/aot/ILLink.Shared/SharedStrings.resx
new file mode 100644 (file)
index 0000000..15749c7
--- /dev/null
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <data name="RequiresUnreferencedCodeTitle" xml:space="preserve">
+    <value>Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code</value>
+  </data>
+  <data name="RequiresUnreferencedCodeMessage" xml:space="preserve">
+    <value>Using member '{0}' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code.{1}{2}</value>
+  </data>
+  <data name="AvoidAssemblyLocationInSingleFileTitle" xml:space="preserve">
+    <value>Avoid accessing Assembly file path when publishing as a single file</value>
+  </data>
+  <data name="AvoidAssemblyLocationInSingleFileMessage" xml:space="preserve">
+    <value>'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</value>
+  </data>
+  <data name="AvoidAssemblyGetFilesInSingleFileTitle" xml:space="preserve">
+    <value>Avoid accessing Assembly file path when publishing as a single file</value>
+  </data>
+  <data name="AvoidAssemblyGetFilesInSingleFileMessage" xml:space="preserve">
+    <value>'{0}' will throw for assemblies embedded in a single-file app</value>
+  </data>
+  <data name="RequiresAssemblyFilesTitle" xml:space="preserve">
+    <value>Avoid calling members marked with 'RequiresAssemblyFilesAttribute' when publishing as a single-file</value>
+  </data>
+  <data name="RequiresAssemblyFilesMessage" xml:space="preserve">
+    <value>Using member '{0}' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app.{1}{2}</value>
+  </data>
+  <data name="RequiresDynamicCodeTitle" xml:space="preserve">
+    <value>Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.</value>
+  </data>
+  <data name="RequiresDynamicCodeMessage" xml:space="preserve">
+    <value>Using member '{0}' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling.{1}{2}</value>
+  </data>
+  <data name="RequiresUnreferencedCodeAttributeMismatchMessage" xml:space="preserve">
+    <value>{0}. 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.</value>
+  </data>
+  <data name="RequiresUnreferencedCodeAttributeMismatchTitle" xml:space="preserve">
+    <value>'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.</value>
+  </data>
+  <data name="RequiresDynamicCodeAttributeMismatchMessage" xml:space="preserve">
+    <value>{0}. 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.</value>
+  </data>
+  <data name="RequiresDynamicCodeAttributeMismatchTitle" xml:space="preserve">
+    <value>'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.</value>
+  </data>
+  <data name="RequiresAssemblyFilesAttributeMismatchMessage" xml:space="preserve">
+    <value>{0}. 'RequiresAssemblyFilesAttribute' annotations must match across all interface implementations or overrides.</value>
+  </data>
+  <data name="RequiresAssemblyFilesAttributeMismatchTitle" xml:space="preserve">
+    <value>'RequiresAssemblyFilesAttribute' annotations must match across all interface implementations or overrides.</value>
+  </data>
+  <data name="BaseRequiresMismatchMessage" xml:space="preserve">
+    <value>Base member '{2}' with '{0}' has a derived member '{1}' without '{0}'</value>
+  </data>
+  <data name="DerivedRequiresMismatchMessage" xml:space="preserve">
+    <value>Member '{1}' with '{0}' overrides base member '{2}' without '{0}'</value>
+  </data>
+  <data name="ImplementationRequiresMismatchMessage" xml:space="preserve">
+    <value>Member '{1}' with '{0}' implements interface member '{2}' without '{0}'</value>
+  </data>
+  <data name="InterfaceRequiresMismatchMessage" xml:space="preserve">
+    <value>Interface member '{2}' with '{0}' has an implementation member '{1}' without '{0}'</value>
+  </data>
+  <data name="RequiresOnBaseClassMessage" xml:space="preserve">
+    <value>Type '{0}' derives from '{1}' which has 'RequiresUnreferencedCodeAttribute'. {2}{3}</value>
+  </data>
+  <data name="RequiresOnBaseClassTitle" xml:space="preserve">
+    <value>Types that derive from a base class with 'RequiresUnreferencedCodeAttribute' need to explicitly use the 'RequiresUnreferencedCodeAttribute' or suppress this warning</value>
+  </data>
+  <data name="DynamicTypeInvocationMessage" xml:space="preserve">
+    <value>Invoking members on dynamic types is not trimming-compatible. Types or members might have been removed by the trimmer.</value>
+  </data>
+  <data name="DynamicTypeInvocationTitle" xml:space="preserve">
+    <value>Using dynamic types might cause types or members to be removed by trimmer.</value>
+  </data>
+  <data name="MakeGenericMethodMessage" xml:space="preserve">
+    <value>Call to '{0}' can not be statically analyzed. It's not possible to guarantee the availability of requirements of the generic method.</value>
+  </data>
+  <data name="MakeGenericTypeMessage" xml:space="preserve">
+    <value>Call to '{0}' can not be statically analyzed. It's not possible to guarantee the availability of requirements of the generic type.</value>
+  </data>
+  <data name="RequiresUnreferencedCodeOnStaticConstructorMessage" xml:space="preserve">
+    <value>'RequiresUnreferencedCodeAttribute' cannot be placed directly on static constructor '{0}', consider placing 'RequiresUnreferencedCodeAttribute' on the type declaration instead.</value>
+  </data>
+  <data name="RequiresUnreferencedCodeOnStaticConstructorTitle" xml:space="preserve">
+    <value>The use of 'RequiresUnreferencedCodeAttribute' on static constructors is disallowed since is a method not callable by the user, is only called by the runtime. Placing the attribute directly on the static constructor will have no effect, instead use 'RequiresUnreferencedCodeAttribute' on the type which will handle warning and silencing from the static constructor.</value>
+  </data>
+  <data name="MakeGenericMethodCannotBeStaticallyAnalyzedMessage" xml:space="preserve">
+    <value>Call to '{0}' can not be statically analyzed. It's not possible to guarantee the availability of requirements of the generic method.</value>
+  </data>
+  <data name="PropertyAccessorParameterInLinqExpressionsCannotBeStaticallyDeterminedMessage" xml:space="preserve">
+    <value>Value passed to the '{0}' parameter of method '{1}' cannot be statically determined as a property accessor.</value>
+  </data>
+  <data name="CorrectnessOfCOMCannotBeGuaranteedMessage" xml:space="preserve">
+    <value>P/invoke method '{0}' declares a parameter with COM marshalling. Correctness of COM interop cannot be guaranteed after trimming. Interfaces and interface members might be removed.</value>
+  </data>
+</root>
index 25fc174..2254764 100644 (file)
@@ -1,6 +1,6 @@
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29123.88
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31814.306
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILCompiler", "ILCompiler\ILCompiler.csproj", "{6856F5F6-E568-493F-AF8A-7F624B5A02A5}"
 EndProject
@@ -16,7 +16,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILCompiler.Compiler", "ILCo
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "repro", "ILCompiler\repro\repro.csproj", "{CBDE0470-E0C9-4693-9A11-ACC117522F3F}"
 EndProject
+Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ILLink.Shared", "ILLink.Shared\ILLink.Shared.shproj", "{FF598E93-8E9E-4091-9F50-61A7572663AE}"
+EndProject
 Global
+       GlobalSection(SharedMSBuildProjectFiles) = preSolution
+               ILLink.Shared\ILLink.Shared.projitems*{ff598e93-8e9e-4091-9f50-61a7572663ae}*SharedItemsImports = 13
+               ILLink.Shared\ILLink.Shared.projitems*{ffbd9619-de6f-4a98-8732-8a14ec3c1a18}*SharedItemsImports = 5
+       EndGlobalSection
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Checked|Any CPU = Checked|Any CPU
                Checked|x64 = Checked|x64