Repository: VKCOM/noverify
Pull request #941 (2021-03-02 15:39:31)

linter: added check for incorrect case of class names in type hints


Patch:
diff --git a/src/linter/root.go b/src/linter/root.go
index fbce021..3420d6a 100644
--- a/src/linter/root.go
+++ b/src/linter/root.go
@@ -925,6 +925,10 @@ func (d *rootWalker) enterClassMethod(meth *ir.ClassMethodStmt) bool {
 		hintReturnType = typ
 	}
 
+	for _, param := range meth.Params {
+		d.checkFuncParam(param.(*ir.Parameter))
+	}
+
 	if meth.PhpDocComment == "" && modif.accessLevel == meta.Public {
 		// Permit having "__call" and other magic method without comments.
 		if !insideInterface && !strings.HasPrefix(nm, "_") {
@@ -1541,6 +1545,32 @@ func (d *rootWalker) checkFuncParam(p *ir.Parameter) {
 		}
 		return true
 	})
+
+	d.checkTypeHintClassCaseFunctionParam(p)
+}
+
+func (d *rootWalker) checkTypeHintClassCaseFunctionParam(p *ir.Parameter) {
+	if !d.metaInfo().IsIndexingComplete() {
+		return
+	}
+
+	typ, ok := d.parseTypeNode(p.VariableType)
+	if !ok {
+		return
+	}
+
+	typ.Iterate(func(typ string) {
+		if meta.IsClassType(typ) {
+			className := typ
+
+			class, ok := d.metaInfo().GetClass(className)
+			if !ok {
+				return
+			}
+
+			d.checkNameCase(p.VariableType, className, class.Name)
+		}
+	})
 }
 
 func (d *rootWalker) enterFunctionCall(s *ir.FunctionCallExpr) bool {


Test patch:
diff --git a/src/tests/checkers/oop_test.go b/src/tests/checkers/oop_test.go
index 0149d94..4b32792 100644
--- a/src/tests/checkers/oop_test.go
+++ b/src/tests/checkers/oop_test.go
@@ -1472,3 +1472,24 @@ function f() {
 	test.Expect = []string{}
 	test.RunAndMatch()
 }
+
+func TestTypeHintClassCaseFunctionParam(t *testing.T) {
+	test := linttest.NewSuite(t)
+	test.AddFile(`<?php
+class Foo {}
+
+class Boo {
+	/** */
+	public function a2(foo $b) {}
+}
+
+function a1(Foo $a, foo $b, boo $c) {}
+`)
+
+	test.Expect = []string{
+		`\foo should be spelled \Foo`,
+		`\foo should be spelled \Foo`,
+		`\boo should be spelled \Boo`,
+	}
+	test.RunAndMatch()
+}
diff --git a/src/tests/golden/testdata/idn/golden.txt b/src/tests/golden/testdata/idn/golden.txt
index bf868c6..9378c51 100644
--- a/src/tests/golden/testdata/idn/golden.txt
+++ b/src/tests/golden/testdata/idn/golden.txt
@@ -1,9 +1,15 @@
+MAYBE   arraySyntax: Use of old array syntax (use short form instead) at testdata/idn/idn.php:64
+    public static function idn_to_ascii($domain, $options, $variant, &$idna_info = array())
+                                                                                   ^^^^^^^
 MAYBE   phpdoc: Missing PHPDoc for "idn_to_ascii" public method at testdata/idn/idn.php:64
     public static function idn_to_ascii($domain, $options, $variant, &$idna_info = array())
                            ^^^^^^^^^^^^
 MAYBE   arraySyntax: Use of old array syntax (use short form instead) at testdata/idn/idn.php:87
         $idna_info = array(
                      
+MAYBE   arraySyntax: Use of old array syntax (use short form instead) at testdata/idn/idn.php:96
+    public static function idn_to_utf8($domain, $options, $variant, &$idna_info = array())
+                                                                                  ^^^^^^^
 MAYBE   phpdoc: Missing PHPDoc for "idn_to_utf8" public method at testdata/idn/idn.php:96
     public static function idn_to_utf8($domain, $options, $variant, &$idna_info = array())
                            ^^^^^^^^^^^