diff --git a/src/__tests__/PhutilLibraryTestCase.php b/src/__tests__/PhutilLibraryTestCase.php --- a/src/__tests__/PhutilLibraryTestCase.php +++ b/src/__tests__/PhutilLibraryTestCase.php @@ -70,15 +70,13 @@ $interfaces = $class->getInterfaces(); foreach ($class->getMethods() as $method) { - $visibility = $this->getVisibility($method); $method_name = $method->getName(); foreach (array_merge($parents, $interfaces) as $extends) { if ($extends->hasMethod($method_name)) { $xmethod = $extends->getMethod($method_name); - $xvisibility = $this->getVisibility($xmethod); - if ($xvisibility != $visibility) { + if (!$this->compareVisibility($xmethod, $method)) { $failures[] = pht( 'Class "%s" implements method "%s" with the wrong visibility. '. 'The method has visibility "%s", but it is defined in parent '. @@ -86,9 +84,9 @@ 'overrides another must always have the same visibility.', $class_name, $method_name, - $visibility, + $this->getVisibility($method), $extends->getName(), - $xvisibility); + $this->getVisibility($xmethod)); } // We found a declaration somewhere, so stop looking. @@ -118,6 +116,23 @@ return phutil_get_library_root_for_path($caller); } + private function compareVisibility( + ReflectionMethod $parent_method, + ReflectionMethod $method) { + + static $bitmask; + + if ($bitmask === null) { + $bitmask = ReflectionMethod::IS_PUBLIC; + $bitmask += ReflectionMethod::IS_PROTECTED; + $bitmask += ReflectionMethod::IS_PRIVATE; + } + + $parent_modifiers = $parent_method->getModifiers(); + $modifiers = $method->getModifiers(); + return !(($parent_modifiers ^ $modifiers) & $bitmask); + } + private function getVisibility(ReflectionMethod $method) { if ($method->isPrivate()) { return 'private';