Giter Site home page Giter Site logo

kalessil / phpinspectionsea Goto Github PK

View Code? Open in Web Editor NEW
1.4K 30.0 119.0 129.73 MB

A Static Code Analyzer for PHP (a PhpStorm/Idea Plugin)

Home Page: https://plugins.jetbrains.com/plugin/7622?pr=phpStorm

License: Other

PHP 20.43% Java 77.90% HTML 1.42% Shell 0.04% Dockerfile 0.05% Kotlin 0.16%
phpstorm php static-analysis php7 awesome intellij intellij-plugin static-code-analysis static-analyzer phpstorm-plugin

phpinspectionsea's Issues

[bug] foreach source/offset validity - ignore boolean in resolved types

There's a false positive in a following case:
We have a function that with this signature:

/**
 * executes a query in the system database
 *
 * @param string $query The SQL query to executes
 * @param string $comment An optional comment explaining the query
 *
 * @return array|bool The result set on success, or false on error
 */
public static function runSingleQuery($query, $comment = '') {...}

Notice the array|bool return value.

Then when we execute the function:

    $result = SystemDatabaseManager::runSingleQuery(...);

    if ($result === false) {
        ...
        return $accountProfiles;
    } else {
        foreach ($result as $record) {
         ... 
         }
    }

In this case the inspection fires "Can't iterate bool (recheck type hints)" even though bool is not the only possible returned value type.

Add tests

Hello,

I am unsure what is the current development workflow, but I think it would be highly valuable if there were tests to assess regressions and also to speed up development (my current workflow involves starting up Intellij IDEA which is a terrible waste of time in my opinion).

Based on https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/comparing_references_inspection, it shouldn't be too hard to adapt the current test data in the php folder so that it can be used to create an automated test suite.

I am not too familiar with Intellij plugin development, but from what I've been able to gather from looking at this code sample (and http://www.jetbrains.org/intellij/sdk/docs/tutorials/writing_tests_for_plugins.html), we could create a small file structure such as

Test configuration (yaml)
- Which inspection to enable
- Any additional meta-data?
-----
<?php
// Case before
-----
<?php
// Case after

Let me know what you think. I'd be willing to work on this if anyone is willing to provide me with some support.

Edit: Apparently tests were added very recently in src/com/kalessil/phpStorm/phpInspectionsEA/tests! Thus I suggest we might discuss a more "scalable" approach than an inspection by inspection test? (that is declare only case files instead of full test classes).

Wrap foreach/for/while

There is already a check for wrapping if statements with braces. It would be nice if that could be extended to also make sure foreach, for and while loops are wrapped as well.

[new] PHPUnit - Allow assertEquals for object comparison

When writing unit tests we often assert if objects retrieved from different places are the same.
assertSame will only succeed when the two variables reference the same object.

But assertEquals will succeed when the two instances have all the same property values.

When the two variables are both objects, and instances from the same class. It would be useful to allow the assertEquals method.

Note: Also need this functionality for variables marked as class array (Object[]).

Disconnected foreach-statements within HTML template

The inspections are reporting HTML in a template foreach to be disconnected.
Here is an example:

<?php foreach($items as $item): ?>
    <div><?= $item ?></div>
<?php endforeach; ?>

In this case, the opening <div> and closing </div> inside the template foreach are reported as disconnected.

[WIP] API from *Impl classes used

Please get rid of *Impl method calls.
screenshot 2016-11-15 11 47 14

If you MISS something in corresponding interfaces, please contact us, we're actively working on improving our APIs

[false-positive] disconnected foreach statements with list(...) as value

I have caught such behaviour at this snippet:

        $arr = [[1,2,3]];
        $compare = 4;
        foreach ($arr as list($a, $b, $c)) {

            if ($b !== $compare) {
                continue;
            }
        }

PHPStorm says that if statement seems to be disconnected from parent foreach. When i use $a variable to compare there is no such warning.

[bug] Tests are bundled inside the plugin

Inside a jar file there is a folder: PhpInspectionsEA.jar!/com/kalessil/phpStorm/phpInspectionsEA/tests

It's not required and cause PhpStorm compatibility tool to issue warning:
com.kalessil.phpStorm.phpInspectionsEA:2.0.1 has 1 problem

------- Stderr: -------
#accessing to unknown class junit.framework.TestCase
at com.intellij.testFramework.UsefulTestCase

I would like to help to fix the issue but unfortunately I couldn't find any script or configuration that actually build jar.

[contrib] Codeception's/Yii's debug statements

Hi,

Awesome plugin, I use it all the time ๐Ÿ‘

However, Codeception the debug statements look like \Codeception\Util\Debug::debug() and those should of course not be present when you commit the code. It would be awesome if PHP Inspections EA would warn me about this.

Also, sometimes PHPStorms adds the use statement for Codeception\Util\Debug, so it is possible there is only Debug::debug() present in the code.

[bug] static methods invocation via this: NPE at QF

null
java.lang.NullPointerException
	at com.kalessil.phpStorm.phpInspectionsEA.inspectors.languageConstructions.DynamicInvocationViaScopeResolutionInspector$TheLocalFix.applyFix(DynamicInvocationViaScopeResolutionInspector.java:121)
	at com.kalessil.phpStorm.phpInspectionsEA.inspectors.languageConstructions.DynamicInvocationViaScopeResolutionInspector$TheLocalFix.applyFix(DynamicInvocationViaScopeResolutionInspector.java:97)
	at com.intellij.codeInspection.ex.QuickFixWrapper.invoke(QuickFixWrapper.java:86)
	at com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler.a(ShowIntentionActionsHandler.java:186)
	at com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler$$Lambda$1992/1565044013.run(Unknown Source)
	at com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler$$Lambda$1993/1584950228.run(Unknown Source)
	at com.intellij.openapi.application.WriteAction.run(WriteAction.java:94)
	at com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler.a(ShowIntentionActionsHandler.java:189)
	at com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler$$Lambda$1991/1868841150.run(Unknown Source)
	at com.intellij.openapi.command.impl.CoreCommandProcessor.a(CoreCommandProcessor.java:149)
	at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:109)
	at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:99)
	at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:85)
	at com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler.chooseActionAndInvoke(ShowIntentionActionsHandler.java:185)
	at com.intellij.codeInsight.intention.impl.IntentionListStep.b(IntentionListStep.java:276)
	at com.intellij.codeInsight.intention.impl.IntentionListStep$$Lambda$1989/1437527521.run(Unknown Source)
	at com.intellij.openapi.application.TransactionGuardImpl.performUserActivity(TransactionGuardImpl.java:204)
	at com.intellij.ui.popup.AbstractPopup.a(AbstractPopup.java:1392)
	at com.intellij.ui.popup.AbstractPopup$$Lambda$1801/56507148.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
	at java.awt.EventQueue.access$400(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:697)
	at java.awt.EventQueue$3.run(EventQueue.java:691)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
	at com.intellij.ide.IdeEventQueue.b(IdeEventQueue.java:843)
	at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:679)
	at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:391)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

Exception after update to 2.0.0

Short name not matched for class com.kalessil.phpStorm.phpInspectionsEA.inspectors.semanticalAnalysis.UnusedConstructorDependenciesInspector: getShortName() = UnusedConstructorDependenciesInspection; ep.shortName = UnnecessaryPropertyDependenciesInspection
java.lang.Throwable
    at com.intellij.openapi.diagnostic.Logger.error(Logger.java:132)
    at com.intellij.codeInspection.ex.InspectionToolWrapper.getTool(InspectionToolWrapper.java:85)
    at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass.getInspectionTools(LocalInspectionsPass.java:652)
    at com.intellij.codeInsight.daemon.impl.LocalInspectionsPassFactory$MyLocalInspectionsPass.getInspectionTools(LocalInspectionsPassFactory.java:94)
    at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass.collectInformationWithProgress(LocalInspectionsPass.java:133)
    at com.intellij.codeInsight.daemon.impl.ProgressableTextEditorHighlightingPass.doCollectInformation(ProgressableTextEditorHighlightingPass.java:82)
    at com.intellij.codeHighlighting.TextEditorHighlightingPass.collectInformation(TextEditorHighlightingPass.java:70)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.a(PassExecutorService.java:433)
    at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1054)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.c(PassExecutorService.java:426)
    at com.intellij.openapi.progress.impl.CoreProgressManager.a(CoreProgressManager.java:568)
    at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:519)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:54)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.b(PassExecutorService.java:425)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.run(PassExecutorService.java:405)
    at com.intellij.concurrency.JobLauncherImpl$VoidForkJoinTask$1.exec(JobLauncherImpl.java:155)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)


java.lang.Throwable
    at com.intellij.openapi.diagnostic.Logger.error(Logger.java:132)
    at com.intellij.codeInspection.ex.InspectionToolWrapper.getTool(InspectionToolWrapper.java:85)
    at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass.getInspectionTools(LocalInspectionsPass.java:652)
    at com.intellij.codeInsight.daemon.impl.LocalInspectionsPassFactory$MyLocalInspectionsPass.getInspectionTools(LocalInspectionsPassFactory.java:94)
    at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass.collectInformationWithProgress(LocalInspectionsPass.java:133)
    at com.intellij.codeInsight.daemon.impl.ProgressableTextEditorHighlightingPass.doCollectInformation(ProgressableTextEditorHighlightingPass.java:82)
    at com.intellij.codeHighlighting.TextEditorHighlightingPass.collectInformation(TextEditorHighlightingPass.java:70)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.a(PassExecutorService.java:433)
    at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1054)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.c(PassExecutorService.java:426)
    at com.intellij.openapi.progress.impl.CoreProgressManager.a(CoreProgressManager.java:568)
    at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:519)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:54)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.b(PassExecutorService.java:425)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.run(PassExecutorService.java:405)
    at com.intellij.concurrency.JobLauncherImpl$VoidForkJoinTask$1.exec(JobLauncherImpl.java:155)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)


java.lang.Throwable
    at com.intellij.openapi.diagnostic.Logger.error(Logger.java:132)
    at com.intellij.codeInspection.ex.InspectionToolWrapper.getTool(InspectionToolWrapper.java:85)
    at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass.getInspectionTools(LocalInspectionsPass.java:652)
    at com.intellij.codeInsight.daemon.impl.LocalInspectionsPassFactory$MyLocalInspectionsPass.getInspectionTools(LocalInspectionsPassFactory.java:94)
    at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass.collectInformationWithProgress(LocalInspectionsPass.java:133)
    at com.intellij.codeInsight.daemon.impl.ProgressableTextEditorHighlightingPass.doCollectInformation(ProgressableTextEditorHighlightingPass.java:82)
    at com.intellij.codeHighlighting.TextEditorHighlightingPass.collectInformation(TextEditorHighlightingPass.java:70)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.a(PassExecutorService.java:433)
    at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1054)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.c(PassExecutorService.java:426)
    at com.intellij.openapi.progress.impl.CoreProgressManager.a(CoreProgressManager.java:568)
    at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:519)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:54)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.b(PassExecutorService.java:425)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.run(PassExecutorService.java:405)
    at com.intellij.concurrency.JobLauncherImpl$VoidForkJoinTask$1.exec(JobLauncherImpl.java:155)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)


java.lang.Throwable
    at com.intellij.openapi.diagnostic.Logger.error(Logger.java:132)
    at com.intellij.codeInspection.ex.InspectionToolWrapper.getTool(InspectionToolWrapper.java:85)
    at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass.getInspectionTools(LocalInspectionsPass.java:652)
    at com.intellij.codeInsight.daemon.impl.WholeFileLocalInspectionsPassFactory$2.getInspectionTools(WholeFileLocalInspectionsPassFactory.java:106)
    at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass.collectInformationWithProgress(LocalInspectionsPass.java:133)
    at com.intellij.codeInsight.daemon.impl.ProgressableTextEditorHighlightingPass.doCollectInformation(ProgressableTextEditorHighlightingPass.java:82)
    at com.intellij.codeHighlighting.TextEditorHighlightingPass.collectInformation(TextEditorHighlightingPass.java:70)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.a(PassExecutorService.java:433)
    at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1054)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.c(PassExecutorService.java:426)
    at com.intellij.openapi.progress.impl.CoreProgressManager.a(CoreProgressManager.java:568)
    at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:519)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:54)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.b(PassExecutorService.java:425)
    at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.run(PassExecutorService.java:405)
    at com.intellij.concurrency.JobLauncherImpl$VoidForkJoinTask$1.exec(JobLauncherImpl.java:155)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)



[fixed, bug] Wrong quick fix for PHP4 style type casting

I have some code similar to the following:
$value = intval($number + ($continue ? ($number < 0 ? 1 : -1) : 1));

When I use the quick-fix provided, it corrects it to:
$value = (int)($number < 0 ? 1 : -1);

Which is incorrect, as it's ignoring the $number + ($continue ...) part.

[new, probable bugs] detect usage of two or more alphabets in class, NS, etc. names

Hello!

I really enjoyed work with plugin and I advice it for my colleagues, thank a lot!

Recently I accept a mistake. I created a class with name contained Cyrillic and Latin characters.
Can you add functionality with inspection for that case (I suppose for namespaces, classes and method names)?
Or suggest different solution for that case?

Thanks

Add a quick "Getting Started" for developers

I think it would be very useful for anyone interested in participating in the development of phpinspectionea if there were a small section of the README.md dedicated to setting up Intellij IDEA to create and debug new inspections and intentions.

  • Setting up Intellij for development
  • Running tests

[ideas] not optimal if conditions

There were many issues related to dependencies of conditions in "not optimal if conditions" inspections. Actually, this task is similar to topological sorting (https://en.wikipedia.org/wiki/Topological_sorting) and may be solved using existing algorithms. And advantage of topological sorting approach is possibility to implement "Quick Fix" solution to reorder conditions correctly.

Currently I see following possible dependencies:

  1. isset($var), !is_null($var), !empty($var) before usage of $var.
  2. isset($var[$key]), array_key_exists($key, $var) before usage of $var[$key].
  3. Type check (is_array, is_object, is_bool, is_int/is_integer/is_long, is_float/is_double/is_real, is_numeric, is_string, is_scalar, is_callable, instanceof, is_a, is_subclass_of) before usage.
  4. function_exists, method_exists, property_exists, class_exists, interface_exists, trait_exists before corresponding usage.
  5. Pass a $var by reference to a function, then usage of $var on the left and right of this condition shouldn't be mixed.
  6. Order of functions calls shouldn't be changed (as they may have side effects).

PS. Not so easy to implement, but maybe someone will have free time to do it.

[new] FQCN to ::class

Hello,

Thanks for your great plugin!
I've got a suggestion for a new inspection:

In frameworks like Zend Framework 2, there are a lot of configuration files looking like this:

namespace Application; 

return [
    'service_manager' => [
        'factories' => [
           'Application\EventListener\SomeListener' => 'Application\EventListener\Factory\SomeListener',
        ],
    ]
];

It would be great if there is an inspection that detects this FQCN and converts it to something like this:

namespace Application; 

return [
    'service_manager' => [
        'factories' => [
           EventListener\SomeListener::class => EventListener\Factory\SomeListener::class,
        ],
    ]
];

Another option would be to import all the use statements like this:

namespace Application; 

use Application\EventListener\SomeListener;
use Application\EventListener\Factory\SomeListenerFactory;

return [
    'service_manager' => [
        'factories' => [
           SomeListener::class => SomeListenerFactory::class,
        ],
    ]
];

With this code there is the problem that both classes can't have the same classname even though they are in another namespace.
This inspection could also apply to the default phpspec specification classes that are being generated.

For older projects, it should be possible to run this inspection by name on the full codebase.

[false-positive] disconnected foreach-statements with Dom/XML classes.

$writer = new \XMLWriter();
$writer->openMemory();

foreach ($dispatchNumbers as $number) {
    $writer->startElement('Order');
    $writer->writeAttribute('DispatchNumber', $number);
    $writer->endElement();
}

$writer->endElement();

echo $writer->outputMemory();

startElement and endElement are marked disconnected.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.