diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java index 096776e53f78..b3482defa348 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java @@ -82,7 +82,7 @@ public class GeeseUtil { } @Nullable - static Alignment calculateRBraceAlignment(PsiElement rBrace, Map alignments, Map blocks) { + static Alignment calculateRBraceAlignment(PsiElement rBrace, Map alignments) { int leadingBraceCount = 0; PsiElement next; @@ -146,11 +146,7 @@ public class GeeseUtil { Alignment alignment = alignments.get(cur); if (alignment == null) { - final GroovyBlock block = blocks.get(cur); alignment = Alignment.createAlignment(true); - if (block != null) { - block.setAlignment(alignment); - } alignments.put(cur, alignment); } return alignment; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java index a0ad58d184f7..48d99924c203 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java @@ -55,7 +55,7 @@ import java.util.Map; * * @author ilyas */ -public abstract class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { +public class GroovyBlock implements Block, GroovyElementTypes, ASTBlock { final protected ASTNode myNode; protected Alignment myAlignment; final protected Indent myIndent; @@ -63,7 +63,6 @@ public abstract class GroovyBlock implements Block, GroovyElementTypes, ASTBlock final protected CommonCodeStyleSettings mySettings; final protected GroovyCodeStyleSettings myGroovySettings; final protected Map myInnerAlignments; - final protected Map myBlocks; protected List mySubBlocks = null; @@ -73,12 +72,10 @@ public abstract class GroovyBlock implements Block, GroovyElementTypes, ASTBlock @Nullable final Wrap wrap, final CommonCodeStyleSettings settings, GroovyCodeStyleSettings groovySettings, - @NotNull Map innerAlignments, Map blocks) { + @NotNull Map innerAlignments) { myNode = node; - myBlocks = blocks; if (groovySettings.USE_FLYING_GEESE_BRACES) { PsiElement psi = myNode.getPsi(); - myBlocks.put(psi, this); if (alignment == null) { alignment = innerAlignments.get(psi); } @@ -119,8 +116,12 @@ public abstract class GroovyBlock implements Block, GroovyElementTypes, ASTBlock } @NotNull + @Override public List getSubBlocks() { - return mySubBlocks; + if (mySubBlocks == null) { + mySubBlocks = new GroovyBlockGenerator(this).generateSubBlocks(); + } + return mySubBlocks; } @Nullable @@ -228,10 +229,6 @@ public abstract class GroovyBlock implements Block, GroovyElementTypes, ASTBlock return isIncomplete(myNode); } - public void setAlignment(Alignment alignment) { - myAlignment = alignment; - } - /** * @param node Tree node * @return true if node is incomplete diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java index d72d4a061660..dcc7e2719d92 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java @@ -82,7 +82,6 @@ public class GroovyBlockGenerator implements GroovyElementTypes { private final Wrap myWrap; private final CommonCodeStyleSettings mySettings; private final Map myInnerAlignments; - private final Map myBlocks; private final GroovyCodeStyleSettings myGroovySettings; public GroovyBlockGenerator(GroovyBlock block) { @@ -93,7 +92,6 @@ public class GroovyBlockGenerator implements GroovyElementTypes { mySettings = myBlock.getSettings(); myInnerAlignments = myBlock.getInnerAlignments(); myGroovySettings = myBlock.getGroovySettings(); - myBlocks = myBlock.myBlocks; } @@ -136,8 +134,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { for (ASTNode childNode : children) { if (childNode.getTextRange().getLength() > 0) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); - subBlocks.add(new GroovySimpleBlock(childNode, myAlignment, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments, - myBlocks)); + subBlocks.add(new GroovyBlock(childNode, myAlignment, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } } return subBlocks; @@ -158,8 +155,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { final Alignment newAlignment = mustAlign(blockPsi, astNodes) ? Alignment.createAlignment() : null; for (ASTNode childNode : astNodes) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); - subBlocks.add(new GroovySimpleBlock(childNode, isKeyword(childNode) ? null : newAlignment, indent, myWrap, mySettings, myGroovySettings, - myInnerAlignments, myBlocks)); + subBlocks.add(new GroovyBlock(childNode, isKeyword(childNode) ? null : newAlignment, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } return subBlocks; } @@ -172,8 +168,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { for (ASTNode childNode : children) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); Alignment alignmentToUse = classLevel ? myAlignment : myInnerAlignments.get(childNode.getPsi()); - subBlocks.add(new GroovySimpleBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments, - myBlocks)); + subBlocks.add(new GroovyBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } return subBlocks; } @@ -182,8 +177,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { final ArrayList subBlocks = new ArrayList(); for (ASTNode childNode : visibleChildren(myNode)) { final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode); - subBlocks.add(new GroovySimpleBlock(childNode, myInnerAlignments.get(childNode.getPsi()), indent, myWrap, mySettings, myGroovySettings, - myInnerAlignments, myBlocks)); + subBlocks.add(new GroovyBlock(childNode, myInnerAlignments.get(childNode.getPsi()), indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } return subBlocks; } @@ -232,9 +226,9 @@ public class GroovyBlockGenerator implements GroovyElementTypes { } } } - else if (GeeseUtil.isClosureRBrace(psi) && myGroovySettings.USE_FLYING_GEESE_BRACES) { + /*else if (GeeseUtil.isClosureRBrace(psi) && myGroovySettings.USE_FLYING_GEESE_BRACES) { myInnerAlignments.put(psi, GeeseUtil.calculateRBraceAlignment(psi, myInnerAlignments, myBlocks)); - } + }*/ else { if (psi instanceof PsiComment) { PsiElement prev = psi.getPrevSibling(); @@ -325,22 +319,19 @@ public class GroovyBlockGenerator implements GroovyElementTypes { final int start = myNode.getTextRange().getStartOffset(); final int end = myNode.getTextRange().getEndOffset(); - subBlocks.add(new GroovySimpleBlock(myNode, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments, - myBlocks) { + subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) { @NotNull public TextRange getTextRange() { return new TextRange(start, start + 3); } }); - subBlocks.add(new GroovySimpleBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments, - myBlocks) { + subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) { @NotNull public TextRange getTextRange() { return new TextRange(start + 3, end - 3); } }); - subBlocks.add(new GroovySimpleBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments, - myBlocks) { + subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) { @NotNull public TextRange getTextRange() { return new TextRange(end - 3, end); @@ -354,15 +345,13 @@ public class GroovyBlockGenerator implements GroovyElementTypes { final int start = myNode.getTextRange().getStartOffset(); final int end = myNode.getTextRange().getEndOffset(); - subBlocks.add(new GroovySimpleBlock(myNode, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments, - myBlocks) { + subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) { @NotNull public TextRange getTextRange() { return new TextRange(start, start + 3); } }); - subBlocks.add(new GroovySimpleBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments, - myBlocks) { + subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) { @NotNull public TextRange getTextRange() { return new TextRange(start + 3, end); @@ -444,8 +433,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { PsiElement psi = childNode.getPsi(); if (!(psi instanceof GrBinaryExpression)) { Alignment alignmentToUse = op == psi ? myInnerAlignments.get(op) : alignment; - list.add(new GroovySimpleBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments, - myBlocks)); + list.add(new GroovyBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } } if (myExpr.getRightOperand() instanceof GrBinaryExpression) { @@ -474,8 +462,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { } if (i < grandChildren.size()) { LOG.assertTrue(nameElement == grandChildren.get(i).getPsi()); - list.add(new MethodCallWithoutQualifierBlock(nameElement, null, myWrap, mySettings, myGroovySettings, topLevel, children, elem, - myInnerAlignments, myBlocks)); + list.add(new MethodCallWithoutQualifierBlock(nameElement, null, myWrap, mySettings, myGroovySettings, topLevel, children, elem, myInnerAlignments)); } return; } @@ -496,7 +483,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { else { Alignment alignmentToUse = myInnerAlignments.get(fst.getPsi()); Indent indent = Indent.getContinuationWithoutFirstIndent(); - list.add(new GroovySimpleBlock(fst, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments, myBlocks)); + list.add(new GroovyBlock(fst, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } addNestedChildrenSuffix(list, alignment, topLevel, children, limit); } @@ -510,7 +497,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { Indent.getContinuationWithoutFirstIndent() : Indent.getNoneIndent(); Alignment alignmentToUse = TokenSets.DOTS.contains(type) ? alignment : myInnerAlignments.get(childNode.getPsi()); - list.add(new GroovySimpleBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments, myBlocks)); + list.add(new GroovyBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments)); } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java index c697f266a297..6fd00921d65f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java @@ -21,6 +21,7 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiRecursiveElementVisitor; import com.intellij.psi.TokenType; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; @@ -36,6 +37,8 @@ import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; +import java.util.Map; + /** * @author ilyas */ @@ -50,9 +53,24 @@ public class GroovyFormattingModelBuilder implements FormattingModelBuilder { assert astNode != null; CommonCodeStyleSettings groovySettings = settings.getCommonSettings(GroovyFileType.GROOVY_LANGUAGE); GroovyCodeStyleSettings customSettings = settings.getCustomSettings(GroovyCodeStyleSettings.class); - final GroovyBlock block = new GroovySimpleBlock(astNode, null, Indent.getAbsoluteNoneIndent(), null, groovySettings, customSettings, - CollectionFactory.hashMap(), - CollectionFactory.hashMap()); + + final Map innerAlignments = CollectionFactory.hashMap(); + if (customSettings.USE_FLYING_GEESE_BRACES) { + element.accept(new PsiRecursiveElementVisitor() { + @Override + public void visitElement(PsiElement element) { + if (GeeseUtil.isClosureRBrace(element)) { + final Alignment alignment = GeeseUtil.calculateRBraceAlignment(element, innerAlignments); + innerAlignments.put(element, alignment); + } + else { + super.visitElement(element); + } + } + }); + } + final GroovyBlock block = + new GroovyBlock(astNode, null, Indent.getAbsoluteNoneIndent(), null, groovySettings, customSettings, innerAlignments); return new GroovyFormattingModel(containingFile, block, FormattingDocumentModelImpl.createOn(containingFile)); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovySimpleBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovySimpleBlock.java deleted file mode 100644 index 960c12d8a0e8..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovySimpleBlock.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2000-2011 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.plugins.groovy.formatter; - -import com.intellij.formatting.Alignment; -import com.intellij.formatting.Indent; -import com.intellij.formatting.Wrap; -import com.intellij.lang.ASTNode; -import com.intellij.psi.PsiElement; -import com.intellij.psi.codeStyle.CommonCodeStyleSettings; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Map; - -/** - * @author Max Medvedev - */ -public class GroovySimpleBlock extends GroovyBlock { - public GroovySimpleBlock(@NotNull ASTNode node, - @Nullable Alignment alignment, - @NotNull Indent indent, - @Nullable Wrap wrap, - CommonCodeStyleSettings settings, - GroovyCodeStyleSettings groovySettings, - @NotNull Map innerAlignments, Map blocks) { - super(node, alignment, indent, wrap, settings, groovySettings, innerAlignments, blocks); - mySubBlocks = new GroovyBlockGenerator(this).generateSubBlocks(); - } -} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java index 51aa16d7887c..001814778e3a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java @@ -33,36 +33,48 @@ import java.util.Map; * @author peter */ public class MethodCallWithoutQualifierBlock extends GroovyBlock { - private final TextRange myRange; + private final PsiElement myNameElement; + private final boolean myTopLevel; + private final List myChildren; + private final PsiElement myElem; - protected MethodCallWithoutQualifierBlock(PsiElement nameElement, - Alignment alignment, - Wrap wrap, - CommonCodeStyleSettings settings, - GroovyCodeStyleSettings groovySettings, - boolean topLevel, - List children, - PsiElement elem, - Map innerAlignments, Map blocks) { - super(nameElement.getNode(), alignment, Indent.getContinuationWithoutFirstIndent(), wrap, settings, groovySettings, innerAlignments,blocks); - myRange = new TextRange(nameElement.getTextRange().getStartOffset(), elem.getTextRange().getEndOffset()); + public MethodCallWithoutQualifierBlock(PsiElement nameElement, + Alignment alignment, + Wrap wrap, + CommonCodeStyleSettings settings, + GroovyCodeStyleSettings groovySettings, + boolean topLevel, + List children, + PsiElement elem, + Map innerAlignments) { + super(nameElement.getNode(), alignment, Indent.getContinuationWithoutFirstIndent(), wrap, settings, groovySettings, innerAlignments); + myNameElement = nameElement; + myTopLevel = topLevel; + myChildren = children; + myElem = elem; + } - mySubBlocks = new ArrayList(); - final GroovySimpleBlock first = - new GroovySimpleBlock(nameElement.getNode(), myInnerAlignments.get(nameElement), Indent.getContinuationWithoutFirstIndent(), myWrap, - mySettings, myGroovySettings, myInnerAlignments, myBlocks); - mySubBlocks.add(first); - new GroovyBlockGenerator(this).addNestedChildrenSuffix(mySubBlocks, myAlignment, topLevel, children, children.size()); + @NotNull + @Override + public List getSubBlocks() { + if (mySubBlocks == null) { + mySubBlocks = new ArrayList(); + mySubBlocks.add( + new GroovyBlock(myNameElement.getNode(), myInnerAlignments.get(myNameElement), Indent.getContinuationWithoutFirstIndent(), myWrap, + mySettings, myGroovySettings, myInnerAlignments)); + new GroovyBlockGenerator(this).addNestedChildrenSuffix(mySubBlocks, myAlignment, myTopLevel, myChildren, myChildren.size()); + } + return mySubBlocks; } @NotNull @Override public TextRange getTextRange() { - return myRange; + return new TextRange(myNameElement.getTextRange().getStartOffset(), myElem.getTextRange().getEndOffset()); } @Override public boolean isLeaf() { return false; } -} +} \ No newline at end of file