From 5b64f3b1c45b829f0cc33d064a851ac7e6bdfcff Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 16 May 2011 12:43:12 +0400 Subject: [PATCH 1/9] correct formatting on visibility changed (IDEA-69467) --- .../AbstractInplaceIntroducer.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractInplaceIntroducer.java index c5382798e221..aec3cc5fce9f 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractInplaceIntroducer.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractInplaceIntroducer.java @@ -179,20 +179,24 @@ public abstract class AbstractInplaceIntroducer extends VariableInplaceIntroduce length = PsiModifier.PRIVATE.length(); } - final int startOffset = textOffset + idx; - final int endOffset; - if (idx == -1) { - endOffset = startOffset; - } - else { - endOffset = textOffset + length; - } - String visibility = getVisibility(); if (visibility == PsiModifier.PACKAGE_LOCAL) { visibility = ""; } - final String finalVisibility = visibility; + + final boolean wasPackageLocal = idx == -1; + final boolean isPackageLocal = visibility.isEmpty(); + + final int startOffset = textOffset + (wasPackageLocal ? 0 : idx); + final int endOffset; + if (wasPackageLocal) { + endOffset = startOffset; + } + else { + endOffset = textOffset + length + (isPackageLocal ? 1 : 0); + } + + final String finalVisibility = visibility + (wasPackageLocal ? " " : ""); Runnable runnable = new Runnable() { @Override From 8d577faa6bff17dff05d30fda4757482ff348df2 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 16 May 2011 13:45:03 +0400 Subject: [PATCH 2/9] revert introduced variable on escape (IDEA-69048) --- .../AbstractInplaceIntroducer.java | 16 -------- .../IntroduceVariableBase.java | 4 +- .../VariableInplaceIntroducer.java | 38 +++++++++++++++++++ 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractInplaceIntroducer.java index aec3cc5fce9f..ff6e0b9b56f6 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractInplaceIntroducer.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractInplaceIntroducer.java @@ -125,22 +125,6 @@ public abstract class AbstractInplaceIntroducer extends VariableInplaceIntroduce super.addHighlights(ranges, editor, highlighters, highlightManager); } - @Nullable - protected static PsiExpression restoreExpression(PsiFile containingFile, - PsiVariable psiVariable, - PsiElementFactory elementFactory, - RangeMarker marker, String exprText) { - if (exprText == null) return null; - if (psiVariable == null || !psiVariable.isValid()) return null; - final PsiElement refVariableElement = containingFile.findElementAt(marker.getStartOffset()); - final PsiExpression expression = PsiTreeUtil.getParentOfType(refVariableElement, PsiReferenceExpression.class); - if (expression instanceof PsiReferenceExpression && (((PsiReferenceExpression)expression).resolve() == psiVariable || - Comparing.strEqual(psiVariable.getName(), ((PsiReferenceExpression)expression).getReferenceName()))) { - return (PsiExpression)expression.replace(elementFactory.createExpressionFromText(exprText, psiVariable)); - } - return expression != null && expression.isValid() && expression.getText().equals(exprText) ? expression : null; - } - protected abstract class VisibilityListener implements ChangeListener { private Project myProject; private final String myCommandName; diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java index 8bbcae485a23..1c8f25d357e2 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -465,6 +465,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme for (PsiExpression occurrence : occurrences) { occurrenceMarkers.add(editor.getDocument().createRangeMarker(occurrence.getTextRange())); } + final String expressionText = expr.getText(); final Runnable runnable = introduce(project, expr, editor, anchorStatement, tempContainer, occurrences, anchorStatementIfAll, settings, variable); CommandProcessor.getInstance().executeCommand( @@ -477,9 +478,10 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme if (elementToRename != null) { editor.getCaretModel().moveToOffset(elementToRename.getTextOffset()); final boolean cantChangeFinalModifier = (hasWriteAccess || inFinalContext) && choice == OccurrencesChooser.ReplaceChoice.ALL; - final VariableInplaceRenamer renamer = + final VariableInplaceIntroducer renamer = new VariableInplaceIntroducer(project, expression, editor, elementToRename, cantChangeFinalModifier, typeSelectorManager.getTypesForAll().length > 1, exprMarker, occurrenceMarkers, IntroduceVariableBase.REFACTORING_NAME, IntroduceVariableBase.REFACTORING_NAME); + renamer.initInitialText(expressionText); PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()); renamer.performInplaceRename(false, new LinkedHashSet(Arrays.asList(suggestedName.names))); } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java index fb50f2d1c0ce..0d5ccb973e92 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java @@ -79,6 +79,7 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer { private boolean myCantChangeFinalModifier; private String myCommandName; private String myTitle; + private String myExpressionText; public VariableInplaceIntroducer(final Project project, final TypeExpression expression, @@ -111,7 +112,10 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer { editor.putUserData(ReassignVariableUtil.OCCURRENCES_KEY, occurrenceMarkers.toArray(new RangeMarker[occurrenceMarkers.size()])); setAdvertisementText(getAdvertisementText(declarationStatement, defaultType, hasTypeSuggestion)); + } + public void initInitialText(String text) { + myExpressionText = text; } @Override @@ -216,6 +220,24 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer { myEditor.getCaretModel().moveToOffset(myExprMarker.getStartOffset()); myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); } + if (myExpressionText != null) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + final PsiDeclarationStatement element = myPointer.getElement(); + if (element != null) { + final PsiElement[] vars = element.getDeclaredElements(); + if (vars.length > 0 && vars[0] instanceof PsiVariable) { + final PsiFile containingFile = element.getContainingFile(); + final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); + for (RangeMarker occurrenceMarker : myOccurrenceMarkers) { + restoreExpression(containingFile, (PsiVariable)vars[0], elementFactory, occurrenceMarker, myExpressionText); + } + element.delete(); + } + } + } + }); + } } } finally { @@ -396,6 +418,22 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer { myBalloon.show(new RelativePoint(new Point(screenPoint.x, y)), Balloon.Position.above); } + @Nullable + protected static PsiExpression restoreExpression(PsiFile containingFile, + PsiVariable psiVariable, + PsiElementFactory elementFactory, + RangeMarker marker, String exprText) { + if (exprText == null) return null; + if (psiVariable == null || !psiVariable.isValid()) return null; + final PsiElement refVariableElement = containingFile.findElementAt(marker.getStartOffset()); + final PsiExpression expression = PsiTreeUtil.getParentOfType(refVariableElement, PsiReferenceExpression.class); + if (expression instanceof PsiReferenceExpression && (((PsiReferenceExpression)expression).resolve() == psiVariable || + Comparing.strEqual(psiVariable.getName(), ((PsiReferenceExpression)expression).getReferenceName()))) { + return (PsiExpression)expression.replace(elementFactory.createExpressionFromText(exprText, psiVariable)); + } + return expression != null && expression.isValid() && expression.getText().equals(exprText) ? expression : null; + } + public class FinalListener implements ActionListener { private final Project myProject; private final String myCommandName; From 3c8b6d332e5055ddf983a34d8449fa1840da8673 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 16 May 2011 13:46:26 +0400 Subject: [PATCH 3/9] IDEA-69442 Radio buttons should be disabled, when sending statistics is not allowed --- .../StatisticsConfigurationComponent.form | 2 +- .../StatisticsConfigurationComponent.java | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form index abc0308b4aaf..a8052abc0fbe 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form +++ b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form @@ -34,7 +34,7 @@ - + diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java index 0d4f1057eb0d..6a113a601d71 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java @@ -21,6 +21,8 @@ import com.intellij.openapi.ui.ex.MultiLineLabel; import javax.swing.*; import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; public class StatisticsConfigurationComponent { @@ -31,10 +33,26 @@ public class StatisticsConfigurationComponent { private JRadioButton myMonthlyRadioButton; private JRadioButton myWeeklyRadioButton; private JLabel myLabel; + private JPanel myRadioButtonPanel; public StatisticsConfigurationComponent() { myTitle.setText("Help improve "+ ApplicationNamesInfo.getInstance().getFullProductName() + " by sending anonymous usage statistics to JetBrains"); myLabel.setText("We're asking your permission to send information about your plugins configuration (what is enabled and what is not)
and feature usage statistics (e.g. how frequently you're using code completion).
This data is anonymous, does not contain any personal information, collected for use only by JetBrains
and will never be transmitted to any third party."); + + myAllowToSendUsagesCheckBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + setRadioButtonsEnabled(); + } + }); + } + + private void setRadioButtonsEnabled() { + final boolean enabled = myAllowToSendUsagesCheckBox.isSelected(); + + myWeeklyRadioButton.setEnabled(enabled); + myMonthlyRadioButton.setEnabled(enabled); + myDailyRadioButton.setEnabled(enabled); } public JPanel getJComponent() { @@ -49,6 +67,7 @@ public class StatisticsConfigurationComponent { final UsageStatisticsPersistenceComponent persistenceComponent = UsageStatisticsPersistenceComponent.getInstance(); myAllowToSendUsagesCheckBox.setSelected(persistenceComponent.isAllowed()); + setRadioButtonsEnabled(); final SendPeriod period = persistenceComponent.getPeriod(); From b0421bf39ff4d102ab87d01e50f21989b0a15501 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Mon, 16 May 2011 13:50:22 +0400 Subject: [PATCH 4/9] IDEA-69678: One must go to next occurrence if replacing even if current occurrence is excluded. --- .../lang-impl/src/com/intellij/find/FindUtil.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/FindUtil.java b/platform/lang-impl/src/com/intellij/find/FindUtil.java index e571082fa986..b3f246d80b70 100644 --- a/platform/lang-impl/src/com/intellij/find/FindUtil.java +++ b/platform/lang-impl/src/com/intellij/find/FindUtil.java @@ -527,6 +527,7 @@ public class FindUtil { ((DocumentEx) document).setInBulkUpdate(true); } } + int newOffset; if (delegate == null || delegate.shouldReplace(result, toReplace)){ boolean reallyReplace = toPrompt; if (reallyReplace) { @@ -538,13 +539,17 @@ public class FindUtil { } TextRange textRange = doReplace(project, document, model, result, toReplace, reallyReplace, rangesToChange); replaced = true; - int newOffset = model.isForward() ? textRange.getEndOffset() : textRange.getStartOffset(); - if (newOffset == offset) { - newOffset += model.isForward() ? 1 : -1; - } - offset = newOffset; + newOffset = model.isForward() ? textRange.getEndOffset() : textRange.getStartOffset(); occurrences++; } + else { + newOffset = model.isForward() ? result.getEndOffset() : result.getStartOffset(); + } + + if (newOffset == offset) { + newOffset += model.isForward() ? 1 : -1; + } + offset = newOffset; } From c2759163dbd1ed55e3b4f11fe4dbb595d1aacdc3 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Mon, 16 May 2011 14:11:25 +0400 Subject: [PATCH 5/9] IDEA-67401 Idea hangs when loading IDETalk --- .../com/intellij/openapi/module/impl/ModuleManagerImpl.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java index 7197d148e006..2621ebdce55e 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java @@ -29,6 +29,7 @@ import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.components.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.*; +import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.ModuleListener; import com.intellij.openapi.project.Project; @@ -566,7 +567,9 @@ public class ModuleManagerImpl extends ModuleManager implements ProjectComponent swingRunnable.run(); } else { - app.invokeAndWait(swingRunnable, ModalityState.defaultModalityState()); + ProgressIndicator pi = ProgressManager.getInstance().getProgressIndicator(); + pi.setText("Loading " + module.getName()); + app.invokeAndWait(swingRunnable, pi.getModalityState()); } } } From 94038d4adb1b3fb46b02449ca591b566f6aba277 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 16 May 2011 13:44:00 +0400 Subject: [PATCH 6/9] IDEA-66819: wrong XML validation/completion when XSDfile includes redefine --- .../reference/impl/providers/SchemaReferencesProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/SchemaReferencesProvider.java b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/SchemaReferencesProvider.java index 6ba8c7a1f586..fed29ddaecee 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/SchemaReferencesProvider.java +++ b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/SchemaReferencesProvider.java @@ -686,9 +686,10 @@ public class SchemaReferencesProvider extends PsiReferenceProvider { } public static @Nullable XmlNSDescriptorImpl findRedefinedDescriptor(XmlTag tag, String text) { + final String localName = XmlUtil.findLocalNameByQualifiedName(text); for(XmlTag parentTag = tag.getParentTag(); parentTag != null; parentTag = parentTag.getParentTag()) { - if (text.equals(parentTag.getAttributeValue("name"))) { + if (localName.equals(parentTag.getAttributeValue("name"))) { final XmlTag grandParent = parentTag.getParentTag(); if (grandParent != null && "redefine".equals(grandParent.getLocalName())) { From b48753bad92ac9e7d0061be96ccb010b92b93c76 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 16 May 2011 14:06:15 +0400 Subject: [PATCH 7/9] wrong package statement: enable move to another package even if package doesn't exist (IDEA-60398) --- .../src/com/intellij/codeInspection/MoveToPackageFix.java | 4 +--- .../WrongPackageStatementInspection.java | 7 ++----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/MoveToPackageFix.java b/java/java-impl/src/com/intellij/codeInspection/MoveToPackageFix.java index 8bd640612856..c8ae428c44ad 100644 --- a/java/java-impl/src/com/intellij/codeInspection/MoveToPackageFix.java +++ b/java/java-impl/src/com/intellij/codeInspection/MoveToPackageFix.java @@ -54,9 +54,7 @@ public class MoveToPackageFix implements LocalQuickFix { && myFile.getManager().isInProject(myFile) && myFile instanceof PsiJavaFile && ((PsiJavaFile) myFile).getClasses().length != 0 - && myTargetPackage != null - && JavaPsiFacade.getInstance(myFile.getProject()).findPackage(myTargetPackage) != null - ; + && myTargetPackage != null; } public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) { diff --git a/java/java-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspection.java b/java/java-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspection.java index 3bd236db3e0e..a880471e3e45 100644 --- a/java/java-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspection.java @@ -63,12 +63,9 @@ public class WrongPackageStatementInspection extends BaseJavaLocalInspectionTool final PsiJavaCodeReferenceElement packageReference = packageStatement.getPackageReference(); PsiPackage classPackage = (PsiPackage)packageReference.resolve(); List availableFixes = new ArrayList(); - if (classPackage == null) { + if (classPackage == null || !Comparing.equal(dirPackage.getQualifiedName(), packageReference.getText(), true)) { availableFixes.add(new AdjustPackageNameFix(packageName)); - } - else if (!Comparing.equal(dirPackage.getQualifiedName(), packageReference.getText(), true)) { - availableFixes.add(new AdjustPackageNameFix(packageName)); - MoveToPackageFix moveToPackageFix = new MoveToPackageFix(classPackage.getQualifiedName()); + MoveToPackageFix moveToPackageFix = new MoveToPackageFix(classPackage != null ? classPackage.getQualifiedName() : packageReference.getText()); if (moveToPackageFix.isAvailable(file)) { availableFixes.add(moveToPackageFix); } From acbbd59111e20c0f10ae1aba6a894a4529311999 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 16 May 2011 14:52:46 +0400 Subject: [PATCH 8/9] scopes editing: hide disabled actions (IDEA-68989) --- .../intellij/ide/util/scopeChooser/GroupByScopeTypeAction.java | 2 +- .../intellij/packageDependencies/ui/ProjectPatternProvider.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/java-impl/src/com/intellij/ide/util/scopeChooser/GroupByScopeTypeAction.java b/java/java-impl/src/com/intellij/ide/util/scopeChooser/GroupByScopeTypeAction.java index 2ed3cced9932..a170e2d7014b 100644 --- a/java/java-impl/src/com/intellij/ide/util/scopeChooser/GroupByScopeTypeAction.java +++ b/java/java-impl/src/com/intellij/ide/util/scopeChooser/GroupByScopeTypeAction.java @@ -47,6 +47,6 @@ public final class GroupByScopeTypeAction extends ToggleAction { public void update(final AnActionEvent e) { super.update(e); - e.getPresentation().setEnabled(DependencyUISettings.getInstance().SCOPE_TYPE != ProjectPatternProvider.FILE); + e.getPresentation().setVisible(DependencyUISettings.getInstance().SCOPE_TYPE != ProjectPatternProvider.FILE); } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/ui/ProjectPatternProvider.java b/platform/lang-impl/src/com/intellij/packageDependencies/ui/ProjectPatternProvider.java index 4e57214ccbb6..02f0336fc7e2 100644 --- a/platform/lang-impl/src/com/intellij/packageDependencies/ui/ProjectPatternProvider.java +++ b/platform/lang-impl/src/com/intellij/packageDependencies/ui/ProjectPatternProvider.java @@ -139,7 +139,7 @@ public class ProjectPatternProvider extends PatternDialectProvider { public void update(final AnActionEvent e) { super.update(e); - e.getPresentation().setEnabled(DependencyUISettings.getInstance().SCOPE_TYPE == FILE); + e.getPresentation().setVisible(DependencyUISettings.getInstance().SCOPE_TYPE == FILE); } } } \ No newline at end of file From c1186a4062b991294ccf48869d9889898cf39d42 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Mon, 16 May 2011 15:04:52 +0400 Subject: [PATCH 9/9] IDEA-69656 Complete Current Statement: Provide support for completing 'condition' section of 'for' statement Incomplete 'for' formatting is corrected --- .../psi/formatter/java/FormattingAstUtil.java | 45 +++++++++++++++++++ .../java/JavaSpacePropertyProcessor.java | 8 ++-- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/FormattingAstUtil.java b/java/java-impl/src/com/intellij/psi/formatter/java/FormattingAstUtil.java index 97fdea129a80..3955e78abd31 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/FormattingAstUtil.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/FormattingAstUtil.java @@ -21,6 +21,7 @@ import com.intellij.psi.TokenType; import com.intellij.psi.impl.source.SourceTreeToPsiMap; import com.intellij.psi.impl.source.tree.JavaElementType; import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.HashSet; @@ -62,6 +63,50 @@ public class FormattingAstUtil { return result; } + @Nullable + public static ASTNode getPrevLeaf(@NotNull final ASTNode node, @NotNull IElementType ... typesToIgnore) { + ASTNode prev = getPrev(node, typesToIgnore); + if (prev == null) { + return null; + } + + ASTNode result = prev; + ASTNode lastChild = prev.getLastChildNode(); + while (lastChild != null) { + result = lastChild; + lastChild = lastChild.getLastChildNode(); + } + + for (IElementType type : typesToIgnore) { + if (result.getElementType() == type) { + return getPrevLeaf(result, typesToIgnore); + } + } + return result; + } + + @Nullable + public static ASTNode getPrev(@NotNull ASTNode node, @NotNull IElementType... typesToIgnore) { + ASTNode prev = node.getTreePrev(); + ASTNode parent = node.getTreeParent(); + while (prev == null && parent != null) { + prev = parent.getTreePrev(); + parent = parent.getTreeParent(); + } + + if (prev == null) { + return null; + } + + for (IElementType type : typesToIgnore) { + if (prev.getElementType() == type) { + return getPrev(prev, typesToIgnore); + } + } + + return prev; + } + /** * Tries to get next non-white space AST node for the given one. * diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java index d23086c6f4a2..41aeb88de04e 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java @@ -1175,11 +1175,9 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor { createSpaceInCode(mySettings.SPACE_WITHIN_FOR_PARENTHESES); } else { - ASTNode prev = FormattingAstUtil.getPrevNonWhiteSpaceNode(myChild2); - if (prev != null && (prev.getElementType() == JavaTokenType.SEMICOLON || prev == statement.getInitialization() - || prev == statement.getCondition())) - { - // Handle empty 'condition' section. + ASTNode prev = FormattingAstUtil.getPrevLeaf(myChild2, TokenType.WHITE_SPACE, TokenType.ERROR_ELEMENT); + if (prev != null && prev.getElementType() == JavaTokenType.SEMICOLON) { + // Handle empty 'initialization' or 'condition' section. createSpaceInCode(mySettings.SPACE_AFTER_SEMICOLON); } else {