Merge remote-tracking branch 'origin/master'

This commit is contained in:
Maxim.Medvedev
2012-02-03 13:54:35 +04:00
11 changed files with 216 additions and 121 deletions
@@ -17,7 +17,7 @@ package com.intellij.codeInsight.folding.impl;
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
import com.intellij.lang.ASTNode;
import com.intellij.lang.folding.FoldingBuilderEx;
import com.intellij.lang.folding.CustomFoldingBuilder;
import com.intellij.lang.folding.FoldingDescriptor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
@@ -33,6 +33,7 @@ import com.intellij.psi.impl.source.PsiClassReferenceType;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod;
import com.intellij.psi.impl.source.tree.JavaDocElementType;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PropertyUtil;
@@ -47,25 +48,27 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
public class JavaFoldingBuilder extends FoldingBuilderEx implements DumbAware {
public class JavaFoldingBuilder extends CustomFoldingBuilder implements DumbAware {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.folding.impl.JavaFoldingBuilder");
private static final String SMILEY = "<~>";
@NotNull
public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement element, @NotNull Document document, boolean quick) {
if (!(element instanceof PsiJavaFile)) {
return FoldingDescriptor.EMPTY;
@Override
protected void buildLanguageFoldRegions(@NotNull List<FoldingDescriptor> descriptors,
@NotNull PsiElement root,
@NotNull Document document,
boolean quick) {
if (!(root instanceof PsiJavaFile)) {
return;
}
PsiJavaFile file = (PsiJavaFile) element;
PsiJavaFile file = (PsiJavaFile) root;
List<FoldingDescriptor> result = new ArrayList<FoldingDescriptor>();
PsiImportList importList = file.getImportList();
if (importList != null) {
PsiImportStatementBase[] statements = importList.getAllImportStatements();
if (statements.length > 1) {
final TextRange rangeToFold = getRangeToFold(importList);
if (rangeToFold != null && rangeToFold.getLength() > 1) {
result.add(new FoldingDescriptor(importList, rangeToFold));
descriptors.add(new FoldingDescriptor(importList, rangeToFold));
}
}
}
@@ -73,7 +76,7 @@ public class JavaFoldingBuilder extends FoldingBuilderEx implements DumbAware {
PsiClass[] classes = file.getClasses();
for (PsiClass aClass : classes) {
ProgressManager.checkCanceled();
addElementsToFold(result, aClass, document, true, quick);
addElementsToFold(descriptors, aClass, document, true, quick);
}
TextRange range = getFileHeader(file);
@@ -94,10 +97,8 @@ public class JavaFoldingBuilder extends FoldingBuilderEx implements DumbAware {
anchorElementToUse = candidate;
}
}
result.add(new FoldingDescriptor(anchorElementToUse, range));
descriptors.add(new FoldingDescriptor(anchorElementToUse, range));
}
return result.toArray(new FoldingDescriptor[result.size()]);
}
private void addElementsToFold(List<FoldingDescriptor> list, PsiClass aClass, Document document, boolean foldJavaDocs, boolean quick) {
@@ -160,14 +161,14 @@ public class JavaFoldingBuilder extends FoldingBuilderEx implements DumbAware {
else if (child instanceof PsiClass) {
addElementsToFold(list, (PsiClass)child, document, true, quick);
}
else if (child instanceof PsiComment) {
else if (child instanceof PsiComment && !isCustomRegionStart(child.getNode()) && !isCustomRegionEnd(child.getNode())) {
addCommentFolds((PsiComment)child, processedComments, list);
}
}
}
@NotNull
public String getPlaceholderText(@NotNull final ASTNode node) {
@Override
protected String getLanguagePlaceholderText(@NotNull ASTNode node, @NotNull TextRange range) {
return getPlaceholderText(SourceTreeToPsiMap.treeElementToPsi(node));
}
@@ -196,7 +197,8 @@ public class JavaFoldingBuilder extends FoldingBuilderEx implements DumbAware {
return "...";
}
public boolean isCollapsedByDefault(@NotNull final ASTNode node) {
@Override
protected boolean isRegionCollapsedByDefault(@NotNull ASTNode node) {
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(node);
JavaCodeFoldingSettings settings = JavaCodeFoldingSettings.getInstance();
if (element instanceof PsiNewExpression || element instanceof PsiJavaToken) {
@@ -734,5 +736,16 @@ public class JavaFoldingBuilder extends FoldingBuilderEx implements DumbAware {
return false;
}
}
@Override
protected boolean isCustomFoldingCandidate(ASTNode node) {
return node.getElementType() == JavaTokenType.END_OF_LINE_COMMENT;
}
@Override
protected boolean isCustomFoldingRoot(ASTNode node) {
IElementType nodeType = node.getElementType();
return nodeType == JavaElementType.CLASS || nodeType == JavaElementType.CODE_BLOCK;
}
}
@@ -0,0 +1,17 @@
public class Test {
<fold text='My private fields'>// <editor-fold desc="My private fields">
private int x;
private int y;
// </editor-fold></fold>
<fold text='My methods'>// <editor-fold desc="My methods">
private void doSomething() <fold text='{...}'>{
StringBuilder s = new StringBuilder();
<fold text='My code'>// <editor-fold desc="My code">
s.append("a");
s.append("b");
// </editor-fold></fold>
System.out.println(s.toString());
}</fold>
// </editor-fold></fold>
}
@@ -133,6 +133,10 @@ class Test {
assertTrue closureStartFold.expanded
assertTrue closureEndFold.expanded
}
public void testCustomFolding() {
myFixture.testFolding("$PathManagerEx.testDataPath/codeInsight/folding/${getTestName(false)}.java");
}
private def configure(String text) {
myFixture.configureByText("a.java", text)
@@ -29,7 +29,7 @@ public abstract class CustomFoldingBuilder extends FoldingBuilderEx implements D
List<FoldingDescriptor> descriptors = new ArrayList<FoldingDescriptor>();
if (CustomFoldingProvider.getAllProviders().length > 0) {
myDefaultProvider = null;
addCustomFoldingRegionsRecursively(root.getNode(), descriptors);
addCustomFoldingRegionsRecursively(null, root.getNode(), descriptors);
}
buildLanguageFoldRegions(descriptors, root, document, quick);
return descriptors.toArray(new FoldingDescriptor[descriptors.size()]);
@@ -54,30 +54,32 @@ public abstract class CustomFoldingBuilder extends FoldingBuilderEx implements D
@NotNull PsiElement root,
@NotNull Document document,
boolean quick);
private void addCustomFoldingRegionsRecursively(@NotNull ASTNode node, List<FoldingDescriptor> descriptors) {
Stack<ASTNode> customFoldingNodesStack = new Stack<ASTNode>(1);
private void addCustomFoldingRegionsRecursively(@Nullable FoldingStack foldingStack,
@NotNull ASTNode node,
List<FoldingDescriptor> descriptors) {
FoldingStack localFoldingStack = isCustomFoldingRoot(node) || foldingStack == null ? new FoldingStack(node) : foldingStack;
for (ASTNode child = node.getFirstChildNode(); child != null; child = child.getTreeNext()) {
if (isCustomRegionStart(child)) {
customFoldingNodesStack.push(child);
localFoldingStack.push(child);
}
else if (isCustomRegionEnd(child)) {
if (!customFoldingNodesStack.isEmpty()) {
ASTNode startNode = customFoldingNodesStack.pop();
if (!localFoldingStack.isEmpty()) {
ASTNode startNode = localFoldingStack.pop();
int startOffset = startNode.getTextRange().getStartOffset();
TextRange range = new TextRange(startOffset, child.getTextRange().getEndOffset());
descriptors.add(new FoldingDescriptor(node, range));
descriptors.add(new FoldingDescriptor(localFoldingStack.getOwner(), range));
}
}
else {
addCustomFoldingRegionsRecursively(child, descriptors);
addCustomFoldingRegionsRecursively(localFoldingStack, child, descriptors);
}
}
}
@Override
public final String getPlaceholderText(@NotNull ASTNode node, @NotNull TextRange range) {
if (mayContainCustomFoldings(node)) {
if (isCustomFoldingRoot(node)) {
PsiFile file = node.getPsi().getContainingFile();
PsiElement contextElement = file.findElementAt(range.getStartOffset());
if (contextElement != null && isCustomFoldingCandidate(contextElement.getNode())) {
@@ -103,7 +105,7 @@ public abstract class CustomFoldingBuilder extends FoldingBuilderEx implements D
@Override
public final boolean isCollapsedByDefault(@NotNull ASTNode node) {
// TODO<rv>: Modify Folding API and pass here folding range.
if (mayContainCustomFoldings(node)) {
if (isCustomFoldingRoot(node)) {
for (ASTNode child = node.getFirstChildNode(); child != null; child = child.getTreeNext()) {
if (isCustomRegionStart(child)) {
String childText = child.getText();
@@ -178,14 +180,28 @@ public abstract class CustomFoldingBuilder extends FoldingBuilderEx implements D
}
/**
* Returns true if the node may contain custom foldings in its immediate child nodes. By default any node will be checked for custom
* foldings but for performance reasons it makes sense to override this method to check only the nodes which actually may contain
* custom folding nodes (for example, group statements).
* Checks if the node is used as custom folding root. Any custom folding elements inside the root are considered to be at the same level
* even if they are located at different levels of PSI tree. Collected folding descriptors always contain only root elements with
* appropriate ranges. The method returns true if the node has any child elements.
*
* @param node The node to check.
* @return True if the node may contain custom folding nodes (true by default).
* @return True if the node is a root for custom foldings.
*/
protected boolean mayContainCustomFoldings(ASTNode node) {
return true;
protected boolean isCustomFoldingRoot(ASTNode node) {
return node.getFirstChildNode() != null;
}
private static class FoldingStack extends Stack<ASTNode> {
private ASTNode owner;
public FoldingStack(@NotNull ASTNode owner) {
super(1);
this.owner = owner;
}
@NotNull
public ASTNode getOwner() {
return this.owner;
}
}
}
@@ -25,12 +25,11 @@ import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.codeInsight.lookup.impl.LookupImpl;
import com.intellij.codeInsight.template.*;
import com.intellij.codeInsight.template.Result;
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
import com.intellij.codeInsight.template.impl.TemplateState;
import com.intellij.injected.editor.VirtualFileWindow;
import com.intellij.openapi.actionSystem.Shortcut;
import com.intellij.openapi.application.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.command.impl.FinishMarkAction;
@@ -41,6 +40,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.extensions.Extensions;
@@ -599,7 +599,7 @@ public abstract class InplaceRefactoring {
if (contains(stringUsage.second.shiftRight(element.getTextRange().getStartOffset()), offset)) return element;
}
LOG.assertTrue(false);
LOG.error(nameIdentifier);
return null;
}
@@ -699,9 +699,14 @@ public abstract class InplaceRefactoring {
}
finally {
if (!bind) {
FinishMarkAction.finish(myProject, myEditor, myMarkAction);
if (myBeforeRevert != null) {
myBeforeRevert.dispose();
try {
((EditorImpl)myEditor).stopDumb();
}
finally {
FinishMarkAction.finish(myProject, myEditor, myMarkAction);
if (myBeforeRevert != null) {
myBeforeRevert.dispose();
}
}
}
}
@@ -22,6 +22,7 @@ import com.intellij.openapi.command.impl.FinishMarkAction;
import com.intellij.openapi.command.impl.StartMarkAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
@@ -207,9 +208,14 @@ public class MemberInplaceRenamer extends VariableInplaceRenamer {
}
}
finally {
FinishMarkAction.finish(myProject, myEditor, markAction);
if (myBeforeRevert != null) {
myEditor.getCaretModel().moveToOffset(myBeforeRevert.getEndOffset());
try {
((EditorImpl)myEditor).stopDumb();
}
finally {
FinishMarkAction.finish(myProject, myEditor, markAction);
if (myBeforeRevert != null) {
myEditor.getCaretModel().moveToOffset(myBeforeRevert.getEndOffset());
}
}
}
}
@@ -223,6 +229,7 @@ public class MemberInplaceRenamer extends VariableInplaceRenamer {
public void finish(boolean success) {
super.finish(success);
if (success) {
((EditorImpl)myEditor).startDumb();
revertState();
}
}
@@ -27,6 +27,7 @@ import com.intellij.openapi.command.impl.FinishMarkAction;
import com.intellij.openapi.command.impl.StartMarkAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.SelectionModel;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
@@ -83,7 +84,6 @@ public class VariableInplaceRenamer extends InplaceRefactoring {
final String initialName,
final String oldName) {
super(editor, elementToRename, project, initialName, oldName);
}
public boolean performInplaceRename() {
@@ -114,7 +114,8 @@ public class VariableInplaceRenamer extends InplaceRefactoring {
final PsiFile containingFile) {
if (appendAdditionalElement(stringUsages)) {
return super.buildTemplateAndStart(refs, stringUsages, scope, containingFile);
} else {
}
else {
final RenameChooser renameChooser = new RenameChooser(myEditor) {
@Override
protected void runRenameTemplate(Collection<Pair<PsiElement, TextRange>> stringUsages) {
@@ -178,63 +179,79 @@ public class VariableInplaceRenamer extends InplaceRefactoring {
}
}
protected void renameSynthetic(String newName) {
}
protected void performRefactoringRename(final String newName,
final StartMarkAction markAction) {
try {
performAutomaticRename(newName);
}
finally {
FinishMarkAction.finish(myProject, myEditor, markAction);
}
}
new WriteCommandAction(myProject, getCommandName()) {
@Override
protected void run(Result result) throws Throwable {
renameSynthetic(newName);
}
}.execute();
protected void performAutomaticRename(String newName) {
PsiNamedElement elementToRename = getVariable();
for (AutomaticRenamerFactory renamerFactory : Extensions.getExtensions(AutomaticRenamerFactory.EP_NAME)) {
if (renamerFactory.isApplicable(elementToRename)) {
final List<UsageInfo> usages = new ArrayList<UsageInfo>();
final AutomaticRenamer renamer = renamerFactory.createRenamer(elementToRename, newName, new ArrayList<UsageInfo>());
if (renamer.hasAnythingToRename()) {
if (!ApplicationManager.getApplication().isUnitTestMode()) {
final AutomaticRenamingDialog renamingDialog = new AutomaticRenamingDialog(myProject, renamer);
renamingDialog.show();
if (!renamingDialog.isOK()) return;
}
final Runnable runnable = new Runnable() {
public void run() {
renamer.findUsages(usages, false, false);
PsiNamedElement elementToRename = getVariable();
for (AutomaticRenamerFactory renamerFactory : Extensions.getExtensions(AutomaticRenamerFactory.EP_NAME)) {
if (renamerFactory.isApplicable(elementToRename)) {
final List<UsageInfo> usages = new ArrayList<UsageInfo>();
final AutomaticRenamer renamer =
renamerFactory.createRenamer(elementToRename, newName, new ArrayList<UsageInfo>());
if (renamer.hasAnythingToRename()) {
if (!ApplicationManager.getApplication().isUnitTestMode()) {
final AutomaticRenamingDialog renamingDialog = new AutomaticRenamingDialog(myProject, renamer);
renamingDialog.show();
if (!renamingDialog.isOK()) return;
}
};
if (!ProgressManager.getInstance()
.runProcessWithProgressSynchronously(runnable, RefactoringBundle.message("searching.for.variables"), true, myProject)) {
return;
}
if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, PsiUtilCore.toPsiElementArray(renamer.getElements()))) return;
final UsageInfo[] usageInfos = usages.toArray(new UsageInfo[usages.size()]);
final MultiMap<PsiElement,UsageInfo> classified = RenameProcessor.classifyUsages(renamer.getElements(), usageInfos);
for (final PsiNamedElement element : renamer.getElements()) {
new WriteCommandAction(myProject, getCommandName()) {
@Override
protected void run(Result result) throws Throwable {
final String newElementName = renamer.getNewName(element);
if (newElementName != null) {
final Collection<UsageInfo> infos = classified.get(element);
RenameUtil.doRenameGenericNamedElement(element, newElementName, infos.toArray(new UsageInfo[infos.size()]), null);
}
final Runnable runnable = new Runnable() {
public void run() {
renamer.findUsages(usages, false, false);
}
}.execute();
};
if (!ProgressManager.getInstance()
.runProcessWithProgressSynchronously(runnable, RefactoringBundle.message("searching.for.variables"), true, myProject)) {
return;
}
if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, PsiUtilCore.toPsiElementArray(renamer.getElements()))) return;
final UsageInfo[] usageInfos = usages.toArray(new UsageInfo[usages.size()]);
final MultiMap<PsiElement, UsageInfo> classified = RenameProcessor.classifyUsages(renamer.getElements(), usageInfos);
for (final PsiNamedElement element : renamer.getElements()) {
new WriteCommandAction(myProject, getCommandName()) {
@Override
protected void run(Result result) throws Throwable {
final String newElementName = renamer.getNewName(element);
if (newElementName != null) {
final Collection<UsageInfo> infos = classified.get(element);
RenameUtil.doRenameGenericNamedElement(element, newElementName, infos.toArray(new UsageInfo[infos.size()]), null);
}
}
}.execute();
}
}
}
}
}
finally {
try {
((EditorImpl)myEditor).stopDumb();
}
finally {
FinishMarkAction.finish(myProject, myEditor, markAction);
}
}
}
@Override
protected String getCommandName() {
PsiNamedElement variable = getVariable();
if (variable == null) {
LOG.error(myElementToRename);
return "Rename";
}
return RefactoringBundle.message("renaming.0.1.to.2", UsageViewUtil.getType(variable), UsageViewUtil.getDescriptiveName(variable),
variable.getName());
}
@@ -277,7 +294,7 @@ public class VariableInplaceRenamer extends InplaceRefactoring {
}
private boolean isIdentifier(final String newName) {
final NamesValidator namesValidator = LanguageNamesValidation.INSTANCE.forLanguage(myLanguage);
return namesValidator == null || namesValidator.isIdentifier(newName, myProject);
}
@@ -19,15 +19,15 @@ import com.intellij.ide.IdeEventQueue;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.editor.VisualPosition;
import com.intellij.ui.components.Magnificator;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.editor.VisualPosition;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.ui.Queryable;
import com.intellij.openapi.ui.TypingTarget;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.ui.components.Magnificator;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -147,7 +147,7 @@ public class EditorComponentImpl extends JComponent implements Scrollable, DataP
((Graphics2D)g).setComposite(AlphaComposite.Src);
UISettings.setupAntialiasing(g);
myEditor.paint(g);
myEditor.paint((Graphics2D)g);
}
finally {
((ApplicationImpl)ApplicationManager.getApplication()).editorPaintFinish();
@@ -109,6 +109,7 @@ import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.*;
import java.awt.font.TextHitInfo;
import java.awt.im.InputMethodRequests;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.lang.reflect.Field;
@@ -129,6 +130,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
public static final Key<Pair<String, String>> EDITABLE_AREA_MARKER = Key.create("editable.area.marker");
private static final boolean HONOR_CAMEL_HUMPS_ON_TRIPLE_CLICK
= Boolean.parseBoolean(System.getProperty("idea.honor.camel.humps.on.triple.click"));
public static final Key<BufferedImage> BUFFER = Key.create("buffer");
private final DocumentImpl myDocument;
private final JPanel myPanel;
@@ -1649,7 +1651,40 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
return isReleased;
}
void paint(Graphics g) {
public void stopDumb() {
putUserData(BUFFER, null);
}
/**
* {@link #stopDumb()} must be performed in finally
*/
public void startDumb() {
final EditorComponentImpl component = getContentComponent();
final Dimension dimension = component.getSize();
BufferedImage image = new BufferedImage(dimension.width, dimension.height, BufferedImage.TYPE_INT_RGB);
final Graphics2D graphics = image.createGraphics();
graphics.setClip(0, 0, dimension.width, dimension.height);
paint(graphics);
putUserData(BUFFER, image);
}
void paint(Graphics2D g) {
Rectangle clip = g.getClipBounds();
if (clip == null) {
return;
}
if (Registry.is("editor.dumb.mode.available")) {
final BufferedImage buffer = getUserData(BUFFER);
if (buffer != null) {
final Point point = new Point(clip.x, clip.y);
SwingUtilities.convertPointFromScreen(point, getContentComponent());
g.drawImage(buffer, null, 0, 0);
return;
}
}
startOptimizedScrolling();
if (myUpdateCursor) {
@@ -1657,11 +1692,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myUpdateCursor = false;
}
Rectangle clip = g.getClipBounds();
if (clip == null) {
return;
}
Rectangle visibleArea = getScrollingModel().getVisibleArea();
if (visibleArea == null) {
@@ -187,3 +187,5 @@ disable.toolwindow.overlayed=true
disable.toolwindow.overlayed.description=Disable transparent toolwindow stripes
core.pooled.threads=20
editor.dumb.mode.available=true
@@ -15,10 +15,6 @@
*/
package org.jetbrains.plugins.groovy.refactoring.rename.inplace;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.command.impl.FinishMarkAction;
import com.intellij.openapi.command.impl.StartMarkAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiNameIdentifierOwner;
import com.intellij.psi.PsiNamedElement;
@@ -39,27 +35,15 @@ public class GrVariableInplaceRenamer extends VariableInplaceRenamer {
super(elementToRename, editor);
}
@Override
protected void performRefactoringRename(final String newName, StartMarkAction markAction) {
try {
new WriteCommandAction(myProject, getCommandName()) {
@Override
protected void run(Result result) throws Throwable {
PsiNamedElement elementToRename = getVariable();
if (elementToRename instanceof ClosureSyntheticParameter && !"it".equals(newName)) {
final GrClosableBlock closure = ((ClosureSyntheticParameter)elementToRename).getClosure();
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
final PsiType type = ((ClosureSyntheticParameter)elementToRename).getTypeGroovy();
final GrParameter newParam = factory.createParameter(newName, TypesUtil.unboxPrimitiveTypeWrapper(type));
final GrParameter added = closure.addParameter(newParam);
GrReferenceAdjuster.shortenReferences(added);
}
}
}.execute();
performAutomaticRename(newName);
}
finally {
FinishMarkAction.finish(myProject, myEditor, markAction);
protected void renameSynthetic(String newName) {
PsiNamedElement elementToRename = getVariable();
if (elementToRename instanceof ClosureSyntheticParameter && !"it".equals(newName)) {
final GrClosableBlock closure = ((ClosureSyntheticParameter)elementToRename).getClosure();
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
final PsiType type = ((ClosureSyntheticParameter)elementToRename).getTypeGroovy();
final GrParameter newParam = factory.createParameter(newName, TypesUtil.unboxPrimitiveTypeWrapper(type));
final GrParameter added = closure.addParameter(newParam);
GrReferenceAdjuster.shortenReferences(added);
}
}
}