diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -226,6 +226,8 @@ 'ArcanistModifierOrderingXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistModifierOrderingXHPASTLinterRuleTestCase.php', 'ArcanistNamingConventionsXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistNamingConventionsXHPASTLinterRule.php', 'ArcanistNamingConventionsXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistNamingConventionsXHPASTLinterRuleTestCase.php', + 'ArcanistNestedNamespacesXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistNestedNamespacesXHPASTLinterRule.php', + 'ArcanistNestedNamespacesXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistNestedNamespacesXHPASTLinterRuleTestCase.php', 'ArcanistNewlineAfterOpenTagXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistNewlineAfterOpenTagXHPASTLinterRule.php', 'ArcanistNewlineAfterOpenTagXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistNewlineAfterOpenTagXHPASTLinterRuleTestCase.php', 'ArcanistNoEffectException' => 'exception/usage/ArcanistNoEffectException.php', @@ -598,6 +600,8 @@ 'ArcanistModifierOrderingXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase', 'ArcanistNamingConventionsXHPASTLinterRule' => 'ArcanistXHPASTLinterRule', 'ArcanistNamingConventionsXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase', + 'ArcanistNestedNamespacesXHPASTLinterRule' => 'ArcanistXHPASTLinterRule', + 'ArcanistNestedNamespacesXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase', 'ArcanistNewlineAfterOpenTagXHPASTLinterRule' => 'ArcanistXHPASTLinterRule', 'ArcanistNewlineAfterOpenTagXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase', 'ArcanistNoEffectException' => 'ArcanistUsageException', diff --git a/src/lint/linter/xhpast/rules/ArcanistNestedNamespacesXHPASTLinterRule.php b/src/lint/linter/xhpast/rules/ArcanistNestedNamespacesXHPASTLinterRule.php new file mode 100644 --- /dev/null +++ b/src/lint/linter/xhpast/rules/ArcanistNestedNamespacesXHPASTLinterRule.php @@ -0,0 +1,29 @@ +selectDescendantsOfType('n_NAMESPACE'); + + foreach ($namespaces as $namespace) { + $nested_namespaces = $namespace->selectDescendantsOfType('n_NAMESPACE'); + + foreach ($nested_namespaces as $nested_namespace) { + $this->raiseLintAtNode( + $nested_namespace, + pht( + '`%s` declarations cannot be nested. '. + 'This construct will cause a PHP fatal error.', + 'namespace')); + } + } + } + +} diff --git a/src/lint/linter/xhpast/rules/__tests__/ArcanistNestedNamespacesXHPASTLinterRuleTestCase.php b/src/lint/linter/xhpast/rules/__tests__/ArcanistNestedNamespacesXHPASTLinterRuleTestCase.php new file mode 100644 --- /dev/null +++ b/src/lint/linter/xhpast/rules/__tests__/ArcanistNestedNamespacesXHPASTLinterRuleTestCase.php @@ -0,0 +1,10 @@ +executeTestsInDirectory(dirname(__FILE__).'/nested-namespaces/'); + } + +} diff --git a/src/lint/linter/xhpast/rules/__tests__/nested-namespaces/nested.lint-test b/src/lint/linter/xhpast/rules/__tests__/nested-namespaces/nested.lint-test new file mode 100644 --- /dev/null +++ b/src/lint/linter/xhpast/rules/__tests__/nested-namespaces/nested.lint-test @@ -0,0 +1,9 @@ +