Making a refactoring plug-in: How to allow changes?

Hi!

I'm trying my hand at making a refactoring plugin or two for IntelliJ to support our transition to EJB and JPA.  The first one I'm making simply turns static accesses to the current class into accesses to a new instance (except for accesses to constants). From the basic plugin tutorial and various postings here, I have been able to get the plug-in running and find the appropriate references. However, I am stumped at how to actually make any changes -- whenever I try to replace an element, I get

Assertion failed: Write access is allowed inside write-action only (see com.intellij.openapi.application.Application.runWriteAction())

I tried placing it in a write action like this:

            ApplicationManager.getApplication().runWriteAction(new Runnable() {
              public void run() {
                elm.replace(elementFactory.createExpressionFromText("new " + currentClass.getName() + "()", elm));
              }
            });

Then I got

Assertion failed: Undoable actions allowed inside commands only (see com.intellij.openapi.command.CommandProcessor.executeCommand())

Looking at its JavaDocs, I find a gazillion undocumented methods to implement, but in another posting here I notice the WriteCommandAction is supposed to do both for me, so I try that:

            new WriteCommandAction.Simple(project, elm.getContainingFile()) {
              public void run() {
                elm.replace(elementFactory.createExpressionFromText("new " + currentClass.getName() + "()", elm));
              }
            }.run();

But then I get the first exception again.

I also tried adding the "startInWriteAction" method to the action class, no difference.

The changes are made, but they are not undoable. What do I have to do to make an undoable action?  And is there a simple, working example of a refactoring somewhere?

I'm attaching the component code I have (with the WriteCommandAction). I run IntelliJ version 8.0.1 on an Ubuntu 8.10 box.

Thanks in advance,
-Lars Clausen



Attachment(s):
StaticToConstructor.java
4 comments
Comment actions Permalink

Hello Lars,

Looking at its JavaDocs, I find a gazillion undocumented methods to
implement, but in another posting here I notice the WriteCommandAction
is supposed to do both for me, so I try that:

new WriteCommandAction.Simple(project,
elm.getContainingFile()) {
�� public void run() {
��
elm.replace(elementFactory.createExpressionFromText("new " +
currentClass.getName() + "()", elm));
�� }
}.run();


You should call the execute() method instead of run(). Calling run() directly
defeats the purpose of using WriteCommandAction - it simply runs your code
directly without any required wrappers.

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

Thank you!  Worth noting that each call to WriteCommandAction.execute() corresponds to one Undo change.

Is there are place where these things are explained? The API itself contains exactly zero documentation of what to use when.

0
Comment actions Permalink

Hello Lars,

Thank you! Worth noting that each call to
WriteCommandAction.execute() corresponds to one Undo change.

Is there are place where these things are explained? The API itself
contains exactly zero documentation of what to use when.


Some information can be found in the following document: http://www.jetbrains.net/confluence/display/IDEADEV/IntelliJIDEAArchitectural+Overview

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

Thanks, I shall give it a read. You link was broken, let's see if this one is better: http://www.jetbrains.net/confluence/display/IDEADEV/IntelliJ+IDEA+Architectural+Overview

0

Please sign in to leave a comment.