Skip to content

Commit 261492c

Browse files
nmauemeta-codesync[bot]
authored andcommitted
HackLint5649: Exempt internal classnames in __Sealed attributes
Summary: ## LLM-generated Summary: Exempts internal classnames referenced in __Sealed user attributes from HackLint5649, while preserving the lint for usage elsewhere. This reduces false positives when sealing APIs that intentionally reference internal types and is validated with tests for class, interface, and method attributes plus an outside-attribute case. --- Session: DEV53002705 Reviewed By: enetsee Differential Revision: D92219643 fbshipit-source-id: fcdc391056830d19b13dc79f1e29d98dbe0a0b2a
1 parent 8476c28 commit 261492c

3 files changed

Lines changed: 34 additions & 1 deletion

File tree

hphp/hack/src/lints/linter_internal_class.ml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ module Env = Tast_env
1313
module Cls = Folded_class
1414
module SN = Naming_special_names
1515

16+
let in_sealed_attribute = ref false
17+
1618
let check_internal_classname pos ci env =
1719
let class_result =
1820
match ci with
@@ -33,9 +35,21 @@ let handler =
3335
object
3436
inherit Tast_visitor.handler_base
3537

38+
method! at_user_attribute _env ua =
39+
match ua.ua_name with
40+
| (_, name) when String.equal name SN.UserAttributes.uaSealed ->
41+
in_sealed_attribute := true
42+
| _ -> in_sealed_attribute := false
43+
44+
method! at_class_ _env _c = in_sealed_attribute := false
45+
46+
method! at_method_ _env _m = in_sealed_attribute := false
47+
48+
method! at_fun_def _env _fd = in_sealed_attribute := false
49+
3650
method! at_expr env (_, _, expr) =
3751
match expr with
3852
| Class_const ((_, p, ci), pstr) when String.equal (snd pstr) "class" ->
39-
check_internal_classname p ci env
53+
if not !in_sealed_attribute then check_internal_classname p ci env
4054
| _ -> ()
4155
end

hphp/hack/test/lint/lint_internal_class.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,20 @@ public function test(): void {
2020
}
2121

2222
}
23+
24+
internal class InternalForSealed {}
25+
26+
<<__Sealed(InternalForSealed::class)>>
27+
interface SealedInterface {}
28+
29+
<<__Sealed(InternalForSealed::class, Foo::class)>>
30+
abstract class SealedClass {}
31+
32+
class ClassWithSealedMethod {
33+
<<__Sealed(InternalForSealed::class)>>
34+
public function sealedMethod(): void {}
35+
}
36+
37+
function uses_internal_outside_sealed(): void {
38+
$x = InternalForSealed::class;
39+
}

hphp/hack/test/lint/lint_internal_class.php.exp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ File "lint_internal_class.php--use.php", line 8, characters 8-13:
44
This is a classname of an `internal` class. Internal classnames are dangerous because they are effectively raw strings. Please avoid them, or make sure that they are never used outside of the module. (Lint[5649])
55
File "lint_internal_class.php--use.php", line 14, characters 10-15:
66
This is a classname of an `internal` class. Internal classnames are dangerous because they are effectively raw strings. Please avoid them, or make sure that they are never used outside of the module. (Lint[5649])
7+
File "lint_internal_class.php--use.php", line 33, characters 8-24:
8+
This is a classname of an `internal` class. Internal classnames are dangerous because they are effectively raw strings. Please avoid them, or make sure that they are never used outside of the module. (Lint[5649])

0 commit comments

Comments
 (0)