Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSven Boemer <sbomer@gmail.com>2021-10-19 21:42:12 +0300
committerGitHub <noreply@github.com>2021-10-19 21:42:12 +0300
commit4c9de67922b2381aed29c6dff2c892ff6467f114 (patch)
tree6ba7c46cab304cae9a2a2107b3e0b050b16613f7 /src
parentc75a5240bd253e2e407438cbaa14c9d1bf714343 (diff)
Nullable annotations part 4 (final) (#2300)
* Nullable annotations part 4 (final) * PR feedback - Clean up extra variables introduced as nullable versions of existing variables. * Fix a few annotations - TryGetMethodStubValue may return null when true - GetReturnType and GetParameterType may return null in some cases * More annotations and PR feedback - Don't resolve a generic typeref that should already be a typedef - Remove some redundant null checks - Turn on nullable annotations for ref assembly - Remove #nullable disable section * Clean up GetInflatedDeclaringType - Remove null check - Replace TryResolve call with an assert - Add comment and asserts justifying null-forgiving operator * Replace exception with assert in accessors * PR feedback - Add parens to improve readability - Throw on diagnostic without message - Remove unnecessary string.empty * Undo DiagnosticString change - Some DiagnosticIds intentionally have no fixed format strings because we generate different strings in different circumstances.
Diffstat (limited to 'src')
-rw-r--r--src/ILLink.Shared/DiagnosticString.cs12
-rw-r--r--src/ILLink.Shared/MessageFormat.cs4
-rw-r--r--src/linker/Linker.Dataflow/DiagnosticUtilities.cs5
-rw-r--r--src/linker/Linker.Dataflow/DynamicallyAccessedMembersBinder.cs2
-rw-r--r--src/linker/Linker.Dataflow/DynamicallyAccessedMembersTypeHierarchy.cs4
-rw-r--r--src/linker/Linker.Dataflow/FlowAnnotations.cs10
-rw-r--r--src/linker/Linker.Dataflow/MethodBodyScanner.cs2
-rw-r--r--src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs25
-rw-r--r--src/linker/Linker.Dataflow/ReflectionPatternContext.cs6
-rw-r--r--src/linker/Linker.Dataflow/ValueNode.cs2
-rw-r--r--src/linker/Linker.Steps/AddBypassNGenStep.cs10
-rw-r--r--src/linker/Linker.Steps/BaseStep.cs14
-rw-r--r--src/linker/Linker.Steps/BaseSubStep.cs12
-rw-r--r--src/linker/Linker.Steps/BodySubstitutionParser.cs4
-rw-r--r--src/linker/Linker.Steps/CleanStep.cs2
-rw-r--r--src/linker/Linker.Steps/CodeRewriterStep.cs27
-rw-r--r--src/linker/Linker.Steps/DescriptorMarker.cs2
-rw-r--r--src/linker/Linker.Steps/DiscoverCustomOperatorsHandler.cs30
-rw-r--r--src/linker/Linker.Steps/DiscoverSerializationHandler.cs21
-rw-r--r--src/linker/Linker.Steps/LinkAttributesParser.cs12
-rw-r--r--src/linker/Linker.Steps/MarkScopeStack.cs4
-rw-r--r--src/linker/Linker.Steps/MarkStep.cs586
-rw-r--r--src/linker/Linker.Steps/MarkSubStepsDispatcher.cs73
-rw-r--r--src/linker/Linker.Steps/OutputStep.cs2
-rw-r--r--src/linker/Linker.Steps/ProcessLinkerXmlBase.cs4
-rw-r--r--src/linker/Linker.Steps/ReflectionBlockedStep.cs14
-rw-r--r--src/linker/Linker.Steps/RootAssemblyInputStep.cs8
-rw-r--r--src/linker/Linker.Steps/SealerStep.cs8
-rw-r--r--src/linker/Linker.Steps/SubStepsDispatcher.cs83
-rw-r--r--src/linker/Linker.Steps/SweepStep.cs18
-rw-r--r--src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs95
-rw-r--r--src/linker/Linker/Annotations.cs11
-rw-r--r--src/linker/Linker/ArrayBuilder.cs2
-rw-r--r--src/linker/Linker/AssemblyDefinitionExtensions.cs2
-rw-r--r--src/linker/Linker/AssemblyResolver.cs18
-rw-r--r--src/linker/Linker/BCL.cs4
-rw-r--r--src/linker/Linker/CompilerGeneratedState.cs8
-rw-r--r--src/linker/Linker/CustomAttributeSource.cs7
-rw-r--r--src/linker/Linker/DependencyInfo.cs6
-rw-r--r--src/linker/Linker/DocumentationSignatureGenerator.PartVisitor.cs5
-rw-r--r--src/linker/Linker/DocumentationSignatureGenerator.cs10
-rw-r--r--src/linker/Linker/DocumentationSignatureParser.cs2
-rw-r--r--src/linker/Linker/Driver.cs159
-rw-r--r--src/linker/Linker/DynamicDependency.cs2
-rw-r--r--src/linker/Linker/EmbeddedXmlInfo.cs12
-rw-r--r--src/linker/Linker/IReflectionPatternRecorder.cs4
-rw-r--r--src/linker/Linker/KnownMembers.cs8
-rw-r--r--src/linker/Linker/LinkContext.cs26
-rw-r--r--src/linker/Linker/LinkerAttributesInformation.cs12
-rw-r--r--src/linker/Linker/LinkerILProcessor.cs12
-rw-r--r--src/linker/Linker/LoggingReflectionPatternRecorder.cs4
-rw-r--r--src/linker/Linker/MarkingHelpers.cs4
-rw-r--r--src/linker/Linker/MemberActionStore.cs11
-rw-r--r--src/linker/Linker/MessageContainer.cs2
-rw-r--r--src/linker/Linker/MessageOrigin.cs35
-rw-r--r--src/linker/Linker/MethodBodyScanner.cs14
-rw-r--r--src/linker/Linker/MethodDefinitionExtensions.cs32
-rw-r--r--src/linker/Linker/MethodReferenceExtensions.cs4
-rw-r--r--src/linker/Linker/ModuleDefinitionExtensions.cs10
-rw-r--r--src/linker/Linker/OverrideInformation.cs6
-rw-r--r--src/linker/Linker/PInvokeInfo.cs10
-rw-r--r--src/linker/Linker/SerializationMarker.cs6
-rw-r--r--src/linker/Linker/SubstitutionInfo.cs2
-rw-r--r--src/linker/Linker/Tracer.cs4
-rw-r--r--src/linker/Linker/TypeHierarchyCache.cs2
-rw-r--r--src/linker/Linker/TypeMapInfo.cs46
-rw-r--r--src/linker/Linker/TypeNameResolver.cs41
-rw-r--r--src/linker/Linker/TypeReferenceExtensions.cs36
-rw-r--r--src/linker/Linker/TypeReferenceWalker.cs2
-rw-r--r--src/linker/Linker/UnconditionalSuppressMessageAttributeState.cs42
-rw-r--r--src/linker/Linker/WarningSuppressionWriter.cs5
-rw-r--r--src/linker/Linker/XmlDependencyRecorder.cs20
-rw-r--r--src/linker/Mono.Linker.csproj1
73 files changed, 957 insertions, 793 deletions
diff --git a/src/ILLink.Shared/DiagnosticString.cs b/src/ILLink.Shared/DiagnosticString.cs
index ba7599c2d..e01cc9b5b 100644
--- a/src/ILLink.Shared/DiagnosticString.cs
+++ b/src/ILLink.Shared/DiagnosticString.cs
@@ -1,4 +1,6 @@
-namespace ILLink.Shared
+using System;
+
+namespace ILLink.Shared
{
public readonly struct DiagnosticString
{
@@ -8,15 +10,15 @@
public DiagnosticString (DiagnosticId diagnosticId)
{
var resourceManager = SharedStrings.ResourceManager;
- _titleFormat = resourceManager.GetString ($"{diagnosticId}Title");
- _messageFormat = resourceManager.GetString ($"{diagnosticId}Message");
+ _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");
- _messageFormat = resourceManager.GetString ($"{diagnosticResourceStringName}Message");
+ _titleFormat = resourceManager.GetString ($"{diagnosticResourceStringName}Title") ?? string.Empty;
+ _messageFormat = resourceManager.GetString ($"{diagnosticResourceStringName}Message") ?? string.Empty;
}
public string GetMessage (params string[] args) =>
diff --git a/src/ILLink.Shared/MessageFormat.cs b/src/ILLink.Shared/MessageFormat.cs
index e8ae020f7..58ac52d14 100644
--- a/src/ILLink.Shared/MessageFormat.cs
+++ b/src/ILLink.Shared/MessageFormat.cs
@@ -1,6 +1,4 @@
-#nullable enable
-
-namespace ILLink.Shared
+namespace ILLink.Shared
{
internal static class MessageFormat
{
diff --git a/src/linker/Linker.Dataflow/DiagnosticUtilities.cs b/src/linker/Linker.Dataflow/DiagnosticUtilities.cs
index 4651bb7da..9aef3fde6 100644
--- a/src/linker/Linker.Dataflow/DiagnosticUtilities.cs
+++ b/src/linker/Linker.Dataflow/DiagnosticUtilities.cs
@@ -1,6 +1,7 @@
// 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
@@ -21,7 +22,7 @@ namespace Mono.Linker.Dataflow
if (declaredParameterIndex >= 0 && declaredParameterIndex < method.Parameters.Count)
return method.Parameters[declaredParameterIndex];
- return null;
+ throw new InvalidOperationException ();
}
internal static string GetParameterNameForErrorMessage (ParameterDefinition parameterDefinition) =>
@@ -33,6 +34,6 @@ namespace Mono.Linker.Dataflow
genericParameter.DeclaringType.GetDisplayName ();
internal static string GetMethodSignatureDisplayName (IMethodSignature methodSignature) =>
- (methodSignature is MethodReference method) ? method.GetDisplayName () : methodSignature.ToString ();
+ (methodSignature is MethodReference method) ? method.GetDisplayName () : (methodSignature.ToString () ?? string.Empty);
}
}
diff --git a/src/linker/Linker.Dataflow/DynamicallyAccessedMembersBinder.cs b/src/linker/Linker.Dataflow/DynamicallyAccessedMembersBinder.cs
index 66b6d17e2..b44dd1cd1 100644
--- a/src/linker/Linker.Dataflow/DynamicallyAccessedMembersBinder.cs
+++ b/src/linker/Linker.Dataflow/DynamicallyAccessedMembersBinder.cs
@@ -7,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
diff --git a/src/linker/Linker.Dataflow/DynamicallyAccessedMembersTypeHierarchy.cs b/src/linker/Linker.Dataflow/DynamicallyAccessedMembersTypeHierarchy.cs
index 2658d7435..f75825871 100644
--- a/src/linker/Linker.Dataflow/DynamicallyAccessedMembersTypeHierarchy.cs
+++ b/src/linker/Linker.Dataflow/DynamicallyAccessedMembersTypeHierarchy.cs
@@ -65,7 +65,7 @@ namespace Mono.Linker.Dataflow
// Base should already be marked (since we're marking its derived type now)
// so we should already have its cached values filled.
- TypeDefinition baseType = _context.TryResolve (type.BaseType);
+ TypeDefinition? baseType = _context.TryResolve (type.BaseType);
Debug.Assert (baseType == null || _context.Annotations.IsMarked (baseType));
if (baseType != null && _typesInDynamicallyAccessedMembersHierarchy.TryGetValue (baseType, out var baseValue)) {
annotation |= baseValue.annotation;
@@ -195,7 +195,7 @@ namespace Mono.Linker.Dataflow
if (applied)
return true;
- TypeDefinition baseType = _context.TryResolve (type.BaseType);
+ TypeDefinition? baseType = _context.TryResolve (type.BaseType);
if (baseType != null)
applied = ApplyDynamicallyAccessedMembersToTypeHierarchyInner (reflectionMethodBodyScanner, baseType);
diff --git a/src/linker/Linker.Dataflow/FlowAnnotations.cs b/src/linker/Linker.Dataflow/FlowAnnotations.cs
index 839fed525..4f4a50dae 100644
--- a/src/linker/Linker.Dataflow/FlowAnnotations.cs
+++ b/src/linker/Linker.Dataflow/FlowAnnotations.cs
@@ -8,8 +8,6 @@ using System.Diagnostics.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
-#nullable enable
-
namespace Mono.Linker.Dataflow
{
class FlowAnnotations
@@ -588,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);
diff --git a/src/linker/Linker.Dataflow/MethodBodyScanner.cs b/src/linker/Linker.Dataflow/MethodBodyScanner.cs
index 84b0b9785..f3cce6d4b 100644
--- a/src/linker/Linker.Dataflow/MethodBodyScanner.cs
+++ b/src/linker/Linker.Dataflow/MethodBodyScanner.cs
@@ -8,8 +8,6 @@ using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
-#nullable enable
-
namespace Mono.Linker.Dataflow
{
/// <summary>
diff --git a/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs b/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs
index 8790e1663..a523de225 100644
--- a/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs
+++ b/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs
@@ -13,8 +13,6 @@ using Mono.Linker.Steps;
using BindingFlags = System.Reflection.BindingFlags;
-#nullable enable
-
namespace Mono.Linker.Dataflow
{
class ReflectionMethodBodyScanner : MethodBodyScanner
@@ -893,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;
}
@@ -1050,9 +1047,8 @@ 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 {
@@ -1199,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++)
@@ -1935,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
@@ -2231,9 +2227,8 @@ 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 {
@@ -2386,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> ();
diff --git a/src/linker/Linker.Dataflow/ReflectionPatternContext.cs b/src/linker/Linker.Dataflow/ReflectionPatternContext.cs
index fd2c11cab..1cd64ce43 100644
--- a/src/linker/Linker.Dataflow/ReflectionPatternContext.cs
+++ b/src/linker/Linker.Dataflow/ReflectionPatternContext.cs
@@ -25,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 (
@@ -35,7 +35,7 @@ namespace Mono.Linker.Dataflow
bool reportingEnabled,
in MessageOrigin origin,
IMetadataTokenProvider memberWithRequirements,
- Instruction instruction = null)
+ Instruction? instruction = null)
{
_context = context;
ReportingEnabled = reportingEnabled;
diff --git a/src/linker/Linker.Dataflow/ValueNode.cs b/src/linker/Linker.Dataflow/ValueNode.cs
index ce2887aff..5e3349db6 100644
--- a/src/linker/Linker.Dataflow/ValueNode.cs
+++ b/src/linker/Linker.Dataflow/ValueNode.cs
@@ -12,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
diff --git a/src/linker/Linker.Steps/AddBypassNGenStep.cs b/src/linker/Linker.Steps/AddBypassNGenStep.cs
index baf492fdd..bbe4e6507 100644
--- a/src/linker/Linker.Steps/AddBypassNGenStep.cs
+++ b/src/linker/Linker.Steps/AddBypassNGenStep.cs
@@ -4,6 +4,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Diagnostics;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
@@ -14,13 +15,15 @@ namespace Mono.Linker.Steps
public class AddBypassNGenStep : BaseStep
{
- AssemblyDefinition coreLibAssembly;
- CustomAttribute bypassNGenAttribute;
+ AssemblyDefinition? coreLibAssembly;
+ CustomAttribute? bypassNGenAttribute;
protected override void ProcessAssembly (AssemblyDefinition assembly)
{
if (Annotations.GetAction (assembly) == AssemblyAction.AddBypassNGen) {
coreLibAssembly = Context.Resolve (assembly.MainModule.TypeSystem.CoreLibrary);
+ if (coreLibAssembly == null)
+ return;
bypassNGenAttribute = null;
if (assembly == coreLibAssembly) {
EnsureBypassNGenAttribute (assembly.MainModule);
@@ -59,13 +62,14 @@ namespace Mono.Linker.Steps
private void EnsureBypassNGenAttribute (ModuleDefinition targetModule)
{
+ Debug.Assert (coreLibAssembly != null);
if (bypassNGenAttribute != null) {
return;
}
ModuleDefinition corelibMainModule = coreLibAssembly.MainModule;
TypeReference bypassNGenAttributeRef = new TypeReference ("System.Runtime", "BypassNGenAttribute", corelibMainModule, targetModule.TypeSystem.CoreLibrary);
TypeDefinition bypassNGenAttributeDef = corelibMainModule.MetadataResolver.Resolve (bypassNGenAttributeRef);
- MethodDefinition bypassNGenAttributeDefaultConstructor = null;
+ MethodDefinition? bypassNGenAttributeDefaultConstructor = null;
if (bypassNGenAttributeDef == null) {
// System.Runtime.BypassNGenAttribute is not found in corelib. Add it.
diff --git a/src/linker/Linker.Steps/BaseStep.cs b/src/linker/Linker.Steps/BaseStep.cs
index eabffedb7..cedd2e5de 100644
--- a/src/linker/Linker.Steps/BaseStep.cs
+++ b/src/linker/Linker.Steps/BaseStep.cs
@@ -27,6 +27,7 @@
//
using System;
+using System.Diagnostics;
using Mono.Cecil;
namespace Mono.Linker.Steps
@@ -35,21 +36,24 @@ namespace Mono.Linker.Steps
public abstract class BaseStep : IStep
{
- private LinkContext _context;
+ private LinkContext? _context;
public LinkContext Context {
- get { return _context; }
+ get {
+ Debug.Assert (_context != null);
+ return _context;
+ }
}
public AnnotationStore Annotations {
- get { return _context.Annotations; }
+ get { return Context.Annotations; }
}
public Tracer Tracer {
- get { return _context.Tracer; }
+ get { return Context.Tracer; }
}
- public MarkingHelpers MarkingHelpers => _context.MarkingHelpers;
+ public MarkingHelpers MarkingHelpers => Context.MarkingHelpers;
public void Process (LinkContext context)
{
diff --git a/src/linker/Linker.Steps/BaseSubStep.cs b/src/linker/Linker.Steps/BaseSubStep.cs
index 9a3aa250a..4826c7014 100644
--- a/src/linker/Linker.Steps/BaseSubStep.cs
+++ b/src/linker/Linker.Steps/BaseSubStep.cs
@@ -1,6 +1,8 @@
// 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 System.Diagnostics;
using Mono.Cecil;
namespace Mono.Linker.Steps
@@ -9,13 +11,19 @@ namespace Mono.Linker.Steps
{
protected AnnotationStore Annotations => Context.Annotations;
- protected LinkContext Context { get; private set; }
+ LinkContext? _context { get; set; }
+ protected LinkContext Context {
+ get {
+ Debug.Assert (_context != null);
+ return _context;
+ }
+ }
public abstract SubStepTargets Targets { get; }
public virtual void Initialize (LinkContext context)
{
- Context = context;
+ _context = context;
}
public virtual bool IsActiveFor (AssemblyDefinition assembly) => true;
diff --git a/src/linker/Linker.Steps/BodySubstitutionParser.cs b/src/linker/Linker.Steps/BodySubstitutionParser.cs
index f79b34da3..bccf3e093 100644
--- a/src/linker/Linker.Steps/BodySubstitutionParser.cs
+++ b/src/linker/Linker.Steps/BodySubstitutionParser.cs
@@ -5,8 +5,6 @@ using System.Linq;
using System.Xml.XPath;
using Mono.Cecil;
-#nullable enable
-
namespace Mono.Linker.Steps
{
public class BodySubstitutionParser : ProcessLinkerXmlBase
@@ -137,7 +135,7 @@ namespace Mono.Linker.Steps
continue;
}
- EmbeddedResource resource = assembly.FindEmbeddedResource (name);
+ EmbeddedResource? resource = assembly.FindEmbeddedResource (name);
if (resource == null) {
LogWarning ($"Could not find embedded resource '{name}' to remove in assembly '{assembly.Name.Name}'.", 2040, resourceNav);
continue;
diff --git a/src/linker/Linker.Steps/CleanStep.cs b/src/linker/Linker.Steps/CleanStep.cs
index 7285b7e5d..4736be28f 100644
--- a/src/linker/Linker.Steps/CleanStep.cs
+++ b/src/linker/Linker.Steps/CleanStep.cs
@@ -58,7 +58,7 @@ namespace Mono.Linker.Steps
CleanType (nested);
}
- static MethodDefinition CheckMethod (TypeDefinition type, MethodDefinition method)
+ static MethodDefinition? CheckMethod (TypeDefinition type, MethodDefinition method)
{
if (method == null)
return null;
diff --git a/src/linker/Linker.Steps/CodeRewriterStep.cs b/src/linker/Linker.Steps/CodeRewriterStep.cs
index 9b9f17010..93d2a933d 100644
--- a/src/linker/Linker.Steps/CodeRewriterStep.cs
+++ b/src/linker/Linker.Steps/CodeRewriterStep.cs
@@ -8,7 +8,13 @@ namespace Mono.Linker.Steps
{
public class CodeRewriterStep : BaseStep
{
- AssemblyDefinition assembly;
+ AssemblyDefinition? assembly;
+ AssemblyDefinition Assembly {
+ get {
+ Debug.Assert (assembly != null);
+ return assembly;
+ }
+ }
protected override void ProcessAssembly (AssemblyDefinition assembly)
{
@@ -47,7 +53,7 @@ namespace Mono.Linker.Steps
var method = new MethodDefinition (".cctor",
MethodAttributes.Static | MethodAttributes.Private | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.HideBySig,
- assembly.MainModule.TypeSystem.Void);
+ Assembly.MainModule.TypeSystem.Void);
type.Methods.Add (method);
@@ -76,7 +82,7 @@ namespace Mono.Linker.Steps
if (!Annotations.HasSubstitutedInit (field))
continue;
- Context.Annotations.TryGetFieldUserValue (field, out object value);
+ Context.Annotations.TryGetFieldUserValue (field, out object? value);
var valueInstr = CreateConstantResultInstruction (Context, field.FieldType, value);
if (valueInstr == null)
@@ -123,11 +129,11 @@ namespace Mono.Linker.Steps
{
var body = new MethodBody (method);
var il = body.GetLinkerILProcessor ();
- MethodReference ctor;
+ MethodReference? ctor;
// Makes the body verifiable
if (method.IsConstructor && !method.DeclaringType.IsValueType) {
- ctor = assembly.MainModule.ImportReference (Context.MarkedKnownMembers.ObjectCtor);
+ ctor = Assembly.MainModule.ImportReference (Context.MarkedKnownMembers.ObjectCtor);
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Call, ctor);
@@ -135,7 +141,7 @@ namespace Mono.Linker.Steps
// import the method into the current assembly
ctor = Context.MarkedKnownMembers.NotSupportedExceptionCtorString;
- ctor = assembly.MainModule.ImportReference (ctor);
+ ctor = Assembly.MainModule.ImportReference (ctor);
il.Emit (OpCodes.Ldstr, "Linked away");
il.Emit (OpCodes.Newobj, ctor);
@@ -161,7 +167,7 @@ namespace Mono.Linker.Steps
if (base_ctor == null)
throw new NotSupportedException ($"Cannot replace constructor for '{method.DeclaringType}' when no base default constructor exists");
- base_ctor = assembly.MainModule.ImportReference (base_ctor);
+ base_ctor = Assembly.MainModule.ImportReference (base_ctor);
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Call, base_ctor);
@@ -208,14 +214,15 @@ namespace Mono.Linker.Steps
throw new NotImplementedException (method.FullName);
}
- public static Instruction CreateConstantResultInstruction (LinkContext context, MethodDefinition method)
+ public static Instruction? CreateConstantResultInstruction (LinkContext context, MethodDefinition method)
{
- context.Annotations.TryGetMethodStubValue (method, out object value);
+ context.Annotations.TryGetMethodStubValue (method, out object? value);
return CreateConstantResultInstruction (context, method.ReturnType, value);
}
- public static Instruction CreateConstantResultInstruction (LinkContext context, TypeReference rtype, object value = null)
+ public static Instruction? CreateConstantResultInstruction (LinkContext context, TypeReference inputRtype, object? value = null)
{
+ TypeReference? rtype = inputRtype;
switch (rtype.MetadataType) {
case MetadataType.ValueType:
var definition = context.TryResolve (rtype);
diff --git a/src/linker/Linker.Steps/DescriptorMarker.cs b/src/linker/Linker.Steps/DescriptorMarker.cs
index 2930a5445..e99708f5e 100644
--- a/src/linker/Linker.Steps/DescriptorMarker.cs
+++ b/src/linker/Linker.Steps/DescriptorMarker.cs
@@ -9,8 +9,6 @@ using System.Xml.XPath;
using Mono.Cecil;
-#nullable enable
-
namespace Mono.Linker.Steps
{
public class DescriptorMarker : ProcessLinkerXmlBase
diff --git a/src/linker/Linker.Steps/DiscoverCustomOperatorsHandler.cs b/src/linker/Linker.Steps/DiscoverCustomOperatorsHandler.cs
index 3cb0e98bb..8497a61ea 100644
--- a/src/linker/Linker.Steps/DiscoverCustomOperatorsHandler.cs
+++ b/src/linker/Linker.Steps/DiscoverCustomOperatorsHandler.cs
@@ -1,6 +1,7 @@
// 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 System.Collections.Generic;
using System.Diagnostics;
using Mono.Cecil;
@@ -9,10 +10,17 @@ namespace Mono.Linker.Steps
{
public class DiscoverOperatorsHandler : IMarkHandler
{
- LinkContext _context;
+ LinkContext? _context;
+ LinkContext Context {
+ get {
+ Debug.Assert (_context != null);
+ return _context;
+ }
+ }
+
bool _seenLinqExpressions;
readonly HashSet<TypeDefinition> _trackedTypesWithOperators;
- Dictionary<TypeDefinition, List<MethodDefinition>> _pendingOperatorsForType;
+ Dictionary<TypeDefinition, List<MethodDefinition>>? _pendingOperatorsForType;
Dictionary<TypeDefinition, List<MethodDefinition>> PendingOperatorsForType {
get {
@@ -74,7 +82,7 @@ namespace Mono.Linker.Steps
void MarkOperator (MethodDefinition method)
{
- _context.Annotations.Mark (method, new DependencyInfo (DependencyKind.PreservedOperator, method.DeclaringType));
+ Context.Annotations.Mark (method, new DependencyInfo (DependencyKind.PreservedOperator, method.DeclaringType));
}
bool ProcessCustomOperators (TypeDefinition type, bool mark)
@@ -93,7 +101,7 @@ namespace Mono.Linker.Steps
Debug.Assert (_seenLinqExpressions);
hasCustomOperators = true;
- if (otherType == null || _context.Annotations.IsMarked (otherType)) {
+ if (otherType == null || Context.Annotations.IsMarked (otherType)) {
MarkOperator (method);
continue;
}
@@ -108,18 +116,18 @@ namespace Mono.Linker.Steps
return hasCustomOperators;
}
- TypeDefinition _nullableOfT;
- TypeDefinition NullableOfT {
+ TypeDefinition? _nullableOfT;
+ TypeDefinition? NullableOfT {
get {
if (_nullableOfT == null)
- _nullableOfT = BCL.FindPredefinedType ("System", "Nullable`1", _context);
+ _nullableOfT = BCL.FindPredefinedType ("System", "Nullable`1", Context);
return _nullableOfT;
}
}
- TypeDefinition NonNullableType (TypeReference type)
+ TypeDefinition? NonNullableType (TypeReference type)
{
- var typeDef = _context.TryResolve (type);
+ var typeDef = Context.TryResolve (type);
if (typeDef == null)
return null;
@@ -134,10 +142,10 @@ namespace Mono.Linker.Steps
type = ((TypeSpecification) type).ElementType;
var nullableType = type as GenericInstanceType;
Debug.Assert (nullableType != null && nullableType.HasGenericArguments && nullableType.GenericArguments.Count == 1);
- return _context.TryResolve (nullableType.GenericArguments[0]);
+ return Context.TryResolve (nullableType.GenericArguments[0]);
}
- bool IsOperator (MethodDefinition method, out TypeDefinition otherType)
+ bool IsOperator (MethodDefinition method, out TypeDefinition? otherType)
{
otherType = null;
diff --git a/src/linker/Linker.Steps/DiscoverSerializationHandler.cs b/src/linker/Linker.Steps/DiscoverSerializationHandler.cs
index 644fd33eb..0b30d6ea4 100644
--- a/src/linker/Linker.Steps/DiscoverSerializationHandler.cs
+++ b/src/linker/Linker.Steps/DiscoverSerializationHandler.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using Mono.Cecil;
using Mono.Linker.Dataflow;
@@ -16,7 +17,13 @@ namespace Mono.Linker.Steps
// - this will discover types in non-"link" assemblies as well
public class DiscoverSerializationHandler : IMarkHandler
{
- LinkContext _context;
+ LinkContext? _context;
+ LinkContext Context {
+ get {
+ Debug.Assert (_context != null);
+ return _context;
+ }
+ }
public void Initialize (LinkContext context, MarkContext markContext)
{
@@ -29,20 +36,20 @@ namespace Mono.Linker.Steps
{
var type = method.DeclaringType;
- if (!_context.SerializationMarker.IsActive (SerializerKind.DataContractSerializer) &&
+ if (!Context.SerializationMarker.IsActive (SerializerKind.DataContractSerializer) &&
method.IsConstructor && !method.IsStatic &&
((type.Namespace == "System.Runtime.Serialization" && type.Name == "DataContractSerializer") ||
(type.Namespace == "System.Runtime.Serialization.Json" && type.Name == "DataContractJsonSerializer"))) {
- _context.SerializationMarker.Activate (SerializerKind.DataContractSerializer);
+ Context.SerializationMarker.Activate (SerializerKind.DataContractSerializer);
}
- if (!_context.SerializationMarker.IsActive (SerializerKind.XmlSerializer) &&
+ if (!Context.SerializationMarker.IsActive (SerializerKind.XmlSerializer) &&
method.IsConstructor && !method.IsStatic &&
type.Namespace == "System.Xml.Serialization" &&
type.Name == "XmlSerializer") {
- _context.SerializationMarker.Activate (SerializerKind.XmlSerializer);
+ Context.SerializationMarker.Activate (SerializerKind.XmlSerializer);
}
}
@@ -88,9 +95,9 @@ namespace Mono.Linker.Steps
return;
if (serializedFor.HasFlag (SerializerKind.DataContractSerializer))
- _context.SerializationMarker.TrackForSerialization (provider, SerializerKind.DataContractSerializer);
+ Context.SerializationMarker.TrackForSerialization (provider, SerializerKind.DataContractSerializer);
if (serializedFor.HasFlag (SerializerKind.XmlSerializer))
- _context.SerializationMarker.TrackForSerialization (provider, SerializerKind.XmlSerializer);
+ Context.SerializationMarker.TrackForSerialization (provider, SerializerKind.XmlSerializer);
}
static bool IsPreservedSerializationAttribute (ICustomAttributeProvider provider, CustomAttribute attribute, out SerializerKind serializerKind)
diff --git a/src/linker/Linker.Steps/LinkAttributesParser.cs b/src/linker/Linker.Steps/LinkAttributesParser.cs
index df4189e8d..b3d64a05e 100644
--- a/src/linker/Linker.Steps/LinkAttributesParser.cs
+++ b/src/linker/Linker.Steps/LinkAttributesParser.cs
@@ -10,8 +10,6 @@ using System.Text;
using System.Xml.XPath;
using Mono.Cecil;
-#nullable enable
-
namespace Mono.Linker.Steps
{
public class LinkAttributesParser : ProcessLinkerXmlBase
@@ -35,7 +33,7 @@ namespace Mono.Linker.Steps
ProcessXml (stripLinkAttributes, _context.IgnoreLinkAttributes);
}
- CustomAttribute[] ProcessAttributes (XPathNavigator nav, ICustomAttributeProvider provider)
+ CustomAttribute[]? ProcessAttributes (XPathNavigator nav, ICustomAttributeProvider provider)
{
var builder = new ArrayBuilder<CustomAttribute> ();
foreach (XPathNavigator argumentNav in nav.SelectChildren ("attribute", string.Empty)) {
@@ -278,8 +276,7 @@ namespace Mono.Linker.Steps
if (!typeref.IsTypeOf ("System", "Type"))
goto default;
- TypeReference type = _context.TypeNameResolver.ResolveTypeName (svalue, memberWithAttribute, out _);
- if (type == null) {
+ if (!_context.TypeNameResolver.TryResolveTypeName (svalue, memberWithAttribute, out TypeReference? type, out _)) {
_context.LogError ($"Could not resolve custom attribute type value '{svalue}'.", 1044, origin: GetMessageOriginForPosition (nav));
return null;
}
@@ -297,8 +294,7 @@ namespace Mono.Linker.Steps
if (string.IsNullOrEmpty (typeName))
typeName = "System.String";
- TypeReference typeref = _context.TypeNameResolver.ResolveTypeName (typeName, memberWithAttribute, out _);
- if (typeref == null) {
+ if (!_context.TypeNameResolver.TryResolveTypeName (typeName, memberWithAttribute, out TypeReference? typeref, out _)) {
_context.LogError ($"The type '{typeName}' used with attribute value '{nav.Value}' could not be found.", 1041, origin: GetMessageOriginForPosition (nav));
return null;
}
@@ -368,7 +364,7 @@ namespace Mono.Linker.Steps
if (string.IsNullOrEmpty (assemblyName)) {
attributeType = _context.GetType (attributeFullName);
} else {
- AssemblyDefinition assembly;
+ AssemblyDefinition? assembly;
try {
assembly = _context.TryResolve (AssemblyNameReference.Parse (assemblyName));
if (assembly == null) {
diff --git a/src/linker/Linker.Steps/MarkScopeStack.cs b/src/linker/Linker.Steps/MarkScopeStack.cs
index 11d8f5d5b..60ff98722 100644
--- a/src/linker/Linker.Steps/MarkScopeStack.cs
+++ b/src/linker/Linker.Steps/MarkScopeStack.cs
@@ -40,7 +40,7 @@ namespace Mono.Linker.Steps
// we will store the suppression context in the SuppressionContextMember.
// For code which is not compiler generated the suppression context
// is the same as the message's origin member.
- IMemberDefinition suppressionContextMember = _scopeStack.GetSuppressionContext (origin.Provider);
+ IMemberDefinition? suppressionContextMember = _scopeStack.GetSuppressionContext (origin.Provider);
_scopeStack.Push (new Scope (new MessageOrigin (origin, suppressionContextMember)));
}
@@ -137,7 +137,7 @@ namespace Mono.Linker.Steps
[Conditional ("DEBUG")]
public void AssertIsEmpty () => Debug.Assert (_scopeStack.Count == 0);
- IMemberDefinition GetSuppressionContext (ICustomAttributeProvider provider)
+ IMemberDefinition? GetSuppressionContext (ICustomAttributeProvider? provider)
{
if (provider is not IMemberDefinition sourceMember)
return null;
diff --git a/src/linker/Linker.Steps/MarkStep.cs b/src/linker/Linker.Steps/MarkStep.cs
index dec6fd1e3..524c9195e 100644
--- a/src/linker/Linker.Steps/MarkStep.cs
+++ b/src/linker/Linker.Steps/MarkStep.cs
@@ -45,7 +45,14 @@ namespace Mono.Linker.Steps
public partial class MarkStep : IStep
{
- protected LinkContext _context;
+ LinkContext? _context;
+ protected LinkContext Context {
+ get {
+ Debug.Assert (_context != null);
+ return _context;
+ }
+ }
+
protected Queue<(MethodDefinition, DependencyInfo, MarkScopeStack.Scope)> _methods;
protected List<(MethodDefinition, MarkScopeStack.Scope)> _virtual_methods;
protected Queue<AttributeProviderPair> _assemblyLevelAttributes;
@@ -57,14 +64,35 @@ namespace Mono.Linker.Steps
protected List<(MethodBody, MarkScopeStack.Scope)> _unreachableBodies;
readonly List<(TypeDefinition Type, MethodBody Body, Instruction Instr)> _pending_isinst_instr;
- UnreachableBlocksOptimizer _unreachableBlocksOptimizer;
- MarkStepContext _markContext;
+ UnreachableBlocksOptimizer? _unreachableBlocksOptimizer;
+ UnreachableBlocksOptimizer UnreachableBlocksOptimizer {
+ get {
+ Debug.Assert (_unreachableBlocksOptimizer != null);
+ return _unreachableBlocksOptimizer;
+ }
+ }
+ MarkStepContext? _markContext;
+ MarkStepContext MarkContext {
+ get {
+ Debug.Assert (_markContext != null);
+ return _markContext;
+ }
+ }
readonly HashSet<TypeDefinition> _entireTypesMarked;
- DynamicallyAccessedMembersTypeHierarchy _dynamicallyAccessedMembersTypeHierarchy;
- MarkScopeStack _scopeStack;
+ DynamicallyAccessedMembersTypeHierarchy? _dynamicallyAccessedMembersTypeHierarchy;
+ MarkScopeStack? _scopeStack;
+ MarkScopeStack ScopeStack {
+ get {
+ Debug.Assert (_scopeStack != null);
+ return _scopeStack;
+ }
+ }
internal DynamicallyAccessedMembersTypeHierarchy DynamicallyAccessedMembersTypeHierarchy {
- get => _dynamicallyAccessedMembersTypeHierarchy;
+ get {
+ Debug.Assert (_dynamicallyAccessedMembersTypeHierarchy != null);
+ return _dynamicallyAccessedMembersTypeHierarchy;
+ }
}
#if DEBUG
@@ -197,9 +225,9 @@ namespace Mono.Linker.Steps
_entireTypesMarked = new HashSet<TypeDefinition> ();
}
- public AnnotationStore Annotations => _context.Annotations;
- public MarkingHelpers MarkingHelpers => _context.MarkingHelpers;
- public Tracer Tracer => _context.Tracer;
+ public AnnotationStore Annotations => Context.Annotations;
+ public MarkingHelpers MarkingHelpers => Context.MarkingHelpers;
+ public Tracer Tracer => Context.Tracer;
public virtual void Process (LinkContext context)
{
@@ -217,7 +245,7 @@ namespace Mono.Linker.Steps
void Initialize ()
{
InitializeCorelibAttributeXml ();
- _context.Pipeline.InitializeMarkHandlers (_context, _markContext);
+ Context.Pipeline.InitializeMarkHandlers (Context, MarkContext);
ProcessMarkedPending ();
}
@@ -228,18 +256,18 @@ namespace Mono.Linker.Steps
// corelib attribute XML can contain modifications to other assemblies.
// We could just mark it here, but the attribute processing isn't necessarily tied to marking,
// so this would rely on implementation details of corelib.
- var coreLib = _context.TryResolve (PlatformAssemblies.CoreLib);
+ var coreLib = Context.TryResolve (PlatformAssemblies.CoreLib);
if (coreLib == null)
return;
- var xmlInfo = EmbeddedXmlInfo.ProcessAttributes (coreLib, _context);
+ var xmlInfo = EmbeddedXmlInfo.ProcessAttributes (coreLib, Context);
if (xmlInfo == null)
return;
// Because the attribute XML can reference other assemblies, they must go in the global store,
// instead of the per-assembly stores.
foreach (var (provider, annotations) in xmlInfo.CustomAttributes)
- _context.CustomAttributes.PrimaryAttributeInfo.AddCustomAttributes (provider, annotations);
+ Context.CustomAttributes.PrimaryAttributeInfo.AddCustomAttributes (provider, annotations);
}
void Complete ()
@@ -258,7 +286,7 @@ namespace Mono.Linker.Steps
Debug.Assert (attr.Provider is ModuleDefinition or AssemblyDefinition);
var assembly = (provider is ModuleDefinition module) ? module.Assembly : provider as AssemblyDefinition;
- using var assemblyScope = _scopeStack.PushScope (new MessageOrigin (assembly));
+ using var assemblyScope = ScopeStack.PushScope (new MessageOrigin (assembly));
if (!Annotations.IsMarked (attr.Attribute) && IsInternalsVisibleAttributeAssemblyMarked (attr.Attribute)) {
MarkCustomAttribute (attr.Attribute, new DependencyInfo (DependencyKind.AssemblyOrModuleAttribute, attr.Provider));
@@ -277,7 +305,7 @@ namespace Mono.Linker.Steps
return false;
}
- var assembly = _context.GetLoadedAssembly (an.Name!);
+ var assembly = Context.GetLoadedAssembly (an.Name!);
if (assembly == null)
return false;
@@ -323,7 +351,7 @@ namespace Mono.Linker.Steps
// Prevent cases where there's nothing on the stack (can happen when marking entire assemblies)
// In which case we would generate warnings with no source (hard to debug)
- using var _ = _scopeStack.CurrentScope.Origin.Provider == null ? _scopeStack.PushScope (new MessageOrigin (type)) : null;
+ using var _ = ScopeStack.CurrentScope.Origin.Provider == null ? ScopeStack.PushScope (new MessageOrigin (type)) : null;
if (!_entireTypesMarked.Add (type))
return;
@@ -389,33 +417,33 @@ namespace Mono.Linker.Steps
// Fully mark any assemblies with copy/save action.
// Unresolved references could get the copy/save action if this is the default action.
- bool scanReferences = IsFullyPreservedAction (_context.TrimAction) || IsFullyPreservedAction (_context.DefaultAction);
+ bool scanReferences = IsFullyPreservedAction (Context.TrimAction) || IsFullyPreservedAction (Context.DefaultAction);
if (!scanReferences) {
// Unresolved references could get the copy/save action if it was set explicitly
// for some referenced assembly that has not been resolved yet
- foreach (var (assemblyName, action) in _context.Actions) {
+ foreach (var (assemblyName, action) in Context.Actions) {
if (!IsFullyPreservedAction (action))
continue;
- var assembly = _context.GetLoadedAssembly (assemblyName);
+ var assembly = Context.GetLoadedAssembly (assemblyName);
if (assembly == null) {
scanReferences = true;
break;
}
// The action should not change from the explicit command-line action
- Debug.Assert (_context.Annotations.GetAction (assembly) == action);
+ Debug.Assert (Context.Annotations.GetAction (assembly) == action);
}
}
// Beware: this works on loaded assemblies, not marked assemblies, so it should not be tied to marking.
// We could further optimize this to only iterate through assemblies if the last mark iteration loaded
// a new assembly, since this is the only way that the set we need to consider could have changed.
- var assembliesToCheck = scanReferences ? _context.GetReferencedAssemblies ().ToArray () : _context.GetAssemblies ();
+ var assembliesToCheck = scanReferences ? Context.GetReferencedAssemblies ().ToArray () : Context.GetAssemblies ();
bool markedNewAssembly = false;
foreach (var assembly in assembliesToCheck) {
- var action = _context.Annotations.GetAction (assembly);
+ var action = Context.Annotations.GetAction (assembly);
if (!IsFullyPreservedAction (action))
continue;
if (!Annotations.IsProcessed (assembly))
@@ -444,7 +472,7 @@ namespace Mono.Linker.Steps
bool ProcessMarkedPending ()
{
- using var emptyScope = _scopeStack.PushScope (new MessageOrigin (null as ICustomAttributeProvider));
+ using var emptyScope = ScopeStack.PushScope (new MessageOrigin (null as ICustomAttributeProvider));
bool marked = false;
foreach (var pending in Annotations.GetMarkedPending ()) {
@@ -501,7 +529,7 @@ namespace Mono.Linker.Steps
Instruction new_instr = Instruction.Create (OpCodes.Pop);
ilProcessor.Replace (instr, new_instr);
- _context.LogMessage ($"Removing typecheck of '{type.FullName}' inside '{item.Body.Method.GetDisplayName ()}' method.");
+ Context.LogMessage ($"Removing typecheck of '{type.FullName}' inside '{item.Body.Method.GetDisplayName ()}' method.");
}
}
@@ -532,7 +560,7 @@ namespace Mono.Linker.Steps
void ProcessVirtualMethods ()
{
foreach ((MethodDefinition method, MarkScopeStack.Scope scope) in _virtual_methods) {
- using (_scopeStack.PushScope (scope))
+ using (ScopeStack.PushScope (scope))
ProcessVirtualMethod (method);
}
}
@@ -551,7 +579,7 @@ namespace Mono.Linker.Steps
if (!Annotations.IsInstantiated (type) && !Annotations.IsRelevantToVariantCasting (type))
continue;
- using (_scopeStack.PushScope (scope))
+ using (ScopeStack.PushScope (scope))
MarkInterfaceImplementations (type);
}
}
@@ -559,7 +587,7 @@ namespace Mono.Linker.Steps
void DiscoverDynamicCastableImplementationInterfaces ()
{
// We could potentially avoid loading all references here: https://github.com/dotnet/linker/issues/1788
- foreach (var assembly in _context.GetReferencedAssemblies ().ToArray ()) {
+ foreach (var assembly in Context.GetReferencedAssemblies ().ToArray ()) {
switch (Annotations.GetAction (assembly)) {
// We only need to search assemblies where we don't mark everything
// Assemblies that are fully marked already mark these types.
@@ -610,7 +638,7 @@ namespace Mono.Linker.Steps
if (Annotations.IsMarked (iface.InterfaceType)) {
// We only need to mark the type definition because the linker will ensure that all marked implemented interfaces and used method implementations
// will be marked on this type as well.
- MarkType (type, new DependencyInfo (DependencyKind.DynamicInterfaceCastableImplementation, iface.InterfaceType), new MessageOrigin (_context.TryResolve (iface.InterfaceType)));
+ MarkType (type, new DependencyInfo (DependencyKind.DynamicInterfaceCastableImplementation, iface.InterfaceType), new MessageOrigin (Context.TryResolve (iface.InterfaceType)));
_dynamicInterfaceCastableImplementationTypes.RemoveAt (i--);
break;
@@ -624,7 +652,7 @@ namespace Mono.Linker.Steps
for (int i = 0; i < _unreachableBodies.Count; i++) {
(var body, var scope) = _unreachableBodies[i];
if (Annotations.IsInstantiated (body.Method.DeclaringType)) {
- using (_scopeStack.PushScope (scope))
+ using (ScopeStack.PushScope (scope))
MarkMethodBody (body);
_unreachableBodies.RemoveAt (i--);
@@ -634,7 +662,7 @@ namespace Mono.Linker.Steps
void ProcessVirtualMethod (MethodDefinition method)
{
- _context.Annotations.EnqueueVirtualMethod (method);
+ Context.Annotations.EnqueueVirtualMethod (method);
var overrides = Annotations.GetOverrides (method);
if (overrides != null) {
@@ -671,16 +699,16 @@ namespace Mono.Linker.Steps
return;
// Interface static veitual methods will be abstract and will also by pass this check to get marked
- if (!isInstantiated && !@base.IsAbstract && _context.IsOptimizationEnabled (CodeOptimizations.OverrideRemoval, method))
+ if (!isInstantiated && !@base.IsAbstract && Context.IsOptimizationEnabled (CodeOptimizations.OverrideRemoval, method))
return;
// Only track instantiations if override removal is enabled and the type is instantiated.
// If it's disabled, all overrides are kept, so there's no instantiation site to blame.
- if (_context.IsOptimizationEnabled (CodeOptimizations.OverrideRemoval, method) && isInstantiated) {
+ if (Context.IsOptimizationEnabled (CodeOptimizations.OverrideRemoval, method) && isInstantiated) {
MarkMethod (method, new DependencyInfo (DependencyKind.OverrideOnInstantiatedType, method.DeclaringType));
} else {
// If the optimization is disabled or it's an abstract type, we just mark it as a normal override.
- Debug.Assert (!_context.IsOptimizationEnabled (CodeOptimizations.OverrideRemoval, method) || @base.IsAbstract);
+ Debug.Assert (!Context.IsOptimizationEnabled (CodeOptimizations.OverrideRemoval, method) || @base.IsAbstract);
MarkMethod (method, new DependencyInfo (DependencyKind.Override, @base));
}
@@ -703,7 +731,7 @@ namespace Mono.Linker.Steps
var interfaceType = overrideInformation.InterfaceType;
var overrideDeclaringType = overrideInformation.Override.DeclaringType;
- if (!IsInterfaceImplementationMarkedRecursively (overrideDeclaringType, interfaceType))
+ if (interfaceType == null || !IsInterfaceImplementationMarkedRecursively (overrideDeclaringType, interfaceType))
return true;
return false;
@@ -713,7 +741,7 @@ namespace Mono.Linker.Steps
{
if (type.HasInterfaces) {
foreach (var intf in type.Interfaces) {
- TypeDefinition resolvedInterface = _context.Resolve (intf.InterfaceType);
+ TypeDefinition? resolvedInterface = Context.Resolve (intf.InterfaceType);
if (resolvedInterface == null)
continue;
@@ -732,7 +760,7 @@ namespace Mono.Linker.Steps
if (typeToExamine.HasInterfaces) {
foreach (var iface in typeToExamine.Interfaces) {
- var resolved = _context.TryResolve (iface.InterfaceType);
+ var resolved = Context.TryResolve (iface.InterfaceType);
if (resolved == null)
continue;
@@ -759,7 +787,7 @@ namespace Mono.Linker.Steps
if (spec.MarshalInfo is CustomMarshalInfo marshaler) {
MarkType (marshaler.ManagedType, reason);
- TypeDefinition type = _context.Resolve (marshaler.ManagedType);
+ TypeDefinition? type = Context.Resolve (marshaler.ManagedType);
if (type != null) {
MarkICustomMarshalerMethods (type, in reason);
MarkCustomMarshalerGetInstance (type, in reason);
@@ -771,18 +799,18 @@ namespace Mono.Linker.Steps
{
if (provider.HasCustomAttributes) {
bool providerInLinkedAssembly = Annotations.GetAction (CustomAttributeSource.GetAssemblyFromCustomAttributeProvider (provider)) == AssemblyAction.Link;
- bool markOnUse = _context.KeepUsedAttributeTypesOnly && providerInLinkedAssembly;
+ bool markOnUse = Context.KeepUsedAttributeTypesOnly && providerInLinkedAssembly;
foreach (CustomAttribute ca in provider.CustomAttributes) {
if (ProcessLinkerSpecialAttribute (ca, provider, reason))
continue;
if (markOnUse) {
- _lateMarkedAttributes.Enqueue ((new AttributeProviderPair (ca, provider), reason, _scopeStack.CurrentScope));
+ _lateMarkedAttributes.Enqueue ((new AttributeProviderPair (ca, provider), reason, ScopeStack.CurrentScope));
continue;
}
- var resolvedAttributeType = _context.Resolve (ca.AttributeType);
+ var resolvedAttributeType = Context.Resolve (ca.AttributeType);
if (resolvedAttributeType == null) {
continue;
}
@@ -799,14 +827,14 @@ namespace Mono.Linker.Steps
return;
IMemberDefinition providerMember = (IMemberDefinition) provider; ;
- using (_scopeStack.PushScope (new MessageOrigin (providerMember)))
- foreach (var dynamicDependency in _context.Annotations.GetLinkerAttributes<DynamicDependency> (providerMember))
+ using (ScopeStack.PushScope (new MessageOrigin (providerMember)))
+ foreach (var dynamicDependency in Context.Annotations.GetLinkerAttributes<DynamicDependency> (providerMember))
MarkDynamicDependency (dynamicDependency, providerMember);
}
bool IsAttributeRemoved (CustomAttribute ca, TypeDefinition attributeType)
{
- foreach (var attr in _context.Annotations.GetLinkerAttributes<RemoveAttributeInstancesAttribute> (attributeType)) {
+ foreach (var attr in Context.Annotations.GetLinkerAttributes<RemoveAttributeInstancesAttribute> (attributeType)) {
var args = attr.Arguments;
if (args.Length == 0)
return true;
@@ -850,7 +878,7 @@ namespace Mono.Linker.Steps
if (isPreserveDependency)
MarkUserDependency (member, ca);
- if (_context.CanApplyOptimization (CodeOptimizations.RemoveDynamicDependencyAttribute, member.DeclaringType.Module.Assembly)) {
+ if (Context.CanApplyOptimization (CodeOptimizations.RemoveDynamicDependencyAttribute, member.DeclaringType.Module.Assembly)) {
// Record the custom attribute so that it has a reason, without actually marking it.
Tracer.AddDirectDependency (ca, reason, marked: false);
} else {
@@ -863,11 +891,11 @@ namespace Mono.Linker.Steps
void MarkDynamicDependency (DynamicDependency dynamicDependency, IMemberDefinition context)
{
Debug.Assert (context is MethodDefinition || context is FieldDefinition);
- AssemblyDefinition assembly;
+ AssemblyDefinition? assembly;
if (dynamicDependency.AssemblyName != null) {
- assembly = _context.TryResolve (dynamicDependency.AssemblyName);
+ assembly = Context.TryResolve (dynamicDependency.AssemblyName);
if (assembly == null) {
- _context.LogWarning ($"Unresolved assembly '{dynamicDependency.AssemblyName}' in 'DynamicDependencyAttribute'.", 2035, _scopeStack.CurrentScope.Origin);
+ Context.LogWarning ($"Unresolved assembly '{dynamicDependency.AssemblyName}' in 'DynamicDependencyAttribute'.", 2035, ScopeStack.CurrentScope.Origin);
return;
}
} else {
@@ -875,41 +903,41 @@ namespace Mono.Linker.Steps
Debug.Assert (assembly != null);
}
- TypeDefinition type;
+ TypeDefinition? type;
if (dynamicDependency.TypeName is string typeName) {
- type = DocumentationSignatureParser.GetTypeByDocumentationSignature (assembly, typeName, _context);
+ type = DocumentationSignatureParser.GetTypeByDocumentationSignature (assembly, typeName, Context);
if (type == null) {
- _context.LogWarning ($"Unresolved type '{typeName}' in 'DynamicDependencyAttribute'.", 2036, _scopeStack.CurrentScope.Origin);
+ Context.LogWarning ($"Unresolved type '{typeName}' in 'DynamicDependencyAttribute'.", 2036, ScopeStack.CurrentScope.Origin);
return;
}
MarkingHelpers.MarkMatchingExportedType (type, assembly, new DependencyInfo (DependencyKind.DynamicDependency, type));
} else if (dynamicDependency.Type is TypeReference typeReference) {
- type = _context.TryResolve (typeReference);
+ type = Context.TryResolve (typeReference);
if (type == null) {
- _context.LogWarning ($"Unresolved type '{typeReference}' in 'DynamicDependencyAtribute'.", 2036, _scopeStack.CurrentScope.Origin);
+ Context.LogWarning ($"Unresolved type '{typeReference}' in 'DynamicDependencyAtribute'.", 2036, ScopeStack.CurrentScope.Origin);
return;
}
} else {
- type = _context.TryResolve (context.DeclaringType);
+ type = Context.TryResolve (context.DeclaringType);
if (type == null) {
- _context.LogWarning ($"Unresolved type '{context.DeclaringType}' in 'DynamicDependencyAttribute'.", 2036, context);
+ Context.LogWarning ($"Unresolved type '{context.DeclaringType}' in 'DynamicDependencyAttribute'.", 2036, context);
return;
}
}
IEnumerable<IMetadataTokenProvider> members;
if (dynamicDependency.MemberSignature is string memberSignature) {
- members = DocumentationSignatureParser.GetMembersByDocumentationSignature (type, memberSignature, _context, acceptName: true);
+ members = DocumentationSignatureParser.GetMembersByDocumentationSignature (type, memberSignature, Context, acceptName: true);
if (!members.Any ()) {
- _context.LogWarning ($"No members were resolved for '{memberSignature}'.", 2037, _scopeStack.CurrentScope.Origin);
+ Context.LogWarning ($"No members were resolved for '{memberSignature}'.", 2037, ScopeStack.CurrentScope.Origin);
return;
}
} else {
var memberTypes = dynamicDependency.MemberTypes;
- members = type.GetDynamicallyAccessedMembers (_context, memberTypes);
+ members = type.GetDynamicallyAccessedMembers (Context, memberTypes);
if (!members.Any ()) {
- _context.LogWarning ($"No members were resolved for '{memberTypes}'.", 2037, _scopeStack.CurrentScope.Origin);
+ Context.LogWarning ($"No members were resolved for '{memberTypes}'.", 2037, ScopeStack.CurrentScope.Origin);
return;
}
}
@@ -950,17 +978,17 @@ namespace Mono.Linker.Steps
protected virtual void MarkUserDependency (IMemberDefinition context, CustomAttribute ca)
{
- _context.LogWarning ($"'PreserveDependencyAttribute' is deprecated. Use 'DynamicDependencyAttribute' instead.", 2033, context);
+ Context.LogWarning ($"'PreserveDependencyAttribute' is deprecated. Use 'DynamicDependencyAttribute' instead.", 2033, context);
- if (!DynamicDependency.ShouldProcess (_context, ca))
+ if (!DynamicDependency.ShouldProcess (Context, ca))
return;
- AssemblyDefinition assembly;
+ AssemblyDefinition? assembly;
var args = ca.ConstructorArguments;
if (args.Count >= 3 && args[2].Value is string assemblyName) {
- assembly = _context.TryResolve (assemblyName);
+ assembly = Context.TryResolve (assemblyName);
if (assembly == null) {
- _context.LogWarning (
+ Context.LogWarning (
$"Could not resolve dependency assembly '{assemblyName}' specified in a 'PreserveDependency' attribute.", 2003, context);
return;
}
@@ -968,24 +996,24 @@ namespace Mono.Linker.Steps
assembly = null;
}
- TypeDefinition td;
+ TypeDefinition? td;
if (args.Count >= 2 && args[1].Value is string typeName) {
AssemblyDefinition assemblyDef = assembly ?? ((MemberReference) context).Module.Assembly;
- td = _context.TryResolve (assemblyDef, typeName);
+ td = Context.TryResolve (assemblyDef, typeName);
if (td == null) {
- _context.LogWarning (
+ Context.LogWarning (
$"Could not resolve dependency type '{typeName}' specified in a 'PreserveDependency' attribute.", 2004, context);
return;
}
MarkingHelpers.MarkMatchingExportedType (td, assemblyDef, new DependencyInfo (DependencyKind.PreservedDependency, ca));
} else {
- td = _context.TryResolve (context.DeclaringType);
+ td = context.DeclaringType;
}
- string member = null;
- string[] signature = null;
+ string? member = null;
+ string[]? signature = null;
if (args.Count >= 1 && args[0].Value is string memberSignature) {
memberSignature = memberSignature.Replace (" ", "");
var sign_start = memberSignature.IndexOf ('(');
@@ -1004,17 +1032,19 @@ namespace Mono.Linker.Steps
return;
}
- if (MarkDependencyMethod (td, member, signature, new DependencyInfo (DependencyKind.PreservedDependency, ca)))
- return;
+ if (member != null) {
+ if (MarkDependencyMethod (td, member, signature, new DependencyInfo (DependencyKind.PreservedDependency, ca)))
+ return;
- if (MarkNamedField (td, member, new DependencyInfo (DependencyKind.PreservedDependency, ca)))
- return;
+ if (MarkNamedField (td, member, new DependencyInfo (DependencyKind.PreservedDependency, ca)))
+ return;
+ }
- _context.LogWarning (
+ Context.LogWarning (
$"Could not resolve dependency member '{member}' declared in type '{td.GetDisplayName ()}' specified in a 'PreserveDependency' attribute.", 2005, context);
}
- bool MarkDependencyMethod (TypeDefinition type, string name, string[] signature, in DependencyInfo reason)
+ bool MarkDependencyMethod (TypeDefinition type, string name, string[]? signature, in DependencyInfo reason)
{
bool marked = false;
@@ -1079,7 +1109,7 @@ namespace Mono.Linker.Steps
MarkCustomAttributeArguments (ca);
TypeReference constructor_type = ca.Constructor.DeclaringType;
- TypeDefinition type = _context.Resolve (constructor_type);
+ TypeDefinition? type = Context.Resolve (constructor_type);
if (type == null) {
return;
@@ -1093,7 +1123,7 @@ namespace Mono.Linker.Steps
{
var attr_type = ca.AttributeType;
- if (_context.KeepUsedAttributeTypesOnly) {
+ if (Context.KeepUsedAttributeTypesOnly) {
switch (attr_type.FullName) {
// These are required by the runtime
case "System.ThreadStaticAttribute":
@@ -1108,7 +1138,7 @@ namespace Mono.Linker.Steps
return true;
}
- TypeDefinition type = _context.Resolve (attr_type);
+ TypeDefinition? type = Context.Resolve (attr_type);
if (type is null || !Annotations.IsMarked (type))
return false;
}
@@ -1121,7 +1151,7 @@ namespace Mono.Linker.Steps
if (Annotations.HasPreservedStaticCtor (type))
return false;
- if (type.IsBeforeFieldInit && _context.IsOptimizationEnabled (CodeOptimizations.BeforeFieldInit, type))
+ if (type.IsBeforeFieldInit && Context.IsOptimizationEnabled (CodeOptimizations.BeforeFieldInit, type))
return false;
return true;
@@ -1182,7 +1212,7 @@ namespace Mono.Linker.Steps
protected virtual void MarkSecurityAttribute (SecurityAttribute sa, in DependencyInfo reason)
{
TypeReference security_type = sa.AttributeType;
- TypeDefinition type = _context.Resolve (security_type);
+ TypeDefinition? type = Context.Resolve (security_type);
if (type == null) {
return;
}
@@ -1205,26 +1235,27 @@ namespace Mono.Linker.Steps
protected void MarkCustomAttributeProperty (CustomAttributeNamedArgument namedArgument, TypeDefinition attribute, ICustomAttribute ca, in DependencyInfo reason)
{
- PropertyDefinition property = GetProperty (attribute, namedArgument.Name);
+ PropertyDefinition? property = GetProperty (attribute, namedArgument.Name);
if (property != null)
MarkMethod (property.SetMethod, reason);
MarkCustomAttributeArgument (namedArgument.Argument, ca);
- if (property != null && _context.Annotations.FlowAnnotations.RequiresDataFlowAnalysis (property.SetMethod)) {
- var scanner = new ReflectionMethodBodyScanner (_context, this, _scopeStack);
+ if (property != null && Context.Annotations.FlowAnnotations.RequiresDataFlowAnalysis (property.SetMethod)) {
+ var scanner = new ReflectionMethodBodyScanner (Context, this, ScopeStack);
scanner.ProcessAttributeDataflow (property.SetMethod, new List<CustomAttributeArgument> { namedArgument.Argument });
}
}
- PropertyDefinition GetProperty (TypeDefinition type, string propertyname)
+ PropertyDefinition? GetProperty (TypeDefinition inputType, string propertyname)
{
+ TypeDefinition? type = inputType;
while (type != null) {
- PropertyDefinition property = type.Properties.FirstOrDefault (p => p.Name == propertyname);
+ PropertyDefinition? property = type.Properties.FirstOrDefault (p => p.Name == propertyname);
if (property != null)
return property;
- type = _context.TryResolve (type.BaseType);
+ type = Context.TryResolve (type.BaseType);
}
return null;
@@ -1241,39 +1272,41 @@ namespace Mono.Linker.Steps
protected void MarkCustomAttributeField (CustomAttributeNamedArgument namedArgument, TypeDefinition attribute, ICustomAttribute ca)
{
- FieldDefinition field = GetField (attribute, namedArgument.Name);
+ FieldDefinition? field = GetField (attribute, namedArgument.Name);
if (field != null)
MarkField (field, new DependencyInfo (DependencyKind.CustomAttributeField, ca));
MarkCustomAttributeArgument (namedArgument.Argument, ca);
- if (field != null && _context.Annotations.FlowAnnotations.RequiresDataFlowAnalysis (field)) {
- var scanner = new ReflectionMethodBodyScanner (_context, this, _scopeStack);
+ if (field != null && Context.Annotations.FlowAnnotations.RequiresDataFlowAnalysis (field)) {
+ var scanner = new ReflectionMethodBodyScanner (Context, this, ScopeStack);
scanner.ProcessAttributeDataflow (field, namedArgument.Argument);
}
}
- FieldDefinition GetField (TypeDefinition type, string fieldname)
+ FieldDefinition? GetField (TypeDefinition inputType, string fieldname)
{
+ TypeDefinition? type = inputType;
while (type != null) {
- FieldDefinition field = type.Fields.FirstOrDefault (f => f.Name == fieldname);
+ FieldDefinition? field = type.Fields.FirstOrDefault (f => f.Name == fieldname);
if (field != null)
return field;
- type = _context.TryResolve (type.BaseType);
+ type = Context.TryResolve (type.BaseType);
}
return null;
}
- MethodDefinition GetMethodWithNoParameters (TypeDefinition type, string methodname)
+ MethodDefinition? GetMethodWithNoParameters (TypeDefinition inputType, string methodname)
{
+ TypeDefinition? type = inputType;
while (type != null) {
- MethodDefinition method = type.Methods.FirstOrDefault (m => m.Name == methodname && !m.HasParameters);
+ MethodDefinition? method = type.Methods.FirstOrDefault (m => m.Name == methodname && !m.HasParameters);
if (method != null)
return method;
- type = _context.TryResolve (type.BaseType);
+ type = Context.TryResolve (type.BaseType);
}
return null;
@@ -1287,9 +1320,9 @@ namespace Mono.Linker.Steps
foreach (var argument in ca.ConstructorArguments)
MarkCustomAttributeArgument (argument, ca);
- var resolvedConstructor = _context.TryResolve (ca.Constructor);
- if (resolvedConstructor != null && _context.Annotations.FlowAnnotations.RequiresDataFlowAnalysis (resolvedConstructor)) {
- var scanner = new ReflectionMethodBodyScanner (_context, this, _scopeStack);
+ var resolvedConstructor = Context.TryResolve (ca.Constructor);
+ if (resolvedConstructor != null && Context.Annotations.FlowAnnotations.RequiresDataFlowAnalysis (resolvedConstructor)) {
+ var scanner = new ReflectionMethodBodyScanner (Context, this, ScopeStack);
scanner.ProcessAttributeDataflow (resolvedConstructor, ca.ConstructorArguments);
}
}
@@ -1340,20 +1373,20 @@ namespace Mono.Linker.Steps
if (CheckProcessed (assembly))
return;
- using var assemblyScope = _scopeStack.PushScope (new MessageOrigin (assembly));
+ using var assemblyScope = ScopeStack.PushScope (new MessageOrigin (assembly));
- EmbeddedXmlInfo.ProcessDescriptors (assembly, _context);
+ EmbeddedXmlInfo.ProcessDescriptors (assembly, Context);
- foreach (Action<AssemblyDefinition> handleMarkAssembly in _markContext.MarkAssemblyActions)
+ foreach (Action<AssemblyDefinition> handleMarkAssembly in MarkContext.MarkAssemblyActions)
handleMarkAssembly (assembly);
// Security attributes do not respect the attributes XML
- if (_context.StripSecurity)
- RemoveSecurity.ProcessAssembly (assembly, _context);
+ if (Context.StripSecurity)
+ RemoveSecurity.ProcessAssembly (assembly, Context);
- MarkExportedTypesTarget.ProcessAssembly (assembly, _context);
+ MarkExportedTypesTarget.ProcessAssembly (assembly, Context);
- if (ProcessReferencesStep.IsFullyPreservedAction (_context.Annotations.GetAction (assembly))) {
+ if (ProcessReferencesStep.IsFullyPreservedAction (Context.Annotations.GetAction (assembly))) {
MarkEntireAssembly (assembly);
return;
}
@@ -1426,7 +1459,7 @@ namespace Mono.Linker.Steps
void ProcessModuleType (AssemblyDefinition assembly)
{
// The <Module> type may have an initializer, in which case we want to keep it.
- TypeDefinition moduleType = assembly.MainModule.Types.FirstOrDefault (t => t.MetadataToken.RID == 1);
+ TypeDefinition? moduleType = assembly.MainModule.Types.FirstOrDefault (t => t.MetadataToken.RID == 1);
if (moduleType != null && moduleType.HasMethods)
MarkType (moduleType, new DependencyInfo (DependencyKind.TypeInAssembly, assembly));
}
@@ -1451,9 +1484,9 @@ namespace Mono.Linker.Steps
Debug.Assert (provider is ModuleDefinition or AssemblyDefinition);
var assembly = (provider is ModuleDefinition module) ? module.Assembly : provider as AssemblyDefinition;
- using var assemblyScope = _scopeStack.PushScope (new MessageOrigin (assembly));
+ using var assemblyScope = ScopeStack.PushScope (new MessageOrigin (assembly));
- var resolved = _context.Resolve (customAttribute.Constructor);
+ var resolved = Context.Resolve (customAttribute.Constructor);
if (resolved == null) {
continue;
}
@@ -1474,12 +1507,18 @@ namespace Mono.Linker.Steps
string attributeFullName = customAttribute.Constructor.DeclaringType.FullName;
switch (attributeFullName) {
- case "System.Diagnostics.DebuggerDisplayAttribute":
- MarkTypeWithDebuggerDisplayAttribute (GetDebuggerAttributeTargetType (assemblyLevelAttribute.Attribute, (AssemblyDefinition) assemblyLevelAttribute.Provider), customAttribute);
- break;
- case "System.Diagnostics.DebuggerTypeProxyAttribute":
- MarkTypeWithDebuggerTypeProxyAttribute (GetDebuggerAttributeTargetType (assemblyLevelAttribute.Attribute, (AssemblyDefinition) assemblyLevelAttribute.Provider), customAttribute);
- break;
+ case "System.Diagnostics.DebuggerDisplayAttribute": {
+ TypeDefinition? targetType = GetDebuggerAttributeTargetType (assemblyLevelAttribute.Attribute, (AssemblyDefinition) assemblyLevelAttribute.Provider);
+ if (targetType != null)
+ MarkTypeWithDebuggerDisplayAttribute (targetType, customAttribute);
+ break;
+ }
+ case "System.Diagnostics.DebuggerTypeProxyAttribute": {
+ TypeDefinition? targetType = GetDebuggerAttributeTargetType (assemblyLevelAttribute.Attribute, (AssemblyDefinition) assemblyLevelAttribute.Provider);
+ if (targetType != null)
+ MarkTypeWithDebuggerTypeProxyAttribute (targetType, customAttribute);
+ break;
+ }
}
}
@@ -1504,7 +1543,7 @@ namespace Mono.Linker.Steps
var customAttribute = attributeProviderPair.Attribute;
var provider = attributeProviderPair.Provider;
- var resolved = _context.Resolve (customAttribute.Constructor);
+ var resolved = Context.Resolve (customAttribute.Constructor);
if (resolved == null) {
continue;
}
@@ -1515,7 +1554,7 @@ namespace Mono.Linker.Steps
}
markOccurred = true;
- using (_scopeStack.PushScope (scope)) {
+ using (ScopeStack.PushScope (scope)) {
MarkCustomAttribute (customAttribute, reason);
MarkSpecialCustomAttributeDependencies (customAttribute, provider);
}
@@ -1534,13 +1573,13 @@ namespace Mono.Linker.Steps
Debug.Assert (reason.Kind == DependencyKind.FieldAccess || reason.Kind == DependencyKind.Ldtoken);
// Blame the field reference (without actually marking) on the original reason.
Tracer.AddDirectDependency (reference, reason, marked: false);
- MarkType (reference.DeclaringType, new DependencyInfo (DependencyKind.DeclaringType, reference), new MessageOrigin (_context.TryResolve (reference)));
+ MarkType (reference.DeclaringType, new DependencyInfo (DependencyKind.DeclaringType, reference), new MessageOrigin (Context.TryResolve (reference)));
// Blame the field definition that we will resolve on the field reference.
reason = new DependencyInfo (DependencyKind.FieldOnGenericInstance, reference);
}
- FieldDefinition field = _context.Resolve (reference);
+ FieldDefinition? field = Context.Resolve (reference);
if (field == null) {
return;
@@ -1558,7 +1597,7 @@ namespace Mono.Linker.Steps
// annotation on a type, not a callsite which uses the annotation. We always want to warn about
// possible reflection access indicated by these annotations.
- var type = _scopeStack.CurrentScope.Origin.Provider as TypeDefinition;
+ var type = ScopeStack.CurrentScope.Origin.Provider as TypeDefinition;
Debug.Assert (type != null);
static bool IsDeclaredWithinType (IMemberDefinition member, TypeDefinition type)
@@ -1571,12 +1610,12 @@ namespace Mono.Linker.Steps
}
var reportOnMember = IsDeclaredWithinType (member, type);
- var memberScope = reportOnMember ? _scopeStack.PushScope (new MessageOrigin (member)) : null;
+ var memberScope = reportOnMember ? ScopeStack.PushScope (new MessageOrigin (member)) : null;
try {
- var origin = _scopeStack.CurrentScope.Origin;
+ var origin = ScopeStack.CurrentScope.Origin;
- if (Annotations.DoesMemberRequireUnreferencedCode (member, out RequiresUnreferencedCodeAttribute requiresUnreferencedCodeAttribute)) {
+ if (Annotations.DoesMemberRequireUnreferencedCode (member, out RequiresUnreferencedCodeAttribute? requiresUnreferencedCodeAttribute)) {
var message = string.Format (
"'DynamicallyAccessedMembersAttribute' on '{0}' or one of its base types references '{1}' which requires unreferenced code.{2}{3}",
type.GetDisplayName (),
@@ -1584,16 +1623,16 @@ namespace Mono.Linker.Steps
MessageFormat.FormatRequiresAttributeMessageArg (requiresUnreferencedCodeAttribute.Message),
MessageFormat.FormatRequiresAttributeMessageArg (requiresUnreferencedCodeAttribute.Url));
var code = reportOnMember ? 2112 : 2113;
- _context.LogWarning (message, code, origin, MessageSubCategory.TrimAnalysis);
+ Context.LogWarning (message, code, origin, MessageSubCategory.TrimAnalysis);
}
- if (_context.Annotations.FlowAnnotations.ShouldWarnWhenAccessedForReflection (member)) {
+ if (Context.Annotations.FlowAnnotations.ShouldWarnWhenAccessedForReflection (member)) {
var message = string.Format (
"'DynamicallyAccessedMembersAttribute' on '{0}' or one of its base types references '{1}' which has 'DynamicallyAccessedMembersAttribute' requirements.",
type.GetDisplayName (),
- (member as MemberReference).GetDisplayName ());
+ ((MemberReference) member).GetDisplayName ());
var code = reportOnMember ? 2114 : 2115;
- _context.LogWarning (message, code, origin, MessageSubCategory.TrimAnalysis);
+ Context.LogWarning (message, code, origin, MessageSubCategory.TrimAnalysis);
}
} finally {
memberScope?.Dispose ();
@@ -1614,21 +1653,21 @@ namespace Mono.Linker.Steps
}
if (reason.Kind != DependencyKind.DynamicallyAccessedMemberOnType &&
- Annotations.DoesFieldRequireUnreferencedCode (field, out RequiresUnreferencedCodeAttribute requiresUnreferencedCodeAttribute) &&
+ Annotations.DoesFieldRequireUnreferencedCode (field, out RequiresUnreferencedCodeAttribute? requiresUnreferencedCodeAttribute) &&
!ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode ())
- ReportRequiresUnreferencedCode (field.GetDisplayName (), requiresUnreferencedCodeAttribute, _scopeStack.CurrentScope.Origin);
+ ReportRequiresUnreferencedCode (field.GetDisplayName (), requiresUnreferencedCodeAttribute, ScopeStack.CurrentScope.Origin);
switch (reason.Kind) {
case DependencyKind.AccessedViaReflection:
case DependencyKind.DynamicDependency:
case DependencyKind.DynamicallyAccessedMember:
case DependencyKind.InteropMethodDependency:
- if (_context.Annotations.FlowAnnotations.ShouldWarnWhenAccessedForReflection (field) &&
+ if (Context.Annotations.FlowAnnotations.ShouldWarnWhenAccessedForReflection (field) &&
!ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode ())
- _context.LogWarning (
+ Context.LogWarning (
$"Field '{field.GetDisplayName ()}' with 'DynamicallyAccessedMembersAttribute' is accessed via reflection. Trimmer can't guarantee availability of the requirements of the field.",
2110,
- _scopeStack.CurrentScope.Origin,
+ ScopeStack.CurrentScope.Origin,
MessageSubCategory.TrimAnalysis);
break;
@@ -1643,7 +1682,7 @@ namespace Mono.Linker.Steps
// Use the original scope for marking the declaring type - it provides better warning message location
MarkType (field.DeclaringType, new DependencyInfo (DependencyKind.DeclaringType, field));
- using var fieldScope = _scopeStack.PushScope (new MessageOrigin (field));
+ using var fieldScope = ScopeStack.PushScope (new MessageOrigin (field));
MarkType (field.FieldType, new DependencyInfo (DependencyKind.FieldType, field));
MarkCustomAttributes (field, new DependencyInfo (DependencyKind.CustomAttribute, field));
MarkMarshalSpec (field, new DependencyInfo (DependencyKind.FieldMarshalSpec, field));
@@ -1660,10 +1699,10 @@ namespace Mono.Linker.Steps
if (!field.DeclaringType.IsValueType && !field.DeclaringType.IsAutoLayout) {
// We also need to walk the base hierarchy because the offset of the field depends on the
// layout of the base.
- TypeDefinition typeWithFields = field.DeclaringType;
+ TypeDefinition? typeWithFields = field.DeclaringType;
while (typeWithFields != null) {
MarkImplicitlyUsedFields (typeWithFields);
- typeWithFields = _context.TryResolve (typeWithFields.BaseType);
+ typeWithFields = Context.TryResolve (typeWithFields.BaseType);
}
}
@@ -1685,8 +1724,8 @@ namespace Mono.Linker.Steps
protected virtual bool IgnoreScope (IMetadataScope scope)
{
- AssemblyDefinition assembly = _context.Resolve (scope);
- return Annotations.GetAction (assembly) != AssemblyAction.Link;
+ AssemblyDefinition? assembly = Context.Resolve (scope);
+ return assembly != null && Annotations.GetAction (assembly) != AssemblyAction.Link;
}
void MarkModule (ModuleDefinition module, DependencyInfo reason)
@@ -1706,7 +1745,7 @@ namespace Mono.Linker.Steps
if (!type.HasMethods)
return;
- if (_context.GetTargetRuntimeVersion () > TargetRuntimeVersion.NET5)
+ if (Context.GetTargetRuntimeVersion () > TargetRuntimeVersion.NET5)
return;
if (type.IsSerializable ()) {
@@ -1717,7 +1756,7 @@ namespace Mono.Linker.Steps
MarkMethodsIf (type.Methods, HasOnSerializeOrDeserializeAttribute, new DependencyInfo (DependencyKind.SerializationMethodForType, type));
}
- protected internal virtual TypeDefinition MarkTypeVisibleToReflection (TypeReference type, TypeDefinition definition, in DependencyInfo reason)
+ protected internal virtual TypeDefinition? MarkTypeVisibleToReflection (TypeReference type, TypeDefinition definition, in DependencyInfo reason)
{
// If a type is visible to reflection, we need to stop doing optimization that could cause observable difference
// in reflection APIs. This includes APIs like MakeGenericType (where variant castability of the produced type
@@ -1776,7 +1815,7 @@ namespace Mono.Linker.Steps
/// <param name="reference">The type reference to mark.</param>
/// <param name="reason">The reason why the marking is occuring</param>
/// <returns>The resolved type definition if the reference can be resolved</returns>
- protected internal virtual TypeDefinition MarkType (TypeReference reference, DependencyInfo reason, MessageOrigin? origin = null)
+ protected internal virtual TypeDefinition? MarkType (TypeReference reference, DependencyInfo reason, MessageOrigin? origin = null)
{
#if DEBUG
if (!_typeReasons.Contains (reason.Kind))
@@ -1785,7 +1824,7 @@ namespace Mono.Linker.Steps
if (reference == null)
return null;
- using var localScope = origin.HasValue ? _scopeStack.PushScope (origin.Value) : null;
+ using var localScope = origin.HasValue ? ScopeStack.PushScope (origin.Value) : null;
(reference, reason) = GetOriginalType (reference, reason);
@@ -1795,7 +1834,7 @@ namespace Mono.Linker.Steps
if (reference is GenericParameter)
return null;
- TypeDefinition type = _context.Resolve (reference);
+ TypeDefinition? type = Context.Resolve (reference);
if (type == null)
return null;
@@ -1814,29 +1853,30 @@ namespace Mono.Linker.Steps
if (type.HasMethods && ShouldMarkTypeStaticConstructor (type) && reason.Kind == DependencyKind.DeclaringTypeOfCalledMethod)
MarkStaticConstructor (type, new DependencyInfo (DependencyKind.TriggersCctorForCalledMethod, reason.Source));
- if (_context.Annotations.HasLinkerAttribute<RemoveAttributeInstancesAttribute> (type)) {
+ if (Context.Annotations.HasLinkerAttribute<RemoveAttributeInstancesAttribute> (type)) {
// Don't warn about references from the removed attribute itself (for example the .ctor on the attribute
// will call MarkType on the attribute type itself).
// If for some reason we do keep the attribute type (could be because of previous reference which would cause IL2045
// or because of a copy assembly with a reference and so on) then we should not spam the warnings due to the type itself.
if (!(reason.Source is IMemberDefinition sourceMemberDefinition && sourceMemberDefinition.DeclaringType == type))
- _context.LogWarning (
+ Context.LogWarning (
$"Attribute '{type.GetDisplayName ()}' is being referenced in code but the trimmer was " +
$"instructed to remove all instances of this attribute. If the attribute instances are necessary make sure to " +
$"either remove the trimmer attribute XML portion which removes the attribute instances, " +
$"or override the removal by using the trimmer XML descriptor to keep the attribute type " +
$"(which in turn keeps all of its instances).",
- 2045, _scopeStack.CurrentScope.Origin, subcategory: MessageSubCategory.TrimAnalysis);
+ 2045, ScopeStack.CurrentScope.Origin, subcategory: MessageSubCategory.TrimAnalysis);
}
if (CheckProcessed (type))
return type;
- MarkModule (type.Scope as ModuleDefinition, new DependencyInfo (DependencyKind.ScopeOfType, type));
+ if (type.Scope is ModuleDefinition module)
+ MarkModule (module, new DependencyInfo (DependencyKind.ScopeOfType, type));
- using var typeScope = _scopeStack.PushScope (new MessageOrigin (type));
+ using var typeScope = ScopeStack.PushScope (new MessageOrigin (type));
- foreach (Action<TypeDefinition> handleMarkType in _markContext.MarkTypeActions)
+ foreach (Action<TypeDefinition> handleMarkType in MarkContext.MarkTypeActions)
handleMarkType (type);
MarkType (type.BaseType, new DependencyInfo (DependencyKind.BaseType, type));
@@ -1844,24 +1884,24 @@ namespace Mono.Linker.Steps
// The DynamicallyAccessedMembers hiearchy processing must be done after the base type was marked
// (to avoid inconsistencies in the cache), but before anything else as work done below
// might need the results of the processing here.
- _dynamicallyAccessedMembersTypeHierarchy.ProcessMarkedTypeForDynamicallyAccessedMembersHierarchy (type);
+ DynamicallyAccessedMembersTypeHierarchy.ProcessMarkedTypeForDynamicallyAccessedMembersHierarchy (type);
if (type.DeclaringType != null)
MarkType (type.DeclaringType, new DependencyInfo (DependencyKind.DeclaringType, type));
MarkCustomAttributes (type, new DependencyInfo (DependencyKind.CustomAttribute, type));
MarkSecurityDeclarations (type, new DependencyInfo (DependencyKind.CustomAttribute, type));
- if (_context.TryResolve (type.BaseType) is TypeDefinition baseType &&
- !_context.Annotations.HasLinkerAttribute<RequiresUnreferencedCodeAttribute> (type) &&
- _context.Annotations.TryGetLinkerAttribute (baseType, out RequiresUnreferencedCodeAttribute effectiveRequiresUnreferencedCode)) {
+ if (Context.TryResolve (type.BaseType) is TypeDefinition baseType &&
+ !Context.Annotations.HasLinkerAttribute<RequiresUnreferencedCodeAttribute> (type) &&
+ Context.Annotations.TryGetLinkerAttribute (baseType, out RequiresUnreferencedCodeAttribute? effectiveRequiresUnreferencedCode)) {
- var currentOrigin = _scopeStack.CurrentScope.Origin;
+ var currentOrigin = ScopeStack.CurrentScope.Origin;
string formatString = SharedStrings.RequiresOnBaseClassMessage;
string arg1 = MessageFormat.FormatRequiresAttributeMessageArg (effectiveRequiresUnreferencedCode.Message);
string arg2 = MessageFormat.FormatRequiresAttributeUrlArg (effectiveRequiresUnreferencedCode.Url);
string message = string.Format (formatString, type, type.BaseType.GetDisplayName (), arg1, arg2);
- _context.LogWarning (message, 2109, currentOrigin, MessageSubCategory.TrimAnalysis);
+ Context.LogWarning (message, 2109, currentOrigin, MessageSubCategory.TrimAnalysis);
}
@@ -1876,7 +1916,7 @@ namespace Mono.Linker.Steps
// This marks static fields of KeyWords/OpCodes/Tasks subclasses of an EventSource type.
// The special handling of EventSource is still needed in .NET6 in library mode
- if ((!_context.DisableEventSourceSpecialHandling || _context.GetTargetRuntimeVersion () < TargetRuntimeVersion.NET6) && BCL.EventTracingForWindows.IsEventSourceImplementation (type, _context)) {
+ if ((!Context.DisableEventSourceSpecialHandling || Context.GetTargetRuntimeVersion () < TargetRuntimeVersion.NET6) && BCL.EventTracingForWindows.IsEventSourceImplementation (type, Context)) {
MarkEventSourceProviders (type);
}
@@ -1911,13 +1951,13 @@ namespace Mono.Linker.Steps
}
if (type.HasInterfaces)
- _typesWithInterfaces.Add ((type, _scopeStack.CurrentScope));
+ _typesWithInterfaces.Add ((type, ScopeStack.CurrentScope));
if (type.HasMethods) {
// For virtuals that must be preserved, blame the declaring type.
MarkMethodsIf (type.Methods, IsVirtualNeededByTypeDueToPreservedScope, new DependencyInfo (DependencyKind.VirtualNeededDueToPreservedScope, type));
if (ShouldMarkTypeStaticConstructor (type) && reason.Kind != DependencyKind.TriggersCctorForCalledMethod) {
- using (_scopeStack.PopToParent ())
+ using (ScopeStack.PopToParent ())
MarkStaticConstructor (type, new DependencyInfo (DependencyKind.CctorForType, type));
}
}
@@ -1965,21 +2005,21 @@ namespace Mono.Linker.Steps
{
}
- TypeDefinition GetDebuggerAttributeTargetType (CustomAttribute ca, AssemblyDefinition asm)
+ TypeDefinition? GetDebuggerAttributeTargetType (CustomAttribute ca, AssemblyDefinition asm)
{
foreach (var property in ca.Properties) {
if (property.Name == "Target")
- return _context.TryResolve ((TypeReference) property.Argument.Value);
+ return Context.TryResolve ((TypeReference) property.Argument.Value);
if (property.Name == "TargetTypeName") {
string targetTypeName = (string) property.Argument.Value;
TypeName typeName = TypeParser.ParseTypeName (targetTypeName);
if (typeName is AssemblyQualifiedTypeName assemblyQualifiedTypeName) {
- AssemblyDefinition assembly = _context.TryResolve (assemblyQualifiedTypeName.AssemblyName.Name);
- return _context.TryResolve (assembly, targetTypeName);
+ AssemblyDefinition? assembly = Context.TryResolve (assemblyQualifiedTypeName.AssemblyName.Name);
+ return assembly == null ? null : Context.TryResolve (assembly, targetTypeName);
}
- return _context.TryResolve (asm, targetTypeName);
+ return Context.TryResolve (asm, targetTypeName);
}
}
@@ -1993,12 +2033,12 @@ namespace Mono.Linker.Steps
foreach (CustomAttribute attribute in type.CustomAttributes) {
var attrType = attribute.Constructor.DeclaringType;
- var resolvedAttributeType = _context.Resolve (attrType);
+ var resolvedAttributeType = Context.Resolve (attrType);
if (resolvedAttributeType == null) {
continue;
}
- if (_context.Annotations.HasLinkerAttribute<RemoveAttributeInstancesAttribute> (resolvedAttributeType) && Annotations.GetAction (type.Module.Assembly) == AssemblyAction.Link)
+ if (Context.Annotations.HasLinkerAttribute<RemoveAttributeInstancesAttribute> (resolvedAttributeType) && Annotations.GetAction (type.Module.Assembly) == AssemblyAction.Link)
continue;
switch (attrType.Name) {
@@ -2012,7 +2052,7 @@ namespace Mono.Linker.Steps
MarkTypeWithDebuggerTypeProxyAttribute (type, attribute);
break;
// The special handling of EventSource is still needed in .NET6 in library mode
- case "EventDataAttribute" when attrType.Namespace == "System.Diagnostics.Tracing" && (!_context.DisableEventSourceSpecialHandling || _context.GetTargetRuntimeVersion () < TargetRuntimeVersion.NET6):
+ case "EventDataAttribute" when attrType.Namespace == "System.Diagnostics.Tracing" && (!Context.DisableEventSourceSpecialHandling || Context.GetTargetRuntimeVersion () < TargetRuntimeVersion.NET6):
if (MarkMethodsIf (type.Methods, MethodDefinitionExtensions.IsPublicInstancePropertyMethod, new DependencyInfo (DependencyKind.ReferencedBySpecialAttribute, type)))
Tracer.AddDirectDependency (attribute, new DependencyInfo (DependencyKind.CustomAttribute, type), marked: false);
break;
@@ -2056,7 +2096,7 @@ namespace Mono.Linker.Steps
void MarkXmlSchemaProvider (TypeDefinition type, CustomAttribute attribute)
{
- if (TryGetStringArgument (attribute, out string name)) {
+ if (TryGetStringArgument (attribute, out string? name)) {
Tracer.AddDirectDependency (attribute, new DependencyInfo (DependencyKind.CustomAttribute, type), marked: false);
MarkNamedMethod (type, name, new DependencyInfo (DependencyKind.ReferencedBySpecialAttribute, attribute));
}
@@ -2068,16 +2108,18 @@ namespace Mono.Linker.Steps
if (args.Count < 1)
return;
- TypeDefinition typeDefinition = null;
+ TypeDefinition? typeDefinition = null;
switch (attribute.ConstructorArguments[0].Value) {
case string s:
- typeDefinition = _context.TryResolve (_context.TypeNameResolver.ResolveTypeName (s, _scopeStack.CurrentScope.Origin.Provider, out AssemblyDefinition assemblyDefinition));
+ if (!Context.TypeNameResolver.TryResolveTypeName (s, ScopeStack.CurrentScope.Origin.Provider, out TypeReference? typeRef, out AssemblyDefinition? assemblyDefinition))
+ break;
+ typeDefinition = Context.TryResolve (typeRef);
if (typeDefinition != null)
MarkingHelpers.MarkMatchingExportedType (typeDefinition, assemblyDefinition, new DependencyInfo (DependencyKind.CustomAttribute, provider));
break;
case TypeReference type:
- typeDefinition = _context.Resolve (type);
+ typeDefinition = Context.Resolve (type);
break;
}
@@ -2092,7 +2134,7 @@ namespace Mono.Linker.Steps
void MarkTypeWithDebuggerDisplayAttribute (TypeDefinition type, CustomAttribute attribute)
{
- if (_context.KeepMembersForDebugger) {
+ if (Context.KeepMembersForDebugger) {
// Members referenced by the DebuggerDisplayAttribute are kept even if the attribute may not be.
// Record a logical dependency on the attribute so that we can blame it for the kept members below.
@@ -2122,19 +2164,19 @@ namespace Mono.Linker.Steps
if (methodName.Contains ('.'))
continue;
- MethodDefinition method = GetMethodWithNoParameters (type, methodName);
+ MethodDefinition? method = GetMethodWithNoParameters (type, methodName);
if (method != null) {
MarkMethod (method, new DependencyInfo (DependencyKind.ReferencedBySpecialAttribute, attribute));
continue;
}
} else {
- FieldDefinition field = GetField (type, realMatch);
+ FieldDefinition? field = GetField (type, realMatch);
if (field != null) {
MarkField (field, new DependencyInfo (DependencyKind.ReferencedBySpecialAttribute, attribute));
continue;
}
- PropertyDefinition property = GetProperty (type, realMatch);
+ PropertyDefinition? property = GetProperty (type, realMatch);
if (property != null) {
if (property.GetMethod != null) {
MarkMethod (property.GetMethod, new DependencyInfo (DependencyKind.ReferencedBySpecialAttribute, attribute));
@@ -2146,12 +2188,14 @@ namespace Mono.Linker.Steps
}
}
- while (type != null) {
+ while (true) {
// Currently if we don't understand the DebuggerDisplayAttribute we mark everything on the type
// This can be improved: dotnet/linker/issues/1873
MarkMethods (type, new DependencyInfo (DependencyKind.KeptForSpecialAttribute, attribute));
MarkFields (type, includeStatic: true, new DependencyInfo (DependencyKind.ReferencedBySpecialAttribute, attribute));
- type = _context.TryResolve (type.BaseType);
+ if (Context.TryResolve (type.BaseType) is not TypeDefinition baseType)
+ break;
+ type = baseType;
}
return;
}
@@ -2160,9 +2204,9 @@ namespace Mono.Linker.Steps
void MarkTypeWithDebuggerTypeProxyAttribute (TypeDefinition type, CustomAttribute attribute)
{
- if (_context.KeepMembersForDebugger) {
+ if (Context.KeepMembersForDebugger) {
object constructorArgument = attribute.ConstructorArguments[0].Value;
- TypeReference proxyTypeReference = constructorArgument as TypeReference;
+ TypeReference? proxyTypeReference = constructorArgument as TypeReference;
if (proxyTypeReference == null) {
if (constructorArgument is string proxyTypeReferenceString) {
proxyTypeReference = type.Module.GetType (proxyTypeReferenceString, runtimeName: true);
@@ -2176,15 +2220,14 @@ namespace Mono.Linker.Steps
Tracer.AddDirectDependency (attribute, new DependencyInfo (DependencyKind.CustomAttribute, type), marked: false);
MarkType (proxyTypeReference, new DependencyInfo (DependencyKind.ReferencedBySpecialAttribute, attribute));
- TypeDefinition proxyType = _context.TryResolve (proxyTypeReference);
- if (proxyType != null) {
+ if (Context.TryResolve (proxyTypeReference) is TypeDefinition proxyType) {
MarkMethods (proxyType, new DependencyInfo (DependencyKind.ReferencedBySpecialAttribute, attribute));
MarkFields (proxyType, includeStatic: true, new DependencyInfo (DependencyKind.ReferencedBySpecialAttribute, attribute));
}
}
}
- static bool TryGetStringArgument (CustomAttribute attribute, out string argument)
+ static bool TryGetStringArgument (CustomAttribute attribute, [NotNullWhen (true)] out string? argument)
{
argument = null;
@@ -2215,7 +2258,7 @@ namespace Mono.Linker.Steps
void MarkSoapHeader (MethodDefinition method, CustomAttribute attribute)
{
- if (!TryGetStringArgument (attribute, out string member_name))
+ if (!TryGetStringArgument (attribute, out string? member_name))
return;
MarkNamedField (method.DeclaringType, member_name, new DependencyInfo (DependencyKind.ReferencedBySpecialAttribute, attribute));
@@ -2247,7 +2290,7 @@ namespace Mono.Linker.Steps
if (property.Name != property_name)
continue;
- using (_scopeStack.PushScope (new MessageOrigin (property))) {
+ using (ScopeStack.PushScope (new MessageOrigin (property))) {
// This marks methods directly without reporting the property.
MarkMethod (property.GetMethod, reason);
MarkMethod (property.SetMethod, reason);
@@ -2263,7 +2306,7 @@ namespace Mono.Linker.Steps
foreach (var iface in type.Interfaces) {
// Only mark interface implementations of interface types that have been marked.
// This enables stripping of interfaces that are never used
- var resolvedInterfaceType = _context.Resolve (iface.InterfaceType);
+ var resolvedInterfaceType = Context.Resolve (iface.InterfaceType);
if (resolvedInterfaceType == null) {
continue;
}
@@ -2370,7 +2413,7 @@ namespace Mono.Linker.Steps
return marked;
}
- protected MethodDefinition MarkMethodIf (Collection<MethodDefinition> methods, Func<MethodDefinition, bool> predicate, in DependencyInfo reason)
+ protected MethodDefinition? MarkMethodIf (Collection<MethodDefinition> methods, Func<MethodDefinition, bool> predicate, in DependencyInfo reason)
{
foreach (MethodDefinition method in methods) {
if (predicate (method)) {
@@ -2399,8 +2442,9 @@ namespace Mono.Linker.Steps
reason);
}
- void MarkICustomMarshalerMethods (TypeDefinition type, in DependencyInfo reason)
+ void MarkICustomMarshalerMethods (TypeDefinition inputType, in DependencyInfo reason)
{
+ TypeDefinition? type = inputType;
do {
if (!type.HasInterfaces)
continue;
@@ -2414,7 +2458,7 @@ namespace Mono.Linker.Steps
// Instead of trying to guess where to find the interface declaration linker walks
// the list of implemented interfaces and resolve the declaration from there
//
- var tdef = _context.Resolve (iface_type);
+ var tdef = Context.Resolve (iface_type);
if (tdef == null) {
return;
}
@@ -2424,7 +2468,7 @@ namespace Mono.Linker.Steps
MarkInterfaceImplementation (iface, new MessageOrigin (type));
return;
}
- } while ((type = _context.TryResolve (type.BaseType)) != null);
+ } while ((type = Context.TryResolve (type.BaseType)) != null);
}
static bool IsNonEmptyStaticConstructor (MethodDefinition method)
@@ -2478,7 +2522,7 @@ namespace Mono.Linker.Steps
void MarkEventSourceProviders (TypeDefinition td)
{
- Debug.Assert (_context.GetTargetRuntimeVersion () < TargetRuntimeVersion.NET6 || !_context.DisableEventSourceSpecialHandling);
+ Debug.Assert (Context.GetTargetRuntimeVersion () < TargetRuntimeVersion.NET6 || !Context.DisableEventSourceSpecialHandling);
foreach (var nestedType in td.NestedTypes) {
if (BCL.EventTracingForWindows.IsProviderName (nestedType.Name))
MarkStaticFields (nestedType, new DependencyInfo (DependencyKind.EventSourceProviderField, td));
@@ -2548,14 +2592,14 @@ namespace Mono.Linker.Steps
var argument = arguments[i];
var parameter = parameters[i];
- TypeDefinition argumentTypeDef = MarkType (argument, new DependencyInfo (DependencyKind.GenericArgumentType, instance));
+ TypeDefinition? argumentTypeDef = MarkType (argument, new DependencyInfo (DependencyKind.GenericArgumentType, instance));
- if (_context.Annotations.FlowAnnotations.RequiresDataFlowAnalysis (parameter)) {
+ if (Context.Annotations.FlowAnnotations.RequiresDataFlowAnalysis (parameter)) {
// The only two implementations of IGenericInstance both derive from MemberReference
Debug.Assert (instance is MemberReference);
- using var _ = _scopeStack.CurrentScope.Origin.Provider == null ? _scopeStack.PushScope (new MessageOrigin (((MemberReference) instance).Resolve ())) : null;
- var scanner = new ReflectionMethodBodyScanner (_context, this, _scopeStack);
+ using var _ = ScopeStack.CurrentScope.Origin.Provider == null ? ScopeStack.PushScope (new MessageOrigin (((MemberReference) instance).Resolve ())) : null;
+ var scanner = new ReflectionMethodBodyScanner (Context, this, ScopeStack);
scanner.ProcessGenericArgumentDataFlow (parameter, argument);
}
@@ -2569,20 +2613,20 @@ namespace Mono.Linker.Steps
}
}
- IGenericParameterProvider GetGenericProviderFromInstance (IGenericInstance instance)
+ IGenericParameterProvider? GetGenericProviderFromInstance (IGenericInstance instance)
{
if (instance is GenericInstanceMethod method)
- return _context.TryResolve (method.ElementMethod);
+ return Context.TryResolve (method.ElementMethod);
if (instance is GenericInstanceType type)
- return _context.TryResolve (type.ElementType);
+ return Context.TryResolve (type.ElementType);
return null;
}
void ApplyPreserveInfo (TypeDefinition type)
{
- using var typeScope = _scopeStack.PushScope (new MessageOrigin (type));
+ using var typeScope = ScopeStack.PushScope (new MessageOrigin (type));
if (Annotations.TryGetPreserve (type, out TypePreserve preserve)) {
if (!Annotations.SetAppliedPreserve (type, preserve))
@@ -2598,11 +2642,11 @@ namespace Mono.Linker.Steps
case TypePreserve.Fields:
if (!MarkFields (type, true, di, true))
- _context.LogWarning ($"Type '{type.GetDisplayName ()}' has no fields to preserve.", 2001, type);
+ Context.LogWarning ($"Type '{type.GetDisplayName ()}' has no fields to preserve.", 2001, type);
break;
case TypePreserve.Methods:
if (!MarkMethods (type, di))
- _context.LogWarning ($"Type '{type.GetDisplayName ()}' has no methods to preserve.", 2002, type);
+ Context.LogWarning ($"Type '{type.GetDisplayName ()}' has no methods to preserve.", 2002, type);
break;
}
}
@@ -2714,7 +2758,7 @@ namespace Mono.Linker.Steps
return true;
}
- static PropertyDefinition SearchPropertiesForMatchingFieldDefinition (FieldDefinition field)
+ static PropertyDefinition? SearchPropertiesForMatchingFieldDefinition (FieldDefinition field)
{
foreach (var property in field.DeclaringType.Properties) {
var instr = property.GetMethod?.Body?.Instructions;
@@ -2762,7 +2806,7 @@ namespace Mono.Linker.Steps
Annotations.MarkIndirectlyCalledMethod (method);
}
- protected virtual MethodDefinition MarkMethod (MethodReference reference, DependencyInfo reason)
+ protected virtual MethodDefinition? MarkMethod (MethodReference reference, DependencyInfo reason)
{
DependencyKind originalReasonKind = reason.Kind;
(reference, reason) = GetOriginalMethod (reference, reason);
@@ -2770,7 +2814,7 @@ namespace Mono.Linker.Steps
if (reference.DeclaringType is ArrayType arrayType) {
MarkType (reference.DeclaringType, new DependencyInfo (DependencyKind.DeclaringType, reference));
- if (reference.Name == ".ctor" && _context.TryResolve (arrayType) is TypeDefinition typeDefinition) {
+ if (reference.Name == ".ctor" && Context.TryResolve (arrayType) is TypeDefinition typeDefinition) {
Annotations.MarkRelevantToVariantCasting (typeDefinition);
}
return null;
@@ -2784,14 +2828,14 @@ namespace Mono.Linker.Steps
reason = new DependencyInfo (DependencyKind.MethodOnGenericInstance, reference);
}
- MethodDefinition method = _context.Resolve (reference);
+ MethodDefinition? method = Context.Resolve (reference);
if (method == null)
return null;
if (Annotations.GetAction (method) == MethodAction.Nothing)
Annotations.SetAction (method, MethodAction.Parse);
- EnqueueMethod (method, reason, _scopeStack.CurrentScope);
+ EnqueueMethod (method, reason, ScopeStack.CurrentScope);
// Use the original reason as it's important to correctly generate warnings
// the updated reason is only useful for better tracking of dependencies.
@@ -2880,7 +2924,7 @@ namespace Mono.Linker.Steps
CheckAndReportRequiresUnreferencedCode (method);
- if (_context.Annotations.FlowAnnotations.ShouldWarnWhenAccessedForReflection (method)) {
+ if (Context.Annotations.FlowAnnotations.ShouldWarnWhenAccessedForReflection (method)) {
// If the current scope has analysis warnings suppressed, don't generate any
if (ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode ())
return;
@@ -2896,10 +2940,10 @@ namespace Mono.Linker.Steps
break;
}
- _context.LogWarning (
+ Context.LogWarning (
$"Method '{method.GetDisplayName ()}' with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. Trimmer can't guarantee availability of the requirements of the method.",
2111,
- _scopeStack.CurrentScope.Origin,
+ ScopeStack.CurrentScope.Origin,
MessageSubCategory.TrimAnalysis);
}
}
@@ -2910,14 +2954,14 @@ namespace Mono.Linker.Steps
// since that attribute automatically suppresses all trim analysis warnings.
// Check both the immediate origin method as well as suppression context method
// since that will be different for compiler generated code.
- var currentOrigin = _scopeStack.CurrentScope.Origin;
+ var currentOrigin = ScopeStack.CurrentScope.Origin;
- ICustomAttributeProvider suppressionContextMember = currentOrigin.SuppressionContextMember;
+ ICustomAttributeProvider? suppressionContextMember = currentOrigin.SuppressionContextMember;
if (suppressionContextMember is MethodDefinition &&
Annotations.IsMethodInRequiresUnreferencedCodeScope ((MethodDefinition) suppressionContextMember))
return true;
- ICustomAttributeProvider originMember = currentOrigin.Provider;
+ ICustomAttributeProvider? originMember = currentOrigin.Provider;
if (originMember is MethodDefinition && suppressionContextMember != originMember &&
Annotations.IsMethodInRequiresUnreferencedCodeScope ((MethodDefinition) originMember))
return true;
@@ -2932,10 +2976,10 @@ namespace Mono.Linker.Steps
if (ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode ())
return;
- if (!Annotations.DoesMethodRequireUnreferencedCode (method, out RequiresUnreferencedCodeAttribute requiresUnreferencedCode))
+ if (!Annotations.DoesMethodRequireUnreferencedCode (method, out RequiresUnreferencedCodeAttribute? requiresUnreferencedCode))
return;
- ReportRequiresUnreferencedCode (method.GetDisplayName (), requiresUnreferencedCode, _scopeStack.CurrentScope.Origin);
+ ReportRequiresUnreferencedCode (method.GetDisplayName (), requiresUnreferencedCode, ScopeStack.CurrentScope.Origin);
}
private void ReportRequiresUnreferencedCode (string displayName, RequiresUnreferencedCodeAttribute requiresUnreferencedCode, MessageOrigin currentOrigin)
@@ -2943,7 +2987,7 @@ namespace Mono.Linker.Steps
string arg1 = MessageFormat.FormatRequiresAttributeMessageArg (requiresUnreferencedCode.Message);
string arg2 = MessageFormat.FormatRequiresAttributeUrlArg (requiresUnreferencedCode.Url);
string message = string.Format (SharedStrings.RequiresUnreferencedCodeMessage, displayName, arg1, arg2);
- _context.LogWarning (message, 2026, currentOrigin, MessageSubCategory.TrimAnalysis);
+ Context.LogWarning (message, 2026, currentOrigin, MessageSubCategory.TrimAnalysis);
}
protected (MethodReference, DependencyInfo) GetOriginalMethod (MethodReference method, DependencyInfo reason)
@@ -2968,9 +3012,9 @@ namespace Mono.Linker.Steps
if (!_methodReasons.Contains (reason.Kind))
throw new InternalErrorException ($"Unsupported method dependency {reason.Kind}");
#endif
- _scopeStack.AssertIsEmpty ();
- using var parentScope = _scopeStack.PushScope (scope);
- using var methodScope = _scopeStack.PushScope (new MessageOrigin (method));
+ ScopeStack.AssertIsEmpty ();
+ using var parentScope = ScopeStack.PushScope (scope);
+ using var methodScope = ScopeStack.PushScope (new MessageOrigin (method));
// Record the reason for marking a method on each call. The logic under CheckProcessed happens
// only once per method.
@@ -2999,9 +3043,9 @@ namespace Mono.Linker.Steps
if (CheckProcessed (method))
return;
- _unreachableBlocksOptimizer.ProcessMethod (method);
+ UnreachableBlocksOptimizer.ProcessMethod (method);
- foreach (Action<MethodDefinition> handleMarkMethod in _markContext.MarkMethodActions)
+ foreach (Action<MethodDefinition> handleMarkMethod in MarkContext.MarkMethodActions)
handleMarkMethod (method);
if (!markedForCall)
@@ -3015,15 +3059,15 @@ namespace Mono.Linker.Steps
MarkRequirementsForInstantiatedTypes (method.DeclaringType);
Tracer.AddDirectDependency (method.DeclaringType, new DependencyInfo (DependencyKind.InstantiatedByCtor, method), marked: false);
} else if (method.IsStaticConstructor () && Annotations.HasLinkerAttribute<RequiresUnreferencedCodeAttribute> (method))
- _context.LogWarning (new DiagnosticString (DiagnosticId.RequiresUnreferencedCodeOnStaticConstructor).GetMessage (method.GetDisplayName ()), (int) DiagnosticId.RequiresUnreferencedCodeOnStaticConstructor, _scopeStack.CurrentScope.Origin, MessageSubCategory.TrimAnalysis);
+ Context.LogWarning (new DiagnosticString (DiagnosticId.RequiresUnreferencedCodeOnStaticConstructor).GetMessage (method.GetDisplayName ()), (int) DiagnosticId.RequiresUnreferencedCodeOnStaticConstructor, ScopeStack.CurrentScope.Origin, MessageSubCategory.TrimAnalysis);
if (method.IsConstructor) {
if (!Annotations.ProcessSatelliteAssemblies && KnownMembers.IsSatelliteAssemblyMarker (method))
Annotations.ProcessSatelliteAssemblies = true;
- } else if (method.IsPropertyMethod ())
- MarkProperty (method.GetProperty (), new DependencyInfo (DependencyKind.PropertyOfPropertyMethod, method));
- else if (method.IsEventMethod ())
- MarkEvent (method.GetEvent (), new DependencyInfo (DependencyKind.EventOfEventMethod, method));
+ } else if (method.TryGetProperty (out PropertyDefinition? property))
+ MarkProperty (property, new DependencyInfo (DependencyKind.PropertyOfPropertyMethod, method));
+ else if (method.TryGetEvent (out EventDefinition? @event))
+ MarkEvent (@event, new DependencyInfo (DependencyKind.EventOfEventMethod, method));
if (method.HasParameters) {
foreach (ParameterDefinition pd in method.Parameters) {
@@ -3042,7 +3086,7 @@ namespace Mono.Linker.Steps
MarkMethodSpecialCustomAttributes (method);
if (method.IsVirtual)
- _virtual_methods.Add ((method, _scopeStack.CurrentScope));
+ _virtual_methods.Add ((method, ScopeStack.CurrentScope));
MarkNewCodeDependencies (method);
@@ -3060,7 +3104,7 @@ namespace Mono.Linker.Steps
MarkMethodBody (method.Body);
if (method.DeclaringType.IsMulticastDelegate ()) {
- string methodPair = null;
+ string? methodPair = null;
if (method.Name == "BeginInvoke")
methodPair = "EndInvoke";
else if (method.Name == "EndInvoke")
@@ -3099,7 +3143,7 @@ namespace Mono.Linker.Steps
Annotations.MarkInstantiated (type);
- using var typeScope = _scopeStack.PushScope (new MessageOrigin (type));
+ using var typeScope = ScopeStack.PushScope (new MessageOrigin (type));
MarkInterfaceImplementations (type);
@@ -3128,14 +3172,12 @@ namespace Mono.Linker.Steps
void MarkExplicitInterfaceImplementation (MethodDefinition method, MethodReference ov)
{
- MethodDefinition resolvedOverride = _context.Resolve (ov);
-
- if (resolvedOverride == null)
+ if (Context.Resolve (ov) is not MethodDefinition resolvedOverride)
return;
if (resolvedOverride.DeclaringType.IsInterface) {
foreach (var ifaceImpl in method.DeclaringType.Interfaces) {
- var resolvedInterfaceType = _context.Resolve (ifaceImpl.InterfaceType);
+ var resolvedInterfaceType = Context.Resolve (ifaceImpl.InterfaceType);
if (resolvedInterfaceType == null) {
continue;
}
@@ -3155,10 +3197,12 @@ namespace Mono.Linker.Steps
if (!method.IsInstanceConstructor ())
return;
- var baseType = _context.Resolve (method.DeclaringType.BaseType);
+ var baseType = Context.Resolve (method.DeclaringType.BaseType);
+ if (baseType == null)
+ break;
if (!MarkDefaultConstructor (baseType, new DependencyInfo (DependencyKind.BaseDefaultCtorForStubbedMethod, method)))
throw new LinkerFatalErrorException (MessageContainer.CreateErrorMessage ($"Cannot stub constructor on '{method.DeclaringType}' when base type does not have default constructor",
- 1006, origin: _scopeStack.CurrentScope.Origin));
+ 1006, origin: ScopeStack.CurrentScope.Origin));
break;
@@ -3170,44 +3214,44 @@ namespace Mono.Linker.Steps
protected virtual void MarkAndCacheConvertToThrowExceptionCtor (DependencyInfo reason)
{
- if (_context.MarkedKnownMembers.NotSupportedExceptionCtorString != null)
+ if (Context.MarkedKnownMembers.NotSupportedExceptionCtorString != null)
return;
- var nse = BCL.FindPredefinedType ("System", "NotSupportedException", _context);
+ var nse = BCL.FindPredefinedType ("System", "NotSupportedException", Context);
if (nse == null)
throw new LinkerFatalErrorException (MessageContainer.CreateErrorMessage ("Missing predefined 'System.NotSupportedException' type", 1007));
MarkType (nse, reason);
var nseCtor = MarkMethodIf (nse.Methods, KnownMembers.IsNotSupportedExceptionCtorString, reason);
- _context.MarkedKnownMembers.NotSupportedExceptionCtorString = nseCtor ??
+ Context.MarkedKnownMembers.NotSupportedExceptionCtorString = nseCtor ??
throw new LinkerFatalErrorException (MessageContainer.CreateErrorMessage ($"Could not find constructor on '{nse.GetDisplayName ()}'", 1008));
- var objectType = BCL.FindPredefinedType ("System", "Object", _context);
+ var objectType = BCL.FindPredefinedType ("System", "Object", Context);
if (objectType == null)
throw new NotSupportedException ("Missing predefined 'System.Object' type");
MarkType (objectType, reason);
var objectCtor = MarkMethodIf (objectType.Methods, MethodDefinitionExtensions.IsDefaultConstructor, reason);
- _context.MarkedKnownMembers.ObjectCtor = objectCtor ??
+ Context.MarkedKnownMembers.ObjectCtor = objectCtor ??
throw new LinkerFatalErrorException (MessageContainer.CreateErrorMessage ($"Could not find constructor on '{objectType.GetDisplayName ()}'", 1008));
}
bool MarkDisablePrivateReflectionAttribute ()
{
- if (_context.MarkedKnownMembers.DisablePrivateReflectionAttributeCtor != null)
+ if (Context.MarkedKnownMembers.DisablePrivateReflectionAttributeCtor != null)
return false;
- var disablePrivateReflection = BCL.FindPredefinedType ("System.Runtime.CompilerServices", "DisablePrivateReflectionAttribute", _context);
+ var disablePrivateReflection = BCL.FindPredefinedType ("System.Runtime.CompilerServices", "DisablePrivateReflectionAttribute", Context);
if (disablePrivateReflection == null)
throw new LinkerFatalErrorException (MessageContainer.CreateErrorMessage ("Missing predefined 'System.Runtime.CompilerServices.DisablePrivateReflectionAttribute' type", 1007));
- using (_scopeStack.PushScope (new MessageOrigin (null as ICustomAttributeProvider))) {
+ using (ScopeStack.PushScope (new MessageOrigin (null as ICustomAttributeProvider))) {
MarkType (disablePrivateReflection, DependencyInfo.DisablePrivateReflectionRequirement);
var ctor = MarkMethodIf (disablePrivateReflection.Methods, MethodDefinitionExtensions.IsDefaultConstructor, new DependencyInfo (DependencyKind.DisablePrivateReflectionRequirement, disablePrivateReflection));
- _context.MarkedKnownMembers.DisablePrivateReflectionAttributeCtor = ctor ??
+ Context.MarkedKnownMembers.DisablePrivateReflectionAttributeCtor = ctor ??
throw new LinkerFatalErrorException (MessageContainer.CreateErrorMessage ($"Could not find constructor on '{disablePrivateReflection.GetDisplayName ()}'", 1010));
}
@@ -3234,17 +3278,17 @@ namespace Mono.Linker.Steps
if (method.IsPInvokeImpl && method.PInvokeInfo != null) {
var pii = method.PInvokeInfo;
Annotations.MarkProcessed (pii.Module, new DependencyInfo (DependencyKind.InteropMethodDependency, method));
- if (!string.IsNullOrEmpty (_context.PInvokesListFile)) {
- _context.PInvokes.Add (new PInvokeInfo {
- AssemblyName = method.DeclaringType.Module.Name,
- EntryPoint = pii.EntryPoint,
- FullName = method.FullName,
- ModuleName = pii.Module.Name
- });
+ if (!string.IsNullOrEmpty (Context.PInvokesListFile)) {
+ Context.PInvokes.Add (new PInvokeInfo (
+ assemblyName: method.DeclaringType.Module.Name,
+ entryPoint: pii.EntryPoint,
+ fullName: method.FullName,
+ moduleName: pii.Module.Name
+ ));
}
}
- TypeDefinition returnTypeDefinition = _context.TryResolve (method.ReturnType);
+ TypeDefinition? returnTypeDefinition = Context.TryResolve (method.ReturnType);
const bool includeStaticFields = false;
if (returnTypeDefinition != null) {
@@ -3265,7 +3309,7 @@ namespace Mono.Linker.Steps
if (paramTypeReference is TypeSpecification paramTypeSpecification) {
paramTypeReference = paramTypeSpecification.ElementType;
}
- TypeDefinition paramTypeDefinition = _context.TryResolve (paramTypeReference);
+ TypeDefinition? paramTypeDefinition = Context.TryResolve (paramTypeReference);
if (paramTypeDefinition != null) {
if (!paramTypeDefinition.IsImport) {
// What we keep here is correct most of the time, but not every time. Fine for now.
@@ -3287,7 +3331,9 @@ namespace Mono.Linker.Steps
case MethodAction.ForceParse:
return true;
case MethodAction.Parse:
- AssemblyDefinition assembly = _context.Resolve (method.DeclaringType.Scope);
+ AssemblyDefinition? assembly = Context.Resolve (method.DeclaringType.Scope);
+ if (assembly == null)
+ return false;
switch (Annotations.GetAction (assembly)) {
case AssemblyAction.Link:
case AssemblyAction.Copy:
@@ -3307,7 +3353,7 @@ namespace Mono.Linker.Steps
{
Tracer.AddDirectDependency (prop, reason, marked: false);
- using var propertyScope = _scopeStack.PushScope (new MessageOrigin (prop));
+ using var propertyScope = ScopeStack.PushScope (new MessageOrigin (prop));
// Consider making this more similar to MarkEvent method?
MarkCustomAttributes (prop, new DependencyInfo (DependencyKind.CustomAttribute, prop));
@@ -3319,7 +3365,7 @@ namespace Mono.Linker.Steps
// Record the event without marking it in Annotations.
Tracer.AddDirectDependency (evt, reason, marked: false);
- using var eventScope = _scopeStack.PushScope (new MessageOrigin (evt));
+ using var eventScope = ScopeStack.PushScope (new MessageOrigin (evt));
MarkCustomAttributes (evt, new DependencyInfo (DependencyKind.CustomAttribute, evt));
MarkMethodIfNotNull (evt.AddMethod, new DependencyInfo (DependencyKind.EventMethod, evt));
@@ -3338,9 +3384,9 @@ namespace Mono.Linker.Steps
protected virtual void MarkMethodBody (MethodBody body)
{
- if (_context.IsOptimizationEnabled (CodeOptimizations.UnreachableBodies, body.Method) && IsUnreachableBody (body)) {
+ if (Context.IsOptimizationEnabled (CodeOptimizations.UnreachableBodies, body.Method) && IsUnreachableBody (body)) {
MarkAndCacheConvertToThrowExceptionCtor (new DependencyInfo (DependencyKind.UnreachableBodyRequirement, body.Method));
- _unreachableBodies.Add ((body, _scopeStack.CurrentScope));
+ _unreachableBodies.Add ((body, ScopeStack.CurrentScope));
return;
}
@@ -3352,7 +3398,7 @@ namespace Mono.Linker.Steps
MarkType (eh.CatchType, new DependencyInfo (DependencyKind.CatchType, body.Method));
bool requiresReflectionMethodBodyScanner =
- ReflectionMethodBodyScanner.RequiresReflectionMethodBodyScannerForMethodBody (_context.Annotations.FlowAnnotations, body.Method);
+ ReflectionMethodBodyScanner.RequiresReflectionMethodBodyScannerForMethodBody (Context.Annotations.FlowAnnotations, body.Method);
foreach (Instruction instruction in body.Instructions)
MarkInstruction (instruction, body.Method, ref requiresReflectionMethodBodyScanner);
@@ -3378,7 +3424,7 @@ namespace Mono.Linker.Steps
// If a type could be on the stack in the body and an interface it implements could be on the stack on the body
// then we need to mark that interface implementation. When this occurs it is not safe to remove the interface implementation from the type
// even if the type is never instantiated
- var implementations = new InterfacesOnStackScanner (_context).GetReferencedInterfaces (body);
+ var implementations = new InterfacesOnStackScanner (Context).GetReferencedInterfaces (body);
if (implementations == null)
return;
@@ -3396,14 +3442,14 @@ namespace Mono.Linker.Steps
case Code.Ldflda: // Field address loads (as those can be used to store values to annotated field and thus must be checked)
case Code.Ldsflda:
requiresReflectionMethodBodyScanner |=
- ReflectionMethodBodyScanner.RequiresReflectionMethodBodyScannerForAccess (_context, (FieldReference) instruction.Operand);
+ ReflectionMethodBodyScanner.RequiresReflectionMethodBodyScannerForAccess (Context, (FieldReference) instruction.Operand);
break;
default: // Other field operations are not interesting as they don't need to be checked
break;
}
- _scopeStack.UpdateCurrentScopeInstructionOffset (instruction.Offset);
+ ScopeStack.UpdateCurrentScopeInstructionOffset (instruction.Offset);
MarkField ((FieldReference) instruction.Operand, new DependencyInfo (DependencyKind.FieldAccess, method));
break;
@@ -3419,9 +3465,9 @@ namespace Mono.Linker.Steps
};
requiresReflectionMethodBodyScanner |=
- ReflectionMethodBodyScanner.RequiresReflectionMethodBodyScannerForCallSite (_context, (MethodReference) instruction.Operand);
+ ReflectionMethodBodyScanner.RequiresReflectionMethodBodyScannerForCallSite (Context, (MethodReference) instruction.Operand);
- _scopeStack.UpdateCurrentScopeInstructionOffset (instruction.Offset);
+ ScopeStack.UpdateCurrentScopeInstructionOffset (instruction.Offset);
MarkMethod ((MethodReference) instruction.Operand, new DependencyInfo (dependencyKind, method));
break;
}
@@ -3430,12 +3476,12 @@ namespace Mono.Linker.Steps
object token = instruction.Operand;
Debug.Assert (instruction.OpCode.Code == Code.Ldtoken);
var reason = new DependencyInfo (DependencyKind.Ldtoken, method);
- _scopeStack.UpdateCurrentScopeInstructionOffset (instruction.Offset);
+ ScopeStack.UpdateCurrentScopeInstructionOffset (instruction.Offset);
if (token is TypeReference typeReference) {
// Error will be reported as part of MarkType
- TypeDefinition type = _context.TryResolve (typeReference);
- MarkTypeVisibleToReflection (typeReference, type, reason);
+ if (Context.TryResolve (typeReference) is TypeDefinition type)
+ MarkTypeVisibleToReflection (typeReference, type, reason);
} else if (token is MethodReference methodReference) {
MarkMethod (methodReference, reason);
} else {
@@ -3448,17 +3494,17 @@ namespace Mono.Linker.Steps
var operand = (TypeReference) instruction.Operand;
switch (instruction.OpCode.Code) {
case Code.Newarr:
- if (_context.TryResolve (operand) is TypeDefinition typeDefinition)
+ if (Context.TryResolve (operand) is TypeDefinition typeDefinition)
Annotations.MarkRelevantToVariantCasting (typeDefinition);
break;
case Code.Isinst:
if (operand is TypeSpecification || operand is GenericParameter)
break;
- if (!_context.CanApplyOptimization (CodeOptimizations.UnusedTypeChecks, method.DeclaringType.Module.Assembly))
+ if (!Context.CanApplyOptimization (CodeOptimizations.UnusedTypeChecks, method.DeclaringType.Module.Assembly))
break;
- TypeDefinition type = _context.Resolve (operand);
+ TypeDefinition? type = Context.Resolve (operand);
if (type == null)
return;
@@ -3473,7 +3519,7 @@ namespace Mono.Linker.Steps
break;
}
- _scopeStack.UpdateCurrentScopeInstructionOffset (instruction.Offset);
+ ScopeStack.UpdateCurrentScopeInstructionOffset (instruction.Offset);
MarkType (operand, new DependencyInfo (DependencyKind.InstructionTypeRef, method));
break;
}
@@ -3487,7 +3533,7 @@ namespace Mono.Linker.Steps
if (Annotations.IsMarked (resolvedInterfaceType))
return true;
- if (!_context.IsOptimizationEnabled (CodeOptimizations.UnusedInterfaces, type))
+ if (!Context.IsOptimizationEnabled (CodeOptimizations.UnusedInterfaces, type))
return true;
// It's hard to know if a com or windows runtime interface will be needed from managed code alone,
@@ -3503,13 +3549,13 @@ namespace Mono.Linker.Steps
if (Annotations.IsMarked (iface))
return;
- using var localScope = origin.HasValue ? _scopeStack.PushScope (origin.Value) : null;
+ using var localScope = origin.HasValue ? ScopeStack.PushScope (origin.Value) : null;
// Blame the type that has the interfaceimpl, expecting the type itself to get marked for other reasons.
MarkCustomAttributes (iface, new DependencyInfo (DependencyKind.CustomAttribute, iface));
// Blame the interface type on the interfaceimpl itself.
MarkType (iface.InterfaceType, reason ?? new DependencyInfo (DependencyKind.InterfaceImplementationInterfaceType, iface));
- Annotations.MarkProcessed (iface, reason ?? new DependencyInfo (DependencyKind.InterfaceImplementationOnType, _scopeStack.CurrentScope.Origin.Provider));
+ Annotations.MarkProcessed (iface, reason ?? new DependencyInfo (DependencyKind.InterfaceImplementationOnType, ScopeStack.CurrentScope.Origin.Provider));
}
//
@@ -3526,7 +3572,7 @@ namespace Mono.Linker.Steps
protected virtual void MarkReflectionLikeDependencies (MethodBody body, bool requiresReflectionMethodBodyScanner)
{
if (requiresReflectionMethodBodyScanner) {
- var scanner = new ReflectionMethodBodyScanner (_context, this, _scopeStack);
+ var scanner = new ReflectionMethodBodyScanner (Context, this, ScopeStack);
scanner.ScanAndProcessReturnValue (body);
}
}
diff --git a/src/linker/Linker.Steps/MarkSubStepsDispatcher.cs b/src/linker/Linker.Steps/MarkSubStepsDispatcher.cs
index d005c248e..f97004fd0 100644
--- a/src/linker/Linker.Steps/MarkSubStepsDispatcher.cs
+++ b/src/linker/Linker.Steps/MarkSubStepsDispatcher.cs
@@ -1,7 +1,9 @@
// 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 System.Collections.Generic;
+using System.Diagnostics;
using Mono.Cecil;
using Mono.Collections.Generic;
@@ -19,12 +21,13 @@ namespace Mono.Linker.Steps
{
readonly List<ISubStep> substeps;
- List<ISubStep> on_assemblies;
- List<ISubStep> on_types;
- List<ISubStep> on_fields;
- List<ISubStep> on_methods;
- List<ISubStep> on_properties;
- List<ISubStep> on_events;
+ CategorizedSubSteps? categorized;
+ CategorizedSubSteps Categorized {
+ get {
+ Debug.Assert (categorized.HasValue);
+ return categorized.Value;
+ }
+ }
public MarkSubStepsDispatcher (IEnumerable<ISubStep> subSteps)
{
@@ -43,7 +46,7 @@ namespace Mono.Linker.Steps
{
CategorizeSubSteps (assembly);
- if (HasSubSteps (on_assemblies))
+ if (HasSubSteps (Categorized.on_assemblies))
DispatchAssembly (assembly);
if (!ShouldDispatchTypes ())
@@ -54,11 +57,11 @@ namespace Mono.Linker.Steps
bool ShouldDispatchTypes ()
{
- return HasSubSteps (on_types)
- || HasSubSteps (on_fields)
- || HasSubSteps (on_methods)
- || HasSubSteps (on_properties)
- || HasSubSteps (on_events);
+ return HasSubSteps (Categorized.on_types)
+ || HasSubSteps (Categorized.on_fields)
+ || HasSubSteps (Categorized.on_methods)
+ || HasSubSteps (Categorized.on_properties)
+ || HasSubSteps (Categorized.on_events);
}
void BrowseTypes (Collection<TypeDefinition> types)
@@ -66,22 +69,22 @@ namespace Mono.Linker.Steps
foreach (TypeDefinition type in types) {
DispatchType (type);
- if (type.HasFields && HasSubSteps (on_fields)) {
+ if (type.HasFields && HasSubSteps (Categorized.on_fields)) {
foreach (FieldDefinition field in type.Fields)
DispatchField (field);
}
- if (type.HasMethods && HasSubSteps (on_methods)) {
+ if (type.HasMethods && HasSubSteps (Categorized.on_methods)) {
foreach (MethodDefinition method in type.Methods)
DispatchMethod (method);
}
- if (type.HasProperties && HasSubSteps (on_properties)) {
+ if (type.HasProperties && HasSubSteps (Categorized.on_properties)) {
foreach (PropertyDefinition property in type.Properties)
DispatchProperty (property);
}
- if (type.HasEvents && HasSubSteps (on_events)) {
+ if (type.HasEvents && HasSubSteps (Categorized.on_events)) {
foreach (EventDefinition @event in type.Events)
DispatchEvent (@event);
}
@@ -93,42 +96,42 @@ namespace Mono.Linker.Steps
void DispatchAssembly (AssemblyDefinition assembly)
{
- foreach (var substep in on_assemblies) {
+ foreach (var substep in Categorized.on_assemblies) {
substep.ProcessAssembly (assembly);
}
}
void DispatchType (TypeDefinition type)
{
- foreach (var substep in on_types) {
+ foreach (var substep in Categorized.on_types) {
substep.ProcessType (type);
}
}
void DispatchField (FieldDefinition field)
{
- foreach (var substep in on_fields) {
+ foreach (var substep in Categorized.on_fields) {
substep.ProcessField (field);
}
}
void DispatchMethod (MethodDefinition method)
{
- foreach (var substep in on_methods) {
+ foreach (var substep in Categorized.on_methods) {
substep.ProcessMethod (method);
}
}
void DispatchProperty (PropertyDefinition property)
{
- foreach (var substep in on_properties) {
+ foreach (var substep in Categorized.on_properties) {
substep.ProcessProperty (property);
}
}
void DispatchEvent (EventDefinition @event)
{
- foreach (var substep in on_events) {
+ foreach (var substep in Categorized.on_events) {
substep.ProcessEvent (@event);
}
}
@@ -141,12 +144,14 @@ namespace Mono.Linker.Steps
void CategorizeSubSteps (AssemblyDefinition assembly)
{
- on_assemblies = new List<ISubStep> ();
- on_types = new List<ISubStep> ();
- on_fields = new List<ISubStep> ();
- on_methods = new List<ISubStep> ();
- on_properties = new List<ISubStep> ();
- on_events = new List<ISubStep> ();
+ categorized = new CategorizedSubSteps {
+ on_assemblies = new List<ISubStep> (),
+ on_types = new List<ISubStep> (),
+ on_fields = new List<ISubStep> (),
+ on_methods = new List<ISubStep> (),
+ on_properties = new List<ISubStep> (),
+ on_events = new List<ISubStep> ()
+ };
foreach (var substep in substeps)
CategorizeSubStep (substep, assembly);
@@ -157,12 +162,12 @@ namespace Mono.Linker.Steps
if (!substep.IsActiveFor (assembly))
return;
- CategorizeTarget (substep, SubStepTargets.Assembly, on_assemblies);
- CategorizeTarget (substep, SubStepTargets.Type, on_types);
- CategorizeTarget (substep, SubStepTargets.Field, on_fields);
- CategorizeTarget (substep, SubStepTargets.Method, on_methods);
- CategorizeTarget (substep, SubStepTargets.Property, on_properties);
- CategorizeTarget (substep, SubStepTargets.Event, on_events);
+ CategorizeTarget (substep, SubStepTargets.Assembly, Categorized.on_assemblies);
+ CategorizeTarget (substep, SubStepTargets.Type, Categorized.on_types);
+ CategorizeTarget (substep, SubStepTargets.Field, Categorized.on_fields);
+ CategorizeTarget (substep, SubStepTargets.Method, Categorized.on_methods);
+ CategorizeTarget (substep, SubStepTargets.Property, Categorized.on_properties);
+ CategorizeTarget (substep, SubStepTargets.Event, Categorized.on_events);
}
static void CategorizeTarget (ISubStep substep, SubStepTargets target, List<ISubStep> list)
diff --git a/src/linker/Linker.Steps/OutputStep.cs b/src/linker/Linker.Steps/OutputStep.cs
index 1917965a1..b28d52c8d 100644
--- a/src/linker/Linker.Steps/OutputStep.cs
+++ b/src/linker/Linker.Steps/OutputStep.cs
@@ -39,7 +39,7 @@ namespace Mono.Linker.Steps
public class OutputStep : BaseStep
{
- private Dictionary<UInt16, TargetArchitecture> architectureMap;
+ private Dictionary<UInt16, TargetArchitecture>? architectureMap;
private enum NativeOSOverride
{
diff --git a/src/linker/Linker.Steps/ProcessLinkerXmlBase.cs b/src/linker/Linker.Steps/ProcessLinkerXmlBase.cs
index fd333cd31..4582a3410 100644
--- a/src/linker/Linker.Steps/ProcessLinkerXmlBase.cs
+++ b/src/linker/Linker.Steps/ProcessLinkerXmlBase.cs
@@ -13,8 +13,6 @@ using System.Xml.Linq;
using System.Xml.XPath;
using Mono.Cecil;
-#nullable enable
-
namespace Mono.Linker.Steps
{
[Flags]
@@ -140,7 +138,7 @@ namespace Mono.Linker.Steps
ProcessAssembly (assembly, assemblyNav, warnOnUnresolvedTypes: false);
} else {
Debug.Assert (!processAllAssemblies);
- AssemblyDefinition assembly = assemblyToProcess ?? _context.TryResolve (name!);
+ AssemblyDefinition? assembly = assemblyToProcess ?? _context.TryResolve (name!);
if (assembly == null) {
LogWarning ($"Could not resolve assembly '{name!.Name}'.", 2007, assemblyNav);
diff --git a/src/linker/Linker.Steps/ReflectionBlockedStep.cs b/src/linker/Linker.Steps/ReflectionBlockedStep.cs
index 22b7e4633..9114f6a19 100644
--- a/src/linker/Linker.Steps/ReflectionBlockedStep.cs
+++ b/src/linker/Linker.Steps/ReflectionBlockedStep.cs
@@ -1,10 +1,18 @@
+using System;
+using System.Diagnostics;
using Mono.Cecil;
namespace Mono.Linker.Steps
{
public class ReflectionBlockedStep : BaseStep
{
- AssemblyDefinition assembly;
+ AssemblyDefinition? assembly;
+ AssemblyDefinition Assembly {
+ get {
+ Debug.Assert (assembly != null);
+ return assembly;
+ }
+ }
protected override void ProcessAssembly (AssemblyDefinition assembly)
{
@@ -56,8 +64,8 @@ namespace Mono.Linker.Steps
{
// We are using DisableReflectionAttribute which is not exact match but it's quite
// close to what we need and it already exists in the BCL
- MethodReference ctor = Context.MarkedKnownMembers.DisablePrivateReflectionAttributeCtor;
- ctor = assembly.MainModule.ImportReference (ctor);
+ MethodReference ctor = Context.MarkedKnownMembers.DisablePrivateReflectionAttributeCtor ?? throw new InvalidOperationException ();
+ ctor = Assembly.MainModule.ImportReference (ctor);
var ca = new CustomAttribute (ctor);
caProvider.CustomAttributes.Add (ca);
diff --git a/src/linker/Linker.Steps/RootAssemblyInputStep.cs b/src/linker/Linker.Steps/RootAssemblyInputStep.cs
index 55b4e7806..47ebc79fa 100644
--- a/src/linker/Linker.Steps/RootAssemblyInputStep.cs
+++ b/src/linker/Linker.Steps/RootAssemblyInputStep.cs
@@ -19,7 +19,7 @@ namespace Mono.Linker.Steps
protected override void Process ()
{
- AssemblyDefinition assembly = LoadAssemblyFile ();
+ AssemblyDefinition? assembly = LoadAssemblyFile ();
if (assembly == null)
return;
@@ -95,13 +95,13 @@ namespace Mono.Linker.Steps
}
}
- AssemblyDefinition LoadAssemblyFile ()
+ AssemblyDefinition? LoadAssemblyFile ()
{
- AssemblyDefinition assembly;
+ AssemblyDefinition? assembly;
if (File.Exists (fileName)) {
assembly = Context.Resolver.GetAssembly (fileName);
- AssemblyDefinition loaded = Context.GetLoadedAssembly (assembly.Name.Name);
+ AssemblyDefinition? loaded = Context.GetLoadedAssembly (assembly.Name.Name);
// The same assembly could be already loaded if there are multiple inputs pointing to same file
if (loaded != null)
diff --git a/src/linker/Linker.Steps/SealerStep.cs b/src/linker/Linker.Steps/SealerStep.cs
index b68203289..cf98d7985 100644
--- a/src/linker/Linker.Steps/SealerStep.cs
+++ b/src/linker/Linker.Steps/SealerStep.cs
@@ -10,7 +10,7 @@ namespace Mono.Linker.Steps
{
public class SealerStep : BaseStep
{
- HashSet<TypeDefinition> referencedBaseTypeCache;
+ HashSet<TypeDefinition>? referencedBaseTypeCache;
public SealerStep ()
{
@@ -56,7 +56,7 @@ namespace Mono.Linker.Steps
}
var bt = Context.TryResolve (type);
- return referencedBaseTypeCache.Contains (bt);
+ return bt != null && referencedBaseTypeCache.Contains (bt);
}
void ProcessType (TypeDefinition type)
@@ -123,7 +123,7 @@ namespace Mono.Linker.Steps
method.IsFinal = true;
}
- bool IsAnyMarked (IEnumerable<OverrideInformation> list)
+ bool IsAnyMarked (IEnumerable<OverrideInformation>? list)
{
if (list == null)
return false;
@@ -135,7 +135,7 @@ namespace Mono.Linker.Steps
return false;
}
- bool IsAnyMarked (List<MethodDefinition> list)
+ bool IsAnyMarked (List<MethodDefinition>? list)
{
if (list == null)
return false;
diff --git a/src/linker/Linker.Steps/SubStepsDispatcher.cs b/src/linker/Linker.Steps/SubStepsDispatcher.cs
index 050010e9c..3ed5a6e1c 100644
--- a/src/linker/Linker.Steps/SubStepsDispatcher.cs
+++ b/src/linker/Linker.Steps/SubStepsDispatcher.cs
@@ -1,13 +1,25 @@
// 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 System.Collections.Generic;
+using System.Diagnostics;
using Mono.Cecil;
using Mono.Collections.Generic;
namespace Mono.Linker.Steps
{
+ struct CategorizedSubSteps
+ {
+ public List<ISubStep> on_assemblies;
+ public List<ISubStep> on_types;
+ public List<ISubStep> on_fields;
+ public List<ISubStep> on_methods;
+ public List<ISubStep> on_properties;
+ public List<ISubStep> on_events;
+ }
+
//
// Generic steps dispatcher is intended to by used by custom linker step which
// consist of multiple steps. It simplifies their implementation as well as the
@@ -17,12 +29,13 @@ namespace Mono.Linker.Steps
{
readonly List<ISubStep> substeps;
- List<ISubStep> on_assemblies;
- List<ISubStep> on_types;
- List<ISubStep> on_fields;
- List<ISubStep> on_methods;
- List<ISubStep> on_properties;
- List<ISubStep> on_events;
+ CategorizedSubSteps? categorized;
+ CategorizedSubSteps Categorized {
+ get {
+ Debug.Assert (categorized.HasValue);
+ return categorized.Value;
+ }
+ }
protected SubStepsDispatcher ()
{
@@ -53,7 +66,7 @@ namespace Mono.Linker.Steps
foreach (var assembly in assemblies) {
CategorizeSubSteps (assembly);
- if (HasSubSteps (on_assemblies))
+ if (HasSubSteps (Categorized.on_assemblies))
DispatchAssembly (assembly);
if (!ShouldDispatchTypes ())
@@ -65,11 +78,11 @@ namespace Mono.Linker.Steps
bool ShouldDispatchTypes ()
{
- return HasSubSteps (on_types)
- || HasSubSteps (on_fields)
- || HasSubSteps (on_methods)
- || HasSubSteps (on_properties)
- || HasSubSteps (on_events);
+ return HasSubSteps (Categorized.on_types)
+ || HasSubSteps (Categorized.on_fields)
+ || HasSubSteps (Categorized.on_methods)
+ || HasSubSteps (Categorized.on_properties)
+ || HasSubSteps (Categorized.on_events);
}
void BrowseTypes (Collection<TypeDefinition> types)
@@ -77,22 +90,22 @@ namespace Mono.Linker.Steps
foreach (TypeDefinition type in types) {
DispatchType (type);
- if (type.HasFields && HasSubSteps (on_fields)) {
+ if (type.HasFields && HasSubSteps (Categorized.on_fields)) {
foreach (FieldDefinition field in type.Fields)
DispatchField (field);
}
- if (type.HasMethods && HasSubSteps (on_methods)) {
+ if (type.HasMethods && HasSubSteps (Categorized.on_methods)) {
foreach (MethodDefinition method in type.Methods)
DispatchMethod (method);
}
- if (type.HasProperties && HasSubSteps (on_properties)) {
+ if (type.HasProperties && HasSubSteps (Categorized.on_properties)) {
foreach (PropertyDefinition property in type.Properties)
DispatchProperty (property);
}
- if (type.HasEvents && HasSubSteps (on_events)) {
+ if (type.HasEvents && HasSubSteps (Categorized.on_events)) {
foreach (EventDefinition @event in type.Events)
DispatchEvent (@event);
}
@@ -104,42 +117,42 @@ namespace Mono.Linker.Steps
void DispatchAssembly (AssemblyDefinition assembly)
{
- foreach (var substep in on_assemblies) {
+ foreach (var substep in Categorized.on_assemblies) {
substep.ProcessAssembly (assembly);
}
}
void DispatchType (TypeDefinition type)
{
- foreach (var substep in on_types) {
+ foreach (var substep in Categorized.on_types) {
substep.ProcessType (type);
}
}
void DispatchField (FieldDefinition field)
{
- foreach (var substep in on_fields) {
+ foreach (var substep in Categorized.on_fields) {
substep.ProcessField (field);
}
}
void DispatchMethod (MethodDefinition method)
{
- foreach (var substep in on_methods) {
+ foreach (var substep in Categorized.on_methods) {
substep.ProcessMethod (method);
}
}
void DispatchProperty (PropertyDefinition property)
{
- foreach (var substep in on_properties) {
+ foreach (var substep in Categorized.on_properties) {
substep.ProcessProperty (property);
}
}
void DispatchEvent (EventDefinition @event)
{
- foreach (var substep in on_events) {
+ foreach (var substep in Categorized.on_events) {
substep.ProcessEvent (@event);
}
}
@@ -152,12 +165,14 @@ namespace Mono.Linker.Steps
void CategorizeSubSteps (AssemblyDefinition assembly)
{
- on_assemblies = new List<ISubStep> ();
- on_types = new List<ISubStep> ();
- on_fields = new List<ISubStep> ();
- on_methods = new List<ISubStep> ();
- on_properties = new List<ISubStep> ();
- on_events = new List<ISubStep> ();
+ categorized = new CategorizedSubSteps {
+ on_assemblies = new List<ISubStep> (),
+ on_types = new List<ISubStep> (),
+ on_fields = new List<ISubStep> (),
+ on_methods = new List<ISubStep> (),
+ on_properties = new List<ISubStep> (),
+ on_events = new List<ISubStep> ()
+ };
foreach (var substep in substeps)
CategorizeSubStep (substep, assembly);
@@ -168,12 +183,12 @@ namespace Mono.Linker.Steps
if (!substep.IsActiveFor (assembly))
return;
- CategorizeTarget (substep, SubStepTargets.Assembly, on_assemblies);
- CategorizeTarget (substep, SubStepTargets.Type, on_types);
- CategorizeTarget (substep, SubStepTargets.Field, on_fields);
- CategorizeTarget (substep, SubStepTargets.Method, on_methods);
- CategorizeTarget (substep, SubStepTargets.Property, on_properties);
- CategorizeTarget (substep, SubStepTargets.Event, on_events);
+ CategorizeTarget (substep, SubStepTargets.Assembly, Categorized.on_assemblies);
+ CategorizeTarget (substep, SubStepTargets.Type, Categorized.on_types);
+ CategorizeTarget (substep, SubStepTargets.Field, Categorized.on_fields);
+ CategorizeTarget (substep, SubStepTargets.Method, Categorized.on_methods);
+ CategorizeTarget (substep, SubStepTargets.Property, Categorized.on_properties);
+ CategorizeTarget (substep, SubStepTargets.Event, Categorized.on_events);
}
static void CategorizeTarget (ISubStep substep, SubStepTargets target, List<ISubStep> list)
diff --git a/src/linker/Linker.Steps/SweepStep.cs b/src/linker/Linker.Steps/SweepStep.cs
index ebc096004..c560d4e13 100644
--- a/src/linker/Linker.Steps/SweepStep.cs
+++ b/src/linker/Linker.Steps/SweepStep.cs
@@ -39,7 +39,6 @@ namespace Mono.Linker.Steps
{
public class SweepStep : BaseStep
{
- AssemblyDefinition[] assemblies;
readonly bool sweepSymbols;
readonly HashSet<AssemblyDefinition> BypassNGenToSave = new HashSet<AssemblyDefinition> ();
@@ -51,7 +50,7 @@ namespace Mono.Linker.Steps
protected override void Process ()
{
// To keep facades, scan all references so that even unused facades are kept
- assemblies = Context.KeepTypeForwarderOnlyAssemblies ?
+ var assemblies = Context.KeepTypeForwarderOnlyAssemblies ?
Context.GetReferencedAssemblies ().ToArray () : Annotations.GetAssemblies ().ToArray ();
// Ensure that any assemblies which need to be removed are marked for deletion,
@@ -122,7 +121,7 @@ namespace Mono.Linker.Steps
case AssemblyAction.AddBypassNGen:
case AssemblyAction.AddBypassNGenUsed:
foreach (var reference in assembly.MainModule.AssemblyReferences) {
- AssemblyDefinition ad = Context.Resolver.Resolve (reference);
+ AssemblyDefinition? ad = Context.Resolver.Resolve (reference);
if (ad == null)
continue;
@@ -386,7 +385,10 @@ namespace Mono.Linker.Steps
if (!providerAsSecurity.HasSecurityDeclarations) {
// If the method or type had security before and all attributes were removed, or no remaining attributes are security attributes,
// then we need to set HasSecurity to false
- if (!provider.HasCustomAttributes || provider.CustomAttributes.All (attr => !IsSecurityAttributeType (Context.TryResolve (attr.AttributeType))))
+ if (!provider.HasCustomAttributes || provider.CustomAttributes.All (attr => {
+ TypeDefinition? attributeType = Context.TryResolve (attr.AttributeType);
+ return attributeType == null || !IsSecurityAttributeType (attributeType);
+ }))
return true;
}
@@ -407,11 +409,11 @@ namespace Mono.Linker.Steps
};
}
- definition = Context.TryResolve (definition.BaseType);
- if (definition == null)
+ var baseDefinition = Context.TryResolve (definition.BaseType);
+ if (baseDefinition == null)
return false;
- return IsSecurityAttributeType (definition);
+ return IsSecurityAttributeType (baseDefinition);
}
protected bool SweepCustomAttributes (ICustomAttributeProvider provider)
@@ -464,7 +466,7 @@ namespace Mono.Linker.Steps
void SweepDebugInfo (Collection<MethodDefinition> methods)
{
- List<ScopeDebugInformation> sweptScopes = null;
+ List<ScopeDebugInformation>? sweptScopes = null;
foreach (var m in methods) {
if (m.DebugInformation == null)
continue;
diff --git a/src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs b/src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs
index e6e52fecb..b48f143bf 100644
--- a/src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs
+++ b/src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;
@@ -17,7 +18,7 @@ namespace Mono.Linker.Steps
public class UnreachableBlocksOptimizer
{
readonly LinkContext _context;
- MethodDefinition IntPtrSize, UIntPtrSize;
+ MethodDefinition? IntPtrSize, UIntPtrSize;
readonly struct ProcessingNode
{
@@ -166,7 +167,7 @@ namespace Mono.Linker.Steps
// To fix this go over the stack and find the "oldest" node with the current version - the "oldest" node which
// is part of the loop:
- LinkedListNode<ProcessingNode> lastNodeWithCurrentVersion = null;
+ LinkedListNode<ProcessingNode>? lastNodeWithCurrentVersion = null;
var candidateNodeToMoveToTop = _processingStack.Last;
bool foundNodesWithNonCurrentVersion = false;
while (candidateNodeToMoveToTop != stackNode) {
@@ -265,7 +266,7 @@ namespace Mono.Linker.Steps
Debug.Assert (_processingMethods.Count == 0);
}
- Instruction AnalyzeMethodForConstantResult (MethodDefinition method, Collection<Instruction> instructions)
+ Instruction? AnalyzeMethodForConstantResult (MethodDefinition method, Collection<Instruction>? instructions)
{
if (method.ReturnType.MetadataType == MetadataType.Void)
return null;
@@ -306,9 +307,9 @@ namespace Mono.Linker.Steps
/// constantResultInstruction is set to an instance if the method returns a constant, otherwise it's set to null
/// false - if the method has not yet been analyzed and the caller should retry later
/// </returns>
- bool TryGetConstantResultForMethod (MethodDefinition method, out Instruction constantResultInstruction)
+ bool TryGetConstantResultForMethod (MethodDefinition method, out Instruction? constantResultInstruction)
{
- if (!_processedMethods.TryGetValue (method, out Instruction methodValue)) {
+ if (!_processedMethods.TryGetValue (method, out Instruction? methodValue)) {
if (_processingMethods.TryGetValue (method, out var stackNode)) {
// Method is already in the stack - not yet processed
// Move it to the top of the stack
@@ -350,7 +351,7 @@ namespace Mono.Linker.Steps
changed = false;
bool hasUnprocessedDependencies = false;
var instructions = reducer.Body.Instructions;
- Instruction targetResult;
+ Instruction? targetResult;
for (int i = 0; i < instructions.Count; ++i) {
var instr = instructions[i];
@@ -416,7 +417,7 @@ namespace Mono.Linker.Steps
if (field == null)
break;
- if (_context.Annotations.TryGetFieldUserValue (field, out object value)) {
+ if (_context.Annotations.TryGetFieldUserValue (field, out object? value)) {
targetResult = CodeRewriterStep.CreateConstantResultInstruction (_context, field.FieldType, value);
if (targetResult == null)
break;
@@ -431,7 +432,7 @@ namespace Mono.Linker.Steps
// which are simple static properties commonly overwritten. Instead of forcing C# code style
// we handle both via static Size property
//
- MethodDefinition sizeOfImpl = null;
+ MethodDefinition? sizeOfImpl = null;
var operand = (TypeReference) instr.Operand;
if (operand.MetadataType == MetadataType.UIntPtr) {
@@ -460,7 +461,7 @@ namespace Mono.Linker.Steps
return !hasUnprocessedDependencies;
}
- static MethodDefinition FindSizeMethod (TypeDefinition type)
+ static MethodDefinition? FindSizeMethod (TypeDefinition? type)
{
if (type == null)
return null;
@@ -471,13 +472,13 @@ namespace Mono.Linker.Steps
struct BodyReducer
{
readonly LinkContext context;
- Dictionary<Instruction, int> mapping;
+ Dictionary<Instruction, int>? mapping;
//
// Sorted list of body instruction indexes which were
// replaced pass-through nop
//
- List<int> conditionInstrsToRemove;
+ List<int>? conditionInstrsToRemove;
public BodyReducer (MethodBody body, LinkContext context)
{
@@ -494,7 +495,7 @@ namespace Mono.Linker.Steps
public int InstructionsReplaced { get; set; }
- public Collection<Instruction> FoldedInstructions { get; private set; }
+ public Collection<Instruction>? FoldedInstructions { get; private set; }
public void Rewrite (int index, Instruction newInstruction)
{
@@ -502,6 +503,7 @@ namespace Mono.Linker.Steps
FoldedInstructions = new Collection<Instruction> (Body.Instructions);
mapping = new Dictionary<Instruction, int> ();
}
+ Debug.Assert (mapping != null);
// Tracks mapping for replaced instructions for easier
// branch targets resolution later
@@ -687,8 +689,9 @@ namespace Mono.Linker.Steps
bool RemoveConditions ()
{
+ Debug.Assert (FoldedInstructions != null);
bool changed = false;
- object left, right;
+ object? left, right;
//
// Finds any branchable instruction and checks if the operand or operands
@@ -825,12 +828,13 @@ namespace Mono.Linker.Steps
return changed;
}
- BitArray GetReachableInstructionsMap (out List<ExceptionHandler> unreachableHandlers)
+ BitArray GetReachableInstructionsMap (out List<ExceptionHandler>? unreachableHandlers)
{
+ Debug.Assert (FoldedInstructions != null);
unreachableHandlers = null;
var reachable = new BitArray (FoldedInstructions.Count);
- Stack<int> condBranches = null;
+ Stack<int>? condBranches = null;
bool exceptionHandlersChecked = !Body.HasExceptionHandlers;
Instruction target;
int i = 0;
@@ -934,6 +938,7 @@ namespace Mono.Linker.Steps
//
int GetInstructionIndex (Instruction instruction)
{
+ Debug.Assert (FoldedInstructions != null && mapping != null);
if (mapping.TryGetValue (instruction, out int idx))
return idx;
@@ -942,8 +947,9 @@ namespace Mono.Linker.Steps
return idx;
}
- bool GetOperandsConstantValues (int index, out object left, out object right)
+ bool GetOperandsConstantValues (int index, out object? left, out object? right)
{
+ Debug.Assert (FoldedInstructions != null);
left = default;
right = default;
@@ -954,7 +960,7 @@ namespace Mono.Linker.Steps
GetConstantValue (FoldedInstructions[index - 1], out right);
}
- static bool GetConstantValue (Instruction instruction, out object value)
+ static bool GetConstantValue (Instruction instruction, out object? value)
{
switch (instruction.OpCode.Code) {
case Code.Ldc_I4_0:
@@ -1084,6 +1090,7 @@ namespace Mono.Linker.Steps
bool IsJumpTargetRange (int firstInstr, int lastInstr)
{
+ Debug.Assert (FoldedInstructions != null);
foreach (var instr in FoldedInstructions) {
switch (instr.OpCode.FlowControl) {
case FlowControl.Branch:
@@ -1112,11 +1119,17 @@ namespace Mono.Linker.Steps
{
readonly MethodBody body;
readonly BitArray reachable;
- readonly List<ExceptionHandler> unreachableExceptionHandlers;
+ readonly List<ExceptionHandler>? unreachableExceptionHandlers;
readonly LinkContext context;
- LinkerILProcessor ilprocessor;
+ LinkerILProcessor? ilprocessor;
+ LinkerILProcessor ILProcessor {
+ get {
+ Debug.Assert (ilprocessor != null);
+ return ilprocessor;
+ }
+ }
- public BodySweeper (MethodBody body, BitArray reachable, List<ExceptionHandler> unreachableEH, LinkContext context)
+ public BodySweeper (MethodBody body, BitArray reachable, List<ExceptionHandler>? unreachableEH, LinkContext context)
{
this.body = body;
this.reachable = reachable;
@@ -1159,9 +1172,9 @@ namespace Mono.Linker.Steps
return true;
}
- public void Process (List<int> conditionInstrsToRemove, out List<Instruction> sentinelNops)
+ public void Process (List<int>? conditionInstrsToRemove, out List<Instruction>? sentinelNops)
{
- List<VariableDefinition> removedVariablesReferences = null;
+ List<VariableDefinition>? removedVariablesReferences = null;
//
// Initial pass which replaces unreachable instructions with nops or
@@ -1181,10 +1194,10 @@ namespace Mono.Linker.Steps
newInstr = Instruction.Create (OpCodes.Nop);
}
- ilprocessor.Replace (i, newInstr);
+ ILProcessor.Replace (i, newInstr);
InstructionsReplaced++;
- VariableDefinition variable = GetVariableReference (instr);
+ VariableDefinition? variable = GetVariableReference (instr);
if (variable != null) {
if (removedVariablesReferences == null)
removedVariablesReferences = new List<VariableDefinition> ();
@@ -1223,12 +1236,12 @@ namespace Mono.Linker.Steps
sentinelNops = new List<Instruction> ();
sentinelNops.Add (nop);
- ilprocessor.Replace (index - 1, Instruction.Create (OpCodes.Pop));
- ilprocessor.Replace (index, nop);
+ ILProcessor.Replace (index - 1, Instruction.Create (OpCodes.Pop));
+ ILProcessor.Replace (index, nop);
} else {
var pop = Instruction.Create (OpCodes.Pop);
- ilprocessor.Replace (index, pop);
- ilprocessor.InsertAfter (pop, Instruction.Create (OpCodes.Pop));
+ ILProcessor.Replace (index, pop);
+ ILProcessor.InsertAfter (pop, Instruction.Create (OpCodes.Pop));
//
// conditionInstrsToRemove is always sorted and instead of
@@ -1238,7 +1251,7 @@ namespace Mono.Linker.Steps
}
break;
case StackBehaviour.Popi:
- ilprocessor.Replace (index, Instruction.Create (OpCodes.Pop));
+ ILProcessor.Replace (index, Instruction.Create (OpCodes.Pop));
InstructionsReplaced++;
break;
}
@@ -1257,7 +1270,7 @@ namespace Mono.Linker.Steps
void CleanRemovedVariables (List<VariableDefinition> variables)
{
foreach (var instr in body.Instructions) {
- VariableDefinition variable = GetVariableReference (instr);
+ VariableDefinition? variable = GetVariableReference (instr);
if (variable == null)
continue;
@@ -1297,7 +1310,7 @@ namespace Mono.Linker.Steps
body.ExceptionHandlers.Remove (eh);
}
- VariableDefinition GetVariableReference (Instruction instruction)
+ VariableDefinition? GetVariableReference (Instruction instruction)
{
switch (instruction.OpCode.Code) {
case Code.Stloc_0:
@@ -1360,8 +1373,8 @@ namespace Mono.Linker.Steps
readonly Collection<Instruction> instructions;
readonly LinkContext context;
- Stack<Instruction> stack_instr;
- Dictionary<int, Instruction> locals;
+ Stack<Instruction>? stack_instr;
+ Dictionary<int, Instruction>? locals;
public ConstantExpressionMethodAnalyzer (LinkContext context, MethodDefinition method)
{
@@ -1379,8 +1392,9 @@ namespace Mono.Linker.Steps
this.instructions = instructions;
}
- public Instruction Result { get; private set; }
+ public Instruction? Result { get; private set; }
+ [MemberNotNullWhen (true, "Result")]
public bool Analyze ()
{
var body = method.Body;
@@ -1388,8 +1402,8 @@ namespace Mono.Linker.Steps
return false;
VariableReference vr;
- Instruction jmpTarget = null;
- Instruction linstr;
+ Instruction? jmpTarget = null;
+ Instruction? linstr;
foreach (var instr in instructions) {
if (jmpTarget != null) {
@@ -1403,6 +1417,8 @@ namespace Mono.Linker.Steps
case Code.Nop:
continue;
case Code.Pop:
+ if (stack_instr == null)
+ Debug.Fail ("Invalid IL?");
stack_instr.Pop ();
continue;
@@ -1501,6 +1517,7 @@ namespace Mono.Linker.Steps
return false;
}
+ [MemberNotNullWhen (true, "Result")]
bool ConvertStackToResult ()
{
if (stack_instr == null)
@@ -1534,9 +1551,9 @@ namespace Mono.Linker.Steps
return false;
}
- Instruction GetLocalsValue (int index, MethodBody body)
+ Instruction? GetLocalsValue (int index, MethodBody body)
{
- if (locals != null && locals.TryGetValue (index, out Instruction instruction))
+ if (locals != null && locals.TryGetValue (index, out Instruction? instruction))
return instruction;
if (!body.InitLocals)
@@ -1559,6 +1576,8 @@ namespace Mono.Linker.Steps
if (locals == null)
locals = new Dictionary<int, Instruction> ();
+ if (stack_instr == null)
+ Debug.Fail ("Invalid IL?");
locals[index] = stack_instr.Pop ();
}
}
diff --git a/src/linker/Linker/Annotations.cs b/src/linker/Linker/Annotations.cs
index 781eaa516..eb5274a46 100644
--- a/src/linker/Linker/Annotations.cs
+++ b/src/linker/Linker/Annotations.cs
@@ -25,7 +25,6 @@
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#nullable enable
using System;
using System.Collections.Generic;
@@ -402,12 +401,12 @@ namespace Mono.Linker
return preserved_exportedtype_members.TryGetValue (type, out preserve);
}
- public bool TryGetMethodStubValue (MethodDefinition method, out object value)
+ public bool TryGetMethodStubValue (MethodDefinition method, out object? value)
{
return MemberActions.TryGetMethodStubValue (method, out value);
}
- public bool TryGetFieldUserValue (FieldDefinition field, out object value)
+ public bool TryGetFieldUserValue (FieldDefinition field, out object? value)
{
return MemberActions.TryGetFieldUserValue (field, out value);
}
@@ -438,17 +437,17 @@ namespace Mono.Linker
return public_api.Contains (provider);
}
- public IEnumerable<OverrideInformation> GetOverrides (MethodDefinition method)
+ public IEnumerable<OverrideInformation>? GetOverrides (MethodDefinition method)
{
return TypeMapInfo.GetOverrides (method);
}
- public IEnumerable<(TypeDefinition InstanceType, InterfaceImplementation ProvidingInterface)> GetDefaultInterfaceImplementations (MethodDefinition method)
+ public IEnumerable<(TypeDefinition InstanceType, InterfaceImplementation ProvidingInterface)>? GetDefaultInterfaceImplementations (MethodDefinition method)
{
return TypeMapInfo.GetDefaultInterfaceImplementations (method);
}
- public List<MethodDefinition> GetBaseMethods (MethodDefinition method)
+ public List<MethodDefinition>? GetBaseMethods (MethodDefinition method)
{
return TypeMapInfo.GetBaseMethods (method);
}
diff --git a/src/linker/Linker/ArrayBuilder.cs b/src/linker/Linker/ArrayBuilder.cs
index d249c4057..0dee12a9d 100644
--- a/src/linker/Linker/ArrayBuilder.cs
+++ b/src/linker/Linker/ArrayBuilder.cs
@@ -14,7 +14,7 @@ namespace Mono.Linker
public bool Any (Predicate<T> callback) => _list?.Exists (callback) == true;
- public T[] ToArray () => _list?.ToArray ();
+ public T[]? ToArray () => _list?.ToArray ();
public int Count => _list?.Count ?? 0;
}
diff --git a/src/linker/Linker/AssemblyDefinitionExtensions.cs b/src/linker/Linker/AssemblyDefinitionExtensions.cs
index d5aced51a..caf0a13f0 100644
--- a/src/linker/Linker/AssemblyDefinitionExtensions.cs
+++ b/src/linker/Linker/AssemblyDefinitionExtensions.cs
@@ -4,7 +4,7 @@ namespace Mono.Linker
{
public static class AssemblyDefinitionExtensions
{
- public static EmbeddedResource FindEmbeddedResource (this AssemblyDefinition assembly, string name)
+ public static EmbeddedResource? FindEmbeddedResource (this AssemblyDefinition assembly, string name)
{
foreach (var resource in assembly.MainModule.Resources) {
if (resource is EmbeddedResource embeddedResource && embeddedResource.Name == name)
diff --git a/src/linker/Linker/AssemblyResolver.cs b/src/linker/Linker/AssemblyResolver.cs
index 73571e5f8..d579dda90 100644
--- a/src/linker/Linker/AssemblyResolver.cs
+++ b/src/linker/Linker/AssemblyResolver.cs
@@ -43,8 +43,8 @@ namespace Mono.Linker
readonly List<MemoryMappedViewStream> _viewStreams = new ();
readonly ReaderParameters _defaultReaderParameters;
- HashSet<string> _unresolvedAssemblies;
- HashSet<string> _reportedUnresolvedAssemblies;
+ HashSet<string>? _unresolvedAssemblies;
+ HashSet<string>? _reportedUnresolvedAssemblies;
public AssemblyResolver (LinkContext context)
{
@@ -58,13 +58,13 @@ namespace Mono.Linker
public string GetAssemblyLocation (AssemblyDefinition assembly)
{
- if (_assemblyToPath.TryGetValue (assembly, out string path))
+ if (_assemblyToPath.TryGetValue (assembly, out string? path))
return path;
throw new InternalErrorException ($"Assembly '{assembly}' was not loaded using linker resolver");
}
- AssemblyDefinition ResolveFromReferences (AssemblyNameReference name)
+ AssemblyDefinition? ResolveFromReferences (AssemblyNameReference name)
{
foreach (var reference in _references) {
foreach (var extension in Extensions) {
@@ -82,9 +82,9 @@ namespace Mono.Linker
return null;
}
- public AssemblyDefinition Resolve (AssemblyNameReference name, bool probing)
+ public AssemblyDefinition? Resolve (AssemblyNameReference name, bool probing)
{
- if (AssemblyCache.TryGetValue (name.Name, out AssemblyDefinition asm))
+ if (AssemblyCache.TryGetValue (name.Name, out AssemblyDefinition? asm))
return asm;
if (_unresolvedAssemblies?.Contains (name.Name) == true) {
@@ -135,7 +135,7 @@ namespace Mono.Linker
public AssemblyDefinition GetAssembly (string file)
{
- MemoryMappedViewStream viewStream = null;
+ MemoryMappedViewStream? viewStream = null;
try {
// Create stream because CreateFromFile(string, ...) uses FileShare.None which is too strict
using var fileStream = new FileStream (file, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, false);
@@ -159,7 +159,7 @@ namespace Mono.Linker
}
}
- public AssemblyDefinition Resolve (AssemblyNameReference name)
+ public AssemblyDefinition? Resolve (AssemblyNameReference name)
{
return Resolve (name, probing: false);
}
@@ -172,7 +172,7 @@ namespace Mono.Linker
static readonly string[] Extensions = new[] { ".dll", ".exe" };
- AssemblyDefinition SearchDirectory (AssemblyNameReference name)
+ AssemblyDefinition? SearchDirectory (AssemblyNameReference name)
{
foreach (var directory in _directories) {
foreach (var extension in Extensions) {
diff --git a/src/linker/Linker/BCL.cs b/src/linker/Linker/BCL.cs
index 3eadf8cd9..23aaedaec 100644
--- a/src/linker/Linker/BCL.cs
+++ b/src/linker/Linker/BCL.cs
@@ -63,10 +63,10 @@ namespace Mono.Linker
"netstandard"
};
- public static TypeDefinition FindPredefinedType (string ns, string name, LinkContext context)
+ public static TypeDefinition? FindPredefinedType (string ns, string name, LinkContext context)
{
foreach (var corlibName in corlibNames) {
- AssemblyDefinition corlib = context.TryResolve (corlibName);
+ AssemblyDefinition? corlib = context.TryResolve (corlibName);
if (corlib == null)
continue;
diff --git a/src/linker/Linker/CompilerGeneratedState.cs b/src/linker/Linker/CompilerGeneratedState.cs
index 34821288b..47780ace0 100644
--- a/src/linker/Linker/CompilerGeneratedState.cs
+++ b/src/linker/Linker/CompilerGeneratedState.cs
@@ -41,7 +41,7 @@ namespace Mono.Linker
case "AsyncIteratorStateMachineAttribute":
case "AsyncStateMachineAttribute":
case "IteratorStateMachineAttribute":
- TypeDefinition stateMachineType = GetFirstConstructorArgumentAsType (attribute);
+ TypeDefinition? stateMachineType = GetFirstConstructorArgumentAsType (attribute);
if (stateMachineType != null) {
if (!_compilerGeneratedTypeToUserCodeMethod.TryAdd (stateMachineType, method)) {
var alreadyAssociatedMethod = _compilerGeneratedTypeToUserCodeMethod[stateMachineType];
@@ -59,7 +59,7 @@ namespace Mono.Linker
}
}
- static TypeDefinition GetFirstConstructorArgumentAsType (CustomAttribute attribute)
+ static TypeDefinition? GetFirstConstructorArgumentAsType (CustomAttribute attribute)
{
if (!attribute.HasConstructorArguments)
return null;
@@ -67,13 +67,13 @@ namespace Mono.Linker
return attribute.ConstructorArguments[0].Value as TypeDefinition;
}
- public MethodDefinition GetUserDefinedMethodForCompilerGeneratedMember (IMemberDefinition sourceMember)
+ public MethodDefinition? GetUserDefinedMethodForCompilerGeneratedMember (IMemberDefinition sourceMember)
{
if (sourceMember == null)
return null;
TypeDefinition compilerGeneratedType = (sourceMember as TypeDefinition) ?? sourceMember.DeclaringType;
- if (_compilerGeneratedTypeToUserCodeMethod.TryGetValue (compilerGeneratedType, out MethodDefinition userDefinedMethod))
+ if (_compilerGeneratedTypeToUserCodeMethod.TryGetValue (compilerGeneratedType, out MethodDefinition? userDefinedMethod))
return userDefinedMethod;
// Only handle async or iterator state machine
diff --git a/src/linker/Linker/CustomAttributeSource.cs b/src/linker/Linker/CustomAttributeSource.cs
index 55f7a11a6..6b5033a8c 100644
--- a/src/linker/Linker/CustomAttributeSource.cs
+++ b/src/linker/Linker/CustomAttributeSource.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using Mono.Cecil;
namespace Mono.Linker
@@ -10,13 +11,13 @@ namespace Mono.Linker
public class CustomAttributeSource
{
public AttributeInfo PrimaryAttributeInfo { get; }
- private readonly Dictionary<AssemblyDefinition, AttributeInfo> _embeddedXmlInfos;
+ private readonly Dictionary<AssemblyDefinition, AttributeInfo?> _embeddedXmlInfos;
readonly LinkContext _context;
public CustomAttributeSource (LinkContext context)
{
PrimaryAttributeInfo = new AttributeInfo ();
- _embeddedXmlInfos = new Dictionary<AssemblyDefinition, AttributeInfo> ();
+ _embeddedXmlInfos = new Dictionary<AssemblyDefinition, AttributeInfo?> ();
_context = context;
}
@@ -34,7 +35,7 @@ namespace Mono.Linker
};
}
- public bool TryGetEmbeddedXmlInfo (ICustomAttributeProvider provider, out AttributeInfo xmlInfo)
+ public bool TryGetEmbeddedXmlInfo (ICustomAttributeProvider provider, [NotNullWhen (true)] out AttributeInfo? xmlInfo)
{
var assembly = GetAssemblyFromCustomAttributeProvider (provider);
diff --git a/src/linker/Linker/DependencyInfo.cs b/src/linker/Linker/DependencyInfo.cs
index 72ab233df..96be4dbf7 100644
--- a/src/linker/Linker/DependencyInfo.cs
+++ b/src/linker/Linker/DependencyInfo.cs
@@ -145,13 +145,13 @@ namespace Mono.Linker
public readonly struct DependencyInfo : IEquatable<DependencyInfo>
{
public DependencyKind Kind { get; }
- public object Source { get; }
- public DependencyInfo (DependencyKind kind, object source) => (Kind, Source) = (kind, source);
+ public object? Source { get; }
+ public DependencyInfo (DependencyKind kind, object? source) => (Kind, Source) = (kind, source);
public static readonly DependencyInfo Unspecified = new DependencyInfo (DependencyKind.Unspecified, null);
public static readonly DependencyInfo AlreadyMarked = new DependencyInfo (DependencyKind.AlreadyMarked, null);
public static readonly DependencyInfo DisablePrivateReflectionRequirement = new DependencyInfo (DependencyKind.DisablePrivateReflectionRequirement, null);
public bool Equals (DependencyInfo other) => (Kind, Source) == (other.Kind, other.Source);
- public override bool Equals (Object obj) => obj is DependencyInfo info && this.Equals (info);
+ public override bool Equals (Object? obj) => obj is DependencyInfo info && this.Equals (info);
public override int GetHashCode () => (Kind, Source).GetHashCode ();
public static bool operator == (DependencyInfo lhs, DependencyInfo rhs) => lhs.Equals (rhs);
public static bool operator != (DependencyInfo lhs, DependencyInfo rhs) => !lhs.Equals (rhs);
diff --git a/src/linker/Linker/DocumentationSignatureGenerator.PartVisitor.cs b/src/linker/Linker/DocumentationSignatureGenerator.PartVisitor.cs
index 3a2e1458c..65211abd9 100644
--- a/src/linker/Linker/DocumentationSignatureGenerator.PartVisitor.cs
+++ b/src/linker/Linker/DocumentationSignatureGenerator.PartVisitor.cs
@@ -146,7 +146,10 @@ namespace Mono.Linker
}
if (typeReference.IsNested) {
- VisitTypeReference (typeReference.GetInflatedDeclaringType (resolver), builder, resolver);
+ Debug.Assert (typeReference is not SentinelType && typeReference is not PinnedType);
+ // GetInflatedDeclaringType may return null for generic parameters, byrefs, and pointers, but these
+ // are separately handled above.
+ VisitTypeReference (typeReference.GetInflatedDeclaringType (resolver)!, builder, resolver);
builder.Append ('.');
}
diff --git a/src/linker/Linker/DocumentationSignatureGenerator.cs b/src/linker/Linker/DocumentationSignatureGenerator.cs
index f473f7759..1a9e545cd 100644
--- a/src/linker/Linker/DocumentationSignatureGenerator.cs
+++ b/src/linker/Linker/DocumentationSignatureGenerator.cs
@@ -28,19 +28,19 @@ namespace Mono.Linker
{
switch (member.MetadataToken.TokenType) {
case TokenType.TypeDef:
- VisitTypeDefinition (member as TypeDefinition, builder, resolver);
+ VisitTypeDefinition ((TypeDefinition) member, builder, resolver);
break;
case TokenType.Method:
- VisitMethod (member as MethodDefinition, builder, resolver);
+ VisitMethod ((MethodDefinition) member, builder, resolver);
break;
case TokenType.Property:
- VisitProperty (member as PropertyDefinition, builder, resolver);
+ VisitProperty ((PropertyDefinition) member, builder, resolver);
break;
case TokenType.Field:
- VisitField (member as FieldDefinition, builder, resolver);
+ VisitField ((FieldDefinition) member, builder, resolver);
break;
case TokenType.Event:
- VisitEvent (member as EventDefinition, builder, resolver);
+ VisitEvent ((EventDefinition) member, builder, resolver);
break;
default:
break;
diff --git a/src/linker/Linker/DocumentationSignatureParser.cs b/src/linker/Linker/DocumentationSignatureParser.cs
index f55c281b4..8a6594e47 100644
--- a/src/linker/Linker/DocumentationSignatureParser.cs
+++ b/src/linker/Linker/DocumentationSignatureParser.cs
@@ -1,8 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-#nullable enable
-
using System;
using System.Collections.Generic;
using System.Diagnostics;
diff --git a/src/linker/Linker/Driver.cs b/src/linker/Linker/Driver.cs
index 79d5413ff..2c52424d5 100644
--- a/src/linker/Linker/Driver.cs
+++ b/src/linker/Linker/Driver.cs
@@ -29,6 +29,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
using System.Runtime.Loader;
@@ -66,7 +67,13 @@ namespace Mono.Linker
readonly Queue<string> arguments;
bool _needAddBypassNGenStep;
- protected LinkContext context;
+ LinkContext? context;
+ protected LinkContext Context {
+ get {
+ Debug.Assert (context != null);
+ return context;
+ }
+ }
public Driver (Queue<string> arguments)
{
@@ -148,7 +155,7 @@ namespace Mono.Linker
void ErrorMissingArgument (string optionName)
{
- context.LogError ($"Missing argument for '{optionName}' option.", 1018);
+ Context.LogError ($"Missing argument for '{optionName}' option.", 1018);
}
// Perform setup of the LinkContext and parse the arguments.
@@ -156,7 +163,7 @@ namespace Mono.Linker
// 0 => successfully set up context with all arguments
// 1 => argument processing stopped early without errors
// -1 => error setting up context
- protected int SetupContext (ILogger customLogger = null)
+ protected int SetupContext (ILogger? customLogger = null)
{
Pipeline p = GetStandardPipeline ();
context = GetDefaultContext (p, customLogger);
@@ -164,9 +171,9 @@ namespace Mono.Linker
var body_substituter_steps = new Stack<string> ();
var xml_custom_attribute_steps = new Stack<string> ();
var custom_steps = new List<string> ();
- var set_optimizations = new List<(CodeOptimizations, string, bool)> ();
+ var set_optimizations = new List<(CodeOptimizations, string?, bool)> ();
bool dumpDependencies = false;
- string dependenciesFileName = null;
+ string? dependenciesFileName = null;
context.StripSecurity = true;
bool new_mvid_used = false;
bool deterministic_used = false;
@@ -253,7 +260,7 @@ namespace Mono.Linker
return -1;
}
- if (!GetStringParam (token, out string substitutionFile))
+ if (!GetStringParam (token, out string? substitutionFile))
return -1;
body_substituter_steps.Push (substitutionFile);
@@ -266,14 +273,14 @@ namespace Mono.Linker
continue;
case "--action": {
- if (!GetStringParam (token, out string actionString))
+ if (!GetStringParam (token, out string? actionString))
return -1;
AssemblyAction? action = ParseAssemblyAction (actionString);
if (action == null)
return -1;
- string assemblyName = GetNextStringValue ();
+ string? assemblyName = GetNextStringValue ();
if (assemblyName == null) {
context.DefaultAction = action.Value;
continue;
@@ -288,7 +295,7 @@ namespace Mono.Linker
continue;
}
case "--trim-mode": {
- if (!GetStringParam (token, out string actionString))
+ if (!GetStringParam (token, out string? actionString))
return -1;
AssemblyAction? action = ParseAssemblyAction (actionString);
@@ -299,7 +306,7 @@ namespace Mono.Linker
continue;
}
case "--custom-step":
- if (!GetStringParam (token, out string custom_step))
+ if (!GetStringParam (token, out string? custom_step))
return -1;
custom_steps.Add (custom_step);
@@ -341,7 +348,7 @@ namespace Mono.Linker
continue;
case "--keep-metadata": {
- if (!GetStringParam (token, out string mname))
+ if (!GetStringParam (token, out string? mname))
return -1;
if (!TryGetMetadataTrimming (mname, out var type))
@@ -382,32 +389,32 @@ namespace Mono.Linker
continue;
case "--disable-opt": {
- if (!GetStringParam (token, out string optName))
+ if (!GetStringParam (token, out string? optName))
return -1;
if (!GetOptimizationName (optName, out var opt))
return -1;
- string assemblyName = GetNextStringValue ();
+ string? assemblyName = GetNextStringValue ();
set_optimizations.Add ((opt, assemblyName, false));
continue;
}
case "--enable-opt": {
- if (!GetStringParam (token, out string optName))
+ if (!GetStringParam (token, out string? optName))
return -1;
if (!GetOptimizationName (optName, out var opt))
return -1;
- string assemblyName = GetNextStringValue ();
+ string? assemblyName = GetNextStringValue ();
set_optimizations.Add ((opt, assemblyName, true));
continue;
}
case "--feature": {
- if (!GetStringParam (token, out string featureName))
+ if (!GetStringParam (token, out string? featureName))
return -1;
if (!GetBoolParam (token, value => {
@@ -440,7 +447,7 @@ namespace Mono.Linker
continue;
case "--output-assemblylist":
- if (!GetStringParam (token, out string assemblyListFile))
+ if (!GetStringParam (token, out string? assemblyListFile))
return -1;
context.AssemblyListFile = assemblyListFile;
@@ -448,7 +455,7 @@ namespace Mono.Linker
continue;
case "--output-pinvokes":
- if (!GetStringParam (token, out string pinvokesListFile))
+ if (!GetStringParam (token, out string? pinvokesListFile))
return -1;
context.PInvokesListFile = pinvokesListFile;
@@ -461,7 +468,7 @@ namespace Mono.Linker
return -1;
}
- if (!GetStringParam (token, out string fileList))
+ if (!GetStringParam (token, out string? fileList))
return -1;
foreach (string file in GetFiles (fileList))
@@ -470,7 +477,7 @@ namespace Mono.Linker
continue;
case "--generate-warning-suppressions":
- if (!GetStringParam (token, out string generateWarningSuppressionsArgument))
+ if (!GetStringParam (token, out string? generateWarningSuppressionsArgument))
return -1;
if (!GetWarningSuppressionWriterFileOutputKind (generateWarningSuppressionsArgument, out var fileOutputKind)) {
@@ -482,7 +489,7 @@ namespace Mono.Linker
continue;
case "--nowarn":
- if (!GetStringParam (token, out string noWarnArgument))
+ if (!GetStringParam (token, out string? noWarnArgument))
return -1;
context.NoWarn.UnionWith (ProcessWarningCodes (noWarnArgument));
@@ -516,7 +523,7 @@ namespace Mono.Linker
continue;
case "--warn":
- if (!GetStringParam (token, out string warnVersionArgument))
+ if (!GetStringParam (token, out string? warnVersionArgument))
return -1;
if (!GetWarnVersion (warnVersionArgument, out WarnVersion version))
@@ -528,7 +535,7 @@ namespace Mono.Linker
case "--singlewarn":
case "--singlewarn+": {
- string assemblyName = GetNextStringValue ();
+ string? assemblyName = GetNextStringValue ();
if (assemblyName != null) {
if (!IsValidAssemblyName (assemblyName)) {
context.LogError ($"Invalid assembly name '{assemblyName}'.", 1036);
@@ -545,7 +552,7 @@ namespace Mono.Linker
}
case "--singlewarn-": {
- string assemblyName = GetNextStringValue ();
+ string? assemblyName = GetNextStringValue ();
if (assemblyName != null) {
if (!IsValidAssemblyName (assemblyName)) {
context.LogError ($"Invalid assembly name '{assemblyName}'.", 1036);
@@ -575,7 +582,7 @@ namespace Mono.Linker
switch (token.Substring (1)) {
case "d":
- if (!GetStringParam (token, out string directory))
+ if (!GetStringParam (token, out string? directory))
return -1;
DirectoryInfo info = new DirectoryInfo (directory);
@@ -584,7 +591,7 @@ namespace Mono.Linker
continue;
case "o":
case "out":
- if (!GetStringParam (token, out string outputDirectory))
+ if (!GetStringParam (token, out string? outputDirectory))
return -1;
context.OutputDirectory = outputDirectory;
@@ -594,7 +601,7 @@ namespace Mono.Linker
context.KeepTypeForwarderOnlyAssemblies = true;
continue;
case "x": {
- if (!GetStringParam (token, out string xmlFile))
+ if (!GetStringParam (token, out string? xmlFile))
return -1;
if (!File.Exists (xmlFile)) {
@@ -606,7 +613,7 @@ namespace Mono.Linker
continue;
}
case "a": {
- if (!GetStringParam (token, out string assemblyFile))
+ if (!GetStringParam (token, out string? assemblyFile))
return -1;
if (!File.Exists (assemblyFile) && assemblyFile.EndsWith (".dll", StringComparison.InvariantCultureIgnoreCase)) {
@@ -649,7 +656,7 @@ namespace Mono.Linker
return 1;
case "reference":
- if (!GetStringParam (token, out string reference))
+ if (!GetStringParam (token, out string? reference))
return -1;
context.Resolver.AddReferenceAssembly (reference);
@@ -756,7 +763,7 @@ namespace Mono.Linker
// to the error code.
// May propagate exceptions, which will result in the process getting an
// exit code determined by dotnet.
- public int Run (ILogger customLogger = null)
+ public int Run (ILogger? customLogger = null)
{
int setupStatus = SetupContext (customLogger);
if (setupStatus > 0)
@@ -764,32 +771,32 @@ namespace Mono.Linker
if (setupStatus < 0)
return 1;
- Pipeline p = context.Pipeline;
+ Pipeline p = Context.Pipeline;
PreProcessPipeline (p);
try {
- p.Process (context);
+ p.Process (Context);
} catch (LinkerFatalErrorException lex) {
- context.LogMessage (lex.MessageContainer);
+ Context.LogMessage (lex.MessageContainer);
Console.Error.WriteLine (lex.ToString ());
Debug.Assert (lex.MessageContainer.Category == MessageCategory.Error);
Debug.Assert (lex.MessageContainer.Code != null);
Debug.Assert (lex.MessageContainer.Code.Value != 0);
return lex.MessageContainer.Code ?? 1;
} catch (ResolutionException e) {
- context.LogError ($"{e.Message}", 1040);
+ Context.LogError ($"{e.Message}", 1040);
} catch (Exception) {
// Unhandled exceptions are usually linker bugs. Ask the user to report it.
- context.LogError ($"IL Trimmer has encountered an unexpected error. Please report the issue at https://github.com/dotnet/linker/issues", 1012);
+ Context.LogError ($"IL Trimmer has encountered an unexpected error. Please report the issue at https://github.com/dotnet/linker/issues", 1012);
// Don't swallow the exception and exit code - rethrow it and let the surrounding tooling decide what to do.
// The stack trace will go to stderr, and the MSBuild task will surface it with High importance.
throw;
} finally {
- context.FlushCachedWarnings ();
- context.Tracer.Finish ();
+ Context.FlushCachedWarnings ();
+ Context.Tracer.Finish ();
}
- return context.ErrorsCount > 0 ? 1 : 0;
+ return Context.ErrorsCount > 0 ? 1 : 0;
}
partial void PreProcessPipeline (Pipeline pipeline);
@@ -815,7 +822,7 @@ namespace Mono.Linker
}
}
- Assembly GetCustomAssembly (string arg)
+ Assembly? GetCustomAssembly (string arg)
{
if (Path.IsPathRooted (arg)) {
var assemblyPath = Path.GetFullPath (arg);
@@ -824,9 +831,9 @@ namespace Mono.Linker
// (or even if a different path specifies the "same" assembly, based on the MVID).
return AssemblyLoadContext.Default.LoadFromAssemblyPath (assemblyPath);
}
- context.LogError ($"The assembly '{arg}' specified for '--custom-step' option could not be found.", 1022);
+ Context.LogError ($"The assembly '{arg}' specified for '--custom-step' option could not be found.", 1022);
} else
- context.LogError ($"The path to the assembly '{arg}' specified for '--custom-step' must be fully qualified.", 1023);
+ Context.LogError ($"The path to the assembly '{arg}' specified for '--custom-step' must be fully qualified.", 1023);
return null;
}
@@ -846,14 +853,14 @@ namespace Mono.Linker
pipeline.AddStepBefore (typeof (MarkStep), new BodySubstituterStep (File.OpenRead (file), file));
}
- protected virtual void AddXmlDependencyRecorder (LinkContext context, string fileName)
+ protected virtual void AddXmlDependencyRecorder (LinkContext context, string? fileName)
{
context.Tracer.AddRecorder (new XmlDependencyRecorder (context, fileName));
}
protected bool AddMarkHandler (Pipeline pipeline, string arg)
{
- if (!TryGetCustomAssembly (ref arg, out Assembly custom_assembly))
+ if (!TryGetCustomAssembly (ref arg, out Assembly? custom_assembly))
return false;
var step = ResolveStep<IMarkHandler> (arg, custom_assembly);
@@ -864,12 +871,12 @@ namespace Mono.Linker
return true;
}
- bool TryGetCustomAssembly (ref string arg, out Assembly assembly)
+ bool TryGetCustomAssembly (ref string arg, [NotNullWhen (true)] out Assembly? assembly)
{
assembly = null;
int pos = arg.IndexOf (",");
if (pos == -1)
- return true;
+ return false;
assembly = GetCustomAssembly (arg.Substring (pos + 1));
if (assembly == null)
@@ -881,24 +888,24 @@ namespace Mono.Linker
protected bool AddCustomStep (Pipeline pipeline, string arg)
{
- if (!TryGetCustomAssembly (ref arg, out Assembly custom_assembly))
+ if (!TryGetCustomAssembly (ref arg, out Assembly? custom_assembly))
return false;
string customStepName;
- string targetName = null;
+ string? targetName = null;
bool before = false;
if (!arg.Contains (':')) {
customStepName = arg;
} else {
string[] parts = arg.Split (':');
if (parts.Length != 2) {
- context.LogError ($"Invalid value '{arg}' specified for '--custom-step' option.", 1024);
+ Context.LogError ($"Invalid value '{arg}' specified for '--custom-step' option.", 1024);
return false;
}
customStepName = parts[1];
if (!parts[0].StartsWith ("-") && !parts[0].StartsWith ("+")) {
- context.LogError ($"Expected '+' or '-' to control new step insertion.", 1025);
+ Context.LogError ($"Expected '+' or '-' to control new step insertion.", 1025);
return false;
}
@@ -912,15 +919,15 @@ namespace Mono.Linker
if (typeof (IStep).IsAssignableFrom (stepType)) {
- var customStep = (IStep) Activator.CreateInstance (stepType);
+ var customStep = (IStep?) Activator.CreateInstance (stepType) ?? throw new InvalidOperationException ();
if (targetName == null) {
pipeline.AppendStep (customStep);
return true;
}
- IStep target = FindStep (pipeline, targetName);
+ IStep? target = FindStep (pipeline, targetName);
if (target == null) {
- context.LogError ($"Pipeline step '{targetName}' could not be found.", 1026);
+ Context.LogError ($"Pipeline step '{targetName}' could not be found.", 1026);
return false;
}
@@ -934,15 +941,15 @@ namespace Mono.Linker
if (typeof (IMarkHandler).IsAssignableFrom (stepType)) {
- var customStep = (IMarkHandler) Activator.CreateInstance (stepType);
+ var customStep = (IMarkHandler?) Activator.CreateInstance (stepType) ?? throw new InvalidOperationException ();
if (targetName == null) {
pipeline.AppendMarkHandler (customStep);
return true;
}
- IMarkHandler target = FindMarkHandler (pipeline, targetName);
+ IMarkHandler? target = FindMarkHandler (pipeline, targetName);
if (target == null) {
- context.LogError ($"Pipeline step '{targetName}' could not be found.", 1026);
+ Context.LogError ($"Pipeline step '{targetName}' could not be found.", 1026);
return false;
}
@@ -954,11 +961,11 @@ namespace Mono.Linker
return true;
}
- context.LogError ($"Custom step '{stepType}' is incompatible with this trimmer version.", 1028);
+ Context.LogError ($"Custom step '{stepType}' is incompatible with this trimmer version.", 1028);
return false;
}
- protected virtual IStep FindStep (Pipeline pipeline, string name)
+ protected virtual IStep? FindStep (Pipeline pipeline, string name)
{
foreach (IStep step in pipeline.GetSteps ()) {
Type t = step.GetType ();
@@ -969,7 +976,7 @@ namespace Mono.Linker
return null;
}
- static IMarkHandler FindMarkHandler (Pipeline pipeline, string name)
+ static IMarkHandler? FindMarkHandler (Pipeline pipeline, string name)
{
foreach (IMarkHandler step in pipeline.MarkHandlers) {
Type t = step.GetType ();
@@ -980,33 +987,33 @@ namespace Mono.Linker
return null;
}
- Type ResolveStepType (string type, Assembly assembly)
+ Type? ResolveStepType (string type, Assembly assembly)
{
- Type step = assembly != null ? assembly.GetType (type) : Type.GetType (type, false);
+ Type? step = assembly != null ? assembly.GetType (type) : Type.GetType (type, false);
if (step == null) {
- context.LogError ($"Custom step '{type}' could not be found.", 1027);
+ Context.LogError ($"Custom step '{type}' could not be found.", 1027);
return null;
}
return step;
}
- TStep ResolveStep<TStep> (string type, Assembly assembly) where TStep : class
+ TStep? ResolveStep<TStep> (string type, Assembly assembly) where TStep : class
{
- Type step = assembly != null ? assembly.GetType (type) : Type.GetType (type, false);
+ Type? step = assembly != null ? assembly.GetType (type) : Type.GetType (type, false);
if (step == null) {
- context.LogError ($"Custom step '{type}' could not be found.", 1027);
+ Context.LogError ($"Custom step '{type}' could not be found.", 1027);
return null;
}
if (!typeof (TStep).IsAssignableFrom (step)) {
- context.LogError ($"Custom step '{type}' is incompatible with this trimmer version.", 1028);
+ Context.LogError ($"Custom step '{type}' is incompatible with this trimmer version.", 1028);
return null;
}
- return (TStep) Activator.CreateInstance (step);
+ return (TStep?) Activator.CreateInstance (step);
}
static string[] GetFiles (string param)
@@ -1022,7 +1029,7 @@ namespace Mono.Linker
{
var lines = new List<string> ();
using (StreamReader reader = new StreamReader (file)) {
- string line;
+ string? line;
while ((line = reader.ReadLine ()) != null)
lines.Add (line);
}
@@ -1049,7 +1056,7 @@ namespace Mono.Linker
return AssemblyAction.AddBypassNGenUsed;
}
- context.LogError ($"Invalid assembly action '{s}'.", 1031);
+ Context.LogError ($"Invalid assembly action '{s}'.", 1031);
return null;
}
@@ -1068,7 +1075,7 @@ namespace Mono.Linker
return AssemblyRootMode.Library;
}
- context.LogError ($"Invalid assembly root mode '{s}'.", 1037);
+ Context.LogError ($"Invalid assembly root mode '{s}'.", 1037);
return null;
}
@@ -1080,7 +1087,7 @@ namespace Mono.Linker
return true;
}
- context.LogError ($"Invalid warning version '{text}'.", 1016);
+ Context.LogError ($"Invalid warning version '{text}'.", 1016);
version = 0;
return false;
}
@@ -1111,7 +1118,7 @@ namespace Mono.Linker
return true;
}
- context.LogError ($"Invalid optimization value '{text}'.", 1029);
+ Context.LogError ($"Invalid optimization value '{text}'.", 1029);
optimization = 0;
return false;
}
@@ -1130,7 +1137,7 @@ namespace Mono.Linker
return true;
}
- context.LogError ($"Invalid metadata value '{text}'.", 1046);
+ Context.LogError ($"Invalid metadata value '{text}'.", 1046);
metadataTrimming = 0;
return false;
}
@@ -1171,11 +1178,11 @@ namespace Mono.Linker
return true;
}
- context.LogError ($"Invalid argument for '{token}' option.", 1030);
+ Context.LogError ($"Invalid argument for '{token}' option.", 1030);
return false;
}
- bool GetStringParam (string token, out string value)
+ bool GetStringParam (string token, [NotNullWhen (true)] out string? value)
{
value = null;
if (arguments.Count < 1) {
@@ -1193,7 +1200,7 @@ namespace Mono.Linker
return false;
}
- string GetNextStringValue ()
+ string? GetNextStringValue ()
{
if (arguments.Count < 1)
return null;
@@ -1206,7 +1213,7 @@ namespace Mono.Linker
return arg;
}
- protected virtual LinkContext GetDefaultContext (Pipeline pipeline, ILogger logger)
+ protected virtual LinkContext GetDefaultContext (Pipeline pipeline, ILogger? logger)
{
return new LinkContext (pipeline, logger ?? new ConsoleLogger (), "output") {
TrimAction = AssemblyAction.Link,
diff --git a/src/linker/Linker/DynamicDependency.cs b/src/linker/Linker/DynamicDependency.cs
index bd139f1c8..8b6c56e13 100644
--- a/src/linker/Linker/DynamicDependency.cs
+++ b/src/linker/Linker/DynamicDependency.cs
@@ -2,8 +2,6 @@ using System;
using System.Diagnostics.CodeAnalysis;
using Mono.Cecil;
-#nullable enable
-
namespace Mono.Linker
{
/// Tracks dependencies created via DynamicDependencyAttribute in the linker.
diff --git a/src/linker/Linker/EmbeddedXmlInfo.cs b/src/linker/Linker/EmbeddedXmlInfo.cs
index 143d41d3c..14871394b 100644
--- a/src/linker/Linker/EmbeddedXmlInfo.cs
+++ b/src/linker/Linker/EmbeddedXmlInfo.cs
@@ -13,7 +13,7 @@ namespace Mono.Linker
{
public static class EmbeddedXmlInfo
{
- static EmbeddedResource GetEmbeddedXml (AssemblyDefinition assembly, Func<Resource, bool> predicate)
+ static EmbeddedResource? GetEmbeddedXml (AssemblyDefinition assembly, Func<Resource, bool> predicate)
{
return assembly.Modules
.SelectMany (mod => mod.Resources)
@@ -32,7 +32,7 @@ namespace Mono.Linker
if (rsc == null)
return;
- DescriptorMarker marker = null;
+ DescriptorMarker? marker = null;
try {
context.LogMessage ($"Processing embedded linker descriptor '{rsc.Name}' from '{assembly.Name}'.");
marker = GetExternalResolveStep (context, rsc, assembly);
@@ -45,7 +45,7 @@ namespace Mono.Linker
marker.Mark ();
}
- public static SubstitutionInfo ProcessSubstitutions (AssemblyDefinition assembly, LinkContext context)
+ public static SubstitutionInfo? ProcessSubstitutions (AssemblyDefinition assembly, LinkContext context)
{
if (context.Annotations.GetAction (assembly) == AssemblyAction.Skip)
return null;
@@ -54,7 +54,7 @@ namespace Mono.Linker
if (rsc == null)
return null;
- BodySubstitutionParser parser = null;
+ BodySubstitutionParser? parser = null;
try {
context.LogMessage ($"Processing embedded substitution descriptor '{rsc.Name}' from '{assembly.Name}'.");
parser = GetExternalSubstitutionParser (context, rsc, assembly);
@@ -70,7 +70,7 @@ namespace Mono.Linker
return substitutionInfo;
}
- public static AttributeInfo ProcessAttributes (AssemblyDefinition assembly, LinkContext context)
+ public static AttributeInfo? ProcessAttributes (AssemblyDefinition assembly, LinkContext context)
{
if (context.Annotations.GetAction (assembly) == AssemblyAction.Skip)
return null;
@@ -79,7 +79,7 @@ namespace Mono.Linker
if (rsc == null)
return null;
- LinkAttributesParser parser = null;
+ LinkAttributesParser? parser = null;
try {
context.LogMessage ($"Processing embedded '{rsc.Name}' from '{assembly.Name}'.");
parser = GetExternalLinkAttributesParser (context, rsc, assembly);
diff --git a/src/linker/Linker/IReflectionPatternRecorder.cs b/src/linker/Linker/IReflectionPatternRecorder.cs
index 411b03a6a..9be6698b8 100644
--- a/src/linker/Linker/IReflectionPatternRecorder.cs
+++ b/src/linker/Linker/IReflectionPatternRecorder.cs
@@ -49,7 +49,7 @@ namespace Mono.Linker
/// This can be null if there's no logical instruction to assign to the pattern.</param>
/// <param name="accessedItem">The item accessed through reflection. This can be one of:
/// TypeDefinition, MethodDefinition, PropertyDefinition, FieldDefinition, EventDefinition, InterfaceImplementation.</param>
- void RecognizedReflectionAccessPattern (ICustomAttributeProvider source, Instruction sourceInstruction, IMetadataTokenProvider accessedItem);
+ void RecognizedReflectionAccessPattern (ICustomAttributeProvider? source, Instruction? sourceInstruction, IMetadataTokenProvider accessedItem);
/// <summary>
/// Called when the linker detected a reflection access but was not able to recognize the entire pattern.
@@ -64,6 +64,6 @@ namespace Mono.Linker
/// <param name="messageCode">Message code to use when reporting the unrecognized pattern as a warning.</param>
/// <remarks>This effectively means that there's a potential hole in the linker marking - some items which are accessed only through
/// reflection may not be marked correctly and thus may fail at runtime.</remarks>
- void UnrecognizedReflectionAccessPattern (in MessageOrigin origin, ICustomAttributeProvider source, Instruction sourceInstruction, IMetadataTokenProvider accessedItem, string message, int messageCode);
+ void UnrecognizedReflectionAccessPattern (in MessageOrigin origin, ICustomAttributeProvider? source, Instruction? sourceInstruction, IMetadataTokenProvider accessedItem, string message, int messageCode);
}
}
diff --git a/src/linker/Linker/KnownMembers.cs b/src/linker/Linker/KnownMembers.cs
index 0b916dbd2..85be9c628 100644
--- a/src/linker/Linker/KnownMembers.cs
+++ b/src/linker/Linker/KnownMembers.cs
@@ -4,11 +4,11 @@ namespace Mono.Linker
{
public class KnownMembers
{
- public MethodDefinition NotSupportedExceptionCtorString { get; set; }
- public MethodDefinition DisablePrivateReflectionAttributeCtor { get; set; }
- public MethodDefinition ObjectCtor { get; set; }
+ public MethodDefinition? NotSupportedExceptionCtorString { get; set; }
+ public MethodDefinition? DisablePrivateReflectionAttributeCtor { get; set; }
+ public MethodDefinition? ObjectCtor { get; set; }
- public TypeDefinition RemoveAttributeInstancesAttributeDefinition { get; set; }
+ public TypeDefinition? RemoveAttributeInstancesAttributeDefinition { get; set; }
public static bool IsNotSupportedExceptionCtorString (MethodDefinition method)
{
diff --git a/src/linker/Linker/LinkContext.cs b/src/linker/Linker/LinkContext.cs
index eba7a7190..23d5a7a6f 100644
--- a/src/linker/Linker/LinkContext.cs
+++ b/src/linker/Linker/LinkContext.cs
@@ -26,8 +26,6 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#nullable enable
-
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -267,27 +265,27 @@ namespace Mono.Linker
string asmname = fullName.Substring (pos + 1);
fullName = fullName.Substring (0, pos);
- AssemblyDefinition assembly = Resolve (AssemblyNameReference.Parse (asmname));
- return assembly.MainModule.GetType (fullName);
+ AssemblyDefinition? assembly = Resolve (AssemblyNameReference.Parse (asmname));
+ return assembly?.MainModule.GetType (fullName);
}
- public AssemblyDefinition TryResolve (string name)
+ public AssemblyDefinition? TryResolve (string name)
{
return TryResolve (new AssemblyNameReference (name, new Version ()));
}
- public AssemblyDefinition TryResolve (AssemblyNameReference name)
+ public AssemblyDefinition? TryResolve (AssemblyNameReference name)
{
return _resolver.Resolve (name, probing: true);
}
- public AssemblyDefinition Resolve (IMetadataScope scope)
+ public AssemblyDefinition? Resolve (IMetadataScope scope)
{
AssemblyNameReference reference = GetReference (scope);
return _resolver.Resolve (reference);
}
- public AssemblyDefinition Resolve (AssemblyNameReference name)
+ public AssemblyDefinition? Resolve (AssemblyNameReference name)
{
return _resolver.Resolve (name);
}
@@ -340,7 +338,7 @@ namespace Mono.Linker
return references;
foreach (AssemblyNameReference reference in assembly.MainModule.AssemblyReferences) {
- AssemblyDefinition definition = Resolve (reference);
+ AssemblyDefinition? definition = Resolve (reference);
if (definition != null)
references.Add (definition);
}
@@ -526,8 +524,8 @@ namespace Mono.Linker
if (WarningSuppressionWriter != null &&
message.IsWarningMessage (out int? code) &&
- message.Origin?.Provider != null)
- WarningSuppressionWriter.AddWarning (code.Value, message.Origin?.Provider);
+ message.Origin?.Provider is Mono.Cecil.ICustomAttributeProvider provider)
+ WarningSuppressionWriter.AddWarning (code.Value, provider);
if (message.Category == MessageCategory.Error || message.Category == MessageCategory.WarningAsError)
ErrorsCount++;
@@ -665,7 +663,7 @@ namespace Mono.Linker
if (_targetRuntime != null)
return _targetRuntime.Value;
- TypeDefinition objectType = BCL.FindPredefinedType ("System", "Object", this);
+ TypeDefinition? objectType = BCL.FindPredefinedType ("System", "Object", this);
_targetRuntime = objectType?.Module.Assembly.Name.Version.Major ?? -1;
return _targetRuntime.Value;
@@ -805,7 +803,9 @@ namespace Mono.Linker
public TypeDefinition? TryResolve (AssemblyDefinition assembly, string typeNameString)
{
// It could be cached if it shows up on fast path
- return TryResolve (_typeNameResolver.ResolveTypeName (assembly, typeNameString));
+ return _typeNameResolver.TryResolveTypeName (assembly, typeNameString, out TypeReference? typeReference)
+ ? TryResolve (typeReference)
+ : null;
}
readonly HashSet<MemberReference> unresolved_reported = new ();
diff --git a/src/linker/Linker/LinkerAttributesInformation.cs b/src/linker/Linker/LinkerAttributesInformation.cs
index ca74c9c3a..0d431999e 100644
--- a/src/linker/Linker/LinkerAttributesInformation.cs
+++ b/src/linker/Linker/LinkerAttributesInformation.cs
@@ -12,9 +12,9 @@ namespace Mono.Linker
{
readonly struct LinkerAttributesInformation
{
- readonly Dictionary<Type, List<Attribute>> _linkerAttributes;
+ readonly Dictionary<Type, List<Attribute>>? _linkerAttributes;
- private LinkerAttributesInformation (Dictionary<Type, List<Attribute>> cache)
+ private LinkerAttributesInformation (Dictionary<Type, List<Attribute>>? cache)
{
this._linkerAttributes = cache;
}
@@ -23,12 +23,12 @@ namespace Mono.Linker
{
Debug.Assert (context.CustomAttributes.HasAny (provider));
- Dictionary<Type, List<Attribute>> cache = null;
+ Dictionary<Type, List<Attribute>>? cache = null;
foreach (var customAttribute in context.CustomAttributes.GetCustomAttributes (provider)) {
var attributeType = customAttribute.AttributeType;
- Attribute attributeValue;
+ Attribute? attributeValue;
switch (attributeType.Name) {
case "RequiresUnreferencedCodeAttribute" when attributeType.Namespace == "System.Diagnostics.CodeAnalysis":
attributeValue = ProcessRequiresUnreferencedCodeAttribute (context, provider, customAttribute);
@@ -84,7 +84,7 @@ namespace Mono.Linker
return attributeList.Cast<T> ();
}
- static Attribute ProcessRequiresUnreferencedCodeAttribute (LinkContext context, ICustomAttributeProvider provider, CustomAttribute customAttribute)
+ static Attribute? ProcessRequiresUnreferencedCodeAttribute (LinkContext context, ICustomAttributeProvider provider, CustomAttribute customAttribute)
{
if (!(provider is MethodDefinition || provider is TypeDefinition))
return null;
@@ -109,7 +109,7 @@ namespace Mono.Linker
return null;
}
- static RemoveAttributeInstancesAttribute BuildRemoveAttributeInstancesAttribute (LinkContext context, TypeDefinition attributeContext, CustomAttribute ca)
+ static RemoveAttributeInstancesAttribute? BuildRemoveAttributeInstancesAttribute (LinkContext context, TypeDefinition attributeContext, CustomAttribute ca)
{
switch (ca.ConstructorArguments.Count) {
case 0:
diff --git a/src/linker/Linker/LinkerILProcessor.cs b/src/linker/Linker/LinkerILProcessor.cs
index 1cc82319c..2be7b138b 100644
--- a/src/linker/Linker/LinkerILProcessor.cs
+++ b/src/linker/Linker/LinkerILProcessor.cs
@@ -43,7 +43,7 @@ namespace Mono.Linker
public void Append (Instruction instruction)
{
- Instruction lastInstruction = Instructions.Count == 0 ? null : Instructions[Instructions.Count - 1];
+ Instruction? lastInstruction = Instructions.Count == 0 ? null : Instructions[Instructions.Count - 1];
RedirectScopeEnd (lastInstruction, instruction);
_ilProcessor.Append (instruction);
}
@@ -64,8 +64,8 @@ namespace Mono.Linker
if (index == -1)
throw new ArgumentOutOfRangeException (nameof (instruction));
- Instruction nextInstruction = Instructions.Count == index + 1 ? null : Instructions[index + 1];
- Instruction previousInstruction = index == 0 ? null : Instructions[index - 1];
+ Instruction? nextInstruction = Instructions.Count == index + 1 ? null : Instructions[index + 1];
+ Instruction? previousInstruction = index == 0 ? null : Instructions[index - 1];
RedirectScopeStart (instruction, nextInstruction);
RedirectScopeEnd (instruction, previousInstruction);
@@ -75,7 +75,7 @@ namespace Mono.Linker
public void RemoveAt (int index) => Remove (Instructions[index]);
- void RedirectScopeStart (Instruction oldTarget, Instruction newTarget)
+ void RedirectScopeStart (Instruction oldTarget, Instruction? newTarget)
{
// In Cecil "start" pointers point to the first instruction in a given scope
// and the "end" pointers point to the first instruction after the given block
@@ -96,14 +96,14 @@ namespace Mono.Linker
}
#pragma warning disable IDE0060 // Remove unused parameter
- static void RedirectScopeEnd (Instruction oldTarget, Instruction newTarget)
+ static void RedirectScopeEnd (Instruction? oldTarget, Instruction? newTarget)
#pragma warning restore IDE0060 // Remove unused parameter
{
// Currently Cecil treats all block boundaries as "starts"
// so nothing to do here.
}
- void ReplaceInstructionReference (Instruction oldTarget, Instruction newTarget)
+ void ReplaceInstructionReference (Instruction oldTarget, Instruction? newTarget)
{
foreach (var instr in Instructions) {
switch (instr.OpCode.FlowControl) {
diff --git a/src/linker/Linker/LoggingReflectionPatternRecorder.cs b/src/linker/Linker/LoggingReflectionPatternRecorder.cs
index 36d8713dc..eb30e5247 100644
--- a/src/linker/Linker/LoggingReflectionPatternRecorder.cs
+++ b/src/linker/Linker/LoggingReflectionPatternRecorder.cs
@@ -37,12 +37,12 @@ namespace Mono.Linker
_context = context;
}
- public void RecognizedReflectionAccessPattern (ICustomAttributeProvider source, Instruction sourceInstruction, IMetadataTokenProvider accessedItem)
+ public void RecognizedReflectionAccessPattern (ICustomAttributeProvider? source, Instruction? sourceInstruction, IMetadataTokenProvider accessedItem)
{
// Do nothing - there's no logging for successfully recognized patterns
}
- public void UnrecognizedReflectionAccessPattern (in MessageOrigin origin, ICustomAttributeProvider source, Instruction sourceInstruction, IMetadataTokenProvider accessedItem, string message, int messageCode)
+ public void UnrecognizedReflectionAccessPattern (in MessageOrigin origin, ICustomAttributeProvider? source, Instruction? sourceInstruction, IMetadataTokenProvider accessedItem, string message, int messageCode)
{
_context.LogWarning (message, messageCode, origin, MessageSubCategory.TrimAnalysis);
}
diff --git a/src/linker/Linker/MarkingHelpers.cs b/src/linker/Linker/MarkingHelpers.cs
index 57dfd6059..887214310 100644
--- a/src/linker/Linker/MarkingHelpers.cs
+++ b/src/linker/Linker/MarkingHelpers.cs
@@ -35,7 +35,9 @@ namespace Mono.Linker
if (typeReference.Scope is AssemblyNameReference) {
var assembly = _context.Resolve (typeReference.Scope);
- if (assembly != null && assembly.MainModule.GetMatchingExportedType (_context.TryResolve (typeReference), out var exportedType))
+ if (assembly != null &&
+ _context.TryResolve (typeReference) is TypeDefinition typeDefinition &&
+ assembly.MainModule.GetMatchingExportedType (typeDefinition, out var exportedType))
MarkExportedType (exportedType, assembly.MainModule, new DependencyInfo (DependencyKind.ExportedType, typeReference));
}
}
diff --git a/src/linker/Linker/MemberActionStore.cs b/src/linker/Linker/MemberActionStore.cs
index c5be4dd52..3826a441b 100644
--- a/src/linker/Linker/MemberActionStore.cs
+++ b/src/linker/Linker/MemberActionStore.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using Mono.Cecil;
namespace Mono.Linker
@@ -9,17 +10,17 @@ namespace Mono.Linker
public class MemberActionStore
{
public SubstitutionInfo PrimarySubstitutionInfo { get; }
- private readonly Dictionary<AssemblyDefinition, SubstitutionInfo> _embeddedXmlInfos;
+ private readonly Dictionary<AssemblyDefinition, SubstitutionInfo?> _embeddedXmlInfos;
readonly LinkContext _context;
public MemberActionStore (LinkContext context)
{
PrimarySubstitutionInfo = new SubstitutionInfo ();
- _embeddedXmlInfos = new Dictionary<AssemblyDefinition, SubstitutionInfo> ();
+ _embeddedXmlInfos = new Dictionary<AssemblyDefinition, SubstitutionInfo?> ();
_context = context;
}
- public bool TryGetSubstitutionInfo (MemberReference member, out SubstitutionInfo xmlInfo)
+ public bool TryGetSubstitutionInfo (MemberReference member, [NotNullWhen (true)] out SubstitutionInfo? xmlInfo)
{
var assembly = member.Module.Assembly;
if (!_embeddedXmlInfos.TryGetValue (assembly, out xmlInfo)) {
@@ -43,7 +44,7 @@ namespace Mono.Linker
return MethodAction.Nothing;
}
- public bool TryGetMethodStubValue (MethodDefinition method, out object value)
+ public bool TryGetMethodStubValue (MethodDefinition method, out object? value)
{
if (PrimarySubstitutionInfo.MethodStubValues.TryGetValue (method, out value))
return true;
@@ -54,7 +55,7 @@ namespace Mono.Linker
return embeddedXml.MethodStubValues.TryGetValue (method, out value);
}
- public bool TryGetFieldUserValue (FieldDefinition field, out object value)
+ public bool TryGetFieldUserValue (FieldDefinition field, out object? value)
{
if (PrimarySubstitutionInfo.FieldValues.TryGetValue (field, out value))
return true;
diff --git a/src/linker/Linker/MessageContainer.cs b/src/linker/Linker/MessageContainer.cs
index f0a4afd09..89d51ff97 100644
--- a/src/linker/Linker/MessageContainer.cs
+++ b/src/linker/Linker/MessageContainer.cs
@@ -274,7 +274,7 @@ namespace Mono.Linker
public bool Equals (MessageContainer other) =>
(Category, Text, Code, SubCategory, Origin) == (other.Category, other.Text, other.Code, other.SubCategory, other.Origin);
- public override bool Equals (object obj) => obj is MessageContainer messageContainer && Equals (messageContainer);
+ public override bool Equals (object? obj) => obj is MessageContainer messageContainer && Equals (messageContainer);
public override int GetHashCode () => (Category, Text, Code, SubCategory, Origin).GetHashCode ();
public int CompareTo (MessageContainer other)
diff --git a/src/linker/Linker/MessageOrigin.cs b/src/linker/Linker/MessageOrigin.cs
index 84357b26a..6bb30e8d1 100644
--- a/src/linker/Linker/MessageOrigin.cs
+++ b/src/linker/Linker/MessageOrigin.cs
@@ -12,29 +12,28 @@ namespace Mono.Linker
{
public readonly struct MessageOrigin : IComparable<MessageOrigin>, IEquatable<MessageOrigin>
{
-#nullable enable
public string? FileName { get; }
public ICustomAttributeProvider? Provider { get; }
- readonly ICustomAttributeProvider _suppressionContextMember;
+ readonly ICustomAttributeProvider? _suppressionContextMember;
public ICustomAttributeProvider? SuppressionContextMember {
get {
Debug.Assert (_suppressionContextMember == null || _suppressionContextMember is IMemberDefinition || _suppressionContextMember is AssemblyDefinition);
return _suppressionContextMember ?? Provider;
}
}
-#nullable disable
+
public int SourceLine { get; }
public int SourceColumn { get; }
public int? ILOffset { get; }
const int HiddenLineNumber = 0xfeefee;
- public MessageOrigin (IMemberDefinition memberDefinition, int? ilOffset = null)
+ public MessageOrigin (IMemberDefinition? memberDefinition, int? ilOffset = null)
: this (memberDefinition as ICustomAttributeProvider, ilOffset)
{
}
- public MessageOrigin (ICustomAttributeProvider provider)
+ public MessageOrigin (ICustomAttributeProvider? provider)
: this (provider, null)
{
}
@@ -49,12 +48,12 @@ namespace Mono.Linker
ILOffset = null;
}
- public MessageOrigin (ICustomAttributeProvider provider, int? ilOffset)
+ public MessageOrigin (ICustomAttributeProvider? provider, int? ilOffset)
: this (provider, ilOffset, null)
{
}
- public MessageOrigin (ICustomAttributeProvider provider, int? ilOffset, ICustomAttributeProvider suppressionContextMember)
+ public MessageOrigin (ICustomAttributeProvider? provider, int? ilOffset, ICustomAttributeProvider? suppressionContextMember)
{
Debug.Assert (provider == null || provider is IMemberDefinition || provider is AssemblyDefinition);
Debug.Assert (suppressionContextMember == null || suppressionContextMember is IMemberDefinition || provider is AssemblyDefinition);
@@ -66,7 +65,7 @@ namespace Mono.Linker
ILOffset = ilOffset;
}
- public MessageOrigin (MessageOrigin other, IMemberDefinition suppressionContextMember)
+ public MessageOrigin (MessageOrigin other, IMemberDefinition? suppressionContextMember)
{
FileName = other.FileName;
Provider = other.Provider;
@@ -76,21 +75,21 @@ namespace Mono.Linker
ILOffset = other.ILOffset;
}
- public override string ToString ()
+ public override string? ToString ()
{
int sourceLine = SourceLine, sourceColumn = SourceColumn;
- string fileName = FileName;
+ string? fileName = FileName;
if (Provider is MethodDefinition method &&
method.DebugInformation.HasSequencePoints) {
var offset = ILOffset ?? 0;
- SequencePoint correspondingSequencePoint = method.DebugInformation.SequencePoints
+ SequencePoint? correspondingSequencePoint = method.DebugInformation.SequencePoints
.Where (s => s.Offset <= offset)?.Last ();
// If the warning comes from hidden line (compiler generated code typically)
// search for any sequence point with non-hidden line number and report that as a best effort.
- if (correspondingSequencePoint.StartLine == HiddenLineNumber) {
+ if (correspondingSequencePoint?.StartLine == HiddenLineNumber) {
correspondingSequencePoint = method.DebugInformation.SequencePoints
- .Where (s => s.StartLine != HiddenLineNumber)?.FirstOrDefault ();
+ .Where (s => s.StartLine != HiddenLineNumber).FirstOrDefault ();
}
if (correspondingSequencePoint != null) {
@@ -118,7 +117,7 @@ namespace Mono.Linker
public bool Equals (MessageOrigin other) =>
(FileName, Provider, SourceLine, SourceColumn, ILOffset) == (other.FileName, other.Provider, other.SourceLine, other.SourceColumn, other.ILOffset);
- public override bool Equals (object obj) => obj is MessageOrigin messageOrigin && Equals (messageOrigin);
+ public override bool Equals (object? obj) => obj is MessageOrigin messageOrigin && Equals (messageOrigin);
public override int GetHashCode () => (FileName, Provider, SourceLine, SourceColumn).GetHashCode ();
public static bool operator == (MessageOrigin lhs, MessageOrigin rhs) => lhs.Equals (rhs);
public static bool operator != (MessageOrigin lhs, MessageOrigin rhs) => !lhs.Equals (rhs);
@@ -128,12 +127,12 @@ namespace Mono.Linker
if (Provider != null && other.Provider != null) {
var thisMember = Provider as IMemberDefinition;
var otherMember = other.Provider as IMemberDefinition;
- TypeDefinition thisTypeDef = (Provider as TypeDefinition) ?? (Provider as IMemberDefinition)?.DeclaringType;
- TypeDefinition otherTypeDef = (other.Provider as TypeDefinition) ?? (other.Provider as IMemberDefinition)?.DeclaringType;
+ TypeDefinition? thisTypeDef = (Provider as TypeDefinition) ?? (Provider as IMemberDefinition)?.DeclaringType;
+ TypeDefinition? otherTypeDef = (other.Provider as TypeDefinition) ?? (other.Provider as IMemberDefinition)?.DeclaringType;
var thisAssembly = thisTypeDef?.Module.Assembly ?? Provider as AssemblyDefinition;
var otherAssembly = otherTypeDef?.Module.Assembly ?? other.Provider as AssemblyDefinition;
- int result = (thisAssembly.Name.Name, thisTypeDef?.Name, thisMember?.Name).CompareTo
- ((otherAssembly.Name.Name, otherTypeDef?.Name, otherMember?.Name));
+ int result = (thisAssembly?.Name.Name, thisTypeDef?.Name, thisMember?.Name).CompareTo
+ ((otherAssembly?.Name.Name, otherTypeDef?.Name, otherMember?.Name));
if (result != 0)
return result;
diff --git a/src/linker/Linker/MethodBodyScanner.cs b/src/linker/Linker/MethodBodyScanner.cs
index cf86c4e8f..a2d68f9c9 100644
--- a/src/linker/Linker/MethodBodyScanner.cs
+++ b/src/linker/Linker/MethodBodyScanner.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;
@@ -11,7 +12,7 @@ namespace Mono.Linker
public static bool IsWorthConvertingToThrow (MethodBody body)
{
// Some bodies are cheaper size wise to leave alone than to convert to a throw
- Instruction previousMeaningful = null;
+ Instruction? previousMeaningful = null;
int meaningfulCount = 0;
foreach (var ins in body.Instructions) {
// Handle ignoring noops because because (1) it's a valid case to ignore
@@ -60,7 +61,7 @@ namespace Mono.Linker
this.context = context;
}
- public IEnumerable<(InterfaceImplementation, TypeDefinition)> GetReferencedInterfaces (MethodBody body)
+ public IEnumerable<(InterfaceImplementation, TypeDefinition)>? GetReferencedInterfaces (MethodBody body)
{
var possibleStackTypes = AllPossibleStackTypes (body.Method);
if (possibleStackTypes.Count == 0)
@@ -80,7 +81,7 @@ namespace Mono.Linker
if (!type.IsClass)
continue;
- TypeDefinition currentType = type;
+ TypeDefinition? currentType = type;
while (currentType?.BaseType != null) // Checking BaseType != null to skip System.Object
{
AddMatchingInterfaces (interfaceImplementations, currentType, interfaceTypes);
@@ -113,7 +114,8 @@ namespace Mono.Linker
foreach (Instruction instruction in body.Instructions) {
if (instruction.Operand is FieldReference fieldReference) {
- AddIfResolved (types, context.TryResolve (fieldReference)?.FieldType);
+ if (context.TryResolve (fieldReference)?.FieldType is TypeReference fieldType)
+ AddIfResolved (types, fieldType);
} else if (instruction.Operand is MethodReference methodReference) {
if (methodReference is GenericInstanceMethod genericInstanceMethod)
AddFromGenericInstance (types, genericInstanceMethod);
@@ -145,12 +147,12 @@ namespace Mono.Linker
return;
foreach (var interfaceType in interfaceTypes) {
- if (HasInterface (type, interfaceType, out InterfaceImplementation implementation))
+ if (HasInterface (type, interfaceType, out InterfaceImplementation? implementation))
results.Add ((implementation, type));
}
}
- bool HasInterface (TypeDefinition type, TypeDefinition interfaceType, out InterfaceImplementation implementation)
+ bool HasInterface (TypeDefinition type, TypeDefinition interfaceType, [NotNullWhen (true)] out InterfaceImplementation? implementation)
{
implementation = null;
if (!type.HasInterfaces)
diff --git a/src/linker/Linker/MethodDefinitionExtensions.cs b/src/linker/Linker/MethodDefinitionExtensions.cs
index caae82ed8..165b75138 100644
--- a/src/linker/Linker/MethodDefinitionExtensions.cs
+++ b/src/linker/Linker/MethodDefinitionExtensions.cs
@@ -1,4 +1,6 @@
-using Mono.Cecil;
+using System;
+using System.Diagnostics.CodeAnalysis;
+using Mono.Cecil;
namespace Mono.Linker
{
@@ -46,24 +48,36 @@ namespace Mono.Linker
(md.SemanticsAttributes & MethodSemanticsAttributes.RemoveOn) != 0;
}
- public static PropertyDefinition GetProperty (this MethodDefinition md)
+ public static bool TryGetProperty (this MethodDefinition md, [NotNullWhen (true)] out PropertyDefinition? property)
{
+ property = null;
+ if (!md.IsPropertyMethod ())
+ return false;
+
TypeDefinition declaringType = md.DeclaringType;
foreach (PropertyDefinition prop in declaringType.Properties)
- if (prop.GetMethod == md || prop.SetMethod == md)
- return prop;
+ if (prop.GetMethod == md || prop.SetMethod == md) {
+ property = prop;
+ return true;
+ }
- return null;
+ return false;
}
- public static EventDefinition GetEvent (this MethodDefinition md)
+ public static bool TryGetEvent (this MethodDefinition md, [NotNullWhen (true)] out EventDefinition? @event)
{
+ @event = null;
+ if (!md.IsEventMethod ())
+ return false;
+
TypeDefinition declaringType = md.DeclaringType;
foreach (EventDefinition evt in declaringType.Events)
- if (evt.AddMethod == md || evt.InvokeMethod == md || evt.RemoveMethod == md)
- return evt;
+ if (evt.AddMethod == md || evt.InvokeMethod == md || evt.RemoveMethod == md) {
+ @event = evt;
+ return true;
+ }
- return null;
+ return false;
}
public static bool IsStaticConstructor (this MethodDefinition method)
diff --git a/src/linker/Linker/MethodReferenceExtensions.cs b/src/linker/Linker/MethodReferenceExtensions.cs
index 446cadbfe..e9272fdb7 100644
--- a/src/linker/Linker/MethodReferenceExtensions.cs
+++ b/src/linker/Linker/MethodReferenceExtensions.cs
@@ -52,7 +52,7 @@ namespace Mono.Linker
return sb.ToString ();
}
- public static TypeReference GetReturnType (this MethodReference method, LinkContext context)
+ public static TypeReference? GetReturnType (this MethodReference method, LinkContext context)
{
if (method.DeclaringType is GenericInstanceType genericInstance)
return TypeReferenceExtensions.InflateGenericType (genericInstance, method.ReturnType, context);
@@ -60,7 +60,7 @@ namespace Mono.Linker
return method.ReturnType;
}
- public static TypeReference GetParameterType (this MethodReference method, int parameterIndex, LinkContext context)
+ public static TypeReference? GetParameterType (this MethodReference method, int parameterIndex, LinkContext context)
{
if (method.DeclaringType is GenericInstanceType genericInstance)
return TypeReferenceExtensions.InflateGenericType (genericInstance, method.Parameters[parameterIndex].ParameterType, context);
diff --git a/src/linker/Linker/ModuleDefinitionExtensions.cs b/src/linker/Linker/ModuleDefinitionExtensions.cs
index 71c266cc6..1ea8bb351 100644
--- a/src/linker/Linker/ModuleDefinitionExtensions.cs
+++ b/src/linker/Linker/ModuleDefinitionExtensions.cs
@@ -1,3 +1,4 @@
+using System.Diagnostics.CodeAnalysis;
using Mono.Cecil;
namespace Mono.Linker
@@ -11,10 +12,10 @@ namespace Mono.Linker
(module.Attributes & ModuleAttributes.ILLibrary) != 0;
}
- public static bool GetMatchingExportedType (this ModuleDefinition module, TypeDefinition typeDefinition, out ExportedType exportedType)
+ public static bool GetMatchingExportedType (this ModuleDefinition module, TypeDefinition typeDefinition, [NotNullWhen (true)] out ExportedType? exportedType)
{
exportedType = null;
- if (!module.HasExportedTypes || typeDefinition == null)
+ if (!module.HasExportedTypes)
return false;
foreach (var et in module.ExportedTypes)
@@ -26,11 +27,8 @@ namespace Mono.Linker
return false;
}
- public static TypeDefinition ResolveType (this ModuleDefinition module, string typeFullName, ITryResolveMetadata resolver)
+ public static TypeDefinition? ResolveType (this ModuleDefinition module, string typeFullName, ITryResolveMetadata resolver)
{
- if (typeFullName == null)
- return null;
-
var type = module.GetType (typeFullName);
if (type != null)
return type;
diff --git a/src/linker/Linker/OverrideInformation.cs b/src/linker/Linker/OverrideInformation.cs
index d40f87637..827045111 100644
--- a/src/linker/Linker/OverrideInformation.cs
+++ b/src/linker/Linker/OverrideInformation.cs
@@ -8,7 +8,7 @@ namespace Mono.Linker
{
readonly ITryResolveMetadata resolver;
- public OverrideInformation (MethodDefinition @base, MethodDefinition @override, ITryResolveMetadata resolver, InterfaceImplementation matchingInterfaceImplementation = null)
+ public OverrideInformation (MethodDefinition @base, MethodDefinition @override, ITryResolveMetadata resolver, InterfaceImplementation? matchingInterfaceImplementation = null)
{
Base = @base;
Override = @override;
@@ -18,7 +18,7 @@ namespace Mono.Linker
public MethodDefinition Base { get; }
public MethodDefinition Override { get; }
- public InterfaceImplementation MatchingInterfaceImplementation { get; }
+ public InterfaceImplementation? MatchingInterfaceImplementation { get; }
public bool IsOverrideOfInterfaceMember {
get {
@@ -29,7 +29,7 @@ namespace Mono.Linker
}
}
- public TypeDefinition InterfaceType {
+ public TypeDefinition? InterfaceType {
get {
if (!IsOverrideOfInterfaceMember)
return null;
diff --git a/src/linker/Linker/PInvokeInfo.cs b/src/linker/Linker/PInvokeInfo.cs
index 590ee163d..84193b153 100644
--- a/src/linker/Linker/PInvokeInfo.cs
+++ b/src/linker/Linker/PInvokeInfo.cs
@@ -18,7 +18,15 @@ namespace Mono.Linker
[DataMember (Name = "moduleName")]
internal string ModuleName { get; set; }
- public int CompareTo (PInvokeInfo other)
+ public PInvokeInfo (string assemblyName, string entryPoint, string fullName, string moduleName)
+ {
+ AssemblyName = assemblyName;
+ EntryPoint = entryPoint;
+ FullName = fullName;
+ ModuleName = moduleName;
+ }
+
+ public int CompareTo (PInvokeInfo? other)
{
if (other == null) return 1;
diff --git a/src/linker/Linker/SerializationMarker.cs b/src/linker/Linker/SerializationMarker.cs
index 2672c83c2..c55b7f306 100644
--- a/src/linker/Linker/SerializationMarker.cs
+++ b/src/linker/Linker/SerializationMarker.cs
@@ -55,7 +55,7 @@ namespace Mono.Linker
SerializerKind ActiveSerializers { get; set; }
- Dictionary<SerializerKind, HashSet<ICustomAttributeProvider>> _trackedRoots;
+ Dictionary<SerializerKind, HashSet<ICustomAttributeProvider>>? _trackedRoots;
Dictionary<SerializerKind, HashSet<ICustomAttributeProvider>> TrackedRoots {
get {
if (_trackedRoots == null)
@@ -65,7 +65,7 @@ namespace Mono.Linker
}
}
- HashSet<TypeDefinition> _recursiveTypes;
+ HashSet<TypeDefinition>? _recursiveTypes;
HashSet<TypeDefinition> RecursiveTypes {
get {
if (_recursiveTypes == null)
@@ -185,7 +185,7 @@ namespace Mono.Linker
// This doesn't handle other TypeSpecs. We are only matching what xamarin-android used to do.
// Arrays will still work because Resolve returns the array element type.
- TypeDefinition type = _context.TryResolve (typeRef);
+ TypeDefinition? type = _context.TryResolve (typeRef);
if (type == null)
return;
diff --git a/src/linker/Linker/SubstitutionInfo.cs b/src/linker/Linker/SubstitutionInfo.cs
index 600714b33..9e54b8043 100644
--- a/src/linker/Linker/SubstitutionInfo.cs
+++ b/src/linker/Linker/SubstitutionInfo.cs
@@ -4,8 +4,6 @@
using System.Collections.Generic;
using Mono.Cecil;
-#nullable enable
-
namespace Mono.Linker
{
public class SubstitutionInfo
diff --git a/src/linker/Linker/Tracer.cs b/src/linker/Linker/Tracer.cs
index 32876937c..28a71a995 100644
--- a/src/linker/Linker/Tracer.cs
+++ b/src/linker/Linker/Tracer.cs
@@ -28,6 +28,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
namespace Mono.Linker
{
@@ -35,7 +36,7 @@ namespace Mono.Linker
{
protected readonly LinkContext context;
- List<IDependencyRecorder> recorders;
+ List<IDependencyRecorder>? recorders;
public Tracer (LinkContext context)
{
@@ -63,6 +64,7 @@ namespace Mono.Linker
recorders.Add (recorder);
}
+ [MemberNotNullWhen (true, "recorders")]
bool IsRecordingEnabled ()
{
return recorders != null;
diff --git a/src/linker/Linker/TypeHierarchyCache.cs b/src/linker/Linker/TypeHierarchyCache.cs
index 470e34f6d..bc036c7a5 100644
--- a/src/linker/Linker/TypeHierarchyCache.cs
+++ b/src/linker/Linker/TypeHierarchyCache.cs
@@ -31,7 +31,7 @@ namespace Mono.Linker
flags |= HierarchyFlags.IsSystemReflectionIReflect;
}
- TypeDefinition baseType = resolvedType;
+ TypeDefinition? baseType = resolvedType;
while (baseType != null) {
if (baseType.Name == "Type" && baseType.Namespace == "System") {
flags |= HierarchyFlags.IsSystemType;
diff --git a/src/linker/Linker/TypeMapInfo.cs b/src/linker/Linker/TypeMapInfo.cs
index 8a5301a23..2d1350290 100644
--- a/src/linker/Linker/TypeMapInfo.cs
+++ b/src/linker/Linker/TypeMapInfo.cs
@@ -54,21 +54,21 @@ namespace Mono.Linker
MapType (type);
}
- public IEnumerable<OverrideInformation> GetOverrides (MethodDefinition method)
+ public IEnumerable<OverrideInformation>? GetOverrides (MethodDefinition method)
{
EnsureProcessed (method.Module.Assembly);
- override_methods.TryGetValue (method, out List<OverrideInformation> overrides);
+ override_methods.TryGetValue (method, out List<OverrideInformation>? overrides);
return overrides;
}
- public List<MethodDefinition> GetBaseMethods (MethodDefinition method)
+ public List<MethodDefinition>? GetBaseMethods (MethodDefinition method)
{
EnsureProcessed (method.Module.Assembly);
- base_methods.TryGetValue (method, out List<MethodDefinition> bases);
+ base_methods.TryGetValue (method, out List<MethodDefinition>? bases);
return bases;
}
- public IEnumerable<(TypeDefinition InstanceType, InterfaceImplementation ProvidingInterface)> GetDefaultInterfaceImplementations (MethodDefinition method)
+ public IEnumerable<(TypeDefinition InstanceType, InterfaceImplementation ProvidingInterface)>? GetDefaultInterfaceImplementations (MethodDefinition method)
{
default_interface_implementations.TryGetValue (method, out var ret);
return ret;
@@ -76,7 +76,7 @@ namespace Mono.Linker
public void AddBaseMethod (MethodDefinition method, MethodDefinition @base)
{
- if (!base_methods.TryGetValue (method, out List<MethodDefinition> methods)) {
+ if (!base_methods.TryGetValue (method, out List<MethodDefinition>? methods)) {
methods = new List<MethodDefinition> ();
base_methods[method] = methods;
}
@@ -84,9 +84,9 @@ namespace Mono.Linker
methods.Add (@base);
}
- public void AddOverride (MethodDefinition @base, MethodDefinition @override, InterfaceImplementation matchingInterfaceImplementation = null)
+ public void AddOverride (MethodDefinition @base, MethodDefinition @override, InterfaceImplementation? matchingInterfaceImplementation = null)
{
- if (!override_methods.TryGetValue (@base, out List<OverrideInformation> methods)) {
+ if (!override_methods.TryGetValue (@base, out List<OverrideInformation>? methods)) {
methods = new List<OverrideInformation> ();
override_methods.Add (@base, methods);
}
@@ -125,7 +125,7 @@ namespace Mono.Linker
// to find the method implementation and record it.
foreach (var interfaceImpl in type.GetInflatedInterfaces (context)) {
foreach (MethodReference interfaceMethod in interfaceImpl.InflatedInterface.GetMethods (context)) {
- MethodDefinition resolvedInterfaceMethod = context.TryResolve (interfaceMethod);
+ MethodDefinition? resolvedInterfaceMethod = context.TryResolve (interfaceMethod);
if (resolvedInterfaceMethod == null)
continue;
@@ -139,7 +139,7 @@ namespace Mono.Linker
continue;
// Try to find an implementation with a name/sig match on the current type
- MethodDefinition exactMatchOnType = TryMatchMethod (type, interfaceMethod);
+ MethodDefinition? exactMatchOnType = TryMatchMethod (type, interfaceMethod);
if (exactMatchOnType != null) {
AnnotateMethods (resolvedInterfaceMethod, exactMatchOnType);
continue;
@@ -181,7 +181,7 @@ namespace Mono.Linker
void MapVirtualMethod (MethodDefinition method)
{
- MethodDefinition @base = GetBaseMethodInTypeHierarchy (method);
+ MethodDefinition? @base = GetBaseMethodInTypeHierarchy (method);
if (@base == null)
return;
@@ -191,7 +191,7 @@ namespace Mono.Linker
void MapOverrides (MethodDefinition method)
{
foreach (MethodReference override_ref in method.Overrides) {
- MethodDefinition @override = context.TryResolve (override_ref);
+ MethodDefinition? @override = context.TryResolve (override_ref);
if (@override == null)
continue;
@@ -199,22 +199,22 @@ namespace Mono.Linker
}
}
- void AnnotateMethods (MethodDefinition @base, MethodDefinition @override, InterfaceImplementation matchingInterfaceImplementation = null)
+ void AnnotateMethods (MethodDefinition @base, MethodDefinition @override, InterfaceImplementation? matchingInterfaceImplementation = null)
{
AddBaseMethod (@override, @base);
AddOverride (@base, @override, matchingInterfaceImplementation);
}
- MethodDefinition GetBaseMethodInTypeHierarchy (MethodDefinition method)
+ MethodDefinition? GetBaseMethodInTypeHierarchy (MethodDefinition method)
{
return GetBaseMethodInTypeHierarchy (method.DeclaringType, method);
}
- MethodDefinition GetBaseMethodInTypeHierarchy (TypeDefinition type, MethodReference method)
+ MethodDefinition? GetBaseMethodInTypeHierarchy (TypeDefinition type, MethodReference method)
{
- TypeReference @base = GetInflatedBaseType (type);
+ TypeReference? @base = GetInflatedBaseType (type);
while (@base != null) {
- MethodDefinition base_method = TryMatchMethod (@base, method);
+ MethodDefinition? base_method = TryMatchMethod (@base, method);
if (base_method != null)
return base_method;
@@ -224,7 +224,7 @@ namespace Mono.Linker
return null;
}
- TypeReference GetInflatedBaseType (TypeReference type)
+ TypeReference? GetInflatedBaseType (TypeReference type)
{
if (type == null)
return null;
@@ -300,7 +300,7 @@ namespace Mono.Linker
}
}
- MethodDefinition TryMatchMethod (TypeReference type, MethodReference method)
+ MethodDefinition? TryMatchMethod (TypeReference type, MethodReference method)
{
foreach (var candidate in type.GetMethods (context)) {
var md = context.TryResolve (candidate);
@@ -327,7 +327,9 @@ namespace Mono.Linker
// we need to track what the generic parameter represent - as we cannot allow it to
// differ between the return type or any parameter
- if (!TypeMatch (candidate.GetReturnType (context), method.GetReturnType (context)))
+ if (candidate.GetReturnType (context) is not TypeReference candidateReturnType ||
+ method.GetReturnType (context) is not TypeReference methodReturnType ||
+ !TypeMatch (candidateReturnType, methodReturnType))
return false;
if (!candidate.HasParameters)
@@ -342,7 +344,9 @@ namespace Mono.Linker
return false;
for (int i = 0; i < cp.Count; i++) {
- if (!TypeMatch (candidate.GetParameterType (i, context), method.GetParameterType (i, context)))
+ if (candidate.GetParameterType (i, context) is not TypeReference candidateParameterType ||
+ method.GetParameterType (i, context) is not TypeReference methodParameterType ||
+ !TypeMatch (candidateParameterType, methodParameterType))
return false;
}
diff --git a/src/linker/Linker/TypeNameResolver.cs b/src/linker/Linker/TypeNameResolver.cs
index 3c6ae6ea0..392aed9e9 100644
--- a/src/linker/Linker/TypeNameResolver.cs
+++ b/src/linker/Linker/TypeNameResolver.cs
@@ -1,4 +1,6 @@
using System;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Reflection.Runtime.TypeParsing;
using Mono.Cecil;
@@ -13,27 +15,29 @@ namespace Mono.Linker
_context = context;
}
- public TypeReference ResolveTypeName (string typeNameString, ICustomAttributeProvider origin, out AssemblyDefinition typeAssembly, bool needsAssemblyName = true)
+ public bool TryResolveTypeName (string typeNameString, ICustomAttributeProvider? origin, [NotNullWhen (true)] out TypeReference? typeReference, [NotNullWhen (true)] out AssemblyDefinition? typeAssembly, bool needsAssemblyName = true)
{
+ typeReference = null;
typeAssembly = null;
if (string.IsNullOrEmpty (typeNameString))
- return null;
+ return false;
TypeName parsedTypeName;
try {
parsedTypeName = TypeParser.ParseTypeName (typeNameString);
} catch (ArgumentException) {
- return null;
+ return false;
} catch (System.IO.FileLoadException) {
- return null;
+ return false;
}
if (parsedTypeName is AssemblyQualifiedTypeName assemblyQualifiedTypeName) {
typeAssembly = _context.TryResolve (assemblyQualifiedTypeName.AssemblyName.Name);
if (typeAssembly == null)
- return null;
+ return false;
- return ResolveTypeName (typeAssembly, assemblyQualifiedTypeName.TypeName);
+ typeReference = ResolveTypeName (typeAssembly, assemblyQualifiedTypeName.TypeName);
+ return typeReference != null;
}
// If parsedTypeName doesn't have an assembly name in it but it does have a namespace,
@@ -47,13 +51,13 @@ namespace Mono.Linker
_ => throw new NotSupportedException ()
};
- if (typeAssembly != null && TryResolveTypeName (typeAssembly, parsedTypeName, out var typeRef))
- return typeRef;
+ if (typeAssembly != null && TryResolveTypeName (typeAssembly, parsedTypeName, out typeReference))
+ return true;
// If type is not found in the caller's assembly, try in core assembly.
typeAssembly = _context.TryResolve (PlatformAssemblies.CoreLib);
- if (typeAssembly != null && TryResolveTypeName (typeAssembly, parsedTypeName, out var typeRefFromSPCL))
- return typeRefFromSPCL;
+ if (typeAssembly != null && TryResolveTypeName (typeAssembly, parsedTypeName, out typeReference))
+ return true;
// It is common to use Type.GetType for looking if a type is available.
// If no type was found only warn and return null.
@@ -64,9 +68,9 @@ namespace Mono.Linker
}
typeAssembly = null;
- return null;
+ return false;
- bool TryResolveTypeName (AssemblyDefinition assemblyDefinition, TypeName typeName, out TypeReference typeReference)
+ bool TryResolveTypeName (AssemblyDefinition assemblyDefinition, TypeName typeName, [NotNullWhen (true)] out TypeReference? typeReference)
{
typeReference = null;
if (assemblyDefinition == null)
@@ -77,17 +81,18 @@ namespace Mono.Linker
}
}
- public TypeReference ResolveTypeName (AssemblyDefinition assembly, string typeNameString)
+ public bool TryResolveTypeName (AssemblyDefinition assembly, string typeNameString, [NotNullWhen (true)] out TypeReference? typeReference)
{
- return ResolveTypeName (assembly, TypeParser.ParseTypeName (typeNameString));
+ typeReference = ResolveTypeName (assembly, TypeParser.ParseTypeName (typeNameString));
+ return typeReference != null;
}
- TypeReference ResolveTypeName (AssemblyDefinition assembly, TypeName typeName)
+ TypeReference? ResolveTypeName (AssemblyDefinition assembly, TypeName typeName)
{
if (typeName is AssemblyQualifiedTypeName assemblyQualifiedTypeName) {
// In this case we ignore the assembly parameter since the type name has assembly in it
var assemblyFromName = _context.TryResolve (assemblyQualifiedTypeName.AssemblyName.Name);
- return ResolveTypeName (assemblyFromName, assemblyQualifiedTypeName.TypeName);
+ return assemblyFromName == null ? null : ResolveTypeName (assemblyFromName, assemblyQualifiedTypeName.TypeName);
}
if (assembly == null || typeName == null)
@@ -98,8 +103,8 @@ namespace Mono.Linker
if (genericTypeRef == null)
return null;
- TypeDefinition genericType = _context.TryResolve (genericTypeRef);
- var genericInstanceType = new GenericInstanceType (genericType);
+ Debug.Assert (genericTypeRef is TypeDefinition);
+ var genericInstanceType = new GenericInstanceType (genericTypeRef);
foreach (var arg in constructedGenericTypeName.GenericArguments) {
var genericArgument = ResolveTypeName (assembly, arg);
if (genericArgument == null)
diff --git a/src/linker/Linker/TypeReferenceExtensions.cs b/src/linker/Linker/TypeReferenceExtensions.cs
index 9077971cf..d72485074 100644
--- a/src/linker/Linker/TypeReferenceExtensions.cs
+++ b/src/linker/Linker/TypeReferenceExtensions.cs
@@ -1,5 +1,6 @@
-using System;
+using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Text;
using Mono.Cecil;
@@ -26,7 +27,7 @@ namespace Mono.Linker
if (type == null)
return sb;
- Stack<TypeReference> genericArguments = null;
+ Stack<TypeReference>? genericArguments = null;
while (true) {
switch (type) {
case ArrayType arrayType:
@@ -61,10 +62,11 @@ namespace Mono.Linker
break;
}
- type = type.DeclaringType;
- if (type == null)
+ if (type.DeclaringType is not TypeReference declaringType)
break;
+ type = declaringType;
+
sb.Insert (0, '.');
}
@@ -109,11 +111,8 @@ namespace Mono.Linker
}
}
- public static TypeReference GetInflatedDeclaringType (this TypeReference type, ITryResolveMetadata resolver)
+ public static TypeReference? GetInflatedDeclaringType (this TypeReference type, ITryResolveMetadata resolver)
{
- if (type == null)
- return null;
-
if (type.IsGenericParameter || type.IsByReference || type.IsPointer)
return null;
@@ -140,9 +139,11 @@ namespace Mono.Linker
return declaringType;
}
- var resolved = resolver.TryResolve (type);
- System.Diagnostics.Debug.Assert (resolved == type);
- return resolved?.DeclaringType;
+ if (type is TypeDefinition typeDefinition)
+ return typeDefinition.DeclaringType;
+
+ Debug.Assert (false);
+ return null;
}
public static IEnumerable<(TypeReference InflatedInterface, InterfaceImplementation OriginalImpl)> GetInflatedInterfaces (this TypeReference typeRef, ITryResolveMetadata resolver)
@@ -153,15 +154,18 @@ namespace Mono.Linker
yield break;
if (typeRef is GenericInstanceType genericInstance) {
- foreach (var interfaceImpl in typeDef.Interfaces)
- yield return (InflateGenericType (genericInstance, interfaceImpl.InterfaceType, resolver), interfaceImpl);
+ foreach (var interfaceImpl in typeDef.Interfaces) {
+ // InflateGenericType only returns null when inflating generic parameters (and the generic instance type doesn't resolve).
+ // Here we are not inflating a generic parameter but an interface type reference.
+ yield return (InflateGenericType (genericInstance, interfaceImpl.InterfaceType, resolver), interfaceImpl)!;
+ }
} else {
foreach (var interfaceImpl in typeDef.Interfaces)
yield return (interfaceImpl.InterfaceType, interfaceImpl);
}
}
- public static TypeReference InflateGenericType (GenericInstanceType genericInstanceProvider, TypeReference typeToInflate, ITryResolveMetadata resolver)
+ public static TypeReference? InflateGenericType (GenericInstanceType genericInstanceProvider, TypeReference typeToInflate, ITryResolveMetadata resolver)
{
if (typeToInflate is ArrayType arrayType) {
var inflatedElementType = InflateGenericType (genericInstanceProvider, arrayType.ElementType, resolver);
@@ -262,7 +266,7 @@ namespace Mono.Linker
public static IEnumerable<MethodReference> GetMethods (this TypeReference type, ITryResolveMetadata resolver)
{
- TypeDefinition typeDef = resolver.TryResolve (type);
+ TypeDefinition? typeDef = resolver.TryResolve (type);
if (typeDef?.HasMethods != true)
yield break;
@@ -341,7 +345,7 @@ namespace Mono.Linker
public static bool IsSubclassOf (this TypeReference type, string ns, string name, ITryResolveMetadata resolver)
{
- TypeDefinition baseType = resolver.TryResolve (type);
+ TypeDefinition? baseType = resolver.TryResolve (type);
while (baseType != null) {
if (baseType.IsTypeOf (ns, name))
return true;
diff --git a/src/linker/Linker/TypeReferenceWalker.cs b/src/linker/Linker/TypeReferenceWalker.cs
index c4f894812..46b5f1a5a 100644
--- a/src/linker/Linker/TypeReferenceWalker.cs
+++ b/src/linker/Linker/TypeReferenceWalker.cs
@@ -7,8 +7,6 @@ using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
-#nullable enable
-
namespace Mono.Linker
{
abstract class TypeReferenceWalker
diff --git a/src/linker/Linker/UnconditionalSuppressMessageAttributeState.cs b/src/linker/Linker/UnconditionalSuppressMessageAttributeState.cs
index 989636447..edf184e1c 100644
--- a/src/linker/Linker/UnconditionalSuppressMessageAttributeState.cs
+++ b/src/linker/Linker/UnconditionalSuppressMessageAttributeState.cs
@@ -29,7 +29,7 @@ namespace Mono.Linker
suppressions = new Dictionary<int, SuppressMessageInfo> ();
_suppressions.Add (provider, suppressions);
} else if (suppressions.ContainsKey (info.Id)) {
- string elementName = provider is MemberReference memberRef ? memberRef.GetDisplayName () : provider.ToString ();
+ string? elementName = provider is MemberReference memberRef ? memberRef.GetDisplayName () : provider.ToString ();
_context.LogMessage ($"Element '{elementName}' has more than one unconditional suppression. Note that only the last one is used.");
}
@@ -42,25 +42,24 @@ namespace Mono.Linker
// (if they're different). This is to correctly handle compiler generated code
// which needs to use suppressions from both the compiler generated scope
// as well as the original user defined method.
- ICustomAttributeProvider suppressionContextMember = warningOrigin.SuppressionContextMember;
+ ICustomAttributeProvider? suppressionContextMember = warningOrigin.SuppressionContextMember;
if (IsSuppressed (id, suppressionContextMember, out info))
return true;
- ICustomAttributeProvider provider = warningOrigin.Provider;
+ ICustomAttributeProvider? provider = warningOrigin.Provider;
if (suppressionContextMember != provider && IsSuppressed (id, provider, out info))
return true;
return false;
}
- bool IsSuppressed (int id, ICustomAttributeProvider warningOrigin, out SuppressMessageInfo info)
+ bool IsSuppressed (int id, ICustomAttributeProvider? warningOrigin, out SuppressMessageInfo info)
{
info = default;
if (warningOrigin == null)
return false;
- ModuleDefinition module = GetModuleFromProvider (warningOrigin);
if (warningOrigin is IMemberDefinition warningOriginMember) {
while (warningOriginMember != null) {
if (IsSuppressedOnElement (id, warningOriginMember, out info))
@@ -70,6 +69,10 @@ namespace Mono.Linker
}
}
+ ModuleDefinition? module = GetModuleFromProvider (warningOrigin);
+ if (module == null)
+ return false;
+
// Check if there's an assembly or module level suppression.
if (IsSuppressedOnElement (id, module, out info) ||
IsSuppressedOnElement (id, module.Assembly, out info))
@@ -78,7 +81,7 @@ namespace Mono.Linker
return false;
}
- bool IsSuppressedOnElement (int id, ICustomAttributeProvider provider, out SuppressMessageInfo info)
+ bool IsSuppressedOnElement (int id, ICustomAttributeProvider? provider, out SuppressMessageInfo info)
{
info = default;
if (provider == null)
@@ -95,12 +98,13 @@ namespace Mono.Linker
// Gather assembly-level suppressions if we haven't already. To ensure that we always cache
// complete information for a member, we will also scan for attributes on any other members
// targeted by the assembly-level suppressions.
- var module = GetModuleFromProvider (provider);
- var assembly = module.Assembly;
- if (InitializedAssemblies.Add (assembly)) {
- foreach (var suppression in DecodeAssemblyAndModuleSuppressions (module)) {
- AddSuppression (suppression.Info, suppression.Target);
- membersToScan.Add (suppression.Target);
+ if (GetModuleFromProvider (provider) is ModuleDefinition module) {
+ var assembly = module.Assembly;
+ if (InitializedAssemblies.Add (assembly)) {
+ foreach (var suppression in DecodeAssemblyAndModuleSuppressions (module)) {
+ AddSuppression (suppression.Info, suppression.Target);
+ membersToScan.Add (suppression.Target);
+ }
}
}
@@ -142,14 +146,14 @@ namespace Mono.Linker
if (attribute.HasProperties) {
foreach (var p in attribute.Properties) {
switch (p.Name) {
- case ScopeProperty:
- info.Scope = p.Argument.Value as string;
+ case ScopeProperty when p.Argument.Value is string scope:
+ info.Scope = scope;
break;
- case TargetProperty:
- info.Target = p.Argument.Value as string;
+ case TargetProperty when p.Argument.Value is string target:
+ info.Target = target;
break;
- case MessageIdProperty:
- info.MessageId = p.Argument.Value as string;
+ case MessageIdProperty when p.Argument.Value is string messageId:
+ info.MessageId = messageId;
break;
}
}
@@ -158,7 +162,7 @@ namespace Mono.Linker
return true;
}
- public static ModuleDefinition GetModuleFromProvider (ICustomAttributeProvider provider)
+ public static ModuleDefinition? GetModuleFromProvider (ICustomAttributeProvider provider)
{
switch (provider.MetadataToken.TokenType) {
case TokenType.Module:
diff --git a/src/linker/Linker/WarningSuppressionWriter.cs b/src/linker/Linker/WarningSuppressionWriter.cs
index 37d5f2aa8..d8421f099 100644
--- a/src/linker/Linker/WarningSuppressionWriter.cs
+++ b/src/linker/Linker/WarningSuppressionWriter.cs
@@ -33,7 +33,10 @@ namespace Mono.Linker
if (provider is not IMemberDefinition memberDefinition)
return;
- var assemblyName = UnconditionalSuppressMessageAttributeState.GetModuleFromProvider (memberDefinition).Assembly.Name;
+ if (UnconditionalSuppressMessageAttributeState.GetModuleFromProvider (provider) is not ModuleDefinition module)
+ return;
+
+ var assemblyName = module.Assembly.Name;
if (!_warnings.TryGetValue (assemblyName, out var warnings)) {
warnings = new HashSet<(int, IMemberDefinition)> ();
_warnings.Add (assemblyName, warnings);
diff --git a/src/linker/Linker/XmlDependencyRecorder.cs b/src/linker/Linker/XmlDependencyRecorder.cs
index 0e3b2f538..6ff4284d8 100644
--- a/src/linker/Linker/XmlDependencyRecorder.cs
+++ b/src/linker/Linker/XmlDependencyRecorder.cs
@@ -39,10 +39,10 @@ namespace Mono.Linker
public const string DefaultDependenciesFileName = "linker-dependencies.xml.gz";
private readonly LinkContext context;
- private XmlWriter writer;
- private Stream stream;
+ private XmlWriter? writer;
+ private Stream? stream;
- public XmlDependencyRecorder (LinkContext context, string fileName = null)
+ public XmlDependencyRecorder (LinkContext context, string? fileName = null)
{
this.context = context;
@@ -83,13 +83,16 @@ namespace Mono.Linker
writer.WriteEndDocument ();
writer.Flush ();
writer.Dispose ();
- stream.Dispose ();
+ stream?.Dispose ();
writer = null;
stream = null;
}
public void RecordDependency (object target, in DependencyInfo reason, bool marked)
{
+ if (writer == null)
+ throw new InvalidOperationException ();
+
if (reason.Kind == DependencyKind.Unspecified)
return;
@@ -97,8 +100,11 @@ namespace Mono.Linker
RecordDependency (reason.Source, target, marked);
}
- public void RecordDependency (object source, object target, bool marked)
+ public void RecordDependency (object? source, object target, bool marked)
{
+ if (writer == null)
+ throw new InvalidOperationException ();
+
if (!ShouldRecord (source) && !ShouldRecord (target))
return;
@@ -136,7 +142,7 @@ namespace Mono.Linker
return false;
}
- string TokenString (object o)
+ string TokenString (object? o)
{
if (o == null)
return "N:null";
@@ -173,7 +179,7 @@ namespace Mono.Linker
}
}
- bool ShouldRecord (object o)
+ bool ShouldRecord (object? o)
{
if (!context.EnableReducedTracing)
return true;
diff --git a/src/linker/Mono.Linker.csproj b/src/linker/Mono.Linker.csproj
index 54612fbcb..391300aad 100644
--- a/src/linker/Mono.Linker.csproj
+++ b/src/linker/Mono.Linker.csproj
@@ -2,7 +2,6 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
- <Nullable>warnings</Nullable>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>