How To Fix Your Use Statements?

Hi all! Today we would like to introduce you our new feature for NetBeans 7.2 which is called Fix Uses....

Have you ever used Java support in NetBeans and its Fix Imports... action? What does it do. It simply goes through your code and tries to resolve missing import statements. And as you know, Java imports are "something like" PHP use statements. So what that our new Fix Uses... action do? Exactly what you mean. It goes through your code and tries to resolve missing use statements.

Note: We need to say, that this implemetation is really first and it doesn't cover all your use cases. But it does its work (which will be described later) and, hopefully, does it correctly.

So lets describe the work, what this new action does:

How to invoke Fix Uses... action?

It's quite simple. Just click inside a namespace, where you want to resolve missing use statements and press Ctrl + Shift + I, go to Source -> Fix Uses..., or right click in a namespace and select Fix Uses....

Note: If you use namespace declarations without brackets, don't invoke Fix Uses... action at the end of a file on a whitespace! It will not work properly, because these whitespaces doesn't belong to a proper namespace. It's a lexer/parser bug. So when you use this action, invoke it somewhere inside a namespace.

Do not invoke Fix Uses... action at the end of a namespace

How to select proper types?

When you successfully invoke Fix Uses... action, two things may happen.

  1. Resolving window occurs, or
  2. nothing - no resolving window occurs.

When resolving window occurs, than you can see all possible classes (types in general) which you can resolve somehow. It means that you can select a proper type from a combo box which will be used for a new use statement.

When nothing happens, then NetBeans thinks that all types are used properly and nothing has to be done.

There is just one think in a resolving window. There is a check box which allows you to remove all unused statements which occur after confirming a resolving window.

Resolving window

If we find some type, which can't be resolved (no type for this unqualified name exists, or you have some typo in PHPDoc), then it's mentioned in resolving window.

Resolving window with unresolvable types

What happens after confirmation of a resolving window?

After confirmation, all resolved (selected) types are inserted into a use statement declaration area which is located right after the namespace declaration and all uses of these types in a code are replaced by their unqualified types. If you wanted to Remove Unused Uses, than they are removed.

Fixed uses

What happens when a conflict of type names occurs?

When a conflict occurs, we try to create a use statement with an alias for every conflicting type (except the first one). No other possibilities are available in this first implementation, but we would like to implement some into the next version (e.g. to prefer unqualified names instead of aliases, etc.).

Conflicts Resolved conflicts

Are there any possibilities, how to customize the default behavior?

Yes. Not too much, but there are three of them. You can find them in Tools -> Options -> Editor -> Formatting -> PHP: Uses

  1. Prefer Fully Qualified Names over Use of Unqualified Names - if it's checked, then it means, that if you have a fully-qualified name used somewhere in a code, it will not be resolved by default (i.e. combo box in a resolving window will have a default value set to "Don't use type").
  2. Prefer Multiple Use Statements Combined - if it's checked, it means, that all resolved types will be inserted as a one use statement with a combined types.
  3. Start Use Statements with a Namespace Separator - if it's checked, then all your resolved types will be prepended by a namespace separator.
Options for Fix Uses... action

And that's all for today and as usual, please test it and if you find something strange, don't hesitate to file a new issue (product php, component Editor). Thanks.

Comments:

Brilliant! This was my most awaited IDE feature since PHP 5.3 is out.

I have just tested it with a big project, full of tricks for the editor, like generating PHP classes at runtime (not proud of that though), and it worked like a charm... Except for the funny bug I've reported.

However, I think the feature should more closely mimic its java counterpart. That is, it should be triggered automatically when the code completion is used. For example, if I type ClassLoader, then Ctrl+Space, and choose Doctrine\Common\ClassLoader, I would like to have only the alias (i.e. ClassLoader) in my code, and the fully qualified name automatically added in the uses group at the top of the file. Inserting the fully qualified name in the code kind of fight against the interest of automatic use statements. The other option would be to stop using the autocompletion, but that would be a shame considering how good Netbeans PHP is becoming at that!

Also, that would be great if the IDE could mark classes for which the use statement has been forgotten, and allow to fix that for that class only with the quickfix shortcut (Alt+Enter). Again, like in Java. But I guess that would not be an easy one to pull out for PHP.

As a side note, I must say I am a bit surprised at how stable this dev version seems to be. I used to play with release candidates some versions ago, and I remember they were quite crashy. Even now, I am still using 7.0.1 because my messy project knocks down the 7.1 when it scans the sources, and in some place the code completion was totally missing. All of that is fixed in the not yet released 7.2. I am impressed. I will continue to use it, and see if that first impression remains.

Posted by Éric O. on April 23, 2012 at 09:22 AM CEST #

Hi,

1)Yes I know that it would be great and I would like to implement such a behavior for some of next releases. I had not a too much time for 7.2 so it work as it works ;)

2) There is such a hint but I think that it work only when you use wualified or non-qualified name of a class...and only simetime :) (yes, it doesn't work so well ;) And I would like to improve it too.

3) Thanks a lot!

Posted by Ondrej Brejla on April 23, 2012 at 09:56 AM CEST #

Currently, Netbeans thinks a `use` statement is unused if it is included only for a docblock annotation.

Is there any plans to make this work for annotations also? Or have the ability to set a whitelist of use statements to ignore?

Posted by Chris Jones on May 02, 2012 at 03:43 PM CEST #

Hi, thanks for your response. But it should work now. If I have this piece of code, use statement is NOT underlined as unused (because it's used in PHPDoc comment).

<?php
use Foo\Bar;

/**
* @param Bar $param
*/
function functionName($param) {}
?>

Do you use a common PHPDoc format? With 2 asterisks at start?

If you think that something doesn't work, file a new issue [1] to editor please. Thanks.

[1] http://netbeans.org/bugzilla/enter_bug.cgi?product=php

Posted by Ondrej Brejla on May 02, 2012 at 03:54 PM CEST #

Ondrej:

In this case, I am talking about annotations that define what class to load. For example, here is a basic Doctrine MongoDB ODM class:

(Notice that the use statement defines how the "@MongoDB" annotation works)

<?php

namespace Acme;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

class User
{
/**
* @var string
* @MongoDB\Id
*/
protected $id;
}

Posted by Chris Jones on May 02, 2012 at 04:09 PM CEST #

Yep, now I understand. But no. We can't handle these type of annotations. It's very "doctrine like". For us, that "@MongoDB\Id" is not an AST type node...it's just some annotation node. We can handle types only for some common annotations, like @param, @var, @method, etc. Resp. we can handle types in those annotations, for which we have a parser. And we can't parse these special annotaions. So sorry, we can't handle it right now, but it could be an enhancement for some of next release.

Posted by Ondrej Brejla on May 02, 2012 at 04:24 PM CEST #

Hey, actually, it really should be a enhancement like a feature request, this is quite annoying, to take care of those annotation use case which are cleaned every time we try to clean use statements. Thanks a lot to point me to your feature request system if you have one.

Posted by jc on November 11, 2012 at 05:14 PM CET #

The feature has been implemented for 7.3. So Doctrine annotations and such should be handled properly.

Posted by Ondrej Brejla on November 11, 2012 at 05:39 PM CET #

Hi,

I'm refactoring my app by adding namespaces instead of long_class_names. I've got a lot of PHP files (hundreds). How to automatically add "use" statements to every file in a project (when suitable of course) when I add the "namespace" keyword to a file with a class?

Thanks.

Posted by Mariusz on March 26, 2014 at 01:15 PM CET #

Post a Comment:
  • HTML Syntax: NOT allowed
About

This blogs is written by NetBeans developers who contribute to the PHP support mainly.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today