Repository: VKCOM/noverify
Pull request #1250 (2025-03-11 02:20:10)

linter: null-safety for static calls, static/non static/ property fetching
[Here](https://github.com/VKCOM/noverify/pull/1245) we added checking null-safety. Here we expanded it for statics and functions


Patch:
diff --git a/docs/checkers_doc.md b/docs/checkers_doc.md
index 587630d..0fe2c4b 100644
--- a/docs/checkers_doc.md
+++ b/docs/checkers_doc.md
@@ -4,7 +4,7 @@
 
 | Total checks | Checks enabled by default | Disabled checks by default | Autofixable checks |
 | ------------ | ------------------------- | -------------------------- | ------------------ |
-| 107           | 89                        | 18                         | 15                 |
+| 117           | 99                        | 18                         | 15                 |
 
 ## Table of contents
  - Enabled by default
@@ -60,7 +60,17 @@
    - [`newAbstract` checker](#newabstract-checker)
    - [`nonPublicInterfaceMember` checker](#nonpublicinterfacemember-checker)
    - [`notExplicitNullableParam` checker (autofixable)](#notexplicitnullableparam-checker)
-   - [`notNullSafety` checker](#notnullsafety-checker)
+   - [`notNullSafetyFunctionArgumentArrayDimFetch` checker](#notnullsafetyfunctionargumentarraydimfetch-checker)
+   - [`notNullSafetyFunctionArgumentConstFetch` checker](#notnullsafetyfunctionargumentconstfetch-checker)
+   - [`notNullSafetyFunctionArgumentFunctionCall` checker](#notnullsafetyfunctionargumentfunctioncall-checker)
+   - [`notNullSafetyFunctionArgumentList` checker](#notnullsafetyfunctionargumentlist-checker)
+   - [`notNullSafetyFunctionArgumentPropertyFetch` checker](#notnullsafetyfunctionargumentpropertyfetch-checker)
+   - [`notNullSafetyFunctionArgumentStaticFunctionCall` checker](#notnullsafetyfunctionargumentstaticfunctioncall-checker)
+   - [`notNullSafetyFunctionArgumentVariable` checker](#notnullsafetyfunctionargumentvariable-checker)
+   - [`notNullSafetyFunctionCall` checker](#notnullsafetyfunctioncall-checker)
+   - [`notNullSafetyPropertyFetch` checker](#notnullsafetypropertyfetch-checker)
+   - [`notNullSafetyStaticFunctionCall` checker](#notnullsafetystaticfunctioncall-checker)
+   - [`notNullSafetyVariable` checker](#notnullsafetyvariable-checker)
    - [`offBy1` checker (autofixable)](#offby1-checker)
    - [`oldStyleConstructor` checker](#oldstyleconstructor-checker)
    - [`paramClobber` checker](#paramclobber-checker)
@@ -1200,7 +1210,156 @@ function f(?string $str = null);
 <p><br></p>
 
 
-### `notNullSafety` checker
+### `notNullSafetyFunctionArgumentArrayDimFetch` checker
+
+#### Description
+
+Report not nullsafety call array.
+
+#### Non-compliant code:
+```php
+class A {
+    public string $value = 'Hello';
+}
+
+function test(A $a): void {
+    echo $a->value;
+}
+
+$arr = [new A(), null];
+test($arr[1]);
+```
+
+#### Compliant code:
+```php
+reported not safety call
+```
+<p><br></p>
+
+
+### `notNullSafetyFunctionArgumentConstFetch` checker
+
+#### Description
+
+Report not nullsafety call
+
+#### Non-compliant code:
+```php
+function f(A $klass);
+						f(null);
+```
+
+#### Compliant code:
+```php
+reported that null passed to non-nullable parameter.
+```
+<p><br></p>
+
+
+### `notNullSafetyFunctionArgumentFunctionCall` checker
+
+#### Description
+
+Report not nullsafety function call.
+
+#### Non-compliant code:
+```php
+class A {
+    public static function hello(): ?string {
+        return "Hello!";
+    }
+}
+
+function test(A $s): void {
+    echo $s;
+}
+
+function testNullable(): ?A{
+	return new A();
+}
+
+test(testNullable());
+```
+
+#### Compliant code:
+```php
+reported not safety call
+```
+<p><br></p>
+
+
+### `notNullSafetyFunctionArgumentList` checker
+
+#### Description
+
+Report not nullsafety call for null list
+
+#### Non-compliant code:
+```php
+test(list($a) = [null]);
+```
+
+#### Compliant code:
+```php
+reported not safety call
+```
+<p><br></p>
+
+
+### `notNullSafetyFunctionArgumentPropertyFetch` checker
+
+#### Description
+
+Report not nullsafety fetching property in function argument.
+
+#### Non-compliant code:
+```php
+
+class User {
+    public $name = "lol";
+}
+
+$user = new User();
+$user = null;
+echo $user->name;
+```
+
+#### Compliant code:
+```php
+reported not safety call
+```
+<p><br></p>
+
+
+### `notNullSafetyFunctionArgumentStaticFunctionCall` checker
+
+#### Description
+
+Report not nullsafety call with static function call usage.
+
+#### Non-compliant code:
+```php
+class A {
+    public static function hello(): ?string {
+        return "Hello!";
+    }
+}
+
+function test(string $s): void {
+    echo $s;
+}
+
+test(A::hello());
+```
+
+#### Compliant code:
+```php
+reported not safety call
+```
+<p><br></p>
+
+
+### `notNullSafetyFunctionArgumentVariable` checker
 
 #### Description
 
@@ -1212,6 +1371,51 @@ function f(A $klass);
 						f(null);
 ```
 
+#### Compliant code:
+```php
+reported not safety call with null in variable.
+```
+<p><br></p>
+
+
+### `notNullSafetyFunctionCall` checker
+
+#### Description
+
+Report not nullsafety function call.
+
+#### Non-compliant code:
+```php
+function getUserOrNull(): ?User { echo "test"; }
+
+$getUserOrNull()->test();
+```
+
+#### Compliant code:
+```php
+reported not safety function call
+```
+<p><br></p>
+
+
+### `notNullSafetyPropertyFetch` checker
+
+#### Description
+
+Report not nullsafety property fetch.
+
+#### Non-compliant code:
+```php
+
+class User {
+    public $name = "lol";
+}
+
+$user = new User();
+$user = null;
+echo $user->name;
+```
+
 #### Compliant code:
 ```php
 reported not safety call
@@ -1219,6 +1423,56 @@ reported not safety call
 <p><br></p>
 
 
+### `notNullSafetyStaticFunctionCall` checker
+
+#### Description
+
+Report not nullsafety function call.
+
+#### Non-compliant code:
+```php
+class A {
+    public static function hello(): ?string {
+        return "Hello!";
+    }
+}
+
+function test(string $s): void {
+    echo $s;
+}
+
+test(A::hello());
+```
+
+#### Compliant code:
+```php
+reported not safety static function call
+```
+<p><br></p>
+
+
+### `notNullSafetyVariable` checker
+
+#### Description
+
+Report not nullsafety call
+
+#### Non-compliant code:
+```php
+$user = new User();
+
+$user = null;
+
+echo $user->name;
+```
+
+#### Compliant code:
+```php
+reported not safety call with null in variable.
+```
+<p><br></p>
+
+
 ### `offBy1` checker
 
 > Auto fix available
diff --git a/src/linter/block.go b/src/linter/block.go
index a8dc54d..1a62392 100644
--- a/src/linter/block.go
+++ b/src/linter/block.go
@@ -1065,10 +1065,105 @@ func (b *blockWalker) checkNullSafetyCallArgsF(args []ir.Node, fn meta.FuncInfo)
 			b.checkListExprNullSafety(arg, fn, i, a, haveVariadic)
 		case *ir.PropertyFetchExpr:
 			b.checkPropertyFetchNullSafety(a, fn, i, haveVariadic)
+		case *ir.StaticCallExpr:
+			b.checkStaticCallNullSafety(arg, fn, i, a, haveVariadic)
+		case *ir.StaticPropertyFetchExpr:
+			b.checkStaticPropertyFetchNullSafety(a, fn, i, haveVariadic)
+		case *ir.FunctionCallExpr:
+			b.checkFunctionCallNullSafety(arg, fn, i, a, haveVariadic)
 		}
 	}
 }
 
+func (b *blockWalker) checkFunctionCallNullSafety(arg ir.Node, fn meta.FuncInfo, paramIndex int, funcCall *ir.FunctionCallExpr, haveVariadic bool) {
+	var funcName string
+
+	var isClearF bool
+	var callType types.Map
+
+	switch f := funcCall.Function.(type) {
+	case *ir.Name:
+		funcName = f.Value
+		isClearF = true
+	case *ir.SimpleVar:
+		funcName = f.Name
+		varInfo, found := b.ctx.sc.GetVar(f)
+
+		if !found {
+			return
+		}
+		callType = varInfo.Type // nolint:ineffassign,staticcheck
+	default:
+		return
+	}
+
+	funcInfo, ok := b.linter.metaInfo().GetFunction("\\" + funcName)
+	if !ok && isClearF {
+		return
+	} else {
+		callType = funcInfo.Typ
+	}
+
+	param := nullSafetyRealParamForCheck(fn, paramIndex, haveVariadic)
+	if haveVariadic && paramIndex >= len(fn.Params)-1 {
+		// For variadic parameter check, if type is mixed then skip.
+		if types.IsTypeMixed(param.Typ) {
+			return
+		}
+	}
+	paramAllowsNull := types.IsTypeNullable(param.Typ)
+	varIsNullable := types.IsTypeNullable(callType)
+	if varIsNullable && !paramAllowsNull {
+		b.report(arg, LevelWarning, "notNullSafetyFunctionArgumentFunctionCall",
+			"not null safety call in function %s signature of param %s when calling function %s",
+			formatSlashesFuncName(fn), param.Name, funcInfo.Name)
+	}
+}
+
+func (b *blockWalker) checkStaticCallNullSafety(arg ir.Node, fn meta.FuncInfo, paramIndex int, staticCallF *ir.StaticCallExpr, haveVariadic bool) {
+	funcName, ok := staticCallF.Call.(*ir.Identifier)
+	if !ok {
+		return
+	}
+
+	var className string
+	switch classNameNode := staticCallF.Class.(type) {
+	case *ir.SimpleVar:
+		varInfo, found := b.ctx.sc.GetVar(classNameNode)
+		if !found {
+			return
+		}
+		className = varInfo.Type.String()
+	case *ir.Name:
+		className = "\\" + classNameNode.Value
+	}
+
+	classInfo, ok := b.r.ctx.st.Info.GetClass(className)
+	if !ok {
+		return
+	}
+
+	funcInfo, ok := classInfo.Methods.Get(funcName.Value)
+	if !ok {
+		return
+	}
+
+	param := nullSafetyRealParamForCheck(fn, paramIndex, haveVariadic)
+	if haveVariadic && paramIndex >= len(fn.Params)-1 {
+		// For variadic parameter check, if type is mixed then skip.
+		if types.IsTypeMixed(param.Typ) {
+			return
+		}
+	}
+	paramAllowsNull := types.IsTypeNullable(param.Typ)
+	varIsNullable := types.IsTypeNullable(funcInfo.Typ)
+	if varIsNullable && !paramAllowsNull {
+		b.report(arg, LevelWarning, "notNullSafetyFunctionArgumentStaticFunctionCall",
+			"not null safety call in function %s signature of param %s when calling static function %s",
+			formatSlashesFuncName(fn), param.Name, funcInfo.Name)
+	}
+}
+
 func (b *blockWalker) checkSimpleVarNullSafety(arg ir.Node, fn meta.FuncInfo, paramIndex int, variable *ir.SimpleVar, haveVariadic bool) {
 	varInfo, ok := b.ctx.sc.GetVar(variable)
 	if !ok {
@@ -1085,7 +1180,7 @@ func (b *blockWalker) checkSimpleVarNullSafety(arg ir.Node, fn meta.FuncInfo, pa
 	paramAllowsNull := types.IsTypeNullable(param.Typ)
 	varIsNullable := types.IsTypeNullable(varInfo.Type)
 	if varIsNullable && !paramAllowsNull {
-		b.report(arg, LevelWarning, "notNullSafety",
+		b.report(arg, LevelWarning, "notNullSafetyFunctionArgumentVariable",
 			"not null safety call in function %s signature of param %s",
 			formatSlashesFuncName(fn), param.Name)
 	}
@@ -1103,7 +1198,7 @@ func (b *blockWalker) checkConstFetchNullSafety(arg ir.Node, fn meta.FuncInfo, p
 	}
 	paramAllowsNull := types.IsTypeNullable(param.Typ)
 	if isNull && !paramAllowsNull {
-		b.report(arg, LevelWarning, "notNullSafety",
+		b.report(arg, LevelWarning, "notNullSafetyFunctionArgumentConstFetch",
 			"null passed to non-nullable parameter %s in function %s",
 			param.Name, formatSlashesFuncName(fn))
 	}
@@ -1128,7 +1223,7 @@ func (b *blockWalker) checkArrayDimFetchNullSafety(arg ir.Node, fn meta.FuncInfo
 	}
 	paramAllowsNull := types.IsTypeNullable(param.Typ)
 	if types.IsTypeNullable(varInfo.Type) && !paramAllowsNull {
-		b.report(arg, LevelWarning, "notNullSafety",
+		b.report(arg, LevelWarning, "notNullSafetyFunctionArgumentArrayDimFetch",
 			"potential null array access in parameter %s of function %s",
 			param.Name, formatSlashesFuncName(fn))
 	}
@@ -1149,7 +1244,7 @@ func (b *blockWalker) checkListExprNullSafety(arg ir.Node, fn meta.FuncInfo, par
 			if simpleVar, ok := item.Val.(*ir.SimpleVar); ok {
 				varInfo, found := b.ctx.sc.GetVar(simpleVar)
 				if found && types.IsTypeNullable(varInfo.Type) && !types.IsTypeNullable(param.Typ) {
-					b.report(arg, LevelWarning, "notNullSafety",
+					b.report(arg, LevelWarning, "notNullSafetyFunctionArgumentList",
 						"potential null value in list assignment for param %s in function %s",
 						param.Name, formatSlashesFuncName(fn))
 				}
@@ -1159,29 +1254,53 @@ func (b *blockWalker) checkListExprNullSafety(arg ir.Node, fn meta.FuncInfo, par
 	}
 }
 
-func (b *blockWalker) getPropertyComputedType(expr *ir.PropertyFetchExpr) (meta.ClassInfo, types.Map) {
-	baseCall, ok := expr.Variable.(*ir.SimpleVar)
-	if !ok {
+func (b *blockWalker) getPropertyComputedType(expr ir.Node) (meta.ClassInfo, types.Map) {
+	var baseNode ir.Node
+	var propertyNode ir.Node
+
+	switch e := expr.(type) {
+	case *ir.PropertyFetchExpr:
+		baseNode = e.Variable
+		propertyNode = e.Property
+	case *ir.StaticPropertyFetchExpr:
+		baseNode = e.Class
+		propertyNode = e.Property
+	default:
 		return meta.ClassInfo{}, types.Map{}
 	}
 
-	varInfo, ok := b.ctx.sc.GetVar(baseCall)
-	if !ok {
+	var classInfo meta.ClassInfo
+	var ok bool
+	var varType string
+
+	if baseCall, ok := baseNode.(*ir.SimpleVar); ok {
+		varInfo, found := b.ctx.sc.GetVar(baseCall)
+		if !found {
+			return meta.ClassInfo{}, types.Map{}
+		}
+		varType = varInfo.Type.String()
+	} else if nameNode, ok := baseNode.(*ir.Name); ok {
+		varType = "\\" + nameNode.Value
+	} else {
 		return meta.ClassInfo{}, types.Map{}
 	}
 
-	classInfo, ok := b.r.ctx.st.Info.GetClass(varInfo.Type.String())
+	classInfo, ok = b.r.ctx.st.Info.GetClass(varType)
 	if !ok {
 		return meta.ClassInfo{}, types.Map{}
 	}
 
-	property, ok := expr.Property.(*ir.Identifier)
-	if !ok {
+	switch prop := propertyNode.(type) {
+	case *ir.Identifier:
+		propertyInfoFromClass := classInfo.Properties[prop.Value]
+		return classInfo, propertyInfoFromClass.Typ
+	case *ir.SimpleVar:
+		// static: $maybeClass::$value
+		propertyInfoFromClass := classInfo.Properties["$"+prop.Name]
+		return classInfo, propertyInfoFromClass.Typ
+	default:
 		return meta.ClassInfo{}, types.Map{}
 	}
-
-	propertyInfoFromClass := classInfo.Properties[property.Value]
-	return classInfo, propertyInfoFromClass.Typ
 }
 
 func (b *blockWalker) checkPropertyFetchNullSafety(expr *ir.PropertyFetchExpr, fn meta.FuncInfo, paramIndex int, haveVariadic bool) {
@@ -1200,6 +1319,17 @@ func (b *blockWalker) checkPropertyFetchNullSafety(expr *ir.PropertyFetchExpr, f
 		return
 	}
 
+	b.checkingPropertyFetchNullSafetyCondition(expr, propType, prp.Value, fn, paramIndex, haveVariadic)
+}
+
+func (b *blockWalker) checkingPropertyFetchNullSafetyCondition(
+	expr ir.Node,
+	propType types.Map,
+	prpName string,
+	fn meta.FuncInfo,
+	paramIndex int,
+	haveVariadic bool,
+) {
 	isPrpNullable := types.IsTypeNullable(propType)
 	param := nullSafetyRealParamForCheck(fn, paramIndex, haveVariadic)
 	if haveVariadic && paramIndex >= len(fn.Params)-1 {
@@ -1208,18 +1338,38 @@ func (b *blockWalker) checkPropertyFetchNullSafety(expr *ir.PropertyFetchExpr, f
 		}
 		paramAllowsNull := types.IsTypeNullable(param.Typ)
 		if isPrpNullable && !paramAllowsNull {
-			b.report(expr, LevelWarning, "notNullSafety",
-				"potential null dereference when accessing property '%s'", prp.Value)
+			b.report(expr, LevelWarning, "notNullSafetyFunctionArgumentPropertyFetch",
+				"potential null dereference when accessing property '%s'", prpName)
 		}
 		return
 	}
 
 	paramAllowsNull := types.IsTypeNullable(param.Typ)
 	if isPrpNullable && !paramAllowsNull {
-		b.report(expr, LevelWarning, "notNullSafety",
-			"potential null dereference when accessing property '%s'", prp.Value)
+		b.report(expr, LevelWarning, "notNullSafetyFunctionArgumentPropertyFetch",
+			"potential null dereference when accessing property '%s'", prpName)
 	}
 }
+
+func (b *blockWalker) checkStaticPropertyFetchNullSafety(expr *ir.StaticPropertyFetchExpr, fn meta.FuncInfo, paramIndex int, haveVariadic bool) {
+	// Recursively check the left part of the chain if it is also a property fetch.
+	if nested, ok := expr.Class.(*ir.StaticPropertyFetchExpr); ok {
+		b.checkStaticPropertyFetchNullSafety(nested, fn, paramIndex, haveVariadic)
+	}
+
+	classInfo, propType := b.getPropertyComputedType(expr)
+	if classInfo.Name == "" || propType.Empty() {
+		return
+	}
+
+	prp, ok := expr.Property.(*ir.SimpleVar)
+	if !ok {
+		return
+	}
+
+	b.checkingPropertyFetchNullSafetyCondition(expr, propType, prp.Name, fn, paramIndex, haveVariadic)
+}
+
 func (b *blockWalker) handleCallArgs(args []ir.Node, fn meta.FuncInfo) {
 	b.checkNullSafetyCallArgsF(args, fn)
 
diff --git a/src/linter/block_linter.go b/src/linter/block_linter.go
index 3343caf..c478c7a 100644
--- a/src/linter/block_linter.go
+++ b/src/linter/block_linter.go
@@ -593,19 +593,40 @@ func (b *blockLinter) checkStmtExpression(s *ir.ExpressionStmt) {
 	// All branches except default try to filter-out common
 	// cases to reduce the number of type solving performed.
 	if irutil.IsAssign(s.Expr) {
+		assign, okCast := s.Expr.(*ir.Assign)
+		if !okCast {
+			return
+		}
+		if v, ok := assign.Variable.(*ir.StaticPropertyFetchExpr); ok {
+			parseState := b.classParseState()
+			left, ok := parseState.Info.GetVarType(v.Class)
+
+			if ok && left.Contains("null") {
+				b.report(s, LevelWarning, "notNullSafetyPropertyFetch",
+					"potential null dereference when accessing static property")
+			}
+		}
 		return
 	}
-	switch s.Expr.(type) {
+	switch expr := s.Expr.(type) {
 	case *ir.ImportExpr, *ir.ExitExpr:
 		// Skip.
 	case *ir.ArrayExpr, *ir.NewExpr:
 		// Report these even if they are not pure.
 		report = true
-	default:
-		typ := b.walker.exprType(s.Expr)
-		if !typ.Is("void") {
-			report = b.walker.sideEffectFree(s.Expr)
+	case *ir.StaticCallExpr:
+		if v, ok := expr.Class.(*ir.SimpleVar); ok {
+			parseState := b.classParseState()
+			left, ok := parseState.Info.GetVarType(v)
+
+			if ok && left.Contains("null") {
+				b.report(s, LevelWarning, "notNullSafetyStaticFunctionCall",
+					"potential null dereference when accessing static call throw $%s", v.Name)
+			}
 		}
+		report = b.isDiscardableExpr(s.Expr)
+	default:
+		report = b.isDiscardableExpr(s.Expr)
 	}
 
 	if report {
@@ -613,6 +634,14 @@ func (b *blockLinter) checkStmtExpression(s *ir.ExpressionStmt) {
 	}
 }
 
+func (b *blockLinter) isDiscardableExpr(expr ir.Node) bool {
+	typ := b.walker.exprType(expr)
+	if !typ.Is("void") {
+		return b.walker.sideEffectFree(expr)
+	}
+	return false
+}
+
 func (b *blockLinter) checkConstFetch(e *ir.ConstFetchExpr) {
 	_, _, defined := solver.GetConstant(b.classParseState(), e.Constant)
 
@@ -1298,6 +1327,20 @@ func (b *blockLinter) checkMethodCall(e *ir.MethodCallExpr) {
 		}
 	}
 
+	switch caller := e.Variable.(type) {
+	case *ir.FunctionCallExpr:
+		switch fn := caller.Function.(type) {
+		case *ir.SimpleVar, *ir.Name:
+			checkNullSafetyWhenMethodCallChain(parseState, b, e, fn)
+		}
+	case *ir.SimpleVar:
+		callerVarType, ok := parseState.Info.GetVarType(caller)
+		if ok && callerVarType.Contains("null") {
+			b.report(e, LevelWarning, "notNullSafetyVariable",
+				"potential null dereference in $%s when accessing method", caller.Name)
+		}
+	}
+
 	if call.info.Deprecated {
 		deprecation := call.info.DeprecationInfo
 
@@ -1315,6 +1358,19 @@ func (b *blockLinter) checkMethodCall(e *ir.MethodCallExpr) {
 	}
 }
 
+func checkNullSafetyWhenMethodCallChain(parseState *meta.ClassParseState, b *blockLinter, e ir.Node, funcExpr ir.Node) {
+	funcCallerName, ok := solver.GetFuncName(parseState, funcExpr)
+	if !ok {
+		return
+	}
+
+	funInfo, ok := parseState.Info.GetFunction(funcCallerName)
+	if ok && funInfo.Typ.Contains("null") {
+		b.report(e, LevelWarning, "notNullSafetyFunctionCall",
+			"potential null dereference in %s when accessing method", funInfo.Name)
+	}
+}
+
 func (b *blockLinter) checkStaticCall(e *ir.StaticCallExpr) {
 	if utils.NameNodeToString(e.Class) == "parent" && b.classParseState().CurrentParentClass == "" {
 		b.report(e, LevelError, "parentNotFound", "Cannot call method on parent as this class does not extend another")
@@ -1388,7 +1444,9 @@ func (b *blockLinter) checkMethodCallPackage(methodClassName string, methodInfo
 }
 
 func (b *blockLinter) checkPropertyFetch(e *ir.PropertyFetchExpr) {
-	fetch := resolvePropertyFetch(b.walker.ctx.sc, b.classParseState(), b.walker.ctx.customTypes, e, b.walker.r.strictMixed)
+	globalMetaInfo := b.classParseState()
+
+	fetch := resolvePropertyFetch(b.walker.ctx.sc, globalMetaInfo, b.walker.ctx.customTypes, e, b.walker.r.strictMixed)
 	if !fetch.canAnalyze {
 		return
 	}
@@ -1396,30 +1454,44 @@ func (b *blockLinter) checkPropertyFetch(e *ir.PropertyFetchExpr) {
 	needShowUndefinedProperty := !fetch.callerTypeIsMixed || b.walker.r.strictMixed
 
 	if !fetch.isFound && !fetch.isMagic &&
-		!b.classParseState().IsTrait &&
+		!globalMetaInfo.IsTrait &&
 		!b.walker.isThisInsideClosure(e.Variable) &&
 		needShowUndefinedProperty {
 		b.report(e.Property, LevelError, "undefinedProperty", "Property {%s}->%s does not exist", fetch.propertyFetchType, fetch.propertyNode.Value)
 	}
 
-	if fetch.isFound && !fetch.isMagic && !canAccess(b.classParseState(), fetch.className, fetch.info.AccessLevel) {
+	if fetch.isFound && !fetch.isMagic && !canAccess(globalMetaInfo, fetch.className, fetch.info.AccessLevel) {
 		b.report(e.Property, LevelError, "accessLevel", "Cannot access %s property %s->%s", fetch.info.AccessLevel, fetch.className, fetch.propertyNode.Value)
 	}
+
+	left, ok := globalMetaInfo.Info.GetVarType(e.Variable)
+	if ok && left.Contains("null") {
+		b.report(e, LevelWarning, "notNullSafetyPropertyFetch",
+			"attempt to access property that can be null")
+	}
 }
 
 func (b *blockLinter) checkStaticPropertyFetch(e *ir.StaticPropertyFetchExpr) {
-	fetch := resolveStaticPropertyFetch(b.classParseState(), e)
+	globalMetaInfo := b.classParseState()
+	fetch := resolveStaticPropertyFetch(globalMetaInfo, e)
+
+	left, ok := globalMetaInfo.Info.GetVarType(e.Class)
+	if ok && left.Contains("null") {
+		b.report(e, LevelWarning, "notNullSafetyPropertyFetch",
+			"attempt to access property that can be null")
+	}
+
 	if !fetch.canAnalyze {
 		return
 	}
 
 	b.checkClassSpecialNameCase(e, fetch.className)
 
-	if !fetch.isFound && !b.classParseState().IsTrait {
+	if !fetch.isFound && !globalMetaInfo.IsTrait {
 		b.report(e.Property, LevelError, "undefinedProperty", "Property %s::$%s does not exist", fetch.className, fetch.propertyName)
 	}
 
-	if fetch.isFound && !canAccess(b.classParseState(), fetch.info.ClassName, fetch.info.Info.AccessLevel) {
+	if fetch.isFound && !canAccess(globalMetaInfo, fetch.info.ClassName, fetch.info.Info.AccessLevel) {
 		b.report(e.Property, LevelError, "accessLevel", "Cannot access %s property %s::$%s", fetch.info.Info.AccessLevel, fetch.info.ClassName, fetch.propertyName)
 	}
 }
diff --git a/src/linter/report.go b/src/linter/report.go
index 26c247f..b8b9b66 100644
--- a/src/linter/report.go
+++ b/src/linter/report.go
@@ -26,15 +26,169 @@ func addBuiltinCheckers(reg *CheckersRegistry) {
 		},
 
 		{
-			Name:     "notNullSafety",
+			Name:     "notNullSafetyFunctionArgumentList",
+			Default:  true,
+			Quickfix: false,
+			Comment:  "Report not nullsafety call for null list",
+			Before:   `test(list($a) = [null]);`,
+			After:    `reported not safety call`,
+		},
+
+		{
+			Name:     "notNullSafetyFunctionArgumentArrayDimFetch",
+			Default:  true,
+			Quickfix: false,
+			Comment:  "Report not nullsafety call array.",
+			Before: `class A {
+    public string $value = 'Hello';
+}
+
+function test(A $a): void {
+    echo $a->value;
+}
+
+$arr = [new A(), null];
+test($arr[1]);`,
+			After: `reported not safety call`,
+		},
+
+		{
+			Name:     "notNullSafetyFunctionArgumentConstFetch",
 			Default:  true,
 			Quickfix: false,
 			Comment:  "Report not nullsafety call",
 			Before: `function f(A $klass);
 						f(null);`,
+			After: `reported that null passed to non-nullable parameter.`,
+		},
+
+		{
+			Name:     "notNullSafetyFunctionArgumentStaticFunctionCall",
+			Default:  true,
+			Quickfix: false,
+			Comment:  "Report not nullsafety call with static function call usage.",
+			Before: `class A {
+    public static function hello(): ?string {
+        return "Hello!";
+    }
+}
+
+function test(string $s): void {
+    echo $s;
+}
+
+test(A::hello());`,
 			After: `reported not safety call`,
 		},
 
+		{
+			Name:     "notNullSafetyFunctionArgumentVariable",
+			Default:  true,
+			Quickfix: false,
+			Comment:  "Report not nullsafety call",
+			Before: `function f(A $klass);
+						f(null);`,
+			After: `reported not safety call with null in variable.`,
+		},
+
+		{
+			Name:     "notNullSafetyFunctionArgumentFunctionCall",
+			Default:  true,
+			Quickfix: false,
+			Comment:  "Report not nullsafety function call.",
+			Before: `class A {
+    public static function hello(): ?string {
+        return "Hello!";
+    }
+}
+
+function test(A $s): void {
+    echo $s;
+}
+
+function testNullable(): ?A{
+	return new A();
+}
+
+test(testNullable());`,
+			After: `reported not safety call`,
+		},
+
+		{
+			Name:     "notNullSafetyFunctionArgumentPropertyFetch",
+			Default:  true,
+			Quickfix: false,
+			Comment:  "Report not nullsafety fetching property in function argument.",
+			Before: `
+class User {
+    public $name = "lol";
+}
+
+$user = new User();
+$user = null;
+echo $user->name;`,
+			After: `reported not safety call`,
+		},
+
+		{
+			Name:     "notNullSafetyPropertyFetch",
+			Default:  true,
+			Quickfix: false,
+			Comment:  "Report not nullsafety property fetch.",
+			Before: `
+class User {
+    public $name = "lol";
+}
+
+$user = new User();
+$user = null;
+echo $user->name;`,
+			After: `reported not safety call`,
+		},
+
+		{
+			Name:     "notNullSafetyVariable",
+			Default:  true,
+			Quickfix: false,
+			Comment:  "Report not nullsafety call",
+			Before: `$user = new User();
+
+$user = null;
+
+echo $user->name;`,
+			After: `reported not safety call with null in variable.`,
+		},
+
+		{
+			Name:     "notNullSafetyFunctionCall",
+			Default:  true,
+			Quickfix: false,
+			Comment:  "Report not nullsafety function call.",
+			Before: `function getUserOrNull(): ?User { echo "test"; }
+
+$getUserOrNull()->test();`,
+			After: `reported not safety function call`,
+		},
+
+		{
+			Name:     "notNullSafetyStaticFunctionCall",
+			Default:  true,
+			Quickfix: false,
+			Comment:  "Report not nullsafety function call.",
+			Before: `class A {
+    public static function hello(): ?string {
+        return "Hello!";
+    }
+}
+
+function test(string $s): void {
+    echo $s;
+}
+
+test(A::hello());`,
+			After: `reported not safety static function call`,
+		},
+
 		{
 			Name:     "notExplicitNullableParam",
 			Default:  true,
diff --git a/src/types/predicates.go b/src/types/predicates.go
index 3d963e3..3c7b284 100644
--- a/src/types/predicates.go
+++ b/src/types/predicates.go
@@ -39,7 +39,7 @@ func IsAlias(s string) bool {
 
 func IsTypeNullable(typ Map) bool {
 	isNullable := false
-	if typ.m == nil {
+	if typ.m == nil || typ.Empty() {
 		return true // We consider that if the type is not inferred, then it is mixed
 	}
 	typ.Iterate(func(t string) {


Test patch:
diff --git a/src/tests/checkers/null_safety_test.go b/src/tests/checkers/null_safety_test.go
index bb8ac88..1c4a2c4 100644
--- a/src/tests/checkers/null_safety_test.go
+++ b/src/tests/checkers/null_safety_test.go
@@ -241,3 +241,176 @@ if ($v !== null) {
 	test.Expect = []string{}
 	test.RunAndMatch()
 }
+
+func TestStaticNullSafety(t *testing.T) {
+	test := linttest.NewSuite(t)
+	test.AddFile(`<?php
+class A {
+    public static $value = 'test';
+    
+    public static function hello(): void {
+        echo "Hello!";
+    }
+}
+
+$maybeClass = rand(0, 1) ? 'A' : null;
+$maybeClass::hello();
+echo $maybeClass::$value;
+`)
+	test.Expect = []string{
+		"Missing PHPDoc for \\A::hello public method",
+		"Call to undefined function rand",
+		"potential null dereference when accessing static call throw $maybeClass",
+		"attempt to access property that can be null",
+	}
+	test.RunAndMatch()
+}
+
+func TestFetchPropertyNullSafety(t *testing.T) {
+	test := linttest.NewSuite(t)
+	test.AddFile(`<?php
+class User {
+    public $name = "lol";
+}
+
+$user = new User();
+$user = null;
+echo $user->name;
+`)
+	test.Expect = []string{
+		"attempt to access property that can be null",
+	}
+	test.RunAndMatch()
+}
+
+func TestStaticPropertyNullSafety(t *testing.T) {
+	test := linttest.NewSuite(t)
+	test.AddFile(`<?php
+class A {
+    public static $value = null;
+    
+    public static function hello(): void {
+        echo "Hello!";
+    }
+}
+
+function test(string $a): void {
+echo "test";
+}
+$maybeClass  = new A();
+test($maybeClass::$value);
+
+`)
+	test.Expect = []string{
+		"Missing PHPDoc for \\A::hello public method",
+		`potential null dereference when accessing property 'value'`,
+	}
+	test.RunAndMatch()
+}
+
+func TestStaticPropertyFetchWithName(t *testing.T) {
+	test := linttest.NewSuite(t)
+	test.AddFile(`<?php
+class A {
+    public static string $value = 'test';
+}
+
+function test(string $s): void {
+    echo $s;
+}
+
+test(A::$value);
+`)
+	test.Expect = []string{}
+	test.RunAndMatch()
+}
+
+func TestStaticPropertyNullFetchWithName(t *testing.T) {
+	test := linttest.NewSuite(t)
+	test.AddFile(`<?php
+class A {
+    public static string $value = null;
+}
+
+function test(string $s): void {
+    echo $s;
+}
+
+test(A::$value);
+`)
+	test.Expect = []string{
+		"potential null dereference when accessing property 'value'",
+	}
+	test.RunAndMatch()
+}
+
+func TestStaticCallNullSafety(t *testing.T) {
+	test := linttest.NewSuite(t)
+	test.AddFile(`<?php
+class A {
+    public static function hello(): ?string {
+        return "Hello!";
+    }
+}
+
+function test(string $s): void {
+    echo $s;
+}
+
+test(A::hello());
+`)
+	test.Expect = []string{
+		"Missing PHPDoc for \\A::hello public method",
+		"not null safety call in function test signature of param s when calling static function hello",
+	}
+	test.RunAndMatch()
+}
+
+func TestStaticCallNullSafetyThrowVariable(t *testing.T) {
+	test := linttest.NewSuite(t)
+	test.AddFile(`<?php
+class A {
+    public static function hello(): ?string {
+        return "Hello!";
+    }
+}
+
+function test(string $s): void {
+    echo $s;
+}
+
+$maybeClass = new A();
+test($maybeClass::hello());
+`)
+	test.Expect = []string{
+		"Missing PHPDoc for \\A::hello public method",
+		"not null safety call in function test signature of param s when calling static function hello",
+	}
+	test.RunAndMatch()
+}
+
+func TestFunctionCallNullSafetyThrowVariable(t *testing.T) {
+	test := linttest.NewSuite(t)
+	test.AddFile(`<?php
+class A {
+    public static function hello(): ?string {
+        return "Hello!";
+    }
+}
+
+function test(A $s): void {
+    echo $s;
+}
+
+function testNullable(): ?A{
+	return new A();
+}
+
+test(testNullable());
+`)
+	test.Expect = []string{
+		"Missing PHPDoc for \\A::hello public method",
+		"not null safety call in function test signature of param s when calling function \\testNullable",
+	}
+	test.RunAndMatch()
+}
diff --git a/src/tests/golden/golden_test.go b/src/tests/golden/golden_test.go
index 19dddd6..88657c9 100644
--- a/src/tests/golden/golden_test.go
+++ b/src/tests/golden/golden_test.go
@@ -96,7 +96,7 @@ func TestGolden(t *testing.T) {
 
 		{
 			Name:    "parsedown",
-			Disable: []string{"missingPhpdoc", "arraySyntax", "phpAliases", "notNullSafety"},
+			Disable: []string{"missingPhpdoc", "arraySyntax", "phpAliases"},
 			Deps: []string{
 				`stubs/phpstorm-stubs/pcre/pcre.php`,
 				`stubs/phpstorm-stubs/mbstring/mbstring.php`,
@@ -105,7 +105,7 @@ func TestGolden(t *testing.T) {
 
 		{
 			Name:    "underscore",
-			Disable: []string{"missingPhpdoc", "phpAliases", "notNullSafety"},
+			Disable: []string{"missingPhpdoc", "phpAliases"},
 			Deps: []string{
 				`stubs/phpstorm-stubs/pcre/pcre.php`,
 			},
@@ -113,7 +113,7 @@ func TestGolden(t *testing.T) {
 
 		{
 			Name:    "phprocksyd",
-			Disable: []string{"missingPhpdoc", "notNullSafety"},
+			Disable: []string{"missingPhpdoc"},
 			Deps: []string{
 				`stubs/phpstorm-stubs/standard/basic.php`,
 				`stubs/phpstorm-stubs/pcntl/pcntl.php`,
@@ -124,7 +124,7 @@ func TestGolden(t *testing.T) {
 
 		{
 			Name:    "flysystem",
-			Disable: []string{"redundantCast", "notNullSafety"},
+			Disable: []string{"redundantCast"},
 			Deps: []string{
 				`stubs/phpstorm-stubs/pcre/pcre.php`,
 				`stubs/phpstorm-stubs/SPL/SPL.php`,
@@ -141,7 +141,7 @@ func TestGolden(t *testing.T) {
 
 		{
 			Name:    "inflector",
-			Disable: []string{"missingPhpdoc", "notNullSafety"},
+			Disable: []string{"missingPhpdoc"},
 			Deps: []string{
 				`stubs/phpstorm-stubs/pcre/pcre.php`,
 				`stubs/phpstorm-stubs/SPL/SPL.php`,
@@ -151,7 +151,7 @@ func TestGolden(t *testing.T) {
 
 		{
 			Name:    "options-resolver",
-			Disable: []string{"missingPhpdoc", "notNullSafety"},
+			Disable: []string{"missingPhpdoc"},
 			Deps: []string{
 				`stubs/phpstorm-stubs/SPL/SPL.php`,
 				`stubs/phpstorm-stubs/Reflection/Reflection.php`,
@@ -164,7 +164,7 @@ func TestGolden(t *testing.T) {
 
 		{
 			Name:    "twitter-api-php",
-			Disable: []string{"missingPhpdoc", "arraySyntax", "notNullSafety"},
+			Disable: []string{"missingPhpdoc", "arraySyntax"},
 			Deps: []string{
 				`stubs/phpstorm-stubs/pcre/pcre.php`,
 				`stubs/phpstorm-stubs/SPL/SPL.php`,
diff --git a/src/tests/golden/testdata/embeddedrules/golden.txt b/src/tests/golden/testdata/embeddedrules/golden.txt
index 50f964a..f3e3719 100644
--- a/src/tests/golden/testdata/embeddedrules/golden.txt
+++ b/src/tests/golden/testdata/embeddedrules/golden.txt
@@ -13,19 +13,19 @@ WARNING argsOrder: Potentially incorrect haystack and needle arguments order at
 WARNING argsOrder: Potentially incorrect replacement and subject arguments order at testdata/embeddedrules/argsOrder.php:32
   $_ = preg_replace($pat, $subj, 'replacement');
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function explode signature of param separator at testdata/embeddedrules/argsOrder.php:41
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function explode signature of param separator at testdata/embeddedrules/argsOrder.php:41
   $_ = explode($s, '/');
                ^^
 WARNING argsOrder: Potentially incorrect delimiter and string arguments order at testdata/embeddedrules/argsOrder.php:41
   $_ = explode($s, '/');
        ^^^^^^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function explode signature of param string at testdata/embeddedrules/argsOrder.php:45
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function explode signature of param string at testdata/embeddedrules/argsOrder.php:45
   $_ = explode('/', $s);
                     ^^
-WARNING notNullSafety: not null safety call in function explode signature of param separator at testdata/embeddedrules/argsOrder.php:46
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function explode signature of param separator at testdata/embeddedrules/argsOrder.php:46
   $_ = explode($delim, $s);
                ^^^^^^
-WARNING notNullSafety: not null safety call in function explode signature of param string at testdata/embeddedrules/argsOrder.php:46
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function explode signature of param string at testdata/embeddedrules/argsOrder.php:46
   $_ = explode($delim, $s);
                        ^^
 WARNING argsOrder: Potentially incorrect replace and string arguments order at testdata/embeddedrules/argsOrder.php:50
diff --git a/src/tests/golden/testdata/flysystem/golden.txt b/src/tests/golden/testdata/flysystem/golden.txt
index bbd2f80..5baee73 100644
--- a/src/tests/golden/testdata/flysystem/golden.txt
+++ b/src/tests/golden/testdata/flysystem/golden.txt
@@ -1,30 +1,177 @@
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function preg_match signature of param subject at testdata/flysystem/src/Adapter/AbstractFtpAdapter.php:358
+            if (preg_match('#^.*:$#', $item)) {
+                                      ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function normalizeObject signature of param item at testdata/flysystem/src/Adapter/AbstractFtpAdapter.php:363
+            $result[] = $this->normalizeObject($item, $base);
+                                               ^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string1 of function strnatcmp at testdata/flysystem/src/Adapter/AbstractFtpAdapter.php:379
+            return strnatcmp($one['path'], $two['path']);
+                             ^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string2 of function strnatcmp at testdata/flysystem/src/Adapter/AbstractFtpAdapter.php:379
+            return strnatcmp($one['path'], $two['path']);
+                                           ^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function forFtpSystemType signature of param systemType at testdata/flysystem/src/Adapter/AbstractFtpAdapter.php:407
+        throw NotSupportedException::forFtpSystemType($systemType);
+                                                      ^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function explode signature of param string at testdata/flysystem/src/Adapter/AbstractFtpAdapter.php:434
+        if (count(explode(' ', $item, 9)) !== 9) {
+                               ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function explode signature of param string at testdata/flysystem/src/Adapter/AbstractFtpAdapter.php:438
+        list($permissions, /* $number */, /* $owner */, /* $group */, $size, $month, $day, $timeOrYear, $name) = explode(' ', $item, 9);
+                                                                                                                              ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function explode signature of param string at testdata/flysystem/src/Adapter/AbstractFtpAdapter.php:502
+        if (count(explode(' ', $item, 4)) !== 4) {
+                               ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function explode signature of param string at testdata/flysystem/src/Adapter/AbstractFtpAdapter.php:506
+        list($date, $time, $size, $name) = explode(' ', $item, 4);
+                                                        ^^^^^
 MAYBE   regexpSimplify: May re-write '/^[0-9]{2,4}-[0-9]{2}-[0-9]{2}/' as '/^\d{2,4}-\d{2}-\d{2}/' at testdata/flysystem/src/Adapter/AbstractFtpAdapter.php:536
         return preg_match('/^[0-9]{2,4}-[0-9]{2}-[0-9]{2}/', $item) ? 'windows' : 'unix';
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 MAYBE   callSimplify: Could simplify to $permissions[0] at testdata/flysystem/src/Adapter/AbstractFtpAdapter.php:548
         return substr($permissions, 0, 1) === 'd' ? 'dir' : 'file';
                ^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function str_split signature of param string at testdata/flysystem/src/Adapter/AbstractFtpAdapter.php:576
+            return array_sum(str_split($part));
+                                       ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function preg_match signature of param subject at testdata/flysystem/src/Adapter/AbstractFtpAdapter.php:593
+            return $line !== '' && ! preg_match('#.* \.(\.)?$|^total#', $line);
+                                                                        ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function getMetadata signature of param path at testdata/flysystem/src/Adapter/AbstractFtpAdapter.php:604
+        return $this->getMetadata($path);
+                                  ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function getMetadata signature of param path at testdata/flysystem/src/Adapter/AbstractFtpAdapter.php:612
+        return $this->getMetadata($path);
+                                  ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function getMetadata signature of param path at testdata/flysystem/src/Adapter/AbstractFtpAdapter.php:620
+        return $this->getMetadata($path);
+                                  ^^^^^
 WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/flysystem/src/Adapter/Ftp.php:134
             $this->connection = @ftp_ssl_connect($this->getHost(), $this->getPort(), $this->getTimeout());
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/flysystem/src/Adapter/Ftp.php:136
             $this->connection = @ftp_connect($this->getHost(), $this->getPort(), $this->getTimeout());
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'connection' at testdata/flysystem/src/Adapter/Ftp.php:156
+            $response = ftp_raw($this->connection, "OPTS UTF8 ON");
+                                ^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'connection' at testdata/flysystem/src/Adapter/Ftp.php:173
+            ftp_set_option($this->connection, FTP_USEPASVADDRESS, ! $this->ignorePassiveAddress);
+                           ^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'connection' at testdata/flysystem/src/Adapter/Ftp.php:176
+        if ( ! ftp_pasv($this->connection, $this->passive)) {
+                        ^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'connection' at testdata/flysystem/src/Adapter/Ftp.php:212
+            $this->connection,
+            ^^^^^^^^^^^^^^^^^
 WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/flysystem/src/Adapter/Ftp.php:233
             @ftp_close($this->connection);
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'connection' at testdata/flysystem/src/Adapter/Ftp.php:233
+            @ftp_close($this->connection);
+                       ^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function fwrite signature of param data at testdata/flysystem/src/Adapter/Ftp.php:245
+        fwrite($stream, $contents);
+                        ^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function guessMimeType signature of param path at testdata/flysystem/src/Adapter/Ftp.php:255
+        $result['mimetype'] = $config->get('mimetype') ?: Util::guessMimeType($path, $contents);
+                                                                              ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function guessMimeType signature of param content at testdata/flysystem/src/Adapter/Ftp.php:255
+        $result['mimetype'] = $config->get('mimetype') ?: Util::guessMimeType($path, $contents);
+                                                                                     ^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function dirname signature of param path at testdata/flysystem/src/Adapter/Ftp.php:265
+        $this->ensureDirectory(Util::dirname($path));
+                                             ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function ftp_fput signature of param remote_filename at testdata/flysystem/src/Adapter/Ftp.php:267
+        if ( ! ftp_fput($this->getConnection(), $path, $resource, $this->transferMode)) {
+                                                ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function ftp_fput signature of param stream at testdata/flysystem/src/Adapter/Ftp.php:267
+        if ( ! ftp_fput($this->getConnection(), $path, $resource, $this->transferMode)) {
+                                                       ^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'transferMode' at testdata/flysystem/src/Adapter/Ftp.php:267
+        if ( ! ftp_fput($this->getConnection(), $path, $resource, $this->transferMode)) {
+                                                                  ^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function ftp_rename signature of param from at testdata/flysystem/src/Adapter/Ftp.php:301
+        return ftp_rename($this->getConnection(), $path, $newpath);
+                                                  ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function ftp_rename signature of param to at testdata/flysystem/src/Adapter/Ftp.php:301
+        return ftp_rename($this->getConnection(), $path, $newpath);
+                                                         ^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function ftp_delete signature of param filename at testdata/flysystem/src/Adapter/Ftp.php:309
+        return ftp_delete($this->getConnection(), $path);
+                                                  ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function listDirectoryContents signature of param directory at testdata/flysystem/src/Adapter/Ftp.php:318
+        $contents = array_reverse($this->listDirectoryContents($dirname, false));
+                                                               ^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter filename of function ftp_delete at testdata/flysystem/src/Adapter/Ftp.php:322
+                if ( ! ftp_delete($connection, $object['path'])) {
+                                               ^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function ftp_rmdir signature of param directory at testdata/flysystem/src/Adapter/Ftp.php:330
+        return ftp_rmdir($connection, $dirname);
+                                      ^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function explode signature of param string at testdata/flysystem/src/Adapter/Ftp.php:339
+        $directories = explode('/', $dirname);
+                                    ^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function preg_match signature of param subject at testdata/flysystem/src/Adapter/Ftp.php:370
+            if (preg_match('~^\./.*~', $item)) {
+                                       ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/flysystem/src/Adapter/Ftp.php:371
+                $listing[$key] = substr($item, 2);
+                                        ^^^^^
 WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/flysystem/src/Adapter/Ftp.php:391
         if (@ftp_chdir($this->getConnection(), $path) === true) {
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function ftp_chdir signature of param directory at testdata/flysystem/src/Adapter/Ftp.php:391
+        if (@ftp_chdir($this->getConnection(), $path) === true) {
+                                               ^^^^^
 MAYBE   regexpSimplify: May re-write '/^total [0-9]*$/' as '/^total \d*$/' at testdata/flysystem/src/Adapter/Ftp.php:407
         if (preg_match('/^total [0-9]*$/', $listing[0])) {
                        ^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter item of function normalizeObject at testdata/flysystem/src/Adapter/Ftp.php:411
+        return $this->normalizeObject($listing[0], '');
+                                      ^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function detectByFilename signature of param filename at testdata/flysystem/src/Adapter/Ftp.php:423
+        $metadata['mimetype'] = MimeType::detectByFilename($path);
+                                                           ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function ftp_mdtm signature of param filename at testdata/flysystem/src/Adapter/Ftp.php:433
+        $timestamp = ftp_mdtm($this->getConnection(), $path);
+                                                      ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function ftp_fget signature of param remote_filename at testdata/flysystem/src/Adapter/Ftp.php:460
+        $result = ftp_fget($this->getConnection(), $stream, $path, $this->transferMode);
+                                                            ^^^^^
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'transferMode' at testdata/flysystem/src/Adapter/Ftp.php:460
+        $result = ftp_fget($this->getConnection(), $stream, $path, $this->transferMode);
+                                                                   ^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function ftp_chmod signature of param filename at testdata/flysystem/src/Adapter/Ftp.php:479
+        if ( ! ftp_chmod($this->getConnection(), $mode, $path)) {
+                                                        ^^^^^
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'connection' at testdata/flysystem/src/Adapter/Ftp.php:544
+        $response = ftp_raw($this->connection, 'HELP');
+                            ^^^^^^^^^^^^^^^^^
 WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/flysystem/src/Adapter/Ftp.php:570
         $response = @ftp_raw($this->connection, trim($command));
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'connection' at testdata/flysystem/src/Adapter/Ftp.php:570
+        $response = @ftp_raw($this->connection, trim($command));
+                             ^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function trim signature of param string at testdata/flysystem/src/Adapter/Ftp.php:570
+        $response = @ftp_raw($this->connection, trim($command));
+                                                     ^^^^^^^^
 WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/flysystem/src/Adapter/Ftpd.php:15
         if (@ftp_chdir($this->getConnection(), $path) === true) {
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function ftp_chdir signature of param directory at testdata/flysystem/src/Adapter/Ftpd.php:15
+        if (@ftp_chdir($this->getConnection(), $path) === true) {
+                                               ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function ftp_rawlist signature of param directory at testdata/flysystem/src/Adapter/Ftpd.php:37
+        $listing = ftp_rawlist($this->getConnection(), $directory, $recursive);
+                                                       ^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function substr at testdata/flysystem/src/Adapter/Ftpd.php:39
+        if ($listing === false || ( ! empty($listing) && substr($listing[0], 0, 5) === "ftpd:")) {
+                                                                ^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function normalizeListing signature of param prefix at testdata/flysystem/src/Adapter/Ftpd.php:43
+        return $this->normalizeListing($listing, $directory);
+                                                 ^^^^^^^^^^
 WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/flysystem/src/Adapter/Local.php:103
             if ( ! @mkdir($root, $this->permissionMap['dir']['public'], true)) {
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -34,18 +181,96 @@ WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/
 MAYBE   ternarySimplify: Could rewrite as `$mkdirError['message'] ?? ''` at testdata/flysystem/src/Adapter/Local.php:111
                 $errorMessage = isset($mkdirError['message']) ? $mkdirError['message'] : '';
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:122
+        $location = $this->applyPathPrefix($path);
+                                           ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:132
+        $location = $this->applyPathPrefix($path);
+                                           ^^^^^
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'writeFlags' at testdata/flysystem/src/Adapter/Local.php:135
+        if (($size = file_put_contents($location, $contents, $this->writeFlags)) === false) {
+                                                             ^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'writeFlags' at testdata/flysystem/src/Adapter/Local.php:135
+        if (($size = file_put_contents($location, $contents, $this->writeFlags)) === false) {
+                                                             ^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:155
+        $location = $this->applyPathPrefix($path);
+                                           ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function stream_copy_to_stream signature of param from at testdata/flysystem/src/Adapter/Local.php:159
+        if ( ! $stream || stream_copy_to_stream($resource, $stream) === false || ! fclose($stream)) {
+                                                ^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:179
+        $location = $this->applyPathPrefix($path);
+                                           ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:198
+        $location = $this->applyPathPrefix($path);
+                                           ^^^^^
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'writeFlags' at testdata/flysystem/src/Adapter/Local.php:199
+        $size = file_put_contents($location, $contents, $this->writeFlags);
+                                                        ^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function guessMimeType signature of param path at testdata/flysystem/src/Adapter/Local.php:209
+        if ($mimetype = $config->get('mimetype') ?: Util::guessMimeType($path, $contents)) {
+                                                                        ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function guessMimeType signature of param content at testdata/flysystem/src/Adapter/Local.php:209
+        if ($mimetype = $config->get('mimetype') ?: Util::guessMimeType($path, $contents)) {
+                                                                               ^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function guessMimeType signature of param path at testdata/flysystem/src/Adapter/Local.php:209
+        if ($mimetype = $config->get('mimetype') ?: Util::guessMimeType($path, $contents)) {
+                                                                        ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function guessMimeType signature of param content at testdata/flysystem/src/Adapter/Local.php:209
+        if ($mimetype = $config->get('mimetype') ?: Util::guessMimeType($path, $contents)) {
+                                                                               ^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:221
+        $location = $this->applyPathPrefix($path);
+                                           ^^^^^
 WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/flysystem/src/Adapter/Local.php:222
         $contents = @file_get_contents($location);
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:236
+        $location = $this->applyPathPrefix($path);
+                                           ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:237
+        $destination = $this->applyPathPrefix($newpath);
+                                              ^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function dirname signature of param path at testdata/flysystem/src/Adapter/Local.php:238
+        $parentDirectory = $this->applyPathPrefix(Util::dirname($newpath));
+                                                                ^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:249
+        $location = $this->applyPathPrefix($path);
+                                           ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:250
+        $destination = $this->applyPathPrefix($newpath);
+                                              ^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:261
+        $location = $this->applyPathPrefix($path);
+                                           ^^^^^
 WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/flysystem/src/Adapter/Local.php:263
         return @unlink($location);
                ^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:300
+        $location = $this->applyPathPrefix($path);
+                                           ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:320
+        $location = $this->applyPathPrefix($path);
+                                           ^^^^^
 WARNING strictCmp: 3rd argument of in_array must be true when comparing strings at testdata/flysystem/src/Adapter/Local.php:324
         if (in_array($mimetype, ['application/octet-stream', 'inode/x-empty', 'application/x-empty'])) {
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:344
+        $location = $this->applyPathPrefix($path);
+                                           ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:365
+        $location = $this->applyPathPrefix($path);
+                                           ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:381
+        $location = $this->applyPathPrefix($dirname);
+                                           ^^^^^^^^
 WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/flysystem/src/Adapter/Local.php:387
             if (false === @mkdir($location, $this->permissionMap['dir'][$visibility], true)
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function applyPathPrefix signature of param path at testdata/flysystem/src/Adapter/Local.php:403
+        $location = $this->applyPathPrefix($dirname);
+                                           ^^^^^^^^
 MAYBE   invalidDocblockType: Void type can only be used as a standalone type for the return type at testdata/flysystem/src/Adapter/Local.php:444
      * @return array|void
                ^^^^^^^^^^
@@ -55,6 +280,9 @@ WARNING invalidDocblockRef: @see tag refers to unknown symbol League\Flysystem\R
 WARNING invalidDocblockRef: @see tag refers to unknown symbol League\Flysystem\ReadInterface::read at testdata/flysystem/src/Adapter/Polyfill/StreamedReadingTrait.php:41
      * @see League\Flysystem\ReadInterface::read()
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func signature of param callback at testdata/flysystem/src/Adapter/Polyfill/StreamedWritingTrait.php:26
+        return call_user_func($fallbackCall, $path, $contents, $config);
+                              ^^^^^^^^^^^^^
 MAYBE   missingPhpdoc: Missing PHPDoc for \League\Flysystem\Adapter\Polyfill\StreamedWritingTrait::write public method at testdata/flysystem/src/Adapter/Polyfill/StreamedWritingTrait.php:58
     abstract public function write($pash, $contents, Config $config);
                              ^^^^^
@@ -103,12 +331,33 @@ WARNING notExplicitNullableParam: parameter with null default value should be ex
 MAYBE   deprecated: Has deprecated class Handler at testdata/flysystem/src/Handler.php:10
 abstract class Handler
 ^
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'path' at testdata/flysystem/src/Handler.php:61
+        $metadata = $this->filesystem->getMetadata($this->path);
+                                                   ^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func_array signature of param callback at testdata/flysystem/src/Handler.php:128
+            return call_user_func_array($callback, $arguments);
+                                        ^^^^^^^^^
 WARNING unused: Variable $e is unused (use $_ to ignore this inspection or specify --unused-var-regex flag) at testdata/flysystem/src/Handler.php:129
         } catch (BadMethodCallException $e) {
                                         ^^
 WARNING notExplicitNullableParam: parameter with null default value should be explicitly nullable at testdata/flysystem/src/Handler.php:28
     public function __construct(FilesystemInterface $filesystem = null, $path = null)
                                 ^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function mountFilesystem signature of param filesystem at testdata/flysystem/src/MountManager.php:57
+            $this->mountFilesystem($prefix, $filesystem);
+                                            ^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function getPrefixAndPath signature of param path at testdata/flysystem/src/MountManager.php:123
+        list($prefix, $path) = $this->getPrefixAndPath($path);
+                                                       ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function invokePluginOnFilesystem signature of param prefix at testdata/flysystem/src/MountManager.php:166
+        return $this->invokePluginOnFilesystem($method, $arguments, $prefix);
+                                                                    ^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter visibility of function setVisibility at testdata/flysystem/src/MountManager.php:243
+                return $filesystem->setVisibility($pathTo, $config['visibility']);
+                                                           ^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func_array signature of param callback at testdata/flysystem/src/MountManager.php:281
+        return call_user_func_array($callback, $arguments);
+                                    ^^^^^^^^^
 WARNING unused: Variable $e is unused (use $_ to ignore this inspection or specify --unused-var-regex flag) at testdata/flysystem/src/MountManager.php:275
         } catch (PluginNotFoundException $e) {
                                          ^^
@@ -124,6 +373,15 @@ WARNING unused: Variable $e is unused (use $_ to ignore this inspection or speci
 WARNING unused: Variable $e is unused (use $_ to ignore this inspection or specify --unused-var-regex flag) at testdata/flysystem/src/Plugin/ForcedRename.php:33
         } catch (FileNotFoundException $e) {
                                        ^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function ucfirst signature of param string at testdata/flysystem/src/Plugin/GetWithMetadata.php:42
+            if ( ! method_exists($this->filesystem, $method = 'get' . ucfirst($key))) {
+                                                                              ^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function ucfirst signature of param string at testdata/flysystem/src/Plugin/GetWithMetadata.php:42
+            if ( ! method_exists($this->filesystem, $method = 'get' . ucfirst($key))) {
+                                                                              ^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func_array signature of param callback at testdata/flysystem/src/Plugin/PluggableTrait.php:72
+        return call_user_func_array($callback, $arguments);
+                                    ^^^^^^^^^
 WARNING unused: Variable $e is unused (use $_ to ignore this inspection or specify --unused-var-regex flag) at testdata/flysystem/src/Plugin/PluggableTrait.php:89
         } catch (PluginNotFoundException $e) {
                                          ^^
@@ -133,21 +391,69 @@ MAYBE   missingPhpdoc: Missing PHPDoc for \League\Flysystem\SafeStorage::storeSa
 MAYBE   missingPhpdoc: Missing PHPDoc for \League\Flysystem\SafeStorage::retrieveSafely public method at testdata/flysystem/src/SafeStorage.php:28
     public function retrieveSafely($key)
                     ^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function array_key_exists signature of param key at testdata/flysystem/src/SafeStorage.php:30
+        if (array_key_exists($key, static::$safeStorage[$this->hash])) {
+                             ^^^^
 MAYBE   missingPhpdoc: Missing PHPDoc for \League\Flysystem\UnreadableFileException::forFileInfo public method at testdata/flysystem/src/UnreadableFileException.php:9
     public static function forFileInfo(SplFileInfo $fileInfo)
                            ^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function pathinfo signature of param path at testdata/flysystem/src/Util.php:214
+            $listing[] = static::pathinfo($directory) + ['type' => 'dir'];
+                                          ^^^^^^^^^^
 MAYBE   missingPhpdoc: Missing PHPDoc for \League\Flysystem\Util::isSeekableStream public method at testdata/flysystem/src/Util.php:258
     public static function isSeekableStream($resource)
                            ^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function stream_get_meta_data signature of param stream at testdata/flysystem/src/Util.php:260
+        $metadata = stream_get_meta_data($resource);
+                                         ^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function trim at testdata/flysystem/src/Util.php:298
+        if ( ! isset($object['dirname']) || trim($object['dirname']) === '') {
+                                                 ^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function trim signature of param string at testdata/flysystem/src/Util.php:304
+        while (isset($parent) && trim($parent) !== '' && ! in_array($parent, $directories)) {
+                                      ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function dirname signature of param path at testdata/flysystem/src/Util.php:306
+            $parent = static::dirname($parent);
+                                      ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function preg_match signature of param subject at testdata/flysystem/src/Util.php:341
+        while (preg_match('#^[a-zA-Z]{1}:[^\\\/]#', $basename)) {
+                                                    ^^^^^^^^^
 MAYBE   regexpSimplify: May re-write '#^[a-zA-Z]{1}:[^\\\/]#' as '#^[a-zA-Z]:[^\\/]#' at testdata/flysystem/src/Util.php:341
         while (preg_match('#^[a-zA-Z]{1}:[^\\\/]#', $basename)) {
                           ^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/flysystem/src/Util.php:342
+            $basename = substr($basename, 2);
+                               ^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function preg_match signature of param subject at testdata/flysystem/src/Util.php:346
+        if (preg_match('#^[a-zA-Z]{1}:$#', $basename)) {
+                                           ^^^^^^^^^
 MAYBE   regexpSimplify: May re-write '#^[a-zA-Z]{1}:$#' as '#^[a-zA-Z]:$#' at testdata/flysystem/src/Util.php:346
         if (preg_match('#^[a-zA-Z]{1}:$#', $basename)) {
                        ^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function rtrim signature of param string at testdata/flysystem/src/Util.php:347
+            $basename = rtrim($basename, ':');
+                              ^^^^^^^^^
 MAYBE   typeHint: Specify the type for the parameter $entry in PHPDoc, 'array' type hint too generic at testdata/flysystem/src/Util/ContentListingFormatter.php:52
     private function addPathInfo(array $entry)
                      ^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter path of function pathinfo at testdata/flysystem/src/Util/ContentListingFormatter.php:54
+        return $entry + Util::pathinfo($entry['path']);
+                                       ^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter haystack of function strpos at testdata/flysystem/src/Util/ContentListingFormatter.php:91
+            ? strpos($entry['path'], $this->directory . '/') === 0
+                     ^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter haystack of function stripos at testdata/flysystem/src/Util/ContentListingFormatter.php:92
+            : stripos($entry['path'], $this->directory . '/') === 0;
+                      ^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string2 of function strcasecmp at testdata/flysystem/src/Util/ContentListingFormatter.php:106
+            : strcasecmp($this->directory, $entry['dirname']) === 0;
+                                           ^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string1 of function strcasecmp at testdata/flysystem/src/Util/ContentListingFormatter.php:117
+            return strcasecmp($a['path'], $b['path']);
+                              ^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string2 of function strcasecmp at testdata/flysystem/src/Util/ContentListingFormatter.php:117
+            return strcasecmp($a['path'], $b['path']);
+                                          ^^^^^^^^^^
 WARNING unused: Variable $e is unused (use $_ to ignore this inspection or specify --unused-var-regex flag) at testdata/flysystem/src/Util/MimeType.php:208
         } catch (ErrorException $e) {
                                 ^^
diff --git a/src/tests/golden/testdata/idn/golden.txt b/src/tests/golden/testdata/idn/golden.txt
index 564ebef..fb12b3d 100644
--- a/src/tests/golden/testdata/idn/golden.txt
+++ b/src/tests/golden/testdata/idn/golden.txt
@@ -7,7 +7,7 @@ MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at tes
 WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/idn/idn.php:67
             @trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', E_USER_DEPRECATED);
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function mb_strtolower signature of param string at testdata/idn/idn.php:71
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function mb_strtolower signature of param string at testdata/idn/idn.php:71
             $domain = mb_strtolower($domain, 'utf-8');
                                     ^^^^^^^
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/idn/idn.php:87
@@ -22,13 +22,13 @@ MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at tes
 WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/idn/idn.php:99
             @trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', E_USER_DEPRECATED);
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function explode signature of param string at testdata/idn/idn.php:102
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function explode signature of param string at testdata/idn/idn.php:102
         $parts = explode('.', $domain);
                               ^^^^^^^
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/idn/idn.php:119
         $idna_info = array(
                      
-WARNING notNullSafety: not null safety call in function mb_strlen signature of param string at testdata/idn/idn.php:152
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function mb_strlen signature of param string at testdata/idn/idn.php:152
         $length = mb_strlen($input, 'utf-8');
                             ^^^^^^
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/idn/idn.php:195
@@ -43,10 +43,10 @@ MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at tes
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/idn/idn.php:194
         $codePoints = array(
                       
-WARNING notNullSafety: not null safety call in function mb_strlen signature of param string at testdata/idn/idn.php:200
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function mb_strlen signature of param string at testdata/idn/idn.php:200
         $length = mb_strlen($input, 'utf-8');
                             ^^^^^^
-WARNING notNullSafety: not null safety call in function mb_substr signature of param string at testdata/idn/idn.php:202
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function mb_substr signature of param string at testdata/idn/idn.php:202
             $char = mb_substr($input, $i, 1, 'utf-8');
                               ^^^^^^
 MAYBE   redundantCast: Expression already has int type at testdata/idn/idn.php:233
@@ -58,13 +58,13 @@ MAYBE   assignOp: Could rewrite as `$k += 36` at testdata/idn/idn.php:234
 MAYBE   redundantCast: Expression already has int type at testdata/idn/idn.php:237
         return $k + (int) (36 * $delta / ($delta + 38));
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function strrpos signature of param haystack at testdata/idn/idn.php:247
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function strrpos signature of param haystack at testdata/idn/idn.php:247
         $pos = strrpos($input, '-');
                        ^^^^^^
-WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/idn/idn.php:249
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/idn/idn.php:249
             $output = substr($input, 0, $pos++);
                              ^^^^^^
-WARNING notNullSafety: not null safety call in function strlen signature of param string at testdata/idn/idn.php:255
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function strlen signature of param string at testdata/idn/idn.php:255
         $inputLength = \strlen($input);
                                ^^^^^^
 MAYBE   assignOp: Could rewrite as `$n += (int) ($i / $outputLength)` at testdata/idn/idn.php:274
diff --git a/src/tests/golden/testdata/inflector/golden.txt b/src/tests/golden/testdata/inflector/golden.txt
index c975a6b..0cd1a41 100644
--- a/src/tests/golden/testdata/inflector/golden.txt
+++ b/src/tests/golden/testdata/inflector/golden.txt
@@ -25,3 +25,9 @@ WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/
 WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/inflector/lib/Doctrine/Common/Inflector/Inflector.php:181
         @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in Doctrine Inflector 3.0. Please update to the new Inflector API.', __METHOD__), E_USER_DEPRECATED);
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function mb_strtolower signature of param string at testdata/inflector/lib/Doctrine/Inflector/Inflector.php:242
+        return mb_strtolower($tableized);
+                             ^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function trim signature of param string at testdata/inflector/lib/Doctrine/Inflector/Inflector.php:480
+        return trim($urlized, '-');
+                    ^^^^^^^^
diff --git a/src/tests/golden/testdata/math/golden.txt b/src/tests/golden/testdata/math/golden.txt
index 80fa121..98474b6 100644
--- a/src/tests/golden/testdata/math/golden.txt
+++ b/src/tests/golden/testdata/math/golden.txt
@@ -1,28 +1,28 @@
 WARNING unused: Variable $a is unused (use $_ to ignore this inspection or specify --unused-var-regex flag) at testdata/math/src/BigDecimal.php:292
         [$a, $b] = $this->scaleValues($this, $that);
          ^^
-WARNING notNullSafety: not null safety call in function of signature of param value at testdata/math/src/BigDecimal.php:588
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function of signature of param value at testdata/math/src/BigDecimal.php:588
         $that = BigNumber::of($that);
                               ^^^^^
 MAYBE   trailingComma: Last element in a multi-line array should have a trailing comma at testdata/math/src/BigInteger.php:435
             new BigInteger($remainder)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function of signature of param value at testdata/math/src/BigInteger.php:742
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function of signature of param value at testdata/math/src/BigInteger.php:742
         $that = BigNumber::of($that);
                               ^^^^^
 MAYBE   ternarySimplify: Could rewrite as `$matches['fractional'] ?? ''` at testdata/math/src/BigNumber.php:90
             $fractional = isset($matches['fractional']) ? $matches['fractional'] : '';
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function isLessThan signature of param that at testdata/math/src/BigNumber.php:173
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function isLessThan signature of param that at testdata/math/src/BigNumber.php:173
             if ($min === null || $value->isLessThan($min)) {
                                                     ^^^^
-WARNING notNullSafety: not null safety call in function isGreaterThan signature of param that at testdata/math/src/BigNumber.php:205
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function isGreaterThan signature of param that at testdata/math/src/BigNumber.php:205
             if ($max === null || $value->isGreaterThan($max)) {
                                                        ^^^^
-WARNING notNullSafety: not null safety call in function add signature of param a at testdata/math/src/BigNumber.php:241
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function add signature of param a at testdata/math/src/BigNumber.php:241
                 $sum = self::add($sum, $value);
                                  ^^^^
-WARNING notNullSafety: not null safety call in function minus signature of param that at testdata/math/src/BigRational.php:365
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function minus signature of param that at testdata/math/src/BigRational.php:365
         return $this->minus($that)->getSign();
                             ^^^^^
 MAYBE   implicitModifiers: Specify the access modifier for \Brick\Math\Internal\Calculator::powmod method explicitly at testdata/math/src/Internal/Calculator.php:260
@@ -31,10 +31,10 @@ MAYBE   implicitModifiers: Specify the access modifier for \Brick\Math\Internal\
 MAYBE   assignOp: Could rewrite as `$number ^= $xor` at testdata/math/src/Internal/Calculator.php:622
         $number = $number ^ $xor;
         ^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function gmp_strval signature of param num at testdata/math/src/Internal/Calculator/GmpCalculator.php:66
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function gmp_strval signature of param num at testdata/math/src/Internal/Calculator/GmpCalculator.php:66
             \gmp_strval($q),
                         ^^
-WARNING notNullSafety: not null safety call in function gmp_strval signature of param num at testdata/math/src/Internal/Calculator/GmpCalculator.php:67
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function gmp_strval signature of param num at testdata/math/src/Internal/Calculator/GmpCalculator.php:67
             \gmp_strval($r)
                         ^^
 MAYBE   trailingComma: Last element in a multi-line array should have a trailing comma at testdata/math/src/Internal/Calculator/GmpCalculator.php:67
diff --git a/src/tests/golden/testdata/mustache/golden.txt b/src/tests/golden/testdata/mustache/golden.txt
index 9987a66..761638c 100644
--- a/src/tests/golden/testdata/mustache/golden.txt
+++ b/src/tests/golden/testdata/mustache/golden.txt
@@ -1,4 +1,4 @@
-WARNING notNullSafety: not null safety call in function realpath signature of param path at testdata/mustache/src/Mustache/Autoloader.php:39
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function realpath signature of param path at testdata/mustache/src/Mustache/Autoloader.php:39
         $realDir = realpath($baseDir);
                             ^^^^^^^^
 MAYBE   ternarySimplify: Could rewrite as `$baseDir ?: 0` at testdata/mustache/src/Mustache/Autoloader.php:56
@@ -28,85 +28,85 @@ WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/
 WARNING useEval: Don't use the 'eval' function at testdata/mustache/src/Mustache/Cache/NoopCache.php:45
         eval('?>' . $value);
         ^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter id of function section at testdata/mustache/src/Mustache/Compiler.php:98
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter id of function section at testdata/mustache/src/Mustache/Compiler.php:98
                         $node[Mustache_Tokenizer::NAME],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter start of function section at testdata/mustache/src/Mustache/Compiler.php:100
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter start of function section at testdata/mustache/src/Mustache/Compiler.php:100
                         $node[Mustache_Tokenizer::INDEX],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter end of function section at testdata/mustache/src/Mustache/Compiler.php:101
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter end of function section at testdata/mustache/src/Mustache/Compiler.php:101
                         $node[Mustache_Tokenizer::END],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter otag of function section at testdata/mustache/src/Mustache/Compiler.php:102
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter otag of function section at testdata/mustache/src/Mustache/Compiler.php:102
                         $node[Mustache_Tokenizer::OTAG],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter ctag of function section at testdata/mustache/src/Mustache/Compiler.php:103
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter ctag of function section at testdata/mustache/src/Mustache/Compiler.php:103
                         $node[Mustache_Tokenizer::CTAG],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 MAYBE   ternarySimplify: Could rewrite as `$node[Mustache_Tokenizer::FILTERS] ?? array()` at testdata/mustache/src/Mustache/Compiler.php:99
                         isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter id of function invertedSection at testdata/mustache/src/Mustache/Compiler.php:111
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter id of function invertedSection at testdata/mustache/src/Mustache/Compiler.php:111
                         $node[Mustache_Tokenizer::NAME],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 MAYBE   ternarySimplify: Could rewrite as `$node[Mustache_Tokenizer::FILTERS] ?? array()` at testdata/mustache/src/Mustache/Compiler.php:112
                         isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter id of function partial at testdata/mustache/src/Mustache/Compiler.php:119
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter id of function partial at testdata/mustache/src/Mustache/Compiler.php:119
                         $node[Mustache_Tokenizer::NAME],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 MAYBE   ternarySimplify: Could rewrite as `$node[Mustache_Tokenizer::INDENT] ?? ''` at testdata/mustache/src/Mustache/Compiler.php:120
                         isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter id of function parent at testdata/mustache/src/Mustache/Compiler.php:127
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter id of function parent at testdata/mustache/src/Mustache/Compiler.php:127
                         $node[Mustache_Tokenizer::NAME],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 MAYBE   ternarySimplify: Could rewrite as `$node[Mustache_Tokenizer::INDENT] ?? ''` at testdata/mustache/src/Mustache/Compiler.php:128
                         isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter id of function blockArg at testdata/mustache/src/Mustache/Compiler.php:137
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter id of function blockArg at testdata/mustache/src/Mustache/Compiler.php:137
                         $node[Mustache_Tokenizer::NAME],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter start of function blockArg at testdata/mustache/src/Mustache/Compiler.php:138
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter start of function blockArg at testdata/mustache/src/Mustache/Compiler.php:138
                         $node[Mustache_Tokenizer::INDEX],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter end of function blockArg at testdata/mustache/src/Mustache/Compiler.php:139
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter end of function blockArg at testdata/mustache/src/Mustache/Compiler.php:139
                         $node[Mustache_Tokenizer::END],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter otag of function blockArg at testdata/mustache/src/Mustache/Compiler.php:140
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter otag of function blockArg at testdata/mustache/src/Mustache/Compiler.php:140
                         $node[Mustache_Tokenizer::OTAG],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter ctag of function blockArg at testdata/mustache/src/Mustache/Compiler.php:141
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter ctag of function blockArg at testdata/mustache/src/Mustache/Compiler.php:141
                         $node[Mustache_Tokenizer::CTAG],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter id of function blockVar at testdata/mustache/src/Mustache/Compiler.php:149
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter id of function blockVar at testdata/mustache/src/Mustache/Compiler.php:149
                         $node[Mustache_Tokenizer::NAME],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter start of function blockVar at testdata/mustache/src/Mustache/Compiler.php:150
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter start of function blockVar at testdata/mustache/src/Mustache/Compiler.php:150
                         $node[Mustache_Tokenizer::INDEX],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter end of function blockVar at testdata/mustache/src/Mustache/Compiler.php:151
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter end of function blockVar at testdata/mustache/src/Mustache/Compiler.php:151
                         $node[Mustache_Tokenizer::END],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter otag of function blockVar at testdata/mustache/src/Mustache/Compiler.php:152
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter otag of function blockVar at testdata/mustache/src/Mustache/Compiler.php:152
                         $node[Mustache_Tokenizer::OTAG],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter ctag of function blockVar at testdata/mustache/src/Mustache/Compiler.php:153
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter ctag of function blockVar at testdata/mustache/src/Mustache/Compiler.php:153
                         $node[Mustache_Tokenizer::CTAG],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter id of function variable at testdata/mustache/src/Mustache/Compiler.php:165
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter id of function variable at testdata/mustache/src/Mustache/Compiler.php:165
                         $node[Mustache_Tokenizer::NAME],
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 MAYBE   ternarySimplify: Could rewrite as `$node[Mustache_Tokenizer::FILTERS] ?? array()` at testdata/mustache/src/Mustache/Compiler.php:166
                         isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter text of function text at testdata/mustache/src/Mustache/Compiler.php:173
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter text of function text at testdata/mustache/src/Mustache/Compiler.php:173
                     $code .= $this->text($node[Mustache_Tokenizer::VALUE], $level);
                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 WARNING unused: Variable $keystr is unused (use $_ to ignore this inspection or specify --unused-var-regex flag) at testdata/mustache/src/Mustache/Compiler.php:289
         $keystr = var_export($key, true);
         ^^^^^^^
-WARNING notNullSafety: not null safety call in function getFindMethod signature of param id at testdata/mustache/src/Mustache/Compiler.php:556
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function getFindMethod signature of param id at testdata/mustache/src/Mustache/Compiler.php:556
         $method   = $this->getFindMethod($name);
                                          ^^^^^
 MAYBE   callSimplify: Could simplify to $id[0] at testdata/mustache/src/Mustache/Compiler.php:646
@@ -187,16 +187,16 @@ MAYBE   callSimplify: Could simplify to $this->stack[] = $value at testdata/must
 MAYBE   callSimplify: Could simplify to $this->blockStack[] = $value at testdata/mustache/src/Mustache/Context.php:49
         array_push($this->blockStack, $value);
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function findVariableInStack signature of param id at testdata/mustache/src/Mustache/Context.php:131
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function findVariableInStack signature of param id at testdata/mustache/src/Mustache/Context.php:131
         $value  = $this->findVariableInStack($first, $this->stack);
                                              ^^^^^^
-WARNING notNullSafety: not null safety call in function findVariableInStack signature of param id at testdata/mustache/src/Mustache/Context.php:138
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function findVariableInStack signature of param id at testdata/mustache/src/Mustache/Context.php:138
             $value = $this->findVariableInStack($chunk, array($value));
                                                 ^^^^^^
-WARNING notNullSafety: not null safety call in function findVariableInStack signature of param id at testdata/mustache/src/Mustache/Context.php:174
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function findVariableInStack signature of param id at testdata/mustache/src/Mustache/Context.php:174
             $value = $this->findVariableInStack($chunk, array($value));
                                                 ^^^^^^
-WARNING notNullSafety: not null safety call in function method_exists signature of param object_or_class at testdata/mustache/src/Mustache/Context.php:218
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function method_exists signature of param object_or_class at testdata/mustache/src/Mustache/Context.php:218
                         if (method_exists($frame, $id)) {
                                           ^^^^^^
 WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condition values at testdata/mustache/src/Mustache/Context.php:213
@@ -205,13 +205,13 @@ WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condit
 MAYBE   ternarySimplify: Could rewrite as `$options['cache_file_mode'] ?? null` at testdata/mustache/src/Mustache/Engine.php:156
                 $mode  = isset($options['cache_file_mode']) ? $options['cache_file_mode'] : null;
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function setCache signature of param cache at testdata/mustache/src/Mustache/Engine.php:160
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function setCache signature of param cache at testdata/mustache/src/Mustache/Engine.php:160
             $this->setCache($cache);
                             ^^^^^^
-WARNING notNullSafety: potential null array access in parameter loader of function setLoader at testdata/mustache/src/Mustache/Engine.php:168
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter loader of function setLoader at testdata/mustache/src/Mustache/Engine.php:168
             $this->setLoader($options['loader']);
                              ^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter partialsLoader of function setPartialsLoader at testdata/mustache/src/Mustache/Engine.php:172
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter partialsLoader of function setPartialsLoader at testdata/mustache/src/Mustache/Engine.php:172
             $this->setPartialsLoader($options['partials_loader']);
                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 MAYBE   misspellComment: "entitity" is a misspelling of "entity" at testdata/mustache/src/Mustache/Engine.php:254
@@ -238,10 +238,10 @@ ERROR   undefinedMethod: Call to undefined method {\Mustache_Cache}->setLogger()
 MAYBE   ternarySimplify: Could rewrite as `$this->delimiters ?: '{{ }}'` at testdata/mustache/src/Mustache/Engine.php:628
             'delimiters'      => $this->delimiters ? $this->delimiters : '{{ }}',
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null dereference when accessing property 'charset' at testdata/mustache/src/Mustache/Engine.php:813
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'charset' at testdata/mustache/src/Mustache/Engine.php:813
         return $compiler->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags);
                                                                                ^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null dereference when accessing property 'strictCallables' at testdata/mustache/src/Mustache/Engine.php:813
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'strictCallables' at testdata/mustache/src/Mustache/Engine.php:813
         return $compiler->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags);
                                                                                                ^^^^^^^^^^^^^^^^^^^^^^
 WARNING notExplicitNullableParam: parameter with null default value should be explicitly nullable at testdata/mustache/src/Mustache/Engine.php:727
@@ -268,46 +268,46 @@ MAYBE   missingPhpdoc: Missing PHPDoc for \Mustache_Exception_UnknownTemplateExc
 WARNING notExplicitNullableParam: parameter with null default value should be explicitly nullable at testdata/mustache/src/Mustache/Exception/UnknownTemplateException.php:23
     public function __construct($templateName, Exception $previous = null)
                                                ^^^^^^^^^
-WARNING notNullSafety: not null safety call in function addLoader signature of param loader at testdata/mustache/src/Mustache/Loader/CascadingLoader.php:35
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function addLoader signature of param loader at testdata/mustache/src/Mustache/Loader/CascadingLoader.php:35
             $this->addLoader($loader);
                              ^^^^^^^
-WARNING notNullSafety: potential null array access in parameter string of function ltrim at testdata/mustache/src/Mustache/Loader/FilesystemLoader.php:64
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function ltrim at testdata/mustache/src/Mustache/Loader/FilesystemLoader.php:64
                 $this->extension = '.' . ltrim($options['extension'], '.');
                                                ^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: null passed to non-nullable parameter context in function file_get_contents at testdata/mustache/src/Mustache/Loader/InlineLoader.php:114
+WARNING notNullSafetyFunctionArgumentConstFetch: null passed to non-nullable parameter context in function file_get_contents at testdata/mustache/src/Mustache/Loader/InlineLoader.php:114
             $data = file_get_contents($this->fileName, false, null, $this->offset);
                                                               ^^^^
 WARNING regexpVet: '\w' intersects with '\d' in [\w\d\.] at testdata/mustache/src/Mustache/Loader/InlineLoader.php:115
             foreach (preg_split("/^@@(?= [\w\d\.]+$)/m", $data, -1) as $chunk) {
                                 ^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null dereference when accessing property 'stream' at testdata/mustache/src/Mustache/Logger/StreamLogger.php:61
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'stream' at testdata/mustache/src/Mustache/Logger/StreamLogger.php:61
             fclose($this->stream);
                    ^^^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function array_key_exists signature of param key at testdata/mustache/src/Mustache/Logger/StreamLogger.php:102
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function array_key_exists signature of param key at testdata/mustache/src/Mustache/Logger/StreamLogger.php:102
         if (!array_key_exists($level, self::$levels)) {
                               ^^^^^^
-WARNING notNullSafety: not null safety call in function writeLog signature of param level at testdata/mustache/src/Mustache/Logger/StreamLogger.php:107
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function writeLog signature of param level at testdata/mustache/src/Mustache/Logger/StreamLogger.php:107
             $this->writeLog($level, $message, $context);
                             ^^^^^^
-WARNING notNullSafety: potential null dereference when accessing property 'url' at testdata/mustache/src/Mustache/Logger/StreamLogger.php:128
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'url' at testdata/mustache/src/Mustache/Logger/StreamLogger.php:128
             $this->stream = fopen($this->url, 'a');
                                   ^^^^^^^^^^
-WARNING notNullSafety: potential null dereference when accessing property 'stream' at testdata/mustache/src/Mustache/Logger/StreamLogger.php:136
+WARNING notNullSafetyFunctionArgumentPropertyFetch: potential null dereference when accessing property 'stream' at testdata/mustache/src/Mustache/Logger/StreamLogger.php:136
         fwrite($this->stream, self::formatLine($level, $message, $context));
                ^^^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function enablePragma signature of param name at testdata/mustache/src/Mustache/Parser.php:58
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function enablePragma signature of param name at testdata/mustache/src/Mustache/Parser.php:58
             $this->enablePragma($pragma);
                                 ^^^^^^^
-WARNING notNullSafety: potential null array access in parameter name of function getNameAndFilters at testdata/mustache/src/Mustache/Parser.php:88
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter name of function getNameAndFilters at testdata/mustache/src/Mustache/Parser.php:88
                 list($name, $filters) = $this->getNameAndFilters($token[Mustache_Tokenizer::NAME]);
                                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter name of function enablePragma at testdata/mustache/src/Mustache/Parser.php:167
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter name of function enablePragma at testdata/mustache/src/Mustache/Parser.php:167
                     $this->enablePragma($token[Mustache_Tokenizer::NAME]);
                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter string of function substr at testdata/mustache/src/Mustache/Parser.php:235
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function substr at testdata/mustache/src/Mustache/Parser.php:235
                 if (substr($next[Mustache_Tokenizer::VALUE], -1) !== "\n") {
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: potential null array access in parameter subject of function preg_match at testdata/mustache/src/Mustache/Parser.php:262
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/mustache/src/Mustache/Parser.php:262
             return preg_match('/^\s*$/', $token[Mustache_Tokenizer::VALUE]);
                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condition values at testdata/mustache/src/Mustache/Parser.php:307
@@ -322,15 +322,15 @@ WARNING errorSilence: Don't use @, silencing errors is bad practice at testdata/
 WARNING unused: Variable $v is unused (use $_ to ignore this inspection or specify --unused-var-regex flag) at testdata/mustache/src/Mustache/Template.php:122
                 foreach ($value as $k => $v) {
                                          ^^
-WARNING notNullSafety: not null safety call in function call_user_func signature of param callback at testdata/mustache/src/Mustache/Template.php:174
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func signature of param callback at testdata/mustache/src/Mustache/Template.php:174
                 ->loadLambda((string) call_user_func($value))
                                                      ^^^^^^
-WARNING notNullSafety: not null safety call in function trim signature of param string at testdata/mustache/src/Mustache/Tokenizer.php:110
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function trim signature of param string at testdata/mustache/src/Mustache/Tokenizer.php:110
         if ($delimiters = trim($delimiters)) {
                                ^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/mustache/src/Mustache/Tokenizer.php:188
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/mustache/src/Mustache/Tokenizer.php:188
                                 if (substr($lastName, -1) === '}') {
                                            ^^^^^^^^^
-WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/mustache/src/Mustache/Tokenizer.php:189
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/mustache/src/Mustache/Tokenizer.php:189
                                     $token[self::NAME] = trim(substr($lastName, 0, -1));
                                                                      ^^^^^^^^^
diff --git a/src/tests/golden/testdata/options-resolver/golden.txt b/src/tests/golden/testdata/options-resolver/golden.txt
index be7cbc6..87db7f2 100644
--- a/src/tests/golden/testdata/options-resolver/golden.txt
+++ b/src/tests/golden/testdata/options-resolver/golden.txt
@@ -1,3 +1,12 @@
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function isDefined signature of param option at testdata/options-resolver/Debug/OptionsResolverIntrospector.php:31
+            if (!$this->isDefined($option)) {
+                                  ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function isDefined signature of param option at testdata/options-resolver/Debug/OptionsResolverIntrospector.php:31
+            if (!$this->isDefined($option)) {
+                                  ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function array_key_exists signature of param key at testdata/options-resolver/Debug/OptionsResolverIntrospector.php:35
+            if (!\array_key_exists($option, $this->{$property})) {
+                                   ^^^^^^^
 MAYBE   typeHint: Specify the return type for the function getNormalizers in PHPDoc, 'array' type hint too generic at testdata/options-resolver/Debug/OptionsResolverIntrospector.php:94
     public function getNormalizers(string $option): array
                     ^^^^^^^^^^^^^^
@@ -34,9 +43,18 @@ WARNING invalidDocblock: @param for non-existing argument $message at testdata/o
 MAYBE   complexity: Too big method: more than 150 lines at testdata/options-resolver/OptionsResolver.php:917
     public function offsetGet($option, bool $triggerDeprecation = true)
                     ^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function verifyTypes signature of param value at testdata/options-resolver/OptionsResolver.php:1000
+                if ($valid = $this->verifyTypes($type, $value, $invalidTypes)) {
+                                                       ^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function verifyTypes signature of param value at testdata/options-resolver/OptionsResolver.php:1000
+                if ($valid = $this->verifyTypes($type, $value, $invalidTypes)) {
+                                                       ^^^^^^
 MAYBE   typeHint: Specify the type for the parameter $invalidTypes in PHPDoc, 'array' type hint too generic at testdata/options-resolver/OptionsResolver.php:1123
     private function verifyTypes(string $type, $value, array &$invalidTypes, int $level = 0): bool
                      ^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function get_class signature of param object at testdata/options-resolver/OptionsResolver.php:1221
+            return \get_class($value);
+                              ^^^^^^
 MAYBE   typeHint: Specify the type for the parameter $values in PHPDoc, 'array' type hint too generic at testdata/options-resolver/OptionsResolver.php:1259
     private function formatValues(array $values): string
                      ^^^^^^^^^^^^
diff --git a/src/tests/golden/testdata/parsedown/golden.txt b/src/tests/golden/testdata/parsedown/golden.txt
index 5a07900..0287d63 100644
--- a/src/tests/golden/testdata/parsedown/golden.txt
+++ b/src/tests/golden/testdata/parsedown/golden.txt
@@ -22,18 +22,87 @@ MAYBE   typeHint: Specify the type for the parameter $lines in PHPDoc, 'array' t
 MAYBE   typeHint: Specify the type for the parameter $lines in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:167
     protected function linesElements(array $lines)
                        ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function chop signature of param string at testdata/parsedown/parsedown.php:174
+            if (chop($line) === '')
+                     ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function strstr signature of param haystack at testdata/parsedown/parsedown.php:186
+            while (($beforeTab = strstr($line, "\t", true)) !== false)
+                                        ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/parsedown/parsedown.php:192
+                    . substr($line, strlen($beforeTab) + 1)
+                             ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function strspn signature of param string at testdata/parsedown/parsedown.php:196
+            $indent = strspn($line, ' ');
+                             ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/parsedown/parsedown.php:198
+            $text = $indent > 0 ? substr($line, $indent) : $line;
+                                         ^^^^^
 MAYBE   typeHint: Specify the type for the parameter $Component in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:319
     protected function extractElement(array $Component)
                        ^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function substr at testdata/parsedown/parsedown.php:358
+            $text = substr($Line['body'], 4);
+                           ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter times of function str_repeat at testdata/parsedown/parsedown.php:380
+                $Block['element']['element']['text'] .= str_repeat("\n", $Block['interrupted']);
+                                                                         ^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function substr at testdata/parsedown/parsedown.php:387
+            $text = substr($Line['body'], 4);
+                           ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter haystack of function strpos at testdata/parsedown/parsedown.php:410
+        if (strpos($Line['text'], '<!--') === 0)
+                   ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter haystack of function strpos at testdata/parsedown/parsedown.php:419
+            if (strpos($Line['text'], '-->') !== false)
+                       ^^^^^^^^^^^^^
 MAYBE   typeHint: Specify the type for the parameter $Block in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:428
     protected function blockCommentContinue($Line, array $Block)
                        ^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter haystack of function strpos at testdata/parsedown/parsedown.php:437
+        if (strpos($Line['text'], '-->') !== false)
+                   ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function strspn at testdata/parsedown/parsedown.php:452
+        $openerLength = strspn($Line['text'], $marker);
+                               ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function strspn signature of param characters at testdata/parsedown/parsedown.php:452
+        $openerLength = strspn($Line['text'], $marker);
+                                              ^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function substr at testdata/parsedown/parsedown.php:459
+        $infostring = trim(substr($Line['text'], $openerLength), "\t ");
+                                  ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter times of function str_repeat at testdata/parsedown/parsedown.php:511
+            $Block['element']['element']['text'] .= str_repeat("\n", $Block['interrupted']);
+                                                                     ^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function strspn at testdata/parsedown/parsedown.php:516
+        if (($len = strspn($Line['text'], $Block['char'])) >= $Block['openerLength']
+                           ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter characters of function strspn at testdata/parsedown/parsedown.php:516
+        if (($len = strspn($Line['text'], $Block['char'])) >= $Block['openerLength']
+                                          ^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function strspn at testdata/parsedown/parsedown.php:516
+        if (($len = strspn($Line['text'], $Block['char'])) >= $Block['openerLength']
+                           ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter characters of function strspn at testdata/parsedown/parsedown.php:516
+        if (($len = strspn($Line['text'], $Block['char'])) >= $Block['openerLength']
+                                          ^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function substr at testdata/parsedown/parsedown.php:517
+            and chop(substr($Line['text'], $len), ' ') === ''
+                            ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function strspn at testdata/parsedown/parsedown.php:541
+        $level = strspn($Line['text'], '#');
+                        ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function trim at testdata/parsedown/parsedown.php:548
+        $text = trim($Line['text'], '#');
+                     ^^^^^^^^^^^^^
 MAYBE   trailingComma: Last element in a multi-line array should have a trailing comma at testdata/parsedown/parsedown.php:560
                 'handler' => array(
                 ^
 MAYBE   typeHint: Specify the type for the parameter $CurrentBlock in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:574
     protected function blockList($Line, array $CurrentBlock = null)
                        ^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:578
+        if (preg_match('/^('.$pattern.'([ ]++|$))(.*+)/', $Line['text'], $matches))
+                                                          ^^^^^^^^^^^^^
 MAYBE   trailingComma: Last element in a multi-line array should have a trailing comma at testdata/parsedown/parsedown.php:633
                     'destination' => 'elements'
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -43,6 +112,12 @@ MAYBE   trailingComma: Last element in a multi-line array should have a trailing
 MAYBE   typeHint: Specify the type for the parameter $Block in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:643
     protected function blockListContinue($Line, array $Block)
                        ^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:656
+                    and preg_match('/^[0-9]++'.$Block['data']['markerTypeRegex'].'(?:[ ]++(.*)|$)/', $Line['text'], $matches)
+                                                                                                     ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:659
+                    and preg_match('/^'.$Block['data']['markerTypeRegex'].'(?:[ ]++(.*)|$)/', $Line['text'], $matches)
+                                                                                              ^^^^^^^^^^^^^
 MAYBE   ternarySimplify: Could rewrite as `$matches[1] ?? ''` at testdata/parsedown/parsedown.php:674
             $text = isset($matches[1]) ? $matches[1] : '';
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -52,9 +127,15 @@ MAYBE   trailingComma: Last element in a multi-line array should have a trailing
 MAYBE   trailingComma: Last element in a multi-line array should have a trailing comma at testdata/parsedown/parsedown.php:680
                 'handler' => array(
                 ^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function substr at testdata/parsedown/parsedown.php:712
+            $text = substr($Line['body'], $requiredIndent);
+                           ^^^^^^^^^^^^^
 MAYBE   typeHint: Specify the type for the parameter $Block in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:729
     protected function blockListComplete(array $Block)
                        ^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:750
+        if (preg_match('/^>[ ]?+(.*+)/', $Line['text'], $matches))
+                                         ^^^^^^^^^^^^^
 MAYBE   regexpSimplify: May re-write '/^>[ ]?+(.*+)/' as '/^> ?+(.*+)/' at testdata/parsedown/parsedown.php:750
         if (preg_match('/^>[ ]?+(.*+)/', $Line['text'], $matches))
                        ^^^^^^^^^^^^^^^^
@@ -64,18 +145,42 @@ MAYBE   trailingComma: Last element in a multi-line array should have a trailing
 MAYBE   typeHint: Specify the type for the parameter $Block in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:767
     protected function blockQuoteContinue($Line, array $Block)
                        ^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:774
+        if ($Line['text'][0] === '>' and preg_match('/^>[ ]?+(.*+)/', $Line['text'], $matches))
+                                                                      ^^^^^^^^^^^^^
 MAYBE   regexpSimplify: May re-write '/^>[ ]?+(.*+)/' as '/^> ?+(.*+)/' at testdata/parsedown/parsedown.php:774
         if ($Line['text'][0] === '>' and preg_match('/^>[ ]?+(.*+)/', $Line['text'], $matches))
                                                     ^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter haystack of function substr_count at testdata/parsedown/parsedown.php:796
+        if (substr_count($Line['text'], $marker) >= 3 and chop($Line['text'], " $marker") === '')
+                         ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr_count signature of param needle at testdata/parsedown/parsedown.php:796
+        if (substr_count($Line['text'], $marker) >= 3 and chop($Line['text'], " $marker") === '')
+                                        ^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function chop at testdata/parsedown/parsedown.php:796
+        if (substr_count($Line['text'], $marker) >= 3 and chop($Line['text'], " $marker") === '')
+                                                               ^^^^^^^^^^^^^
 MAYBE   typeHint: Specify the type for the parameter $Block in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:811
     protected function blockSetextHeader($Line, array $Block = null)
                        ^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function chop at testdata/parsedown/parsedown.php:818
+        if ($Line['indent'] < 4 and chop(chop($Line['text'], ' '), $Line['text'][0]) === '')
+                                              ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:836
+        if (preg_match('/^<[\/]?+(\w*)(?:[ ]*+'.$this->regexHtmlAttribute.')*+[ ]*+(\/)?>/', $Line['text'], $matches))
+                                                                                             ^^^^^^^^^^^^^
 WARNING strictCmp: 3rd argument of in_array must be true when comparing strings at testdata/parsedown/parsedown.php:840
             if (in_array($element, $this->textLevelElements))
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 MAYBE   typeHint: Specify the type for the parameter $Block in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:857
     protected function blockMarkupContinue($Line, array $Block)
                        ^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter haystack of function strpos at testdata/parsedown/parsedown.php:874
+        if (strpos($Line['text'], ']') !== false
+                   ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:875
+            and preg_match('/^\[(.+?)\]:[ ]*+<?(\S+?)>?(?:[ ]+["\'(](.+)["\')])?[ ]*+$/', $Line['text'], $matches)
+                                                                                          ^^^^^^^^^^^^^
 MAYBE   regexpSimplify: May re-write '/^\[(.+?)\]:[ ]*+<?(\S+?)>?(?:[ ]+["\'(](.+)["\')])?[ ]*+$/' as '/^\[(.+?)\]: *+<?(\S+?)>?(?: +["'(](.+)["')])? *+$/' at testdata/parsedown/parsedown.php:875
             and preg_match('/^\[(.+?)\]:[ ]*+<?(\S+?)>?(?:[ ]+["\'(](.+)["\')])?[ ]*+$/', $Line['text'], $matches)
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -85,39 +190,135 @@ MAYBE   ternarySimplify: Could rewrite as `$matches[3] ?? null` at testdata/pars
 MAYBE   typeHint: Specify the type for the parameter $Block in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:897
     protected function blockTable($Line, array $Block = null)
                        ^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter haystack of function strpos at testdata/parsedown/parsedown.php:906
+            and strpos($Line['text'], '|') === false
+                       ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter haystack of function strpos at testdata/parsedown/parsedown.php:907
+            and strpos($Line['text'], ':') === false
+                       ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function chop at testdata/parsedown/parsedown.php:913
+        if (chop($Line['text'], ' -:|') !== '')
+                 ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function trim signature of param string at testdata/parsedown/parsedown.php:922
+        $divider = trim($divider);
+                        ^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function trim signature of param string at testdata/parsedown/parsedown.php:957
+        $header = trim($header);
+                       ^^^^^^^
 MAYBE   trailingComma: Last element in a multi-line array should have a trailing comma at testdata/parsedown/parsedown.php:973
                 'handler' => array(
                 ^
 MAYBE   typeHint: Specify the type for the parameter $Block in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:1020
     protected function blockTableContinue($Line, array $Block)
                        ^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter haystack of function strpos at testdata/parsedown/parsedown.php:1027
+        if (count($Block['alignments']) === 1 or $Line['text'][0] === '|' or strpos($Line['text'], '|'))
+                                                                                    ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function trim signature of param string at testdata/parsedown/parsedown.php:1033
+            $row = trim($row);
+                        ^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function trim signature of param string at testdata/parsedown/parsedown.php:1042
+                $cell = trim($cell);
+                             ^^^^^
 MAYBE   trailingComma: Last element in a multi-line array should have a trailing comma at testdata/parsedown/parsedown.php:1046
                     'handler' => array(
                     ^
 MAYBE   typeHint: Specify the type for the parameter $Block in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:1093
     protected function paragraphContinue($Line, array $Block)
                        ^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function strlen signature of param string at testdata/parsedown/parsedown.php:1242
+            'extent' => strlen($text),
+                               ^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:1262
+        if (preg_match('/^(['.$marker.']++)[ ]*+(.+?)[ ]*+(?<!['.$marker.'])\1(?!'.$marker.')/s', $Excerpt['text'], $matches))
+                                                                                                  ^^^^^^^^^^^^^^^^
 MAYBE   regexpSimplify: May re-write '/[ ]*+\n/' as '/ *+\n/' at testdata/parsedown/parsedown.php:1265
             $text = preg_replace('/[ ]*+\n/', ' ', $text);
                                  ^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter haystack of function strpos at testdata/parsedown/parsedown.php:1284
+        if (strpos($Excerpt['text'], '>') !== false
+                   ^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:1285
+            and preg_match("/^<((mailto:)?$commonMarkEmail)>/i", $Excerpt['text'], $matches)
+                                                                 ^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:1316
+        if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches))
+                                                                                        ^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:1320
+        elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches))
+                                                    ^^^^^^^^^^^^^^^^
 MAYBE   trailingComma: Last element in a multi-line array should have a trailing comma at testdata/parsedown/parsedown.php:1333
                 'handler' => array(
                 ^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function substr at testdata/parsedown/parsedown.php:1360
+        $Excerpt['text']= substr($Excerpt['text'], 1);
+                                 ^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function preg_match signature of param subject at testdata/parsedown/parsedown.php:1408
+        if (preg_match('/\[((?:[^][]++|(?R))*+)\]/', $remainder, $matches))
+                                                     ^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/parsedown/parsedown.php:1414
+            $remainder = substr($remainder, $extent);
+                                ^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function preg_match signature of param subject at testdata/parsedown/parsedown.php:1421
+        if (preg_match('/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?:[ ]+("[^"]*+"|\'[^\']*+\'))?\s*+[)]/', $remainder, $matches))
+                                                                                                        ^^^^^^^^^^
 MAYBE   regexpSimplify: May re-write '/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?:[ ]+("[^"]*+"|\'[^\']*+\'))?\s*+[)]/' as '/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?: +("[^"]*+"|'[^']*+'))?\s*+[)]/' at testdata/parsedown/parsedown.php:1421
         if (preg_match('/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?:[ ]+("[^"]*+"|\'[^\']*+\'))?\s*+[)]/', $remainder, $matches))
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function preg_match signature of param subject at testdata/parsedown/parsedown.php:1434
+            if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches))
+                                              ^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function strtolower signature of param string at testdata/parsedown/parsedown.php:1437
+                $definition = strtolower($definition);
+                                         ^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter haystack of function strpos at testdata/parsedown/parsedown.php:1465
+        if ($this->markupEscaped or $this->safeMode or strpos($Excerpt['text'], '>') === false)
+                                                              ^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:1470
+        if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w[\w-]*+[ ]*+>/s', $Excerpt['text'], $matches))
+                                                                                 ^^^^^^^^^^^^^^^^
 MAYBE   regexpSimplify: May re-write '/^<\/\w[\w-]*+[ ]*+>/s' as '/^<\/\w[\w-]*+ *+>/s' at testdata/parsedown/parsedown.php:1470
         if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w[\w-]*+[ ]*+>/s', $Excerpt['text'], $matches))
                                                        ^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:1478
+        if ($Excerpt['text'][1] === '!' and preg_match('/^<!---?[^>-](?:-?+[^-])*-->/s', $Excerpt['text'], $matches))
+                                                                                         ^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:1486
+        if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w[\w-]*+(?:[ ]*+'.$this->regexHtmlAttribute.')*+[ ]*+\/?>/s', $Excerpt['text'], $matches))
+                                                                                                                          ^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function substr at testdata/parsedown/parsedown.php:1497
+        if (substr($Excerpt['text'], 1, 1) !== ' ' and strpos($Excerpt['text'], ';') !== false
+                   ^^^^^^^^^^^^^^^^
 MAYBE   callSimplify: Could simplify to $Excerpt['text'][1] at testdata/parsedown/parsedown.php:1497
         if (substr($Excerpt['text'], 1, 1) !== ' ' and strpos($Excerpt['text'], ';') !== false
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter haystack of function strpos at testdata/parsedown/parsedown.php:1497
+        if (substr($Excerpt['text'], 1, 1) !== ' ' and strpos($Excerpt['text'], ';') !== false
+                                                              ^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:1498
+            and preg_match('/^&(#?+[0-9a-zA-Z]++);/', $Excerpt['text'], $matches)
+                                                      ^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:1516
+        if ($Excerpt['text'][1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches))
+                                                                                    ^^^^^^^^^^^^^^^^
 MAYBE   trailingComma: Last element in a multi-line array should have a trailing comma at testdata/parsedown/parsedown.php:1522
                     'handler' => array(
                     ^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter haystack of function strpos at testdata/parsedown/parsedown.php:1539
+        if (strpos($Excerpt['context'], 'http') !== false
+                   ^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:1540
+            and preg_match('/\bhttps?+:[\/]{2}[^\s<]+\b\/*+/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE)
+                                                                 ^^^^^^^^^^^^^^^^^^^
 MAYBE   regexpSimplify: May re-write '/\bhttps?+:[\/]{2}[^\s<]+\b\/*+/ui' as '~\bhttps?+:/{2}[^\s<]+\b/*+~ui' at testdata/parsedown/parsedown.php:1540
             and preg_match('/\bhttps?+:[\/]{2}[^\s<]+\b\/*+/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE)
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter haystack of function strpos at testdata/parsedown/parsedown.php:1562
+        if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w++:\/{2}[^ >]++)>/i', $Excerpt['text'], $matches))
+                   ^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter subject of function preg_match at testdata/parsedown/parsedown.php:1562
+        if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w++:\/{2}[^ >]++)>/i', $Excerpt['text'], $matches))
+                                                                                                ^^^^^^^^^^^^^^^^
 MAYBE   typeHint: Specify the type for the parameter $Element in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:1591
     protected function handle(array $Element)
                        ^^^^^^
@@ -130,9 +331,15 @@ MAYBE   typeHint: Specify the type for the parameter $Elements in PHPDoc, 'array
 MAYBE   typeHint: Specify the type for the parameter $Element in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:1637
     protected function elementApplyRecursive($closure, array $Element)
                        ^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func signature of param callback at testdata/parsedown/parsedown.php:1639
+        $Element = call_user_func($closure, $Element);
+                                  ^^^^^^^^
 MAYBE   typeHint: Specify the type for the parameter $Element in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:1653
     protected function elementApplyRecursiveDepthFirst($closure, array $Element)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func signature of param callback at testdata/parsedown/parsedown.php:1664
+        $Element = call_user_func($closure, $Element);
+                                  ^^^^^^^^
 MAYBE   typeHint: Specify the type for the parameter $Elements in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:1669
     protected function elementsApplyRecursive($closure, array $Elements)
                        ^^^^^^^^^^^^^^^^^^^^^^
@@ -157,6 +364,18 @@ MAYBE   ternarySimplify: Could rewrite as `$Element['autobreak'] ?? isset($Eleme
 WARNING strictCmp: 3rd argument of in_array must be true when comparing strings at testdata/parsedown/parsedown.php:1807
         if ( ! in_array('', $lines)
                ^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function preg_match signature of param pattern at testdata/parsedown/parsedown.php:1829
+        while (preg_match($regexp, $text, $matches, PREG_OFFSET_CAPTURE))
+                          ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function preg_match signature of param subject at testdata/parsedown/parsedown.php:1829
+        while (preg_match($regexp, $text, $matches, PREG_OFFSET_CAPTURE))
+                                   ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/parsedown/parsedown.php:1832
+            $before = substr($text, 0, $offset);
+                             ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/parsedown/parsedown.php:1833
+            $after = substr($text, $offset + strlen($matches[0][0]));
+                            ^^^^^
 MAYBE   implicitModifiers: Specify the access modifier for \Parsedown::parse method explicitly at testdata/parsedown/parsedown.php:1854
     function parse($text)
              ^^^^^
@@ -169,6 +388,21 @@ WARNING unused: Variable $val is unused (use $_ to ignore this inspection or spe
 MAYBE   typeHint: Specify the type for the parameter $Element in PHPDoc, 'array' type hint too generic at testdata/parsedown/parsedown.php:1900
     protected function filterUnsafeUrlInAttribute(array $Element, $attribute)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function htmlspecialchars signature of param string at testdata/parsedown/parsedown.php:1921
+        return htmlspecialchars($text, $allowQuotes ? ENT_NOQUOTES : ENT_QUOTES, 'UTF-8');
+                                ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function strlen signature of param string at testdata/parsedown/parsedown.php:1926
+        $len = strlen($needle);
+                      ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function strlen signature of param string at testdata/parsedown/parsedown.php:1928
+        if ($len > strlen($string))
+                          ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/parsedown/parsedown.php:1934
+            return strtolower(substr($string, 0, $len)) === strtolower($needle);
+                                     ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function strtolower signature of param string at testdata/parsedown/parsedown.php:1934
+            return strtolower(substr($string, 0, $len)) === strtolower($needle);
+                                                                       ^^^^^^^
 MAYBE   implicitModifiers: Specify the access modifier for \Parsedown::instance method explicitly at testdata/parsedown/parsedown.php:1938
     static function instance($name = 'default')
                     ^^^^^^^^
diff --git a/src/tests/golden/testdata/phprocksyd/golden.txt b/src/tests/golden/testdata/phprocksyd/golden.txt
index 0cbf272..9439964 100644
--- a/src/tests/golden/testdata/phprocksyd/golden.txt
+++ b/src/tests/golden/testdata/phprocksyd/golden.txt
@@ -28,12 +28,36 @@ WARNING useExitOrDie: Don't use the 'exit' function at testdata/phprocksyd/Phpro
 WARNING useExitOrDie: Don't use the 'exit' function at testdata/phprocksyd/Phprocksyd.php:129
                 exit(1);
                 ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function stream_socket_accept signature of param socket at testdata/phprocksyd/Phprocksyd.php:200
+        $client = stream_socket_accept($server, self::ACCEPT_TIMEOUT, $peername);
+                                       ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function pcntl_wait signature of param status at testdata/phprocksyd/Phprocksyd.php:231
+            $pid = pcntl_wait($status, WNOHANG);
+                              ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function pcntl_wexitstatus signature of param status at testdata/phprocksyd/Phprocksyd.php:241
+                    $Res->retcode = pcntl_wexitstatus($status);
+                                                      ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function rtrim signature of param string at testdata/phprocksyd/Phprocksyd.php:272
+            $req = rtrim($req);
+                         ^^^^
 ERROR   constCase: Constant 'NULL' should be used in lower case as 'null' at testdata/phprocksyd/Phprocksyd.php:321
             $n = stream_select($read, $write, $except, NULL);
                                                        ^^^^
 WARNING useExitOrDie: Don't use the 'exit' function at testdata/phprocksyd/Phprocksyd.php:325
                 exit(1);
                 ^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter character of function ord at testdata/phprocksyd/Phprocksyd.php:360
+        return ord($buf[0]) << 24 | ord($buf[1]) << 16 | ord($buf[2]) << 8 | ord($buf[3]);
+                   ^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter character of function ord at testdata/phprocksyd/Phprocksyd.php:360
+        return ord($buf[0]) << 24 | ord($buf[1]) << 16 | ord($buf[2]) << 8 | ord($buf[3]);
+                                        ^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter character of function ord at testdata/phprocksyd/Phprocksyd.php:360
+        return ord($buf[0]) << 24 | ord($buf[1]) << 16 | ord($buf[2]) << 8 | ord($buf[3]);
+                                                             ^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter character of function ord at testdata/phprocksyd/Phprocksyd.php:360
+        return ord($buf[0]) << 24 | ord($buf[1]) << 16 | ord($buf[2]) << 8 | ord($buf[3]);
+                                                                                 ^^^^^^^
 WARNING invalidDocblock: Malformed @param $stream_id tag (maybe type is missing?) at testdata/phprocksyd/Phprocksyd.php:364
      * @param $stream_id
               ^^^^^^^^^^
@@ -67,6 +91,9 @@ WARNING useExitOrDie: Don't use the 'exit' function at testdata/phprocksyd/Phpro
 ERROR   undefinedMethod: Call to undefined method {mixed}->run() at testdata/phprocksyd/Phprocksyd.php:479
                 $instance->run($req['params']);
                            ^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function stream_get_meta_data signature of param stream at testdata/phprocksyd/Phprocksyd.php:522
+                $meta = stream_get_meta_data($v);
+                                             ^^
 WARNING useExitOrDie: Don't use the 'exit' function at testdata/phprocksyd/Phprocksyd.php:557
                         exit(1);
                         ^^^^^^^
@@ -82,6 +109,12 @@ WARNING useExitOrDie: Don't use the 'exit' function at testdata/phprocksyd/Phpro
 WARNING useExitOrDie: Don't use the 'exit' function at testdata/phprocksyd/Simple.php:38
             exit(1);
             ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function stream_socket_accept signature of param socket at testdata/phprocksyd/Simple.php:65
+        $client = stream_socket_accept($server, 1, $peername);
+                                       ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function rtrim signature of param string at testdata/phprocksyd/Simple.php:116
+            $res = json_decode(rtrim($req), true);
+                                     ^^^^
 ERROR   constCase: Constant 'NULL' should be used in lower case as 'null' at testdata/phprocksyd/Simple.php:158
             $n = stream_select($read, $write, $except, NULL);
                                                        ^^^^
diff --git a/src/tests/golden/testdata/qrcode/golden.txt b/src/tests/golden/testdata/qrcode/golden.txt
index e201c4c..3fb44dc 100644
--- a/src/tests/golden/testdata/qrcode/golden.txt
+++ b/src/tests/golden/testdata/qrcode/golden.txt
@@ -4,10 +4,10 @@ MAYBE   missingPhpdoc: Missing PHPDoc for \QRCode::output_image public method at
 MAYBE   missingPhpdoc: Missing PHPDoc for \QRCode::render_image public method at testdata/qrcode/qrcode.php:53
   public function render_image() {
                   ^^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function imagecreatetruecolor signature of param width at testdata/qrcode/qrcode.php:56
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function imagecreatetruecolor signature of param width at testdata/qrcode/qrcode.php:56
     $image = imagecreatetruecolor($width, $height);
                                   ^^^^^^
-WARNING notNullSafety: not null safety call in function imagecreatetruecolor signature of param height at testdata/qrcode/qrcode.php:56
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function imagecreatetruecolor signature of param height at testdata/qrcode/qrcode.php:56
     $image = imagecreatetruecolor($width, $height);
                                           ^^^^^^^
 MAYBE   ternarySimplify: Could rewrite as `$this->options['bc'] ?? 'FFFFFF'` at testdata/qrcode/qrcode.php:59
@@ -16,21 +16,24 @@ MAYBE   ternarySimplify: Could rewrite as `$this->options['bc'] ?? 'FFFFFF'` at
 MAYBE   ternarySimplify: Could rewrite as `$this->options['fc'] ?? '000000'` at testdata/qrcode/qrcode.php:63
     $fgcolor = (isset($this->options['fc']) ? $this->options['fc'] : '000000');
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function floor signature of param num at testdata/qrcode/qrcode.php:72
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function floor signature of param num at testdata/qrcode/qrcode.php:72
       $scale = (($scale > 1) ? floor($scale) : 1);
                                      ^^^^^^
-WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:134
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:134
     $r     = hexdec(substr($color, 0, 2));
                            ^^^^^^
-WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:135
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:135
     $g     = hexdec(substr($color, 2, 2));
                            ^^^^^^
-WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:136
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:136
     $b     = hexdec(substr($color, 4, 2));
                            ^^^^^^
-WARNING notNullSafety: not null safety call in function imagecolorallocate signature of param image at testdata/qrcode/qrcode.php:137
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function imagecolorallocate signature of param image at testdata/qrcode/qrcode.php:137
     return imagecolorallocate($image, $r, $g, $b);
                               ^^^^^^
+WARNING notNullSafetyFunctionArgumentFunctionCall: not null safety call in function strtolower signature of param string when calling function \preg_replace at testdata/qrcode/qrcode.php:143
+    switch (strtolower(preg_replace('/[^A-Za-z0-9]/', '', $options['s']))) {
+                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 WARNING deadCode: Unreachable code at testdata/qrcode/qrcode.php:155
     return null;
            ^^^^
@@ -40,7 +43,7 @@ MAYBE   trailingComma: Last element in a multi-line array should have a trailing
 WARNING unused: Variable $mode is unused (use $_ to ignore this inspection or specify --unused-var-regex flag) at testdata/qrcode/qrcode.php:177
     list($mode, $vers, $ec, $data) = $this->qr_encode_data($data, $ecl);
          ^^^^^
-WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:200
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:200
     $data = substr($data, 0, $max_chars);
                    ^^^^^
 WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condition values at testdata/qrcode/qrcode.php:203
@@ -49,19 +52,19 @@ WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condit
 WARNING maybeUndefined: Possibly undefined variable $code at testdata/qrcode/qrcode.php:221
     while (count($code) % 8) {
                  ^^^^^
-WARNING notNullSafety: not null safety call in function preg_match signature of param subject at testdata/qrcode/qrcode.php:268
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function preg_match signature of param subject at testdata/qrcode/qrcode.php:268
     if (preg_match($numeric, $data)) {
                              ^^^^^
-WARNING notNullSafety: not null safety call in function preg_match signature of param subject at testdata/qrcode/qrcode.php:271
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function preg_match signature of param subject at testdata/qrcode/qrcode.php:271
     if (preg_match($alphanumeric, $data)) {
                                   ^^^^^
-WARNING notNullSafety: not null safety call in function preg_match signature of param subject at testdata/qrcode/qrcode.php:274
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function preg_match signature of param subject at testdata/qrcode/qrcode.php:274
     if (preg_match($kanji, $data)) {
                            ^^^^^
-WARNING notNullSafety: not null safety call in function strlen signature of param string at testdata/qrcode/qrcode.php:281
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function strlen signature of param string at testdata/qrcode/qrcode.php:281
     $length = strlen($data);
                      ^^^^^
-WARNING notNullSafety: not null safety call in function strlen signature of param string at testdata/qrcode/qrcode.php:295
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function strlen signature of param string at testdata/qrcode/qrcode.php:295
     $length = strlen($data);
                      ^^^^^
 WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testdata/qrcode/qrcode.php:297
@@ -73,7 +76,7 @@ WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testd
 WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condition values at testdata/qrcode/qrcode.php:296
     switch ($version_group) {
     ^
-WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:316
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:316
       $group = substr($data, $i, 3);
                       ^^^^^
 WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testdata/qrcode/qrcode.php:318
@@ -85,7 +88,7 @@ WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testd
 WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condition values at testdata/qrcode/qrcode.php:317
       switch (strlen($group)) {
       ^
-WARNING notNullSafety: not null safety call in function strlen signature of param string at testdata/qrcode/qrcode.php:339
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function strlen signature of param string at testdata/qrcode/qrcode.php:339
     $length   = strlen($data);
                        ^^^^^
 WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testdata/qrcode/qrcode.php:341
@@ -97,7 +100,7 @@ WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testd
 WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condition values at testdata/qrcode/qrcode.php:340
     switch ($version_group) {
     ^
-WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:359
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:359
       $group = substr($data, $i, 2);
                       ^^^^^
 MAYBE   callSimplify: Could simplify to $group[0] at testdata/qrcode/qrcode.php:361
@@ -106,7 +109,7 @@ MAYBE   callSimplify: Could simplify to $group[0] at testdata/qrcode/qrcode.php:
 MAYBE   callSimplify: Could simplify to $group[1] at testdata/qrcode/qrcode.php:362
         $c2     = strpos($alphabet, substr($group, 1, 1));
                                     ^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function strlen signature of param string at testdata/qrcode/qrcode.php:390
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function strlen signature of param string at testdata/qrcode/qrcode.php:390
     $length = strlen($data);
                      ^^^^^
 WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testdata/qrcode/qrcode.php:393
@@ -115,13 +118,13 @@ WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testd
 WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condition values at testdata/qrcode/qrcode.php:391
     switch ($version_group) {
     ^
-WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:413
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:413
       $ch     = ord(substr($data, $i, 1));
                            ^^^^^
 MAYBE   callSimplify: Could simplify to $data[$i] at testdata/qrcode/qrcode.php:413
       $ch     = ord(substr($data, $i, 1));
                     ^^^^^^^^^^^^^^^^^^^^
-WARNING notNullSafety: not null safety call in function strlen signature of param string at testdata/qrcode/qrcode.php:428
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function strlen signature of param string at testdata/qrcode/qrcode.php:428
     $length = strlen($data);
                      ^^^^^
 WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testdata/qrcode/qrcode.php:430
@@ -133,7 +136,7 @@ WARNING caseBreak: Add break or '// fallthrough' to the end of the case at testd
 WARNING switchDefault: Add 'default' branch to avoid unexpected unhandled condition values at testdata/qrcode/qrcode.php:429
     switch ($version_group) {
     ^
-WARNING notNullSafety: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:447
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function substr signature of param string at testdata/qrcode/qrcode.php:447
       $group = substr($data, $i, 2);
                       ^^^^^
 MAYBE   callSimplify: Could simplify to $group[0] at testdata/qrcode/qrcode.php:448
diff --git a/src/tests/golden/testdata/twitter-api-php/golden.txt b/src/tests/golden/testdata/twitter-api-php/golden.txt
index 2c6f30f..37b4117 100644
--- a/src/tests/golden/testdata/twitter-api-php/golden.txt
+++ b/src/tests/golden/testdata/twitter-api-php/golden.txt
@@ -1,12 +1,18 @@
 WARNING invalidDocblock: @package name must be a start part of class namespace at testdata/twitter-api-php/TwitterAPIExchange.php:9
  * @package  Twitter-API-PHP
    ^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter string of function substr at testdata/twitter-api-php/TwitterAPIExchange.php:117
+        if (isset($array['status']) && substr($array['status'], 0, 1) === '@')
+                                              ^^^^^^^^^^^^^^^^
 MAYBE   callSimplify: Could simplify to $array['status'][0] at testdata/twitter-api-php/TwitterAPIExchange.php:117
         if (isset($array['status']) && substr($array['status'], 0, 1) === '@')
                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 WARNING unused: Variable $key is unused (use $_ to ignore this inspection or specify --unused-var-regex flag) at testdata/twitter-api-php/TwitterAPIExchange.php:122
         foreach ($array as $key => &$value)
                            ^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function explode signature of param string at testdata/twitter-api-php/TwitterAPIExchange.php:164
+                list($key, $value) = explode('=', $field);
+                                                  ^^^^^^
 WARNING strictCmp: 3rd argument of in_array must be true when comparing strings at testdata/twitter-api-php/TwitterAPIExchange.php:207
         if (!in_array(strtolower($requestMethod), array('post', 'get', 'put', 'delete')))
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -19,9 +25,18 @@ MAYBE   invalidDocblockType: Use bool type instead of boolean at testdata/twitte
 WARNING strictCmp: 3rd argument of in_array must be true when comparing strings at testdata/twitter-api-php/TwitterAPIExchange.php:286
         if (in_array(strtolower($this->requestMethod), array('put', 'delete')))
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function rawurlencode signature of param string at testdata/twitter-api-php/TwitterAPIExchange.php:345
+            $return[] = rawurlencode($key) . '=' . rawurlencode($value);
+                                                                ^^^^^^
 MAYBE   trailingComma: Last element in a multi-line array should have a trailing comma at testdata/twitter-api-php/TwitterAPIExchange.php:366
                 'oauth_signature_method', 'oauth_timestamp', 'oauth_token', 'oauth_version'))) {
                                                                             ^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function rawurlencode signature of param string at testdata/twitter-api-php/TwitterAPIExchange.php:367
+                $values[] = "$key=\"" . rawurlencode($value) . "\"";
+                                                     ^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function setGetfield signature of param string at testdata/twitter-api-php/TwitterAPIExchange.php:391
+            $this->setGetfield($data);
+                               ^^^^^
 MAYBE   invalidDocblockType: Use int type instead of integer at testdata/twitter-api-php/TwitterAPIExchange.php:404
      * @return integer
                ^^^^^^^
diff --git a/src/tests/golden/testdata/underscore/golden.txt b/src/tests/golden/testdata/underscore/golden.txt
index 0c2f2d2..9aaf1ba 100644
--- a/src/tests/golden/testdata/underscore/golden.txt
+++ b/src/tests/golden/testdata/underscore/golden.txt
@@ -1,3 +1,6 @@
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func signature of param callback at testdata/underscore/underscore.php:48
+      call_user_func($iterator, $v, $k, $collection);
+                     ^^^^^^^^^
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/underscore/underscore.php:60
     if(is_null($collection)) return self::_wrap(array());
                                                 ^^^^^^^
@@ -7,18 +10,36 @@ MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at tes
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/underscore/underscore.php:65
     $return = array();
               ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func signature of param callback at testdata/underscore/underscore.php:67
+      $return[] = call_user_func($iterator, $v, $k, $collection);
+                                 ^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function array_reduce signature of param callback at testdata/underscore/underscore.php:85
+    return self::_wrap(array_reduce($collection, $iterator, $memo));
+                                                 ^^^^^^^^^
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/underscore/underscore.php:113
     $return = array();
               ^^^^^^^
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/underscore/underscore.php:193
     $return = array();
               ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func signature of param callback at testdata/underscore/underscore.php:195
+      if(call_user_func($iterator, $val)) $return[] = $val;
+                        ^^^^^^^^^
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/underscore/underscore.php:207
     $return = array();
               ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func signature of param callback at testdata/underscore/underscore.php:209
+      if(!call_user_func($iterator, $val)) $return[] = $val;
+                         ^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func signature of param callback at testdata/underscore/underscore.php:224
+      if(call_user_func($iterator, $val)) return $val;
+                        ^^^^^^^^^
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/underscore/underscore.php:248
     if($n === 0) return self::_wrap(array());
                                     ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function array_splice signature of param offset at testdata/underscore/underscore.php:262
+    return self::_wrap(array_splice($collection, $index));
+                                                 ^^^^^^
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/underscore/underscore.php:284
     if($n === 0) $result = array();
                            ^^^^^^^
@@ -67,6 +88,9 @@ MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at tes
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/underscore/underscore.php:456
         if($step > 0 && $step > $stop) return self::_wrap(array($start));
                                                           ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function range signature of param step at testdata/underscore/underscore.php:458
+    $results = range($start, $stop, $step);
+                                    ^^^^^
 MAYBE   arrayAccess: Array access to non-array type \__|mixed at testdata/underscore/underscore.php:480
       if(!is_array($return_arrays[$k])) $return_arrays[$k] = array();
                    ^^^^^^^^^^^^^^
@@ -103,6 +127,9 @@ WARNING unused: Variable $v is unused (use $_ to ignore this inspection or speci
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/underscore/underscore.php:545
     $result = array();
               ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function array_key_exists signature of param key at testdata/underscore/underscore.php:549
+      if(!array_key_exists($key, $result)) $result[$key] = array();
+                           ^^^^
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/underscore/underscore.php:549
       if(!array_key_exists($key, $result)) $result[$key] = array();
                                                            ^^^^^^^
@@ -112,6 +139,12 @@ WARNING unused: Variable $__ is unused (use $_ to ignore this inspection or spec
 WARNING unused: Variable $args is unused (use $_ to ignore this inspection or specify --unused-var-regex flag) at testdata/underscore/underscore.php:615
     $args = self::_wrapArgs(func_get_args(), 1);
     ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function get_class signature of param object at testdata/underscore/underscore.php:658
+    return self::_wrap(get_class_methods(get_class($object)));
+                                                   ^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function array_key_exists signature of param key at testdata/underscore/underscore.php:703
+    return self::_wrap(array_key_exists($key, $collection));
+                                        ^^^^
 ERROR   undefinedProperty: Property {\__|mixed|null}->isEqual does not exist at testdata/underscore/underscore.php:723
       if(is_object($a) && isset($a->isEqual)) return self::_wrap($a->isEqual($b));
                                     ^^^^^^^
@@ -124,6 +157,18 @@ ERROR   undefinedMethod: Call to undefined method {mixed|null}->isEqual() at tes
 MAYBE   arrayAccess: Array access to non-array type \__|mixed|null at testdata/underscore/underscore.php:725
       if(is_array($a) && array_key_exists('isEqual', $a)) return self::_wrap($a['isEqual']($b));
                                                                              ^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function is_nan signature of param num at testdata/underscore/underscore.php:772
+    return self::_wrap((is_int($item) || is_float($item)) && !is_nan($item) && !is_infinite($item));
+                                                                     ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function is_infinite signature of param num at testdata/underscore/underscore.php:772
+    return self::_wrap((is_int($item) || is_float($item)) && !is_nan($item) && !is_infinite($item));
+                                                                                            ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function get_class signature of param object at testdata/underscore/underscore.php:793
+    return self::_wrap(is_object($item) && get_class($item) === 'DateTime');
+                                                     ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function is_nan signature of param num at testdata/underscore/underscore.php:800
+    return self::_wrap(is_nan($item));
+                              ^^^^^
 ERROR   undefinedProperty: Property {mixed}->_uniqueId does not exist at testdata/underscore/underscore.php:822
     $_instance->_uniqueId++;
                 ^^^^^^^^^
@@ -154,30 +199,72 @@ MAYBE   trailingComma: Last element in a multi-line array should have a trailing
 ERROR   undefinedProperty: Property {mixed}->_template_settings does not exist at testdata/underscore/underscore.php:909
       $ts = $class_name::getInstance()->_template_settings;
                                         ^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter pattern of function preg_match_all at testdata/underscore/underscore.php:913
+      preg_match_all($ts['escape'], $code, $vars, PREG_SET_ORDER);
+                     ^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function preg_match_all signature of param subject at testdata/underscore/underscore.php:913
+      preg_match_all($ts['escape'], $code, $vars, PREG_SET_ORDER);
+                                    ^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter pattern of function preg_match_all at testdata/underscore/underscore.php:920
+      preg_match_all($ts['interpolate'], $code, $vars, PREG_SET_ORDER);
+                     ^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function preg_match_all signature of param subject at testdata/underscore/underscore.php:920
+      preg_match_all($ts['interpolate'], $code, $vars, PREG_SET_ORDER);
+                                         ^^^^^
+WARNING notNullSafetyFunctionArgumentArrayDimFetch: potential null array access in parameter pattern of function preg_match_all at testdata/underscore/underscore.php:927
+      preg_match_all($ts['evaluate'], $code, $vars, PREG_SET_ORDER);
+                     ^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function preg_match_all signature of param subject at testdata/underscore/underscore.php:927
+      preg_match_all($ts['evaluate'], $code, $vars, PREG_SET_ORDER);
+                                      ^^^^^
 MAYBE   deprecated: Call to deprecated function create_function (since: 7.2, reason: Use anonymous functions instead, removed: 8.0) at testdata/underscore/underscore.php:940
       $func = create_function('$context', $code);
               ^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function htmlentities signature of param string at testdata/underscore/underscore.php:952
+    return self::_wrap(htmlentities($item));
+                                    ^^^^^
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/underscore/underscore.php:970
         return md5(join('_', array(
                              
 MAYBE   trailingComma: Last element in a multi-line array should have a trailing comma at testdata/underscore/underscore.php:972
           var_export($args, true)
           ^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func_array signature of param callback at testdata/underscore/underscore.php:978
+        $_instance->_memoized[$key] = call_user_func_array($function, $args);
+                                                           ^^^^^^^^^
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/underscore/underscore.php:995
       $key = md5(join('', array(
                           
 MAYBE   trailingComma: Last element in a multi-line array should have a trailing comma at testdata/underscore/underscore.php:997
         $wait
         ^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func_array signature of param callback at testdata/underscore/underscore.php:1005
+        return call_user_func_array($function, func_get_args());
+                                    ^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentFunctionCall: not null safety call in function md5 signature of param string when calling function \var_export at testdata/underscore/underscore.php:1021
+      $key = md5(var_export($function, true));
+                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func_array signature of param callback at testdata/underscore/underscore.php:1023
+        $_instance->_onced[$key] = call_user_func_array($function, func_get_args());
+                                                        ^^^^^^^^^
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/underscore/underscore.php:1036
       $args = array_merge(array($function), func_get_args());
                           ^^^^^^^^^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func_array signature of param callback at testdata/underscore/underscore.php:1037
+      return call_user_func_array($wrapper, $args);
+                                  ^^^^^^^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function call_user_func_array signature of param callback at testdata/underscore/underscore.php:1068
+      if($_instance->_aftered[$key] >= $count) return call_user_func_array($function, func_get_args());
+                                                                           ^^^^^^^^^
 MAYBE   arraySyntax: Use the short form '[]' instead of the old 'array()' at testdata/underscore/underscore.php:1102
     $filled_args = array();
                    ^^^^^^^
 WARNING unused: Foreach key $k is unused, can simplify $k => $v to just $v at testdata/underscore/underscore.php:1107
       foreach($caller_args as $k=>$v) {
                               ^^
+WARNING notNullSafetyFunctionArgumentVariable: not null safety call in function array_pad signature of param length at testdata/underscore/underscore.php:1112
+    return array_pad($filled_args, $num_args, null);
+                                   ^^^^^^^^^
 ERROR   classMembersOrder: Property $_uniqueId must go before methods in the class __ at testdata/underscore/underscore.php:817
   public $_uniqueId = -1;
   ^^^^^^^^^^^^^^^^^^^^^^^