Triggering 'Create Method' intention


1)
I'd like to trigger this intention from my own code (from an inspection,
I suspect), and supply it all the necessary type information. Any hints how
to do such a thing?

2)
I assume the 'Cannot resolve method xxx' message comes from an Annotator,
not from an inspection (since I can't configure it). Correct?


12 comments

Hello Taras,

TT> 1)
TT> I'd like to trigger this intention from my own code (from an inspection,
TT> I suspect), and supply it all the necessary type information. Any hints
how
TT> to do such a thing?

QuickFixFactory.getInstance().createAddMethodFix() should be what you need.

TT> 2)
TT> I assume the 'Cannot resolve method xxx' message comes from an Annotator,
TT> not from an inspection (since I can't configure it). Correct?

It's not an annotator, it's part of our built-in highlighting (which is very
big and monolithic as it was developed before we got the annotators API).

--
Dmitry Jemerov
Software Developer
http://www.jetbrains.com/
"Develop with Pleasure!"


0

Hello Dmitry,

Hello Taras,

TT>> 1)
TT>> I'd like to trigger this intention from my own code (from an
TT>> inspection,
TT>> I suspect), and supply it all the necessary type information. Any
TT>> hints

how

TT>> to do such a thing?
TT>>

QuickFixFactory.getInstance().createAddMethodFix() should be what you
need.


Is there a pre-Demetra variant as well? I'd really like to do this in Irida
as well.

TT>> 2)
TT>> I assume the 'Cannot resolve method xxx' message comes from an
TT>> Annotator,
TT>> not from an inspection (since I can't configure it). Correct?

It's not an annotator, it's part of our built-in highlighting (which
is very big and monolithic as it was developed before we got the
annotators API).


Just a quick sanity check:
-My inspection scans for this "pseudo method call" (for instance, some XML
method-call syntax)
-I apply my own QuickFix, returned from my inspection
-Inside my QuickFix, I call the IntentionAction returned from the QuickFixFactory

I just call addMethodIntentionAction.invoke(project, editor, psiFile) from
my own QuickFix, without any special Runnable magic?
And the psiFile argument is the currrent file, not the one where the IntentionAction
will operate, correct?

Thanks


0

Hello Taras,

>> QuickFixFactory.getInstance().createAddMethodFix() should be what you
>> need.
>>
TT> Is there a pre-Demetra variant as well? I'd really like to do this
TT> in Irida as well.

Pre-Demetra it wasn't in the OpenAPI.

TT> Just a quick sanity check:
TT> -My inspection scans for this "pseudo method call" (for instance, some
XML
TT> method-call syntax)
TT> -I apply my own QuickFix, returned from my inspection
TT> -Inside my QuickFix, I call the IntentionAction returned from the
TT> QuickFixFactory

The API was designed to register the IntentionActions returned from the factory
directly as QuickFixes, but I guess you can do the wrapping as well.

TT> I just call addMethodIntentionAction.invoke(project, editor, psiFile)
from
TT> my own QuickFix, without any special Runnable magic?

If you're calling invoke() from the invoke() of your own quickfix, the Runnable
magic should be already in place. Otherwise, you'll need to commit the PSI
before calling invoke() and to surround the call in a command and a write
action.

TT> And the psiFile argument is the currrent file, not the one where the
IntentionAction
TT> will operate, correct?

Correct.

--
Dmitry Jemerov
Software Developer
http://www.jetbrains.com/
"Develop with Pleasure!"


0

Hello Dmitry,

TT>> Just a quick sanity check:
TT>> -My inspection scans for this "pseudo method call" (for instance,
TT>> some XML method-call syntax)
TT>> -I apply my own QuickFix, returned from my inspection
TT>> -Inside my QuickFix, I call the IntentionAction returned from the
TT>> QuickFixFactory

The API was designed to register the IntentionActions returned from
the factory directly as QuickFixes, but I guess you can do the
wrapping as well.


Could you explain a bit? Where are they registered "as QuickFixes"?
The only place I know so far where QuickFixes are registered is on inspections.

TT>> I just call addMethodIntentionAction.invoke(project, editor,
TT>> psiFile)
TT>>

from

TT>> my own QuickFix, without any special Runnable magic?
TT>>

If you're calling invoke() from the invoke() of your own quickfix, the
Runnable magic should be already in place. Otherwise, you'll need to
commit the PSI before calling invoke() and to surround the call in a
command and a write action.


I think I make an error in my original post.
Isn't one of the characteristics of a QuickFix that it can run without dialogs
etc (Just "apply")?

So I assume that this is actually wrong:
My Inspection -> My QuickFix -> AddMethod intention action

If I understand correctly, it should be:
My Inspection (to do the highlighting)
MyIntentionAction (using similar contitional logic as the inspection) ->
AddMethod intention action


0

Hello Taras,

TT>>> Just a quick sanity check:
TT>>> -My inspection scans for this "pseudo method call" (for instance,
TT>>> some XML method-call syntax)
TT>>> -I apply my own QuickFix, returned from my inspection
TT>>> -Inside my QuickFix, I call the IntentionAction returned from the
TT>>> QuickFixFactory
>> The API was designed to register the IntentionActions returned from
>> the factory directly as QuickFixes, but I guess you can do the
>> wrapping as well.
>>
TT> Could you explain a bit? Where are they registered "as QuickFixes"?
TT> The only place I know so far where QuickFixes are registered is on
TT> inspections.

Annotation.registerFix()

TT>
TT>>> I just call addMethodIntentionAction.invoke(project, editor,
TT>>> psiFile)
TT>>>
>> from
>>
TT>>> my own QuickFix, without any special Runnable magic?
TT>>>
>> If you're calling invoke() from the invoke() of your own quickfix,
>> the Runnable magic should be already in place. Otherwise, you'll need
>> to commit the PSI before calling invoke() and to surround the call in
>> a command and a write action.
>>
TT> I think I make an error in my original post.
TT> Isn't one of the characteristics of a QuickFix that it can run
TT> without dialogs etc (Just "apply")?
TT> So I assume that this is actually wrong:
TT> My Inspection -> My QuickFix -> AddMethod intention action
TT> If I understand correctly, it should be:
TT> My Inspection (to do the highlighting)
TT> MyIntentionAction (using similar contitional logic as the
TT> inspection) -> AddMethod intention action

Sorry, I don't understand which part of this paragraph is a question. :)
Yes, the AddMethodFix will work without showing any dialogs.

--
Dmitry Jemerov
Software Developer
http://www.jetbrains.com/
"Develop with Pleasure!"


0

Hello Dmitry,

Sorry, I don't understand which part of this paragraph is a question.
:) Yes, the AddMethodFix will work without showing any dialogs.


It's just my beginners terminology confusion, I think. Are the following
statements true?

Inspections can do the same analysis as IntentionAction, but can be run in
batch mode.
Inspections can return QuickFix(es), IntentionActions usually contain such
code themselves
QuickFix has no UI, just applyFix(), without any user interaction.
IntentionActions can do the same thing as QuickFixes, but can also include
more user interaction.
General difference between QuickFix and IntentionAction is UI-less versus
some UI interaction.

For instance: the AddMethodIntentionAction does have some user interaction:

If I call it on the following fragment (method "foo" does not exist), it
will something like 'Live Template' to let me select parameter and return
types:
-


foo("test") -> Create method
-


For the created parameter, it will suggest valid possibilities: Object, String,
CharSequence, etc
So (I assume), AddMethodIntentionAction could not be implemented as QuickFix,
since it required interaction.

Am I correct so far? Thanks for explaining something that must seem very
basic.


0

Hi Taras,

Inspection quick fixes are allowed user inaction too, but this is of course not very useful in batch mode. However several refactorings are called by some InspectionGadgets quick fixes in on-the-fly mode for example. The LocalInspectionTool methods get passed a boolean parameter isOnTheFly which tells whether it is called in batch mode or not. This can be used to see if a quick fix with user interaction is allowed to be created.

Bas

0

Hello Bas,

Inspection quick fixes are allowed user inaction too, but this is of
course not very useful in batch mode.


Ok, I'm trying to do this now. How do I get hold of an Editor inside my LocalQuickFix?

However several refactorings are
called by some InspectionGadgets quick fixes in on-the-fly mode for
example.


Can you name one?

The LocalInspectionTool methods get passed a boolean
parameter isOnTheFly which tells whether it is called in batch mode or
not. This can be used to see if a quick fix with user interaction is
allowed to be created.


Thanks. This clears things up, a little. For instance, the QuickFixFactory
returns IntentionActions :)


0

Hi Taras,

Ok, I'm trying to do this now. How do I get hold of
an Editor inside my LocalQuickFix?


FileEditorManager.getInstance(project).getSelectedTextEditor() will work I think.

However several refactorings are
called by some InspectionGadgets quick fixes in

on-the-fly mode for

example.


Can you name one?


the "Public inner class" inspection or if you are looking at the sources com.siyeh.ig.fixes.MoveClassFix

Bas

0

Hello Dmitry,

QuickFixFactory.getInstance().createAddMethodFix() should be what you
need.


Thanks, that works great.

However, when this intention is invoked from the IDEA user interface, it
seems to do a kind of Live Template expansion:
-return type choice (inferred from call site)
-parameter type choice (inferred from call site)
-method body completion

Can I make it do the same thinks as well? ;)


0

Hello Taras,

>> QuickFixFactory.getInstance().createAddMethodFix() should be what you
>> need.
>>
TT> Thanks, that works great.
TT>
TT> However, when this intention is invoked from the IDEA user
TT> interface, it
TT> seems to do a kind of Live Template expansion:
TT> -return type choice (inferred from call site)
TT> -parameter type choice (inferred from call site)
TT> -method body completion
TT> Can I make it do the same thinks as well? ;)

Right now the real "create method from usage" quickfix, which does all of
these things, can't be created through OpenAPI. You can file a JIRA request
to add the API for this.

--
Dmitry Jemerov
Software Developer
http://www.jetbrains.com/
"Develop with Pleasure!"


0

Hello Dmitry,

Right now the real "create method from usage" quickfix, which does all
of these things, can't be created through OpenAPI. You can file a JIRA
request to add the API for this.


Done: IDEA-9296


0

Please sign in to leave a comment.