diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
index 0efd42831..b3b5cc7a6 100644
--- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
+++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
@@ -90,6 +90,7 @@
+
diff --git a/ICSharpCode.Decompiler/NRTAttributes.cs b/ICSharpCode.Decompiler/NRTAttributes.cs
new file mode 100644
index 000000000..bdcaab026
--- /dev/null
+++ b/ICSharpCode.Decompiler/NRTAttributes.cs
@@ -0,0 +1,25 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace System.Diagnostics.CodeAnalysis
+{
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
+ internal sealed class MemberNotNullWhenAttribute : Attribute
+ {
+ public bool ReturnValue { get; }
+
+ public string[] Members { get; }
+
+ public MemberNotNullWhenAttribute(bool returnValue, string member)
+ {
+ ReturnValue = returnValue;
+ Members = new string[1] { member };
+ }
+
+ public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
+ {
+ ReturnValue = returnValue;
+ Members = members;
+ }
+ }
+}
diff --git a/ICSharpCode.Decompiler/TypeSystem/IEvent.cs b/ICSharpCode.Decompiler/TypeSystem/IEvent.cs
index 732840c62..635b031da 100644
--- a/ICSharpCode.Decompiler/TypeSystem/IEvent.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/IEvent.cs
@@ -18,12 +18,17 @@
#nullable enable
+using System.Diagnostics.CodeAnalysis;
+
namespace ICSharpCode.Decompiler.TypeSystem
{
public interface IEvent : IMember
{
+ [MemberNotNullWhen(true, nameof(AddAccessor))]
bool CanAdd { get; }
+ [MemberNotNullWhen(true, nameof(RemoveAccessor))]
bool CanRemove { get; }
+ [MemberNotNullWhen(true, nameof(InvokeAccessor))]
bool CanInvoke { get; }
IMethod? AddAccessor { get; }
diff --git a/ICSharpCode.Decompiler/TypeSystem/IMethod.cs b/ICSharpCode.Decompiler/TypeSystem/IMethod.cs
index 26e4626c8..6438a1315 100644
--- a/ICSharpCode.Decompiler/TypeSystem/IMethod.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/IMethod.cs
@@ -19,6 +19,7 @@
#nullable enable
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Reflection;
namespace ICSharpCode.Decompiler.TypeSystem
@@ -81,6 +82,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
///
/// Gets whether the method is a property/event accessor.
///
+ [MemberNotNullWhen(true, nameof(AccessorOwner))]
bool IsAccessor { get; }
///
diff --git a/ICSharpCode.Decompiler/TypeSystem/IProperty.cs b/ICSharpCode.Decompiler/TypeSystem/IProperty.cs
index f8b6203d1..cad688dbe 100644
--- a/ICSharpCode.Decompiler/TypeSystem/IProperty.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/IProperty.cs
@@ -18,6 +18,8 @@
#nullable enable
+using System.Diagnostics.CodeAnalysis;
+
namespace ICSharpCode.Decompiler.TypeSystem
{
///
@@ -25,7 +27,9 @@ namespace ICSharpCode.Decompiler.TypeSystem
///
public interface IProperty : IParameterizedMember
{
+ [MemberNotNullWhen(true, nameof(Getter))]
bool CanGet { get; }
+ [MemberNotNullWhen(true, nameof(Setter))]
bool CanSet { get; }
IMethod? Getter { get; }
diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs
index abc4252ea..c3760e42e 100644
--- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs
@@ -67,7 +67,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
var (accessorOwner, semanticsAttribute) = module.PEFile.MethodSemanticsLookup.GetSemantics(handle);
const MethodAttributes finalizerAttributes = (MethodAttributes.Virtual | MethodAttributes.Family | MethodAttributes.HideBySig);
this.typeParameters = MetadataTypeParameter.Create(module, this, def.GetGenericParameters());
- if (semanticsAttribute != 0)
+ if (semanticsAttribute != 0 && !accessorOwner.IsNil
+ && accessorOwner.Kind is HandleKind.PropertyDefinition or HandleKind.EventDefinition)
{
this.symbolKind = SymbolKind.Accessor;
this.accessorOwner = accessorOwner;
@@ -129,7 +130,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public bool HasBody => module.metadata.GetMethodDefinition(handle).HasBody();
-
public IMember AccessorOwner {
get {
if (accessorOwner.IsNil)
diff --git a/ICSharpCode.Decompiler/TypeSystem/NormalizeTypeVisitor.cs b/ICSharpCode.Decompiler/TypeSystem/NormalizeTypeVisitor.cs
index 505a06359..8f097f683 100644
--- a/ICSharpCode.Decompiler/TypeSystem/NormalizeTypeVisitor.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/NormalizeTypeVisitor.cs
@@ -1,6 +1,22 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
+// Copyright (c) 2019 Daniel Grunwald
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this
+// software and associated documentation files (the "Software"), to deal in the Software
+// without restriction, including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
+// to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or
+// substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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 ICSharpCode.Decompiler.TypeSystem.Implementation;
diff --git a/ICSharpCode.Decompiler/TypeSystem/Nullability.cs b/ICSharpCode.Decompiler/TypeSystem/Nullability.cs
index 17ce52520..fc934ebea 100644
--- a/ICSharpCode.Decompiler/TypeSystem/Nullability.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/Nullability.cs
@@ -1,6 +1,20 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
+// Copyright (c) 2019 Daniel Grunwald
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this
+// software and associated documentation files (the "Software"), to deal in the Software
+// without restriction, including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
+// to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or
+// substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
namespace ICSharpCode.Decompiler.TypeSystem
{
diff --git a/ICSharpCode.Decompiler/TypeSystem/TypeVisitor.cs b/ICSharpCode.Decompiler/TypeSystem/TypeVisitor.cs
index da76087c7..d5636fe24 100644
--- a/ICSharpCode.Decompiler/TypeSystem/TypeVisitor.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/TypeVisitor.cs
@@ -16,6 +16,8 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
+#nullable enable
+
using ICSharpCode.Decompiler.TypeSystem.Implementation;
namespace ICSharpCode.Decompiler.TypeSystem