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;
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;
}
--- /dev/null
+// 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);
+ }
+}
// 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;
using System.Reflection;
using Mono.Cecil;
-#nullable enable
-
namespace Mono.Linker
{
// Temporary workaround - should be removed once linker can be upgraded to build against
// 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;
using Mono.Cecil;
using Mono.Cecil.Cil;
-#nullable enable
-
namespace Mono.Linker.Dataflow
{
class FlowAnnotations
{
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);
// 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;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
-#nullable enable
-
namespace Mono.Linker.Dataflow
{
/// <summary>
-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.
// 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;
using BindingFlags = System.Reflection.BindingFlags;
-#nullable enable
-
namespace Mono.Linker.Dataflow
{
class ReflectionMethodBodyScanner : MethodBodyScanner
// 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;
}
}
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 ();
// 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++)
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
} 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.
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> ();
// 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;
#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 (
bool reportingEnabled,
in MessageOrigin origin,
IMetadataTokenProvider memberWithRequirements,
- Instruction instruction = null)
+ Instruction? instruction = null)
{
_context = context;
ReportingEnabled = reportingEnabled;
// 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;
// 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;
using GenericParameter = Mono.Cecil.GenericParameter;
using TypeDefinition = Mono.Cecil.TypeDefinition;
-#nullable enable
-
namespace Mono.Linker.Dataflow
{
public enum ValueNodeKind
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
+using ILLink.Shared;
using Internal.IL;
using Internal.TypeSystem;
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()));
}
}
{
// 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()));
}
}
// 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(
// 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(
// 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)));
}
// 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)));
}
}
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);
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
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),
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),
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),
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),
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(),
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(),
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,
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),
// // 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,
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
{
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
- }
- }
}
}
<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>
--- /dev/null
+// 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);
+ }
+}
--- /dev/null
+// 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}";
+ }
+}
--- /dev/null
+// 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;
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' < '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
--- /dev/null
+<?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>
--- /dev/null
+// 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);
+ }
+ }
+}
--- /dev/null
+<?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>
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
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