-
Notifications
You must be signed in to change notification settings - Fork 1
Rules
Nullarihyon has some assumptions on analysis to minimize number of false positives.
If local variable declaration is with initial value, and without explicit nullability annotation, the nullability of the variable is propagated from nullability of initial value.
NSNumber *x = @1; // x is _Nonnull
NSNumber * _Nullable y = @3; // y is _Nullable because the declaration has nullability annotation
NSNumber *z = y; // z is _Nullable because y is _Nullable
This helps analyzing without nullability on variables.
The following program would have warning on dictionary[key]
without nullability propagation.
NSDictionary *dictionary;
NSNumber *key = condition ? @1 : @2;
NSString *value = dictionary[key];
The nullability propagation also would make extra warning however.
NSDictionary *dictionary;
NSString *name = @"initial value";
name = dictionary[@"name"];
The dictionary[@"name"]
is _Nullable
, and then name
is assumed to be _Nonnull
by nullability propagation, it would have an extra warning, which would not be reported without nullability propagation.
For that case, you can explicitly declare variable with nullability.
NSDictionary *dictionary;
NSString * _Nullable name = @"initial value";
name = dictionary[@"name"];
self
is assumed to be _Nonnull
in Nullarihyon on right hand side.
And on LHS, self
is treated as _Nullable
.
This assumption makes
- Having
_Nonnull
returning method call_Nonnull
- Assigning
[super init]
things toself
without warning, even if it returns_Nullable
The following methods are assumed having _Nonnull
return types, if no nullability is specified.
-[C init]
-[C class]
+[C alloc]
+[C class]
Loop variables are assumed to be _Nonnull
.
for (NSString *x in collection) {
// x is _Nonnull
}
I believe this makes sense because most collections including NSArray
and NSDictionary
do not allow having nil
. However, you can define custom collection which may contain nil
. For that, just add nullability annotation.
for (NSString * _Nullable x in collection) {
// x is _Nullable
}
When condition clause of if
is reference to variable, the variable is treated as _Nonnull
in then clause of the if
.
NSString * _Nullable x;
if (x) {
// x is _Nonnull
} else {
// x is _Nullable
}
// x is _Nullable
This rule also applies to logical and &&
expression.
NSNumber * _Nullable x;
NSString * _Nullable y;
if (x && y) {
// x and y are _Nonnull
}
BOOL flag = x && [y isEqualToString:[x stringValue]]; // [x stringValue] is _Nonnull
This makes a warning if you have assignment in then clause of if
.
NSNumber * _Nullable x;
NSNumber * _Nullable y;
if (x) {
x = y; // Warning: x is _Nonnull here
}
Add cast for that case.
Using Nullarihyon would make programmers to write many casts. Nullarihyon takes responsibility for that situation.
It checks
- If the cast is not incorrect
- If the cast is required
Feel free to write casts if you need.
It also checks casts and report warnings when:
- The cast is to
_Nonnull
type, and - The cast changes type
NSString * _Nullable a;
NSString * _Nonnull x = (NSString * _Nonnull)a; // This is ok
NSObject * _Nonnull y = (NSObject * _Nonnull)a; // Warning: changes type from NSString to NSObject
NSObject *z = (NSObject *)a; // This is ok; not a cast to _Nonnull
The exception is when source type is id
.
id _Nullable a;
NSString * _Nonnull x = (NSString * _Nonnull)a; // This is ok
Nullarihyon also checks unnecessary casts.
This is introduced by changing method type to return from _Nullable
to _Nonnull
.
NSString *x = [YouClass someMethod]; // Assume someMethod returns _Nullable
// Have to write cast because nullability of x is propagated as _Nullable
NSString * _Nonnull y = (NSString * _Nonnull)x;
However, you will change the type of someMethod
to _Nonnull
.
And then nullability of x
will be _Nonnull
.
Now, the cast to NSString * _Nonnull
is unnecessary.
Nullarihyon will report warning for that.
Casts are unnecessary when
- The destination type is
_Nonnull
- The source type is
_Nonnull
- It does not change other than nullability
and they will be reported.