[ANN] Intention Power-Pack 0.4 released


Changes since version 0.3.1

  • New intention: convert != to equals(): foo!=bar -> !foo.equals(bar)

  • New intention: Convert C-style array declaration to Java-style: int foo[] -> int[] foo

(Note: this only works on local variables and parameters so for, not fields)

  • Completed semantics for "convert switch to if" and "convert if to switch". Even the wierdest and most bizarre edge cases should work now.


Available at http://www.intellij.org/twiki/bin/view/Main/IntentionPowerPack. Requires Aurora build 818 or greater

18 comments
Comment actions Permalink

Dave Griffith wrote:


Changes since version 0.3.1

  • New intention: convert != to equals(): foo!=bar -> !foo.equals(bar)

  • New intention: Convert C-style array declaration to Java-style: int

foo[] -> int[] foo (Note: this only works on local variables and
parameters so for, not fields)


Why? It is just PsiVariable.normalizeDeclaration() so it should work pretty
much anyware, shouldn't it? Or am I missing something?

Friendly,
Dmitry
--
Dmitry Lomov
IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"

0
Comment actions Permalink

>Why? It is just PsiVariable.normalizeDeclaration() so it should work pretty
>much anyware, shouldn't it? Or am I missing something?

Nope, I was missing something, namely the existence of PsiVariable.normalizeDeclaration(). It looks like I duplicated the functionality for PsiParameter and PsiDeclarationStatement, and didn't want to tackle it yet for PsiField, since there doesn't seem to be any good automation around finding multiple fields in a single declaration.

I guess I should have looked up PsiVariable.normalizeDeclaration() in the Psi documentation, and that would have avoided this problem.

Oh, wait...

0
Comment actions Permalink

wow.

So...
int[] foo, bar;
creates two int arrays, not one array and one int?

0
Comment actions Permalink

Um, yeah, exactly.

If you want to create an array and an int in one declaration, you say



My plugin shouldn't be changing one to the other.

0
Comment actions Permalink

Huh. I just never knew that. I thought Java worked like C in that respect. That's nice.

0
Comment actions Permalink

issue :
A double is required to undo an intention,
except when you first move the cursor back to the exact location where
the intention was called.

Alain

0
Comment actions Permalink

Alain Ravet wrote:

issue : A double is required to undo an intention,
except when..



Of course,the issue is not the double , but the caret move, that
triggers it.
I shoud have written :
"some intentions don't preserve the caret position, forcing a double
to undo their actions".

Alain

0
Comment actions Permalink

Dave
instead of !foo.equals(bar)
why not foo.equals(bar) == false

IMHO the second is much more readable and you are less likely to miss the

0
Comment actions Permalink


Hurm. I'm not doing anything about the caret position (that in itself is a known issue), so it's going to be a tough problem to fix. Tougher, since five minutes mousing around can't seem to reproduce it. If you've got an example, I'd love to see it.

0
Comment actions Permalink


This intention was added as a pair to an inspection I've created that looks for Object == and !=, and allows you to replace them with .equals() or !.equals(). I did have questions about the visibility of the !, but really dislike the verbosity of == false or == true. (There's already an intention for simplifying boolean literal equality, and my coming inspection plugin includes a check for this construct, allowing you to remove it wholesale from a codebase.)

0
Comment actions Permalink

Dave Griffith wrote:

> If you've got an example, I'd love to see it.


'Invert if condition' on

//flip this
i|f(3 <= 4)
{

}


Result :
//flip this
|if ( 3 > 4 ) {}


Note :
after the intention, the caret is at the same location - 'i|f' -, but
after 0.5sec, it moves in front of the '|if', requiring a double
to undo.

Alain

0
Comment actions Permalink

Exception with #859 and ipp 0.4

ERROR - com.intellij.ide.IdeEventQueue - Error during dispatching
of
java.awt.event.InvocationEvent[INVOCATION_DEFAULT,runnable=com.intellij.code
Insight.d.a.co@1daa93d,notifier=null,catchExceptions=false,when=105824455521
4] on sun.awt.windows.WToolkit@9cf10d
ERROR - com.intellij.ide.IdeEventQueue - IntelliJ IDEA (Aurora)
Build #859
ERROR - com.intellij.ide.IdeEventQueue - JDK: 1.4.2
ERROR - com.intellij.ide.IdeEventQueue - VM: Java HotSpot(TM)
Client VM
ERROR - com.intellij.ide.IdeEventQueue - Vendor: Sun Microsystems
Inc.
ERROR - com.intellij.ide.IdeEventQueue - OS: Windows 2000
ERROR - com.intellij.ide.IdeEventQueue - Last Action:
EditorPreviousWord
ERROR - com.intellij.ide.IdeEventQueue -
java.lang.NullPointerException
at
com.siyeh.ipp.psiutils.ExceptionUtils.calculateExceptionsThrown(ExceptionUti
ls.java:231)
at
com.siyeh.ipp.psiutils.ExceptionUtils.calculateExceptionsThrown(ExceptionUti
ls.java:78)
at
com.siyeh.ipp.psiutils.ExceptionUtils.calculateExceptionsThrown(ExceptionUti
ls.java:306)
at
com.siyeh.ipp.psiutils.ExceptionUtils.calculateExceptionsThrown(ExceptionUti
ls.java:115)
at
com.siyeh.ipp.psiutils.ExceptionUtils.calculateExceptionsThrown(ExceptionUti
ls.java:126)
at
com.siyeh.ipp.psiutils.ExceptionUtils.calculateExceptionsThrown(ExceptionUti
ls.java:306)
at
com.siyeh.ipp.exceptions.DetailExceptionsPredicate.satisfiedBy(DetailExcepti
onsPredicate.java:37)
at com.siyeh.ipp.Intention.findMatchingElement(Intention.java:112)
at com.siyeh.ipp.Intention.isAvailable(Intention.java:126)
at com.intellij.codeInsight.d.a.cf.c(cf.java:66)
at com.intellij.codeInsight.d.a.cf.b(cf.java:96)
at com.intellij.codeInsight.d.a.co.run(co.java:3)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at com.intellij.ide.s.a(s.java:96)
at com.intellij.ide.s.dispatchEvent(s.java:99)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown
Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown
Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)


0
Comment actions Permalink

Does anyone else spend way too much time changing string concats to StringBuffer appends?

I think that would be a great intention for this plugin...

great work on this thing Dave!

0
Comment actions Permalink

Does anyone else spend way too much time changing string concats to StringBuffer appends?


Yes, I did. Sometimes it makes the code more readable to me.

>I think that would be a great intention for this plugin...

+1

Tom

0
Comment actions Permalink


Hmmm. My gut feel is that this would be too hard for a simple intention, and rates a full refactoring. The problem is local within a method, but not within a single statement or expression, as all of my intentions in IPP are to date. In an ideal world, I would have to backtrace to wherever the first string gets appended to (by +=, say), and then change the variable to a StringBuffer and the concatenations to ".append()", and then find an appropriate place to put a ".toString()". If I were really badass, I'd come up with a reasonable guess as to initial StringBuffer capacity. All in all, really difficult, even more than switch->if.

A slightly less powerful change would be to turn any given chained concatenation expression to "new StringBuffer()" followed by calls to ".append()", and end with a "toString()" if the result isn't used in a context where both Strings and StringBuffers are valid (essentially just concatenation and .append()). This is local to an expression, thus manageable. It is essentially the optimization that Java compilers are required to do, but exposed to the user, and would serve as a decent launching point for more hand-optimizations by the user (i.e., merging the StringBuffers). Difficult, and with a lot of fiddly special cases, but doable within the scope of Intention Power Pack.

To make it perfect, I'd also want special case intentions for using string concatenation inside a Writer .print() or .println() expression. Splitting those out automatically into multiple .print()/.println() would be wicked usefule.

In any case, IntentionPowerPack is on temporary hold until I release InspectionGadgets (probably the day after tomorrow), and after that I'm more likely to handle IG bugs (oy) than IPP extensions. I wouldn't expect modifications to Intention Pack until early-mid September. If someone is ballsy enough to try the concatenation->.append() intention before then, more power to 'em, and don't hesitate to reuse any IPP code they need as examples or base. It'd rule.

0
Comment actions Permalink

Thanks for such great plugin.

You might want to consider doing http://www.intellij.net/tracker/idea/viewSCR?publicId=14602

Jacques

0
Comment actions Permalink

Interesting bug with IPP

Where storyDetailPanel is not known (red).

After Alt-Enter where | is the builtin intentions (create field,rename...) are
1) available as usual w/o IPP
2) not available if IPP is the only plugin loaded.

0

Please sign in to leave a comment.