Page MenuHomePhabricator

D13935.id35100.diff
No OneTemporary

D13935.id35100.diff

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
@@ -248,6 +248,8 @@
'ArcanistPHPOpenTagXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistPHPOpenTagXHPASTLinterRuleTestCase.php',
'ArcanistPHPShortTagXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPHPShortTagXHPASTLinterRule.php',
'ArcanistPHPShortTagXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistPHPShortTagXHPASTLinterRuleTestCase.php',
+ 'ArcanistPaamayimNekudotayimSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPaamayimNekudotayimSpacingXHPASTLinterRule.php',
+ 'ArcanistPaamayimNekudotayimSpacingXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistPaamayimNekudotayimSpacingXHPASTLinterRuleTestCase.php',
'ArcanistParenthesesSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParenthesesSpacingXHPASTLinterRule.php',
'ArcanistParenthesesSpacingXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistParenthesesSpacingXHPASTLinterRuleTestCase.php',
'ArcanistParseStrUseXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParseStrUseXHPASTLinterRule.php',
@@ -289,6 +291,8 @@
'ArcanistRubyLinter' => 'lint/linter/ArcanistRubyLinter.php',
'ArcanistRubyLinterTestCase' => 'lint/linter/__tests__/ArcanistRubyLinterTestCase.php',
'ArcanistScriptAndRegexLinter' => 'lint/linter/ArcanistScriptAndRegexLinter.php',
+ 'ArcanistSelfClassReferenceXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistSelfClassReferenceXHPASTLinterRule.php',
+ 'ArcanistSelfClassReferenceXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistSelfClassReferenceXHPASTLinterRuleTestCase.php',
'ArcanistSelfMemberReferenceXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistSelfMemberReferenceXHPASTLinterRule.php',
'ArcanistSelfMemberReferenceXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistSelfMemberReferenceXHPASTLinterRuleTestCase.php',
'ArcanistSemicolonSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistSemicolonSpacingXHPASTLinterRule.php',
@@ -618,6 +622,8 @@
'ArcanistPHPOpenTagXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistPHPShortTagXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistPHPShortTagXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
+ 'ArcanistPaamayimNekudotayimSpacingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
+ 'ArcanistPaamayimNekudotayimSpacingXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistParenthesesSpacingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistParenthesesSpacingXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistParseStrUseXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
@@ -659,6 +665,8 @@
'ArcanistRubyLinter' => 'ArcanistExternalLinter',
'ArcanistRubyLinterTestCase' => 'ArcanistExternalLinterTestCase',
'ArcanistScriptAndRegexLinter' => 'ArcanistLinter',
+ 'ArcanistSelfClassReferenceXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
+ 'ArcanistSelfClassReferenceXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistSelfMemberReferenceXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistSelfMemberReferenceXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistSemicolonSpacingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
diff --git a/src/lint/linter/xhpast/rules/ArcanistKeywordCasingXHPASTLinterRule.php b/src/lint/linter/xhpast/rules/ArcanistKeywordCasingXHPASTLinterRule.php
--- a/src/lint/linter/xhpast/rules/ArcanistKeywordCasingXHPASTLinterRule.php
+++ b/src/lint/linter/xhpast/rules/ArcanistKeywordCasingXHPASTLinterRule.php
@@ -15,73 +15,95 @@
public function process(XHPASTNode $root) {
$keywords = $root->selectTokensOfTypes(array(
- 'T_REQUIRE_ONCE',
- 'T_REQUIRE',
- 'T_EVAL',
- 'T_INCLUDE_ONCE',
- 'T_INCLUDE',
- 'T_LOGICAL_OR',
- 'T_LOGICAL_XOR',
- 'T_LOGICAL_AND',
- 'T_PRINT',
- 'T_INSTANCEOF',
+ 'T_ABSTRACT',
+ 'T_ARRAY',
+ 'T_AS',
+ 'T_BREAK',
+ 'T_CALLABLE',
+ 'T_CASE',
+ 'T_CATCH',
+ 'T_CLASS',
'T_CLONE',
- 'T_NEW',
- 'T_EXIT',
- 'T_IF',
- 'T_ELSEIF',
+ 'T_CONST',
+ 'T_CONTINUE',
+ 'T_DECLARE',
+ 'T_DEFAULT',
+ 'T_DO',
+ 'T_ECHO',
'T_ELSE',
+ 'T_ELSEIF',
+ 'T_EMPTY',
+ 'T_ENDDECLARE',
+ 'T_ENDFOR',
+ 'T_ENDFOREACH',
'T_ENDIF',
- 'T_ECHO',
- 'T_DO',
- 'T_WHILE',
+ 'T_ENDSWITCH',
'T_ENDWHILE',
+ 'T_EVAL',
+ 'T_EXIT',
+ 'T_EXTENDS',
+ 'T_FINAL',
+ 'T_FINALLY',
'T_FOR',
- 'T_ENDFOR',
'T_FOREACH',
- 'T_ENDFOREACH',
- 'T_DECLARE',
- 'T_ENDDECLARE',
- 'T_AS',
- 'T_SWITCH',
- 'T_ENDSWITCH',
- 'T_CASE',
- 'T_DEFAULT',
- 'T_BREAK',
- 'T_CONTINUE',
- 'T_GOTO',
'T_FUNCTION',
- 'T_CONST',
- 'T_RETURN',
- 'T_TRY',
- 'T_CATCH',
- 'T_THROW',
- 'T_USE',
'T_GLOBAL',
- 'T_PUBLIC',
- 'T_PROTECTED',
- 'T_PRIVATE',
- 'T_FINAL',
- 'T_ABSTRACT',
- 'T_STATIC',
- 'T_VAR',
- 'T_UNSET',
- 'T_ISSET',
- 'T_EMPTY',
+ 'T_GOTO',
'T_HALT_COMPILER',
- 'T_CLASS',
- 'T_INTERFACE',
- 'T_EXTENDS',
+ 'T_IF',
'T_IMPLEMENTS',
+ 'T_INCLUDE',
+ 'T_INCLUDE_ONCE',
+ 'T_INSTANCEOF',
+ 'T_INSTEADOF',
+ 'T_INTERFACE',
+ 'T_ISSET',
'T_LIST',
- 'T_ARRAY',
+ 'T_LOGICAL_AND',
+ 'T_LOGICAL_OR',
+ 'T_LOGICAL_XOR',
'T_NAMESPACE',
- 'T_INSTEADOF',
- 'T_CALLABLE',
+ 'T_NEW',
+ 'T_PRINT',
+ 'T_PRIVATE',
+ 'T_PROTECTED',
+ 'T_PUBLIC',
+ 'T_REQUIRE',
+ 'T_REQUIRE_ONCE',
+ 'T_RETURN',
+ 'T_STATIC',
+ 'T_SWITCH',
+ 'T_THROW',
'T_TRAIT',
+ 'T_TRY',
+ 'T_UNSET',
+ 'T_USE',
+ 'T_VAR',
+ 'T_WHILE',
'T_YIELD',
- 'T_FINALLY',
));
+
+ // Because there is no `T_SELF` or `T_PARENT` token.
+ $class_static_accesses = $root
+ ->selectDescendantsOfType('n_CLASS_DECLARATION')
+ ->selectDescendantsOfType('n_CLASS_STATIC_ACCESS');
+ foreach ($class_static_accesses as $class_static_access) {
+ $class_ref = $class_static_access->getChildByIndex(0);
+
+ switch (strtolower($class_ref->getConcreteString())) {
+ case 'parent':
+ case 'self':
+ $tokens = $class_ref->getTokens();
+
+ if (count($tokens) > 1) {
+ break;
+ }
+
+ $keywords[] = head($tokens);
+ break;
+ }
+ }
+
foreach ($keywords as $keyword) {
$value = $keyword->getValue();
diff --git a/src/lint/linter/xhpast/rules/ArcanistPaamayimNekudotayimSpacingXHPASTLinterRule.php b/src/lint/linter/xhpast/rules/ArcanistPaamayimNekudotayimSpacingXHPASTLinterRule.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/ArcanistPaamayimNekudotayimSpacingXHPASTLinterRule.php
@@ -0,0 +1,38 @@
+<?php
+
+final class ArcanistPaamayimNekudotayimSpacingXHPASTLinterRule
+ extends ArcanistXHPASTLinterRule {
+
+ const ID = 90;
+
+ public function getLintName() {
+ return pht('Paamayim Nekudotayim Spacing');
+ }
+
+ public function getLintSeverity() {
+ return ArcanistLintSeverity::SEVERITY_WARNING;
+ }
+
+ public function process(XHPASTNode $root) {
+ $double_colons = $root->selectTokensOfType('T_PAAMAYIM_NEKUDOTAYIM');
+
+ foreach ($double_colons as $double_colon) {
+ $tokens = $double_colon->getNonsemanticTokensBefore() +
+ $double_colon->getNonsemanticTokensAfter();
+
+ foreach ($tokens as $token) {
+ if ($token->isAnyWhitespace()) {
+ if (strpos($token->getValue(), "\n") !== false) {
+ continue;
+ }
+
+ $this->raiseLintAtToken(
+ $token,
+ pht('Unnecessary whitespace around double colon operator.'),
+ '');
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/lint/linter/xhpast/rules/ArcanistSelfClassReferenceXHPASTLinterRule.php b/src/lint/linter/xhpast/rules/ArcanistSelfClassReferenceXHPASTLinterRule.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/ArcanistSelfClassReferenceXHPASTLinterRule.php
@@ -0,0 +1,44 @@
+<?php
+
+final class ArcanistSelfClassReferenceXHPASTLinterRule
+ extends ArcanistXHPASTLinterRule {
+
+ const ID = 89;
+
+ public function getLintName() {
+ return pht('Self Class Reference');
+ }
+
+ public function getLintSeverity() {
+ return ArcanistLintSeverity::SEVERITY_WARNING;
+ }
+
+ public function process(XHPASTNode $root) {
+ $class_declarations = $root->selectDescendantsOfType('n_CLASS_DECLARATION');
+
+ foreach ($class_declarations as $class_declaration) {
+ $class_name = $class_declaration
+ ->getChildOfType(1, 'n_CLASS_NAME')
+ ->getConcreteString();
+ $instantiations = $class_declaration->selectDescendantsOfType('n_NEW');
+
+ foreach ($instantiations as $instantiation) {
+ $type = $instantiation->getChildByIndex(0);
+
+ if ($type->getTypeName() != 'n_CLASS_NAME') {
+ continue;
+ }
+
+ if (strtolower($type->getConcreteString()) == strtolower($class_name)) {
+ $this->raiseLintAtNode(
+ $type,
+ pht(
+ 'Use `%s` to instantiate the current class.',
+ 'self'),
+ 'self');
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/lint/linter/xhpast/rules/ArcanistSelfMemberReferenceXHPASTLinterRule.php b/src/lint/linter/xhpast/rules/ArcanistSelfMemberReferenceXHPASTLinterRule.php
--- a/src/lint/linter/xhpast/rules/ArcanistSelfMemberReferenceXHPASTLinterRule.php
+++ b/src/lint/linter/xhpast/rules/ArcanistSelfMemberReferenceXHPASTLinterRule.php
@@ -54,43 +54,6 @@
'self');
}
}
-
- static $self_refs = array(
- 'parent',
- 'self',
- 'static',
- );
-
- if (!in_array(strtolower($class_ref_name), $self_refs)) {
- continue;
- }
-
- if ($class_ref_name != strtolower($class_ref_name)) {
- $this->raiseLintAtNode(
- $class_ref,
- pht('PHP keywords should be lowercase.'),
- strtolower($class_ref_name));
- }
- }
- }
-
- $double_colons = $root->selectTokensOfType('T_PAAMAYIM_NEKUDOTAYIM');
-
- foreach ($double_colons as $double_colon) {
- $tokens = $double_colon->getNonsemanticTokensBefore() +
- $double_colon->getNonsemanticTokensAfter();
-
- foreach ($tokens as $token) {
- if ($token->isAnyWhitespace()) {
- if (strpos($token->getValue(), "\n") !== false) {
- continue;
- }
-
- $this->raiseLintAtToken(
- $token,
- pht('Unnecessary whitespace around double colon operator.'),
- '');
- }
}
}
}
diff --git a/src/lint/linter/xhpast/rules/__tests__/ArcanistPaamayimNekudotayimSpacingXHPASTLinterRuleTestCase.php b/src/lint/linter/xhpast/rules/__tests__/ArcanistPaamayimNekudotayimSpacingXHPASTLinterRuleTestCase.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/__tests__/ArcanistPaamayimNekudotayimSpacingXHPASTLinterRuleTestCase.php
@@ -0,0 +1,11 @@
+<?php
+
+final class ArcanistPaamayimNekudotayimSpacingXHPASTLinterRuleTestCase
+ extends ArcanistXHPASTLinterRuleTestCase {
+
+ public function testLinter() {
+ $this->executeTestsInDirectory(
+ dirname(__FILE__).'/paamayim-nekudotayim-spacing/');
+ }
+
+}
diff --git a/src/lint/linter/xhpast/rules/__tests__/ArcanistSelfClassReferenceXHPASTLinterRuleTestCase.php b/src/lint/linter/xhpast/rules/__tests__/ArcanistSelfClassReferenceXHPASTLinterRuleTestCase.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/__tests__/ArcanistSelfClassReferenceXHPASTLinterRuleTestCase.php
@@ -0,0 +1,10 @@
+<?php
+
+final class ArcanistSelfClassReferenceXHPASTLinterRuleTestCase
+ extends ArcanistXHPASTLinterRuleTestCase {
+
+ public function testLinter() {
+ $this->executeTestsInDirectory(dirname(__FILE__).'/self-class-reference/');
+ }
+
+}
diff --git a/src/lint/linter/xhpast/rules/__tests__/keyword-casing/parent.lint-test b/src/lint/linter/xhpast/rules/__tests__/keyword-casing/parent.lint-test
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/__tests__/keyword-casing/parent.lint-test
@@ -0,0 +1,17 @@
+<?php
+
+class Foo extends Bar {
+ public static function doSomething() {
+ return PARENT::doSomething();
+ }
+}
+~~~~~~~~~~
+warning:6:12
+~~~~~~~~~~
+<?php
+
+class Foo extends Bar {
+ public static function doSomething() {
+ return parent::doSomething();
+ }
+}
diff --git a/src/lint/linter/xhpast/rules/__tests__/keyword-casing/self.lint-test b/src/lint/linter/xhpast/rules/__tests__/keyword-casing/self.lint-test
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/__tests__/keyword-casing/self.lint-test
@@ -0,0 +1,17 @@
+<?php
+
+class Foo extends Bar {
+ public static function doSomething() {
+ return SELF::doSomethingElse();
+ }
+}
+~~~~~~~~~~
+warning:2:1
+~~~~~~~~~~
+<?php
+
+class Foo extends Bar {
+ public static function doSomething() {
+ return SELF::doSomethingElse();
+ }
+}
diff --git a/src/lint/linter/xhpast/rules/__tests__/paamayim-nekudotayim-spacing/paamayim-nekudotayim-spacing.lint-test b/src/lint/linter/xhpast/rules/__tests__/paamayim-nekudotayim-spacing/paamayim-nekudotayim-spacing.lint-test
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/__tests__/paamayim-nekudotayim-spacing/paamayim-nekudotayim-spacing.lint-test
@@ -0,0 +1,32 @@
+<?php
+
+class Foo extends Bar {
+ public function bar() {
+ echo self::FOOBAR;
+ echo self :: FOOBAR;
+ }
+}
+
+MyClass :: myMethod();
+
+SomeReallyLongClassName
+ ::someMethod();
+~~~~~~~~~~
+warning:6:14
+warning:6:17
+warning:10:8
+warning:10:11
+~~~~~~~~~~
+<?php
+
+class Foo extends Bar {
+ public function bar() {
+ echo self::FOOBAR;
+ echo self::FOOBAR;
+ }
+}
+
+MyClass::myMethod();
+
+SomeReallyLongClassName
+ ::someMethod();
diff --git a/src/lint/linter/xhpast/rules/__tests__/self-class-reference/self-class-references.lint-test b/src/lint/linter/xhpast/rules/__tests__/self-class-reference/self-class-references.lint-test
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/__tests__/self-class-reference/self-class-references.lint-test
@@ -0,0 +1,17 @@
+<?php
+
+class Foo extends Bar {
+ public static function newInstance() {
+ return new Foo();
+ }
+}
+~~~~~~~~~~
+warning:5:16
+~~~~~~~~~~
+<?php
+
+class Foo extends Bar {
+ public static function newInstance() {
+ return new self();
+ }
+}
diff --git a/src/lint/linter/xhpast/rules/__tests__/self-member-reference/self-member-reference.lint-test b/src/lint/linter/xhpast/rules/__tests__/self-member-reference/self-member-reference.lint-test
--- a/src/lint/linter/xhpast/rules/__tests__/self-member-reference/self-member-reference.lint-test
+++ b/src/lint/linter/xhpast/rules/__tests__/self-member-reference/self-member-reference.lint-test
@@ -3,59 +3,19 @@
class Foo extends Bar {
const FOOBAR = 'FOOBAR';
- public function __construct() {
- PARENT::__construct(null);
- }
-
- public function bar() {
- echo self::FOOBAR;
- echo Self :: FOOBAR;
- }
-
- public function baz(Foo $x) {
- echo static::FOOBAR;
+ public function baz() {
echo Foo::FOOBAR;
-
- $x::bar();
}
}
-
-MyClass :: myMethod();
-
-SomeReallyLongClassName
- ::someMethod();
~~~~~~~~~~
-advice:7:5
-advice:12:10
-advice:12:14
-advice:12:17
-advice:17:10
-advice:23:8
-advice:23:11
+advice:8:10
~~~~~~~~~~
<?php
class Foo extends Bar {
const FOOBAR = 'FOOBAR';
- public function __construct() {
- parent::__construct(null);
- }
-
- public function bar() {
- echo self::FOOBAR;
- echo self::FOOBAR;
- }
-
- public function baz(Foo $x) {
- echo static::FOOBAR;
+ public function baz() {
echo self::FOOBAR;
-
- $x::bar();
}
}
-
-MyClass::myMethod();
-
-SomeReallyLongClassName
- ::someMethod();

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 11, 12:12 AM (1 w, 17 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7483200
Default Alt Text
D13935.id35100.diff (16 KB)

Event Timeline