[ANN] Intention Power-Pack 0.1 released
IntentionPowerPack -- Now that IntelliJ has opened up the intentions API, it's time to start abusing it! Here's a bunch of handy intentions to automate some small but common Java programming tasks. Let me know what you think, and remember that feature requests make the best 'thank yous'.
Provided Intentions
Boolean manipulations:
Convert 'and' to 'or': (foo && bar) -> !(!foo || !bar)
Convert 'or' to 'and': (foo || bar) -> !(!foo && !bar)
(To use: click on the '&&' or '||' operator, and trigger the intention)
Equality manipulations:
Flip 'equals': foo.equals(bar) -> bar.equals(foo)
Convert 'equals' to '==': foo.equals(bar) -> foo == bar
Convert '==' to 'equals': foo == bar -> foo.equals(bar)
(To use: click on a 'equals' or '==' operator, and trigger the intention)
Comparison manipulations:
Invert Comparison: foo !(foo >= bar)
Flip Comparison: foo < bar -> bar >]]> foo
(To use: click on a comparison operator, and trigger the intention)
Integer manipulation:
Convert integer literal to decimal: 0x12 -> 18
Convert integer literal to octal: 18 -> 022
Convert integer literal to hexidecimal: 022 -> 0x12
(To use: click on an integer or long literal, and trigger the intention)
*
JUnit manipulation:*
Convert 'assertEquals' to 'assertTrue': assertEquals("hey!", true, foo) <-> assertTrue("hey!", foo);
Convert 'assertEquals' to 'assertFalse': assertEquals("hey!", false, foo) <-> assertFalse("hey!", foo);
Convert 'assertEquals' to 'assertNull': assertEquals("hey!", null, foo) <-> assertNull("hey!", foo);
(To use: click on the method name, and trigger the intention)
Multiply to Shift optimizations:
Convert multiply to right-shift: foo * 8 <-> foo << 3
Convert multiply-assign to right-shift: foo *= 8 <-> foo <<= 3
Convert divide to left-shift: foo / 8 <-> foo >> 3
Convert divide-assign to left-shift: foo /= 8 <-> foo >>= 3
(To use: click on the operator, and trigger the intention)
Control flow (Experimental):
Replace ?: return with if-else: return foo?bar:baz; -> if(foo){return bar;}else{return baz;}
Replace ?: assignment with if-else: bar=foo?1:2; -> if(foo){ bar = 1;}else{ baz = 2;}
(To use, click on the 'return' or assignment operator, and trigger the intention.
Note that since I haven't figured out how to reformat the newly created text, you'll probably want
to do a reformat afterwards yourself.)
Installation: Go to http://www.intellij.org/twiki/bin/view/Main/IntentionPowerPack, Get the ipp.jar file,
drop it in your IntelliJ plugins directory, and restart IDEA
Future directions and TODOs:
New intentions --
Replace if-else with conditional operator
Replace switch with if
Replace if with switch
Create subclass
Parse value
Wrap value
Change fully qualified name to unqualified name
Replace literal with already existing constant in scope
Activate the intention in more places (i.e., anywhere in an expression, not just on the operator)
Intentions should trigger reformatting of changed text
General cleanup and refactoring (Code should be much smaller and better structured)
Figure out what the "familyName" property of an intention actually is, and set it appropriately
请先登录再写评论。
Feature requests??? This is more than I could have hoped for, already. :)
Great plugin, thanks a lot!
Andrei
"Dave Griffith" <dave.griffith@trilogy.com> wrote in message
news:5659896.1053699118644.JavaMail.jrun@is.intellij.net...
>
it's time to start abusing it! Here's a bunch of handy intentions to
automate some small but common Java programming tasks. Let me know what you
think, and remember that feature requests make the best 'thank yous'.
>
>
>
>
>
>
foo) <-> assertTrue("hey!", foo);
foo) <-> assertFalse("hey!", foo);
foo) <-> assertNull("hey!", foo);
>
>
if(foo){return bar;}else{return baz;}
1;}else{ baz = 2;}
intention.
text, you'll probably want
>
>
http://www.intellij.org/twiki/bin/view/Main/IntentionPowerPack, Get the
ipp.jar file,
>
not just on the operator)
structured)
set it appropriately
I guess this works only with Aurora, right?
Dave Griffith wrote:
Worse. It only works with Aurora build 816.
i can tell already that this is going to be great! thanks. my first request is that you rename the jar to be something like intentions.jar to be less cryptic.
or intentionspowerpack.jar to make sure that you don't clash with the 35 other intentions plugins that will surely spring forth fully formed from 35 authors IDEAs.
+1.
"Andrei Oprea" <aoprea@creditwave.com> wrote in message
news:balble$7k0$1@is.intellij.net...
>
>
API,
you
intention)
and
>
>
Sorry, ipp.jar is an in-joke, with personal significance, and it stays. If you don't like it, rename it yourself.
As an aside, I'm not sure how many intentions plugins there are likely to be. I've picked a lot of the low-hanging fruit already, and will soon doing more of the easy ones. Without IDEA opening up the 'yellow-line' warnings API, I'm not sure how much value there is in a some of the other ones people have suggested.
--Dave
"Dave Griffith" <dave.griffith@trilogy.com> wrote in message news:5659896.1053699118644.JavaMail.jrun@is.intellij.net...
>
How about adding also
Convert '==' to 'equals': foo == bar --> (foo == null ? bar == null : foo.equals(bar)) ?
--Oleg
Really easy, although I'm not absolutely sure of the value. It would need a new name so that it doesn't clash with the existing == -> .equals() conversion.
the value is that if foo is null, foo.equals(bar) will generate an NPE, while foo==bar will still be true.
Got it. However, I thought of one other problem with the transformation you suggest. If either foo or bar is an expression with side-effects, they could get executed twice.
Here is one in line with wrapping. I am not sure you were thinking of it
already.
Obviously boxing and unboxing builtin types would be a nice intention so it
would be nice to do it on Collection and arrays:
methodArray -> Arrays.asList(methodArray)
methodCollection -> methodCollection.toArray();
Obviously boxing and unboxing would be very helpful to fix type mismatch
errors. However they might be useful outside of error fixing when doing
Programming by intention or to create iterators for example. So maybe you
can start simply to offer these two anytime the caret is in a variable of
type collection or array. Definitively a lot easier than looking up a method
parameter type or a right hand side of an assignment or just detecting that
the operation on that variable was only permitted to the other kind
(array.size() or array.iterator() )
Other little remark. Right now the intentions are only available when the
caret is after the operator. To make it more intuitive they should also be
available when the caret is just before:
< and <
Great tool! Thanks for a great plugin and thanks to JetBrains for opening up
this API.
Jacques
not just on the operator)
structured)
set it appropriately
This is very useful plugin.
The only problem I see is the following exception stack trace:
2003-05-25 03:46:03,695 ERROR -
com.intellij.ide.IdeEventQueue - Error during dispatching of
java.awt.event.InvocationEvent[INVOCATION_DEFAULT,runnable=com.intellij.codeInsight.k.a.cn@1112aa9,notifier=null,catchExceptions=false,when=1053848763695]
on sun.awt.windows.WToolkit@7c5ff
2003-05-25 03:46:03,695 ERROR -
com.intellij.ide.IdeEventQueue - IntelliJ IDEA (Aurora) Build #816
2003-05-25 03:46:03,695 ERROR -
com.intellij.ide.IdeEventQueue - JDK: 1.4.1_02
2003-05-25 03:46:03,695 ERROR -
com.intellij.ide.IdeEventQueue - VM: Java HotSpot(TM) Client VM
2003-05-25 03:46:03,695 ERROR -
com.intellij.ide.IdeEventQueue - Vendor: Sun Microsystems Inc.
2003-05-25 03:46:03,695 ERROR -
com.intellij.ide.IdeEventQueue - OS: Windows XP
2003-05-25 03:46:03,695 ERROR -
com.intellij.ide.IdeEventQueue - Last Action: EditorBackSpace
2003-05-25 03:46:03,705 ERROR -
com.intellij.ide.IdeEventQueue -
java.lang.NullPointerException
at
com.siyeh.ipp.RemoveBooleanEqualityIntention.isAvailable(RemoveBooleanEqualityIntention.java:54)
at com.intellij.codeInsight.k.a.ce.c(ce.java:44)
at com.intellij.codeInsight.k.a.ce.b(ce.java:96)
at com.intellij.codeInsight.k.a.cn.run(cn.java:3)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at com.intellij.ide.t.a(t.java:116)
at com.intellij.ide.t.dispatchEvent(t.java:16)
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)
/kesh
Wow, that was fast! :) Congratulations!
I'll publish a sample plugin with a simple conditional-to-if intention later
today - so you can grasp some ideas on PSI usage.
Cheers,
Dmitry
Dave Griffith wrote:
--
Dmitry Lomov
IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"
>Other little remark. Right now the intentions are only >available when the
>caret is after the operator. To make it more intuitive >they should also be
>available when the caret is just before:
>|< and <|
When I release 0.2 (probably Thursday), it will contains changes such that the intentions work anywhere in the expression or statement to be changed, not just on the operator.
Boxing and unboxing turn out to be difficult, since the API doesn't give any help with expected types. I'm moving that one into the 'maybe' category, but I like your idea.
--Dave
Sweet. I've already figured out some of the tricks (the next version triggers reformatting of changed code, for instance), but anything to give some pointers would be appreciated.
(And, as always, if JetBrains feels like incorporating any of the ideas or code into the main product, you are absolutely encouraged to do so.)
--Dave
Dave, excellent work!
Tom
On Fri, 23 May 2003 14:11:58 +0000 (UTC), Dave Griffith
<dave.griffith@trilogy.com> wrote:
>
>
>
>
>
>
>
>
>
>
>
>
>
--
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
See
http://www.intellij.org/twiki/bin/view/Main/IntentionPlugins
for some info. There is a sample plugin there, namely conditional operator
to if statement convetor, that works for any conditional (not just in
assignments/returns). You are more than welcome to study its source.
Cheers,
Dmitry
Dave Griffith wrote:
--
Dmitry Lomov
IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"
Dave Griffith wrote:
>>Other little remark. Right now the intentions are only >available when the
>>caret is after the operator. To make it more intuitive >they should also be
>>available when the caret is just before:
>>|< and <|
For boxing and unboxing you can try AutoBoxingPlugin I have created.
/kesh
This is another exception I've got when I was trying to convert
1000000000000000000L value to hex form.
2003-05-26 18:33:10,413 ERROR - and.impl.CommandProcessorImpl -
2003-05-26 18:33:10,413 ERROR - and.impl.CommandProcessorImpl
- IntelliJ IDEA (Aurora) Build #816
2003-05-26 18:33:10,413 ERROR -
mand.impl.CommandProcessorImpl - JDK 1.4.1_02
2003-05-26 18:33:10,413 ERROR -
mand.impl.CommandProcessorImpl - VM: Java HotSpot(TM) Client VM
2003-05-26 18:33:10,413 ERROR -
mand.impl.CommandProcessorImpl - Vendor: Sun Microsystems Inc.
2003-05-26 18:33:10,413 ERROR -
mand.impl.CommandProcessorImpl - OS: Windows XP
2003-05-26 18:33:10,413 ERROR -
mand.impl.CommandProcessorImpl - Last Action: ShowIntentionActions
2003-05-26 18:33:10,413 ERROR -
mand.impl.CommandProcessorImpl - Current Command: Convert to hex
2003-05-26 18:33:10,413 ERROR - mand.impl.CommandProcessorImpl -
java.lang.NumberFormatException: For input string: "1000000000000000000"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at
com.siyeh.ipp.ConvertIntegerToHexIntention.invoke(ConvertIntegerToHexInt
ntion.java:64)
at com.intellij.codeInsight.intention.b.cs.run(cs.java:3)
at com.intellij.openapi.application.b.d.runWriteAction(d.java:217)
at com.intellij.codeInsight.intention.b.cr.run(cr.java:3)
at com.intellij.openapi.command.b.b.executeCommand(b.java:1)
at com.intellij.codeInsight.intention.b.da.run(da.java:3)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at com.intellij.ide.t.a(t.java:116)
at com.intellij.ide.t.dispatchEvent(t.java:16)
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)
Testing ....
-
if (a == b) ...
Negate also flips: if (!(b != a)) ...
-
if (longLongName == name) ...
Flip and negate: caret stays in the same column -> it should stay in the
same relative column (positioned on the equals sign).
-
if (null == name) ...
Replace == with .equals(): if (null.equals(name)) ...
-
if (name.equals(null)) ...
Flip .equals(): if (null.equals(name)) ...
-
if (name.equals(whatever)) ...
Replace .equals() with == flips: if (whatever == name) ...
-
More complicated...
if (rows == null || rows.length == 0)
Replace || with &&:
if (!(!(rows == null) && !(rows.length == 0)))
Very ugly. Can't we - I mean you - hmm, thatis :) can something be done
about this?
-
Ipp is looking very good.
Carlos