Fix false positive warnings for package on top (#1214)

diff --git a/warn/warn_cosmetic.go b/warn/warn_cosmetic.go
index 9061619..04dfaa2 100644
--- a/warn/warn_cosmetic.go
+++ b/warn/warn_cosmetic.go
@@ -117,6 +117,15 @@
 	firstStmtIndex := -1 // index of the first seen non string, comment or load statement
 	for i := 0; i < len(f.Stmt); i++ {
 		stmt := f.Stmt[i]
+
+		// Assign statements may define variables that are used by the package statement,
+		// e.g. visibility declarations. To avoid false positive detections and also
+		// for keeping things simple, the warning should be just suppressed if there's
+		// any assignment statement, even if it's not used by the package declaration.
+		if _, ok := stmt.(*build.AssignExpr); ok {
+			break
+		}
+
 		_, isString := stmt.(*build.StringExpr) // typically a docstring
 		_, isComment := stmt.(*build.CommentBlock)
 		_, isLoad := stmt.(*build.LoadStmt)
@@ -171,8 +180,8 @@
 	for _, load := range misplacedPackages {
 		findings = append(findings, makeLinterFinding(load,
 			"Package declaration should be at the top of the file, after the load() statements, "+
-				"but before any call to a rule or a macro. "+
-				"package_group() and licenses() may be called before package().", replacements...))
+					"but before any call to a rule or a macro. "+
+					"package_group() and licenses() may be called before package().", replacements...))
 	}
 
 	return findings
diff --git a/warn/warn_cosmetic_test.go b/warn/warn_cosmetic_test.go
index 0009ca6..81d9c13 100644
--- a/warn/warn_cosmetic_test.go
+++ b/warn/warn_cosmetic_test.go
@@ -185,6 +185,60 @@
 foo(baz)`,
 		[]string{":11: Package declaration should be at the top of the file, after the load() statements, but before any call to a rule or a macro. package_group() and licenses() may be called before package()."},
 		scopeDefault|scopeBzl|scopeBuild)
+
+	checkFindingsAndFix(t,
+		"package-on-top",
+		`
+"""This is a docstring"""
+
+load(":foo.bzl", "foo")
+load(":bar.bzl", baz = "bar")
+
+VISIBILITY = baz
+
+foo()
+
+package(default_visibility = VISIBILITY)`,
+		`
+"""This is a docstring"""
+
+load(":foo.bzl", "foo")
+load(":bar.bzl", baz = "bar")
+
+VISIBILITY = baz
+
+foo()
+
+package(default_visibility = VISIBILITY)`,
+		[]string{},
+		scopeDefault|scopeBzl|scopeBuild)
+
+	checkFindingsAndFix(t,
+		"package-on-top",
+		`
+"""This is a docstring"""
+
+load(":foo.bzl", "foo")
+load(":bar.bzl", baz = "bar")
+
+irrelevant = baz
+
+foo()
+
+package()`,
+		`
+"""This is a docstring"""
+
+load(":foo.bzl", "foo")
+load(":bar.bzl", baz = "bar")
+
+irrelevant = baz
+
+foo()
+
+package()`,
+		[]string{},
+		scopeDefault|scopeBzl|scopeBuild)
 }
 
 func TestLoadOnTop(t *testing.T) {