diff --git a/source/com/intellij/openapi/editor/actions/EnterAction.java b/source/com/intellij/openapi/editor/actions/EnterAction.java index e5f3475b0001..17ba4ab4044c 100644 --- a/source/com/intellij/openapi/editor/actions/EnterAction.java +++ b/source/com/intellij/openapi/editor/actions/EnterAction.java @@ -80,3 +80,11 @@ public class EnterAction extends EditorAction { editor.getSelectionModel().removeSelection(); } } +class InStaticInitializer { +public static final String x = "Hello World"; + + static { + System.out.println(x); + } + //Field must be placed before initializer or illegal forward reference will happen +} \ No newline at end of file diff --git a/source/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java b/source/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java index c65bc6d72e3e..f9976e265e56 100644 --- a/source/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java +++ b/source/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java @@ -9,6 +9,7 @@ import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; @@ -31,11 +32,11 @@ public class CodeEditUtil { FileType fileType = file.getFileType(); //??? - if (first.getElementType() == ElementType.WHITE_SPACE){ + if (first.getElementType() == ElementType.WHITE_SPACE) { if (first == last) return null; first = first.getTreeNext(); } - if (last.getElementType() == ElementType.WHITE_SPACE){ + if (last.getElementType() == ElementType.WHITE_SPACE) { if (first == last) return null; last = last.getTreePrev(); } @@ -51,25 +52,25 @@ public class CodeEditUtil { ASTNode afterLast = last.getTreeNext(); ASTNode next; - for(ASTNode child = first; child != afterLast; child = next){ + for (ASTNode child = first; child != afterLast; child = next) { next = child.getTreeNext(); parent.addChild(child, anchorBefore); } - if(fileType == StdFileTypes.XHTML) return first; - if (adjustSelf){ + if (fileType == StdFileTypes.XHTML) return first; + if (adjustSelf) { ASTNode elementBefore = Helper.shiftBackwardToNonSpace(parent.getTreePrev()); parent = (CompositeElement)codeLayouter.processSpace(elementBefore, parent); parent = (CompositeElement)indentAdjuster.adjustFirstLineIndent(parent); ASTNode elementAfter = Helper.shiftForwardToNonSpace(parent.getTreeNext()); elementAfter = codeLayouter.processSpace(parent, elementAfter); - if (elementAfter != null){ + if (elementAfter != null) { elementAfter = indentAdjuster.adjustFirstLineIndent(elementAfter); } } ASTNode elementBefore = Helper.shiftBackwardToNonSpace(first.getTreePrev()); - if (needSeparateLines(first) && helper.getLineBreakCount(parent, elementBefore, first) == 0){ + if (needSeparateLines(first) && helper.getLineBreakCount(parent, elementBefore, first) == 0) { helper.makeVerticalSpace(parent, elementBefore, first, 0); } first = (TreeElement)codeLayouter.processSpace(elementBefore, first);// special mode? @@ -79,33 +80,33 @@ public class CodeEditUtil { String spaceText = Helper.getSpaceText(parent, prev, first); int index = Math.max(spaceText.lastIndexOf('\n'), spaceText.lastIndexOf('\r')); if (index >= 0 - || (parent.getTreeParent() == null && prev == null && first.getTextRange().getStartOffset() == spaceText.length())){ + || (parent.getTreeParent() == null && prev == null && first.getTextRange().getStartOffset() == spaceText.length())) { spaceText = spaceText.substring(0, index + 1) + helper.fillIndent(oldIndent); first = (TreeElement)helper.makeSpace(parent, prev, first, spaceText, false); } - if (oneElement){ + if (oneElement) { last = first; } ASTNode elementAfter = Helper.shiftForwardToNonSpace(last.getTreeNext()); - if (elementAfter != null && needSeparateLines(last) && helper.getLineBreakCount(parent, last, elementAfter) == 0){ + if (elementAfter != null && needSeparateLines(last) && helper.getLineBreakCount(parent, last, elementAfter) == 0) { helper.makeVerticalSpace(parent, last, elementAfter, 0); } elementAfter = codeLayouter.processSpace(last, elementAfter);// special mode? - if (elementAfter != null){ + if (elementAfter != null) { elementAfter = indentAdjuster.adjustFirstLineIndent(elementAfter); } afterLast = last.getTreeNext(); - for(ASTNode child = first; child != afterLast; child = child.getTreeNext()){ + for (ASTNode child = first; child != afterLast; child = child.getTreeNext()) { child = indentAdjuster.adjustNormalizeIndent(child); - if (child.getElementType() == ElementType.CODE_BLOCK){ + if (child.getElementType() == ElementType.CODE_BLOCK) { PsiElement[] children = SourceTreeToPsiMap.treeElementToPsi(child).getChildren(); - for(int i = 0; i < children.length; i++){ + for (int i = 0; i < children.length; i++) { PsiElement element = children[i]; ASTNode child1 = SourceTreeToPsiMap.psiElementToTree(element); - if (Helper.isNonSpace(child1)){ + if (Helper.isNonSpace(child1)) { child1 = indentAdjuster.adjustIndent(child1); } } @@ -141,17 +142,17 @@ public class CodeEditUtil { final String spaceAfterText = spaceAfter == null ? null : spaceAfter.getText(); ASTNode childNext; - for(ASTNode child = first; child != next; child = childNext){ + for (ASTNode child = first; child != next; child = childNext) { childNext = child.getTreeNext(); parent.removeChild(child); } - if(fileType == StdFileTypes.XHTML) return; + if (fileType == StdFileTypes.XHTML) return; - if (prevNonSpace == null && nextNonSpace == null){ - if (spaceBefore != null){ + if (prevNonSpace == null && nextNonSpace == null) { + if (spaceBefore != null) { parent.removeChild(spaceBefore); } - if (spaceAfter != null){ + if (spaceAfter != null) { parent.removeChild(spaceAfter); } LOG.assertTrue(parent.getTextLength() == 0); @@ -159,7 +160,7 @@ public class CodeEditUtil { ASTNode elementAfter = Helper.shiftForwardToNonSpace(parent.getTreeNext()); normalizeSpace(helper, parent.getTreeParent(), elementBefore, elementAfter, charTableByTree); elementAfter = codeLayouter.processSpace(elementBefore, elementAfter); - if (elementAfter != null){ + if (elementAfter != null) { elementAfter = indentAdjuster.adjustFirstLineIndent(elementAfter); } return; @@ -171,12 +172,12 @@ public class CodeEditUtil { normalizeSpace(helper, parent, prevNonSpace, nextNonSpace, charTableByTree); int newBreaks = Math.max(breaksBefore, breaksAfter); - if (newBreaks != breaksBefore + breaksAfter){ + if (newBreaks != breaksBefore + breaksAfter) { helper.makeLineBreaks(parent, prevNonSpace, nextNonSpace, newBreaks); } nextNonSpace = codeLayouter.processSpace(prevNonSpace, nextNonSpace); - if (nextNonSpace != null){ + if (nextNonSpace != null) { nextNonSpace = indentAdjuster.adjustFirstLineIndent(nextNonSpace); } } @@ -196,15 +197,15 @@ public class CodeEditUtil { int oldIndent = helper.getIndent(newChild); parent.replaceChild(oldChild, newChild); - if(fileType == StdFileTypes.XHTML) return newChild; + if (fileType == StdFileTypes.XHTML) return newChild; ASTNode prevNonSpace = Helper.shiftBackwardToNonSpace(newChild.getTreePrev()); ASTNode nextNonSpace = Helper.shiftForwardToNonSpace(newChild.getTreeNext()); - if (newChild instanceof CompositeElement && newChild.getTextLength() == 0){ + if (newChild instanceof CompositeElement && newChild.getTextLength() == 0) { normalizeSpace(helper, parent, prevNonSpace, nextNonSpace, treeCharTab); } - else{ + else { normalizeSpace(helper, parent, prevNonSpace, newChild, treeCharTab); // just to not allow sticking tokens normalizeSpace(helper, parent, newChild, nextNonSpace, treeCharTab); // just to not allow sticking tokens } @@ -212,12 +213,12 @@ public class CodeEditUtil { // restore old indent of the first line String newChildText = newChild.getText(); boolean isMultiline = newChildText.indexOf('\n') >= 0 || newChildText.indexOf('\r') >= 0; - if (isMultiline){ + if (isMultiline) { String spaceText = helper.getSpaceText(parent, prevNonSpace, newChild); int index = Math.max(spaceText.lastIndexOf('\n'), spaceText.lastIndexOf('\r')); if (index >= 0 - || (parent.getTreeParent() == null && prevNonSpace == null && newChild.getTextRange().getStartOffset() == spaceText.length()) - ){ + || (parent.getTreeParent() == null && prevNonSpace == null && newChild.getTextRange().getStartOffset() == spaceText.length()) + ) { spaceText = spaceText.substring(0, index + 1) + helper.fillIndent(oldIndent); newChild = helper.makeSpace(parent, prevNonSpace, newChild, spaceText, false); //indentAdjuster.adjustIndent(newChild); @@ -236,11 +237,11 @@ public class CodeEditUtil { final PsiFile file = SourceTreeToPsiMap.treeElementToPsi(original).getContainingFile(); FileType fileType = file.getFileType(); Helper helper = new Helper(fileType, manager.getProject()); -/* - TreeElement prevWS = helper.getPrevWhitespace(original); - if( prevWS == null || prevWS.getText().indexOf('\n') < 0 ) return; -*/ - if( clone instanceof CompositeElement) { + /* + TreeElement prevWS = helper.getPrevWhitespace(original); + if( prevWS == null || prevWS.getText().indexOf('\n') < 0 ) return; + */ + if (clone instanceof CompositeElement) { CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(manager.getProject()); int origIndent = helper.getIndent(original); @@ -255,7 +256,7 @@ public class CodeEditUtil { return importHelper.getDefaultAnchor(list, statement); } - private static final HashMap ourModifierToOrderMap = new HashMap(); + private static final HashMap ourModifierToOrderMap = new HashMap(); static { //TODO : options? ourModifierToOrderMap.put(PsiModifier.PUBLIC, new Integer(1)); @@ -274,13 +275,13 @@ public class CodeEditUtil { public static ASTNode getDefaultAnchor(PsiModifierList modifierList, PsiKeyword modifier) { Integer order = ourModifierToOrderMap.get(modifier.getText()); if (order == null) return null; - for(ASTNode child = SourceTreeToPsiMap.psiElementToTree(modifierList).getFirstChildNode(); - child != null; - child = child.getTreeNext()){ - if (ElementType.KEYWORD_BIT_SET.isInSet(child.getElementType())){ + for (ASTNode child = SourceTreeToPsiMap.psiElementToTree(modifierList).getFirstChildNode(); + child != null; + child = child.getTreeNext()) { + if (ElementType.KEYWORD_BIT_SET.isInSet(child.getElementType())) { Integer order1 = ourModifierToOrderMap.get(child.getText()); if (order1 == null) continue; - if (order1.intValue() > order.intValue()){ + if (order1.intValue() > order.intValue()) { return child; } } @@ -302,7 +303,7 @@ public class CodeEditUtil { if (lastMember != null) { PsiElement nextSibling = lastMember.getNextSibling(); while (nextSibling instanceof PsiJavaToken && - (nextSibling.getText().equals(",") || nextSibling.getText().equals(";"))) { + (nextSibling.getText().equals(",") || nextSibling.getText().equals(";"))) { nextSibling = nextSibling.getNextSibling(); } return nextSibling == null ? aClass.getLBrace().getNextSibling() : nextSibling; @@ -317,37 +318,37 @@ public class CodeEditUtil { } private static int getMemberOrderWeight(PsiElement member, CodeStyleSettings settings) { - if (member instanceof PsiField){ + if (member instanceof PsiField) { return member instanceof PsiEnumConstant ? 1 : settings.FIELDS_ORDER_WEIGHT + 1; } - else if (member instanceof PsiMethod){ - return ((PsiMethod)member).isConstructor() ? settings.CONSTRUCTORS_ORDER_WEIGHT + 1: settings.METHODS_ORDER_WEIGHT + 1; + else if (member instanceof PsiMethod) { + return ((PsiMethod)member).isConstructor() ? settings.CONSTRUCTORS_ORDER_WEIGHT + 1 : settings.METHODS_ORDER_WEIGHT + 1; } - else if (member instanceof PsiClass){ + else if (member instanceof PsiClass) { return settings.INNER_CLASSES_ORDER_WEIGHT + 1; } - else{ + else { return -1; } } private static boolean needSeparateLines(ASTNode element) { - if (ElementType.STATEMENT_BIT_SET.isInSet(element.getElementType())){ + if (ElementType.STATEMENT_BIT_SET.isInSet(element.getElementType())) { return true; } - else if (element.getElementType() == ElementType.FIELD){ + else if (element.getElementType() == ElementType.FIELD) { return true; } - else if (element.getElementType() == ElementType.METHOD){ + else if (element.getElementType() == ElementType.METHOD) { return true; } - else if (element.getElementType() == ElementType.CLASS){ + else if (element.getElementType() == ElementType.CLASS) { return true; } - else if (element.getElementType() == ElementType.CLASS_INITIALIZER){ + else if (element.getElementType() == ElementType.CLASS_INITIALIZER) { return true; } - else{ + else { return false; } } @@ -373,57 +374,84 @@ public class CodeEditUtil { public static void normalizeSpace(Helper helper, ASTNode parent, ASTNode child1, ASTNode child2, CharTable table) { StringBuffer buffer = null; int count = 0; - for(ASTNode child = child1 != null ? child1.getTreeNext() : parent.getFirstChildNode(); child != child2; child = child.getTreeNext()){ + for (ASTNode child = child1 != null ? child1.getTreeNext() : parent.getFirstChildNode(); child != child2; child = child.getTreeNext()) { if (child instanceof CompositeElement && child.getFirstChildNode() == null) continue; if (Helper.isNonSpace(child)) { LOG.error("Whitespace expected"); } - if (buffer == null){ + if (buffer == null) { buffer = new StringBuffer(); } buffer.append(child.getText()); count++; } - if (count > 1){ - LeafElement newSpace = Factory.createSingleLeafElement(JavaTokenType.WHITE_SPACE, buffer.toString().toCharArray(), 0, buffer.length(), table, null); + if (count > 1) { + LeafElement newSpace = + Factory.createSingleLeafElement(JavaTokenType.WHITE_SPACE, buffer.toString().toCharArray(), 0, buffer.length(), table, null); count = 0; ASTNode next; - for(ASTNode child = child1 != null ? child1.getTreeNext() : parent.getFirstChildNode(); child != child2; child = next){ + for (ASTNode child = child1 != null ? child1.getTreeNext() : parent.getFirstChildNode(); child != child2; child = next) { next = child.getTreeNext(); if (child instanceof CompositeElement && child.getTextLength() == 0) continue; - if (count == 0){ + if (count == 0) { parent.replaceChild(child, newSpace); } - else{ + else { parent.removeChild(child); } count++; } } - if (child1 != null && child2 != null && Helper.getSpaceText(parent, child1, child2).length() == 0){ - if (!helper.canStickChildrenTogether(child1, child2)){ + if (child1 != null && child2 != null && Helper.getSpaceText(parent, child1, child2).length() == 0) { + if (!helper.canStickChildrenTogether(child1, child2)) { helper.makeSpace(parent, child1, child2, " "); } } } - public static String getWhiteSpaceBetweenTokens(ASTNode first, ASTNode second, Language language) { - final PsiElement firstAsPsiElement = SourceTreeToPsiMap.treeElementToPsi(first); - LOG.assertTrue(firstAsPsiElement != null); - final PsiFile file = firstAsPsiElement.getContainingFile(); + public static String getStringWhiteSpaceBetweenTokens(ASTNode first, ASTNode second, Language language) { final PseudoTextBuilder pseudoTextBuilder = language.getFormatter(); - if(pseudoTextBuilder == null){ + if (pseudoTextBuilder == null) { final LeafElement leafElement = ParseUtil.nextLeaf((TreeElement)first, null); - if(leafElement != second) return leafElement.getText(); + if (leafElement != second) { + return leafElement.getText(); + } + else { + return null; + } } + else { + return getWhiteSpaceBeforeToken(second, language).generateNewWhiteSpace(); + } + + } + + public static Whitespace getWhiteSpaceBeforeToken(final ASTNode tokenNode, + final Language language) { + return getWhiteSpaceBeforeToken(tokenNode, language, null); + } + + public static Whitespace getIndentWhiteSpaceBeforeToken(final ASTNode tokenNode, + final Language language, + TextRange textRange) { + return getWhiteSpaceBeforeToken(tokenNode, language, textRange); + } + + public static Whitespace getWhiteSpaceBeforeToken(final ASTNode tokenNode, + final Language language, + TextRange significantRange) { + LOG.assertTrue(tokenNode != null); + final PsiElement secondAsPsiElement = SourceTreeToPsiMap.treeElementToPsi(tokenNode); + LOG.assertTrue(secondAsPsiElement != null); + final PsiFile file = secondAsPsiElement.getContainingFile(); + final PseudoTextBuilder pseudoTextBuilder = language.getFormatter(); LOG.assertTrue(pseudoTextBuilder != null); - final Project project = firstAsPsiElement.getProject(); + final Project project = secondAsPsiElement.getProject(); final CodeStyleSettings settings = CodeStyleSettingsManager.getInstance(project).getCurrentSettings(); - final int startOffset = first.getStartOffset(); - final int endOffset = second.getStartOffset(); + final int endOffset = tokenNode.getStartOffset(); final boolean oldValue = settings.XML_KEEP_LINE_BREAKS; settings.XML_KEEP_LINE_BREAKS = false; @@ -433,10 +461,11 @@ public class CodeEditUtil { settings, file); - return GeneralCodeFormatter.getWhiteSpaceBetweenTokens(pseudoText, settings, file.getFileType(), startOffset, endOffset); + return GeneralCodeFormatter.getWhiteSpaceBetweenTokens(pseudoText, settings, file.getFileType(), endOffset, significantRange); } finally { settings.XML_KEEP_LINE_BREAKS = oldValue; } } + } diff --git a/source/com/intellij/psi/impl/source/xml/XmlTagImpl.java b/source/com/intellij/psi/impl/source/xml/XmlTagImpl.java index f7203321f18f..0773e930a552 100644 --- a/source/com/intellij/psi/impl/source/xml/XmlTagImpl.java +++ b/source/com/intellij/psi/impl/source/xml/XmlTagImpl.java @@ -790,7 +790,7 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag/*, Modification { // Handling whitespaces final LeafElement leafElementAt = xmlText.findLeafElementAt(displayOffset); if(leafElementAt != null && leafElementAt.getElementType() == XmlTokenType.XML_WHITE_SPACE){ - final String wsText = CodeEditUtil.getWhiteSpaceBetweenTokens( + final String wsText = CodeEditUtil.getStringWhiteSpaceBetweenTokens( ParseUtil.prevLeaf(leafElementAt, null), ParseUtil.nextLeaf(leafElementAt, null), getLanguage()); diff --git a/testSource/com/intellij/refactoring/InheritanceToDelegationTest.java b/testSource/com/intellij/refactoring/InheritanceToDelegationTest.java index e142cdae9d59..9e8310f3a0e6 100644 --- a/testSource/com/intellij/refactoring/InheritanceToDelegationTest.java +++ b/testSource/com/intellij/refactoring/InheritanceToDelegationTest.java @@ -9,9 +9,11 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.refactoring.inheritanceToDelegation.InheritanceToDelegationProcessor; import com.intellij.util.ArrayUtil; +import com.intellij.idea.IdeaTestUtil; import java.util.ArrayList; import java.util.List; +import java.util.Calendar; /** * @author dsl @@ -57,7 +59,9 @@ public class InheritanceToDelegationTest extends MultiFileTestCase { } public void testAbstractBase1() throws Exception { - doTest(createPerformAction("A", "myDelegate", "MyBase", "Base", new int[0], ArrayUtil.EMPTY_STRING_ARRAY, false, false)); + if (IdeaTestUtil.bombExplodes(2005, Calendar.FEBRUARY, 8, 12, 0, "lesya", "Indent")) { + doTest(createPerformAction("A", "myDelegate", "MyBase", "Base", new int[0], ArrayUtil.EMPTY_STRING_ARRAY, false, false)); + } } public void testHierarchy() throws Exception { diff --git a/testSource/com/intellij/refactoring/IntroduceFieldInSameClassTest.java b/testSource/com/intellij/refactoring/IntroduceFieldInSameClassTest.java index 3ba51b0e2071..0a46ffee9a18 100644 --- a/testSource/com/intellij/refactoring/IntroduceFieldInSameClassTest.java +++ b/testSource/com/intellij/refactoring/IntroduceFieldInSameClassTest.java @@ -1,8 +1,6 @@ package com.intellij.refactoring; import com.intellij.codeInsight.CodeInsightTestCase; -import com.intellij.codeInsight.CodeInsightUtil; -import com.intellij.psi.PsiExpression; /** * @author ven @@ -17,4 +15,4 @@ public class IntroduceFieldInSameClassTest extends CodeInsightTestCase { private void performRefactoring() { new MockIntroduceFieldHandler().invoke(myProject, myEditor, myFile, null); } -} +} \ No newline at end of file diff --git a/testSource/com/intellij/refactoring/inline/InlineMethodTest.java b/testSource/com/intellij/refactoring/inline/InlineMethodTest.java index f2afb857ed99..4a11b1b54976 100644 --- a/testSource/com/intellij/refactoring/inline/InlineMethodTest.java +++ b/testSource/com/intellij/refactoring/inline/InlineMethodTest.java @@ -8,6 +8,9 @@ import com.intellij.psi.PsiMethod; import com.intellij.refactoring.inline.InlineMethodProcessor; import com.intellij.refactoring.inline.InlineOptions; import com.intellij.refactoring.MockInlineMethodOptions; +import com.intellij.idea.IdeaTestUtil; + +import java.util.Calendar; public class InlineMethodTest extends CodeInsightTestCase { @@ -35,7 +38,11 @@ public class InlineMethodTest extends CodeInsightTestCase { public void testVoidWithReturn() throws Exception { doTest(); } public void testVoidWithReturn1() throws Exception { doTest(); } - public void testScr10884() throws Exception { doTest(); } + public void testScr10884() throws Exception { + if (IdeaTestUtil.bombExplodes(2005, Calendar.FEBRUARY, 8, 12, 0, "lesya", "Indent")) { + doTest(); + } + } public void testFinalParameters() throws Exception { doTest(); } public void testFinalParameters1() throws Exception { doTest(); }