diff --git a/src/lint/linter/xhpast/rules/ArcanistNamespaceFirstStatementXHPASTLinterRule.php b/src/lint/linter/xhpast/rules/ArcanistNamespaceFirstStatementXHPASTLinterRule.php --- a/src/lint/linter/xhpast/rules/ArcanistNamespaceFirstStatementXHPASTLinterRule.php +++ b/src/lint/linter/xhpast/rules/ArcanistNamespaceFirstStatementXHPASTLinterRule.php @@ -6,7 +6,8 @@ const ID = 98; public function getLintName() { - return pht('`%s` Statement Must Be The First Statement', 'namespace'); + return pht('`%s` Statement Must Be The First Statement Or After Only `%s` + calls', 'namespace', 'declare'); } public function process(XHPASTNode $root) { @@ -18,18 +19,26 @@ $statements = $root->getChildOfType(0, 'n_STATEMENT_LIST'); - // Ignore the first statement, which should be `n_OPEN_TAG`. - $second_statement = $statements->getChildByIndex(1)->getChildByIndex(0); - - if ($second_statement->getTypeName() != 'n_NAMESPACE') { - $this->raiseLintAtNode( - $second_statement, - pht( - 'A script which contains a `%s` statement expects the very first '. - 'statement to be a `%s` statement. Otherwise, a PHP fatal error '. - 'will occur. %s', - 'namespace', - 'namespace', $second_statement->getTypeName())); + foreach ($statements->getChildren() as $statement) { + if ($statement->getTypeName() === 'n_OPEN_TAG') { + continue; + } + $statement_type = $statement->getChildByIndex(0)->getTypeName(); + if ($statement_type === 'n_DECLARE') { + continue; + } else if ($statement_type !== 'n_NAMESPACE') { + $this->raiseLintAtNode( + $statement, + pht( + 'A script which contains a `%s` statement expects it is the very '. + 'first statement or only after `%s` statements. Otherwise, a PHP '. + 'fatal error will occur. %s', + 'namespace', + 'declare', + $statement_type)); + } else { + break; + } } } diff --git a/src/lint/linter/xhpast/rules/__tests__/namespace-first-statement/declare-before-namespace.lint-test b/src/lint/linter/xhpast/rules/__tests__/namespace-first-statement/declare-before-namespace.lint-test new file mode 100644 --- /dev/null +++ b/src/lint/linter/xhpast/rules/__tests__/namespace-first-statement/declare-before-namespace.lint-test @@ -0,0 +1,4 @@ +