Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15343668
D13935.id35100.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
16 KB
Referenced Files
None
Subscribers
None
D13935.id35100.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D13935: Improve the "self member reference" linter rule
Attached
Detach File
Event Timeline
Log In to Comment