My first intention: Please take a look at it...

I started to create a new intention. It is working now - but I feel that I have missed the best way, especially when replacing the code ;).

Could you please show me, how to solve this problem "in the right way"?

Thanks



/*

  • Copyright (c) 2005 Your Corporation. All Rights Reserved.

*/
package de.xore.plugins.idea.renaming;

import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaFile;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiReturnStatement;
import com.intellij.psi.PsiReferenceExpression;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;

/**

  • <p/>

  • Date: 08.03.2005<br> Time: 23:42:12<br>

*

  • Systems</a>

*/
public class CollectionsWrapperIntention implements IntentionAction {
public String getText() {
return "Wrap collection";
}

public String getFamilyName() {
return "---WrapCollectionsFamily";
}

public boolean isAvailable( Project project, Editor editor, PsiFile file ) {
if ( !( file instanceof PsiJavaFile ) ) {
return false;
}

try {
PsiJavaFile javaFile = ( PsiJavaFile ) file;
PsiElement actualElement = javaFile.findElementAt( editor.getCaretModel().getOffset() );

PsiReturnStatement returnStatement = ( PsiReturnStatement ) PsiTreeUtil.getParentOfType( actualElement, PsiReturnStatement.class );
PsiMethod psiMethod = ( PsiMethod ) PsiTreeUtil.getParentOfType( actualElement, PsiMethod.class );

PsiReferenceExpression returnReference = ( PsiReferenceExpression ) PsiTreeUtil.getChildOfType( returnStatement, PsiReferenceExpression.class );

PsiManager manager = actualElement.getManager();
PsiClassType listType = manager.getElementFactory().createTypeByFQClassName( "java.util.List", actualElement.getResolveScope() );

if ( !listType.isAssignableFrom( returnReference.getType() ) ) {
return false;
}

if ( !psiMethod.getName().equalsIgnoreCase( "get" + returnReference.getText() ) ) {
return false;
}
} catch ( Throwable e ) {
return false;
}

return true;
}

public void invoke( Project project, Editor editor, PsiFile file ) throws IncorrectOperationException {
PsiJavaFile javaFile = ( PsiJavaFile ) file;
PsiElement actualElement = javaFile.findElementAt( editor.getCaretModel().getOffset() );

PsiReturnStatement returnStatement = ( PsiReturnStatement ) PsiTreeUtil.getParentOfType( actualElement, PsiReturnStatement.class );
PsiReferenceExpression returnReference = ( PsiReferenceExpression ) PsiTreeUtil.getChildOfType( returnStatement, PsiReferenceExpression.class );

int offset = returnReference.getTextOffset();
int length = returnReference.getTextLength();

editor.getDocument().replaceString( offset, offset + length, "Collections.unmodifiableList(" + returnReference.getText() + ")" );
}

public boolean startInWriteAction() {
return true;
}
}

6 comments
Comment actions Permalink

Johannes Schneider wrote:

PsiReferenceExpression returnReference = ( PsiReferenceExpression ) PsiTreeUtil.getChildOfType( returnStatement, PsiReferenceExpression.class );

int offset = returnReference.getTextOffset();
int length = returnReference.getTextLength();

editor.getDocument().replaceString( offset, offset + length, "Collections.unmodifiableList(" + returnReference.getText() + ")" );


You can do something like this instead (untested):

PsiManager mgr = PsiManager.getInstance(editor.getProject());
PsiElement e = mgr.getElementFactory.createExpressionFromText("Collections.unmodifiableList(" + returnReference.getText() + ")",
returnReference.getContext());

mgr.getCodeStyleManager().reformat(returnReference.replace(e));

Didn't look too closely at the rest of your code, but it seemed fine so far.

HTH,
Sascha

0
Comment actions Permalink

Thank you for your answer - I'll change that.

0
Comment actions Permalink

Just one more question.
I would like to add an import statement for java.util.Collections if necessary.

How can that be done?

0
Comment actions Permalink

Johannes Schneider wrote:

Just one more question.
I would like to add an import statement for java.util.Collections if necessary.

How can that be done?


Use "java.util.Collections" in the createExpressionFromText()-call and change the code to

e = returnReference.replace(e);
mgr.getCodeStyleManager().shortenClassReferences(e);
mgr.getCodeStyleManager().reformat(e);

HTH,
Sascha

0
Comment actions Permalink

Thank you ;).


Sorry for posting again - but I have one more problem...
The next step is wrapping the "setter".

The problem is, that I have to add a second expression. But I am not able to add a semicolon...



PsiAssignmentExpression assignExpr = ( PsiAssignmentExpression ) PsiTreeUtil.getParentOfType( actualElement, PsiAssignmentExpression.class );
PsiMethod method = ( PsiMethod ) PsiTreeUtil.getParentOfType( actualElement, PsiMethod.class );

PsiExpression clearExpression = manager.getElementFactory().createExpressionFromText( assignExpr.getLExpression().getText() + ".clear()", method.getContext() );
PsiExpression addAllExpression = manager.getElementFactory().createExpressionFromText( assignExpr.getLExpression().getText() + ".addAll(" + assignExpr.getRExpression().getText() + ")", method.getContext() );


PsiElement changedExpression = assignExpr.replace( clearExpression );
changedExpression.getParent().addAfter( addAllExpression, changedExpression );


manager.getCodeStyleManager().reformat( method );


This adds the second statement - but without a semicolon...

0
Comment actions Permalink

Okay - found it ;)

Just use "Statements" instead of "Expressions"



PsiStatement clearStatement = manager.getElementFactory().createStatementFromText( assignExpr.getLExpression().getText() + ".clear();", method.getContext() );
PsiStatement addAllStatement = manager.getElementFactory().createStatementFromText( assignExpr.getLExpression().getText() + ".addAll(" + assignExpr.getRExpression().getText() + ");", method.getContext() );


PsiElement changedExpression = assignStatement.replace( clearStatement );
changedExpression.getParent().addAfter( addAllStatement, changedExpression );

manager.getCodeStyleManager().reformat( method );

0

Please sign in to leave a comment.