Summary: `instanceof` should be used instead of `is_a`. I need to do a bit more research here to see if there are any edge cases.
Test Plan: Added unit tests.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14573
Summary:
Extends `ArcanistSelfMemberReferenceXHPASTLinterRule` to warn about the use of a hardcoded class name instead of `self` when instantiating a class. Arguably, we should maybe rename the linter rule from `ArcanistSelfMemberReferenceXHPASTLinterRule` to `ArcanistSelfUsageXHPASTLinterRule`, or even maybe split this rule into three separate rules:
- `ArcanistSelfMemberReferenceXHPASTLinterRule`
- `ArcanistSelfSpacingXHPASTLinterRule`
- `ArcanistSelfClassReferenceXHPASTLinterRule`.
Test Plan: Added to existing test cases.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D13935
Summary: Add a linter rule which advises against public class properties.
Test Plan: Added unit tests.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14641
Summary: Adds a linter rule which ensures that binary integers are written in lowercase (i.e. `0b1` instead of `0B1`).
Test Plan: Added test cases.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14644
Summary: Binary integers (such as `0b1`) were added to PHP 5.4 and cannot be used in earlier versions.
Test Plan: Added a test case.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14643
Summary: PHP doesn't handle octals very well. Basically, it seems that any numeric scalar matching `/^0\d+$/` will be treated as an octal, whereas this should be `/^0[0-7]+$/`. As a result, `08` and `09` are both treated as `0` (because they are invalid octals. This diff adds a linter rule to detect this abnormality.
Test Plan: Added unit tests.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: epriestley
Differential Revision: https://secure.phabricator.com/D14604
Summary: Demonstrates the use of `CaseInsensitiveArray`. Depends on D14624.
Test Plan: Ran unit tests.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14625
Summary: Fix a minor issue in which changing a function call to a type cast affects the result of an expression.
Test Plan: Added test case.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14623
Summary: Hexadecimal numbers should be written as `0xFF` and not `0xff` or `0Xff`.
Test Plan: Added test cases.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14612
Summary: Adds a linter rule for spacing after the `&` token, similar to `ArcanistUnaryPrefixExpressionSpacingXHPASTLinterRule`.
Test Plan: Added test cases.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14602
Summary: Type casts should be used instead of calls to the `*val` functions as function calls impose additional overhead.
Test Plan: Added unit tests.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14572
Summary: If a `namespace` is used within a PHP script, it must be the first statement.
Test Plan: Added unit tests.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14526
Summary:
`interface`s cannot contain `abstract` methods. This construct will cause a PHP fatal error:
```
Access type for interface method SomeInterface::someMethod() must be omitted
```
Test Plan: Added test cases.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14562
Summary:
`interface` methods cannot contain a body. This construct will cause a fatal error:
```
PHP Fatal error: Interface function X::Y() cannot contain body in /home/josh/workspace/github.com/phacility/arcanist/test.php on line 4
```
Test Plan: Added unit tests.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14561
Summary: A user reported to me that `arc lint` was failing with an error message along the lines of "argument 1 passed to `idx` must be of type array, bool given". I suspect that the user is running an older version of PHP, which means that `array_combine(array(), array())` is returning `false` instead of the expected `array()`. Instead, avoid calling `array_combine` on an empty array.
Test Plan: I don't have PHP 5.3 easily accessible to test this.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: epriestley
Differential Revision: https://secure.phabricator.com/D14567
Summary: Return values within constructors are acceptable if they are within a closure or anonymous function.
Test Plan: Added a test case.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14564
Summary:
`abstract` methods cannot contain a body.
```
PHP Fatal error: Abstract function X::Y() cannot contain body in /home/josh/workspace/github.com/phacility/arcanist/test.php on line 4
```
Test Plan: Added unit tests.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14560
Summary:
A class containing `abstract` methods must itself be marked as `abstract`.
```
PHP Fatal error: Class X contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (X::Y) in /home/josh/workspace/github.com/phacility/arcanist/test.php on line 5
```
Test Plan: Added unit tests.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14559
Summary:
Methods cannot be marked as both `abstract` and `private`. This language construct will cause a fatal error:
```
PHP Fatal error: Abstract function X::Y() cannot be declared private in /home/josh/workspace/github.com/phacility/arcanist/test.php on line 4
```
Test Plan: Added unit tests.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14558
Summary: Add a linter rule to detect symbols which are aliased with the same name, such as `use X\Y\Z as Z`. This is unnecessary and is more-simply expressed as `use X\Y\Z`.
Test Plan: Added unit tests.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14557
Summary:
When importing or aliases a symbol with a `use` statement, the leading namespace separator is optional and does not modify the behavior. That is, `use \X` is equivalent to `use X`. As such, the latter syntax should be preferred because it is more concise.
According to the [[http://php.net/manual/en/language.namespaces.importing.php | PHP documentation]]:
> Note that for namespaced names (fully qualified namespace names containing namespace separator, such as `Foo\Bar` as opposed to global names that do not, such as `FooBar`), the leading backslash is unnecessary and not recommended, as import names must be fully qualified, and are not processed relative to the current namespace.
Test Plan: Added test cases.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: epriestley
Differential Revision: https://secure.phabricator.com/D14517
Summary: This is failing locally with `cppcheck` version 1.69.
Test Plan: Ran `arc unit`.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14524
Summary: Fix the `PHPCompatibilityXHPASTLinterRule` after changes to the way in which #xhpast parses `use` statements. Depends on D14518.
Test Plan: Unit tests
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14519
Summary:
Although it is technically possible to return a value from a PHP constructor, it is rather odd and should be avoided. See some discussion on [[http://stackoverflow.com/q/11904255 | StackOverflow]]. Consider the following example:
```lang=php
class SomeClass {
public function __construct() {
return 'quack';
}
}
```
This doesn't work:
```lang=php, counterexample
echo new SomeClas();
```
This, strangely, does work:
```lang=php
echo id(new SomeClass())->__construct();
```
Test Plan: Added unit tests.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14516
Summary:
Add a linter rule to detect static method calls which //should// reference the `parent` class instead of a hardcoded class reference. For example, consider the following:
```lang=php, counterexample
class SomeClass extends AnotherClass {
public function someMethod() {
AnotherClass::someOtherMethod();
}
}
```
This should instead be written as:
```lang=php
class SomeClass extends AnotherClass {
public function someMethod() {
parent::someOtherMethod();
}
}
```
Test Plan: Added unit tests.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin, epriestley
Differential Revision: https://secure.phabricator.com/D14443
Summary:
Separate XHPAST linter rules in isolation from other rules and formalize the concept of a "linter rule". As the number of XHPAST linter rules grows (we currently have around 80), it becomes increasingly difficult to manage all of the test cases because `ArcanistXHPASTLinterTestCase` currently tests the entire linter (i.e. //all// linter rules) rather than testing individual rules in isolation. See D13534 for a situation in which this is painful. This is particularly bad for third party development because unit tests could break at any time depending on upstream changes.
Basically, in order to facilitate the unit testing of XHPAST linter rules in isolation, I have made the following changes:
# Added a `setRules()` method to `ArcanistXHPASTLinter`. Currently, `ArcanistXHPASTLinter` loads all `ArcanistXHPASTLinterRule` subclasses unconditionally. The `setRules()` method provides a way to override the configured linter rules.
# Formalize the concept of a "linter rule". The `ArcanistXHPASTLinterRule` class was introduced in D10541. I feel that the modularization of `ArcanistXHPASTLinter` has made the linter much more maintainable and easily testable and I intend to extend this concept to other linters, such as `ArcanistTextLinter`.
Test Plan: Ran unit tests.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14010
Summary: Adjusts `ArcanistBraceFormattingXHPASTLinterRule` after changes to the way in which XHPAST parses namespaces. Depends on D14498.
Test Plan: Unit tests are now passing.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14499
Summary:
csslint offers some diagnostics related to all the document without any
relevant line number.
In such case, arc lint failed, as setLine expects null or an integer,
but not an empty string.
The 'char' and 'line' attributes in XML report are now optional.
Fixes T9804.
Test Plan: test case to repro the issue added
Reviewers: chad, joshuaspence, #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin
Maniphest Tasks: T9804
Differential Revision: https://secure.phabricator.com/D14497
Summary: I've been thinking about this for a while... why not just fold `ArcanistPhutilXHPASTLinter` into `ArcanistXHPASTLinter`?
Test Plan: `arc unit`
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D13867
Summary: Ref T8742. As mentioned in D13512. This still needs some work, but looks roughly how I expect it to. Mainly, I want to move the standards stuff to the linter itself rather than the linter rule. I wanted to push this out for some initial feedback though.
Test Plan: This still needs work.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Maniphest Tasks: T8742
Differential Revision: https://secure.phabricator.com/D13942
Summary:
Linters can now use the `version` configuration value to specify the required
version of the external binary. The version number may be prefixed with <, <=,
>, >=, or = to specify the version comparison operator (default: =).
PHP's native `version_compare()` function is used to perform the comparison.
Fixes T4954.
Test Plan: Tested against a sample of external linters.
Reviewers: joshuaspence, epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin, joshuaspence
Projects: #lint
Maniphest Tasks: T4954
Differential Revision: https://secure.phabricator.com/D14298
Summary:
See discussion in D13737. If you're using this linter to match messages which //sometimes// have a character, you can get `""` (empty string) matches when the expression doesn't match. We'll complain about these later.
Instead, cast the matches the expected types.
Test Plan: @csilvers confirmed fix, see D13737.
Reviewers: chad, csilvers
Reviewed By: csilvers
Subscribers: spicyj, csilvers
Differential Revision: https://secure.phabricator.com/D14307
Summary:
This is in a similar vein as D14220 and sets a name on linter
messages. This should handle issues from D14165.
Test Plan: Run as many of the changed linters as possible + existing linter tests.
Reviewers: chad, #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D14225
Summary: Fixes T9498
Test Plan: Run `arc lint` with errors that get caught and reported by `ArcanistClosureLinter`
Reviewers: joshuaspence, epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Maniphest Tasks: T9498
Differential Revision: https://secure.phabricator.com/D14220
Summary: Ref T9145. Fixes T9316. We now require "name" and "code" has a maximum length (currently, this is 32, but the next diff will raise it to 128).
Test Plan:
- Installed PHPCS.
- Hit both the "name" and "code" issues.
- Applied this patch.
- Got better errors sooner.
Reviewers: chad
Reviewed By: chad
Subscribers: aik099
Maniphest Tasks: T9145, T9316
Differential Revision: https://secure.phabricator.com/D14165
Summary: Closes T9353. I think this makes all descriptions at least basically informative.
Test Plan: arc linters - I can now understand what each one is about.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin
Maniphest Tasks: T9353
Differential Revision: https://secure.phabricator.com/D14106