Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions tests/xtro-sharpie/xtro-report/xtro-report.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>

<WarningsAsErrors>Nullable</WarningsAsErrors>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<Compile Include="../xtro-sharpie/Filter.cs">
Expand Down
2 changes: 1 addition & 1 deletion tests/xtro-sharpie/xtro-sanity/Sanitizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ static List<Frameworks> GetAllFrameworks ()

static Frameworks GetFrameworks (string platform)
{
return Frameworks.GetFrameworks (ApplePlatformExtensions.Parse (platform), false);
return Frameworks.GetFrameworks (ApplePlatformExtensions.Parse (platform), false)!;
}

static List<Frameworks> GetFrameworks (IEnumerable<string> platforms)
Expand Down
3 changes: 3 additions & 0 deletions tests/xtro-sharpie/xtro-sanity/xtro-sanity.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>

<WarningsAsErrors>Nullable</WarningsAsErrors>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\..\..\tools\common\Frameworks.cs">
Expand Down
13 changes: 7 additions & 6 deletions tests/xtro-sharpie/xtro-sharpie/AttributeHelpers.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using Sharpie.Bind;

namespace Extrospection {
Expand All @@ -10,7 +11,7 @@ static bool Skip (ICustomAttributeProvider item)
}

// These both return out Version and bool as you can have an an attribute with no version (null) which is different no matching attribute at all
public static bool FindDeprecated (ICustomAttributeProvider item, out Version version)
public static bool FindDeprecated (ICustomAttributeProvider item, [NotNullWhen (true)] out Version? version)
{
version = null;

Expand All @@ -23,7 +24,7 @@ public static bool FindDeprecated (ICustomAttributeProvider item, out Version ve
return false;
}

public static bool FindObsolete (ICustomAttributeProvider item, out Version version)
public static bool FindObsolete (ICustomAttributeProvider item, [NotNullWhen (true)] out Version? version)
{
version = null;

Expand Down Expand Up @@ -70,7 +71,7 @@ public static bool HasObsolete (CustomAttribute attribute, Platforms platform)
return attribute.Constructor.DeclaringType.Name == "ObsoleteAttribute";
}

static bool GetPlatformVersion (CustomAttribute attribute, out Version version)
static bool GetPlatformVersion (CustomAttribute attribute, out Version? version)
{
// Three different Attribute flavors
// (PlatformName platform, PlatformArchitecture architecture = PlatformArchitecture.None, string message = null)
Expand All @@ -95,7 +96,7 @@ public static bool FindObjcDeprecated (IEnumerable<Attr> attrs, out VersionTuple
{
var attr = attrs.GetAvailabilityAttributes ().FirstOrDefault (x => x.AvailabilityAttributeDeprecated.HasValue && !x.AvailabilityAttributeDeprecated.Value.IsEmptyVersionTuple && x.AvailabilityAttributePlatformIdentifierName == Helpers.ClangPlatformName);
if (attr is not null) {
version = attr.AvailabilityAttributeDeprecated.Value;
version = attr.AvailabilityAttributeDeprecated!.Value;
return true;
} else {
version = VersionTuple.Empty;
Expand All @@ -111,7 +112,7 @@ public static bool HasAnyDeprecationForCurrentPlatform (ICustomAttributeProvider
// Properties are a special case as it is generated on the property itself and not the individual get_ \ set_ methods
// Cecil does not have a link between the MethodDefinition we have and the hosting PropertyDefinition, so we have to dig to find the match
if (item is MethodDefinition method) {
PropertyDefinition property = method.DeclaringType.Properties.FirstOrDefault (p => p.GetMethod == method || p.SetMethod == method);
var property = method.DeclaringType.Properties.FirstOrDefault (p => p.GetMethod == method || p.SetMethod == method);
if (property is not null && HasAnyDeprecationForCurrentPlatform (property)) {
return true;
}
Expand Down Expand Up @@ -159,7 +160,7 @@ public static bool HasAnyAdvice (ICustomAttributeProvider item)
// Properties are a special case for [Advice], as it is generated on the property itself and not the individual get_ \ set_ methods
// Cecil does not have a link between the MethodDefinition we have and the hosting PropertyDefinition, so we have to dig to find the match
if (item is MethodDefinition method) {
PropertyDefinition property = method.DeclaringType.Properties.FirstOrDefault (p => p.GetMethod == method || p.SetMethod == method);
var property = method.DeclaringType.Properties.FirstOrDefault (p => p.GetMethod == method || p.SetMethod == method);
if (property is not null && HasAdviced (property.CustomAttributes))
return true;
}
Expand Down
9 changes: 4 additions & 5 deletions tests/xtro-sharpie/xtro-sharpie/DeprecatedCheck.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public override void EndVisit ()

void ProcessObjcEntry (string objcClassName, VersionTuple objcVersion)
{
TypeDefinition managedType = ManagedTypes.FirstOrDefault (x => Helpers.GetName (x) == objcClassName && x.IsPublic);
var managedType = ManagedTypes.FirstOrDefault (x => Helpers.GetName (x) == objcClassName && x.IsPublic);
if (managedType is not null) {
var framework = Helpers.GetFramework (managedType);
if (framework is not null)
Expand All @@ -60,7 +60,7 @@ void ProcessObjcSelector (string fullname, VersionTuple objcVersion)
string objcClassName = fullname.Substring (class_method ? 1 : 0, n);
string selector = fullname.Substring (n + 2);

TypeDefinition managedType = ManagedTypes.FirstOrDefault (x => Helpers.GetName (x) == objcClassName);
var managedType = ManagedTypes.FirstOrDefault (x => Helpers.GetName (x) == objcClassName);
if (managedType is not null) {
var framework = Helpers.GetFramework (managedType);
if (framework is null)
Expand Down Expand Up @@ -92,7 +92,7 @@ void ProcessCFunction (string fullname, VersionTuple objcVersion)
}
}

public void ProcessItem (ICustomAttributeProvider item, string itemName, VersionTuple objcVersion, string framework)
public void ProcessItem (ICustomAttributeProvider item, string? itemName, VersionTuple objcVersion, string framework)
{
// Our bindings do not need have [Deprecated] for ancient versions we don't support anymore
if (VersionHelpers.VersionTooOldToCare (objcVersion))
Expand All @@ -114,8 +114,7 @@ public void ProcessItem (ICustomAttributeProvider item, string itemName, Version
}

// Some APIs have both a [Deprecated] and [Obsoleted]. Bias towards [Obsoleted].
Version managedVersion;
bool foundObsoleted = AttributeHelpers.FindObsolete (item, out managedVersion);
bool foundObsoleted = AttributeHelpers.FindObsolete (item, out var managedVersion);
if (foundObsoleted) {
if (managedVersion is not null && !ManagedBeforeOrEqualToObjcVersion (objcVersion, managedVersion))
Log.On (framework).Add ($"!deprecated-attribute-wrong! {itemName} has {managedVersion} not {objcVersion} on [Obsoleted] attribute");
Expand Down
6 changes: 3 additions & 3 deletions tests/xtro-sharpie/xtro-sharpie/DesignatedInitializerCheck.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ public DesignatedInitializerCheck (BindingResult bindingResult)
static Dictionary<string, TypeDefinition> types = new Dictionary<string, TypeDefinition> ();
static Dictionary<string, MethodDefinition> methods = new Dictionary<string, MethodDefinition> ();

static TypeDefinition GetType (ObjCInterfaceDecl decl)
static TypeDefinition? GetType (ObjCInterfaceDecl decl)
{
types.TryGetValue (decl.Name, out var td);
return td;
}

static MethodDefinition GetMethod (ObjCMethodDecl decl)
static MethodDefinition? GetMethod (ObjCMethodDecl decl)
{
methods.TryGetValue (decl.GetName (), out var md);
return md;
Expand All @@ -51,7 +51,7 @@ public override void VisitManagedMethod (MethodDefinition method)
public override void VisitObjCMethodDecl (ObjCMethodDecl decl)
{
// don't process methods (or types) that are unavailable for the current platform
if (!decl.IsAvailable () || !(decl.DeclContext as Decl).IsAvailable ())
if (!decl.IsAvailable () || !(((Decl) decl.DeclContext!).IsAvailable ()))
return;

var method = GetMethod (decl);
Expand Down
4 changes: 2 additions & 2 deletions tests/xtro-sharpie/xtro-sharpie/EnumCheck.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ namespace Extrospection {

class EnumCheck : BaseVisitor {
class ManagedValue {
public FieldDefinition Field;
public EnumConstantDecl Decl;
public required FieldDefinition Field;
public EnumConstantDecl? Decl;
}

Dictionary<string, TypeDefinition> enums = new Dictionary<string, TypeDefinition> (StringComparer.InvariantCultureIgnoreCase);
Expand Down
4 changes: 2 additions & 2 deletions tests/xtro-sharpie/xtro-sharpie/FieldCheck.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ void CheckAttributes (string memberName, ICustomAttributeProvider p)
&& ca.Constructor.DeclaringType.Name != "FieldAttribute`1")
continue;

var name = ca.ConstructorArguments [0].Value as string;
var name = (string) ca.ConstructorArguments [0].Value!;

if (!fields.TryGetValue (name, out var mr))
fields.Add (name, p as MemberReference);
fields.Add (name, (MemberReference) p);
else {
// not critical and quite noisy with current API profile
// Console.WriteLine ("!duplicate-field-name! {0} [Field] exists as both {1} and {2}", name, memberName, mr.FullName);
Expand Down
29 changes: 18 additions & 11 deletions tests/xtro-sharpie/xtro-sharpie/Helpers.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Diagnostics.CodeAnalysis;

namespace Extrospection {

public enum Platforms {
Expand Down Expand Up @@ -252,7 +254,9 @@ static bool IsStatic (this TypeDefinition self)
return (self.IsSealed && self.IsAbstract);
}

public static string GetName (this ObjCMethodDecl self)

[return: NotNullIfNotNull (nameof (self))]
public static string? GetName (this ObjCMethodDecl? self)
{
if (self is null)
return null;
Expand All @@ -263,15 +267,15 @@ public static string GetName (this ObjCMethodDecl self)
if (self.DeclContext is ObjCCategoryDecl category) {
sb.Append (category.ClassInterface.Name);
} else {
sb.Append ((self.DeclContext as NamedDecl).Name);
sb.Append (((NamedDecl) self.DeclContext!).Name);
}
sb.Append ("::");
var sel = self.Selector.ToString ();
sb.Append (string.IsNullOrEmpty (sel) ? self.Name : sel);
return sb.ToString ();
}

public static string GetName (this TypeDefinition self)
public static string? GetName (this TypeDefinition? self)
{
if ((self is null) || !self.HasCustomAttributes)
return null;
Expand Down Expand Up @@ -309,13 +313,13 @@ public static string GetName (this TypeDefinition self)
return null;
}

public static string GetName (this MethodDefinition self)
public static string? GetName (this MethodDefinition? self)
{
if (self is null)
return null;

var type = self.DeclaringType;
string tname = self.DeclaringType.GetName ();
string? tname = self.DeclaringType.GetName ();
// a static type is not used for static selectors
bool is_static = !type.IsStatic () && self.IsStatic;

Expand All @@ -340,7 +344,7 @@ public static string GetName (this MethodDefinition self)
return sb.ToString ();
}

public static string GetSelector (this MethodDefinition self)
public static string? GetSelector (this MethodDefinition self)
{
if ((self is null) || !self.HasCustomAttributes)
return null;
Expand Down Expand Up @@ -375,9 +379,12 @@ public static bool IsObsolete (this ICustomAttributeProvider provider)
return false;
}

public static PropertyDefinition FindProperty (this MethodReference method)
public static PropertyDefinition? FindProperty (this MethodReference? method)
{
var def = method?.Resolve ();
if (method is null)
return null;

var def = method.Resolve ();
if (def is null)
return null;

Expand Down Expand Up @@ -409,7 +416,7 @@ public static string GetFramework (TypeReference type)

public static string GetFramework (MethodDefinition method)
{
string framework = null;
string? framework = null;
if (method.HasPInvokeInfo)
framework = Path.GetFileNameWithoutExtension (method.PInvokeInfo.Module.Name);
else
Expand All @@ -423,7 +430,7 @@ public static string GetFramework (MemberReference member)
return MapFramework (framework);
}

public static string GetFramework (Decl decl)
public static string? GetFramework (Decl decl)
{
var header_file = decl.PresumedLoc?.FileName;
if (header_file is null)
Expand Down Expand Up @@ -469,7 +476,7 @@ public static string MapFramework (string candidate)
}
}

public static (T, T) Sort<T> (T o1, T o2)
public static (T, T) Sort<T> (T o1, T o2) where T : notnull
{
if (StringComparer.Ordinal.Compare (o1.ToString (), o2.ToString ()) < 0)
return (o2, o1);
Expand Down
5 changes: 2 additions & 3 deletions tests/xtro-sharpie/xtro-sharpie/Log.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
namespace Extrospection {

static class Log {
static Dictionary<string, List<string>> lists = new Dictionary<string, List<string>> (StringComparer.OrdinalIgnoreCase);
static Dictionary<string, List<string>> lists = new (StringComparer.OrdinalIgnoreCase);

public static IList<string> On (string fx)
{
List<string> list;
if (!lists.TryGetValue (fx, out list)) {
if (!lists.TryGetValue (fx, out var list)) {
list = new List<string> ();
lists.Add (fx, list);
}
Expand Down
12 changes: 6 additions & 6 deletions tests/xtro-sharpie/xtro-sharpie/NullabilityCheck.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ public NullabilityCheck (BindingResult bindingResult)
{
}

static TypeDefinition GetType (ObjCInterfaceDecl decl)
static TypeDefinition? GetType (ObjCInterfaceDecl decl)
{
types.TryGetValue (decl.Name, out var td);
return td;
}

static MethodDefinition GetMethod (ObjCMethodDecl decl)
static MethodDefinition? GetMethod (ObjCMethodDecl decl)
{
methods.TryGetValue (decl.GetName (), out var md);
return md;
Expand Down Expand Up @@ -91,7 +91,7 @@ static Null [] GetNullable (ICustomAttributeProvider cap)
// Type is `System.Byte[]` and value is a `CustomAttributeArgument[]`
// each with a `Type` of `System.Byte` and where value is a `byte`
case "System.Byte[]":
var caa = first.Value as CustomAttributeArgument [];
var caa = (CustomAttributeArgument []) first.Value;
var length = caa.Length;
var values = new Null [length];
for (int i = 0; i < length; i++)
Expand All @@ -106,11 +106,11 @@ static Null [] GetNullable (ICustomAttributeProvider cap)
public override void VisitObjCMethodDecl (ObjCMethodDecl decl)
{
// don't process methods (or types) that are unavailable for the current platform
if (!decl.IsAvailable () || !(decl.DeclContext as Decl).IsAvailable ())
if (!decl.IsAvailable () || !(((Decl) decl.DeclContext!).IsAvailable ()))
return;

// don't process deprecated methods (or types)
if (decl.IsDeprecated () || (decl.DeclContext as Decl).IsDeprecated ())
if (decl.IsDeprecated () || (((Decl) decl.DeclContext!).IsDeprecated ()))
return;

var method = GetMethod (decl);
Expand Down Expand Up @@ -203,7 +203,7 @@ public override void VisitObjCMethodDecl (ObjCMethodDecl decl)
ICustomAttributeProvider cap;
// the managed attributes are on the property, not the special methods
if (method.IsGetter) {
var property = method.FindProperty ();
var property = method.FindProperty ()!;
// also `null_resettable` will only show something (natively) on the setter (since it does not return null, but accept it)
// in this case we'll trust xtro checking the setter only (if it exists, if not then it can't be `null_resettable`)
if (property.SetMethod is not null)
Expand Down
15 changes: 7 additions & 8 deletions tests/xtro-sharpie/xtro-sharpie/ObjCInterfaceCheck.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public override void VisitManagedType (TypeDefinition type)
if (!type.HasCustomAttributes)
return;

string rname = null;
string? rname = null;
bool wrapper = true;
bool skip = false;

Expand All @@ -24,7 +24,7 @@ public override void VisitManagedType (TypeDefinition type)
case "RegisterAttribute":
rname = type.Name;
if (ca.HasConstructorArguments) {
rname = (ca.ConstructorArguments [0].Value as string);
rname = (string?) ca.ConstructorArguments [0].Value;
if (ca.ConstructorArguments.Count > 1)
wrapper = (bool) ca.ConstructorArguments [1].Value;
}
Expand All @@ -47,8 +47,7 @@ public override void VisitManagedType (TypeDefinition type)
}
}
if (!skip && wrapper && !String.IsNullOrEmpty (rname)) {
TypeDefinition td;
if (!type_map.TryGetValue (rname, out td)) {
if (!type_map.TryGetValue (rname, out var td)) {
type_map.Add (rname, type);
type_map_copy.Add (rname, type);
} else {
Expand Down Expand Up @@ -149,22 +148,22 @@ public override void EndVisit ()
}

// - version check
bool ImplementProtocol (string protocol, TypeDefinition td)
bool ImplementProtocol (string protocol, TypeDefinition? td)
{
if (td is null)
return false;
if (td.HasInterfaces) {
foreach (var intf in td.Interfaces) {
TypeReference ifaceType;
ifaceType = intf?.InterfaceType;
if (protocol == GetProtocolName (ifaceType?.Resolve ()))
ifaceType = intf.InterfaceType;
if (protocol == GetProtocolName (ifaceType.Resolve ()))
return true;
}
}
return ImplementProtocol (protocol, td.BaseType?.Resolve ());
}

public static string GetProtocolName (TypeDefinition td)
public static string? GetProtocolName (TypeDefinition td)
{
if (!td.HasCustomAttributes)
return null;
Expand Down
Loading