IDEA-85100 Deleting wrapped lines with Ctrl+Y doen't work properly with "soft wrapped" lines

*) more tests have been refactored and checked;
*) refactoring;
This commit is contained in:
Denis.Zhdanov
2012-05-16 09:34:09 +04:00
parent 2bcfa96ad8
commit 4703151399
10 changed files with 96 additions and 104 deletions
@@ -34,10 +34,7 @@ import javax.swing.tree.DefaultMutableTreeNode;
* Describes the fields, methods, and inner class declarations of a class. This information is used to reorder
* these declarations within an outer class.
*/
public abstract class ClassContentsEntry
extends RangeEntry
implements FilePopupEntry
{
public abstract class ClassContentsEntry extends RangeEntry implements FilePopupEntry {
public ClassContentsEntry(@Nullable final PsiElement start,
@Nullable final PsiElement end,
final int modifiers,
@@ -237,7 +237,7 @@ public class ClassEntry extends ClassContentsEntry implements FilePopupEntry {
* @param clazz
* @return starting element index for the portion of the enumeration class following its enum declarations.
*/
private int findLastEnumTerminator(PsiClass clazz) {
private static int findLastEnumTerminator(PsiClass clazz) {
int startElementIndex = 0;
// go until we hit RBrace (non-inclusive), or semicolon (inclusive)
boolean foundLBrace = false;
@@ -263,25 +263,31 @@ public class ClassEntry extends ClassContentsEntry implements FilePopupEntry {
return startElementIndex;
}
private int parseField(PsiElement child, MemberAttributes attributes, int i, final PsiClass psiClass) {
private static int parseField(PsiElement child, MemberAttributes attributes, int i, final PsiClass psiClass) {
attributes.field = (PsiField)child;
LOG.debug("enter parseField: child=" +
(child == null ? "null" : child.toString()));
attributes.name = attributes.field.getName();
if (attributes.field.getTypeElement() == null) {
attributes.type = attributes.field.getContainingClass().getName(); // if enum, use class as type
final PsiClass containingClass = attributes.field.getContainingClass();
final PsiTypeElement typeElement = attributes.field.getTypeElement();
if (typeElement == null && containingClass != null) {
attributes.type = containingClass.getName(); // if enum, use class as type
}
else {
attributes.type = attributes.field.getTypeElement().getText();
else if (typeElement != null) {
attributes.type = typeElement.getText();
}
final PsiModifierList modifierList = attributes.field.getModifierList();
if (modifierList != null) {
attributes.modifierString = modifierList.getText();
}
attributes.modifierString = attributes.field.getModifierList().getText();
attributes.modifiers = ModifierUtils.getModifierMask(attributes.modifierString);
if (attributes.field.getContainingClass().isInterface()) {
if (containingClass != null && containingClass.isInterface()) {
// all fields in an interface are constants, hence "public static final"
attributes.modifiers |= Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;
}
if (attributes.field.getInitializer() instanceof PsiNewExpression) {
final PsiElement lc = attributes.field.getInitializer().getLastChild();
final PsiExpression initializer = attributes.field.getInitializer();
if (initializer instanceof PsiNewExpression) {
final PsiElement lc = initializer.getLastChild();
if (lc instanceof PsiAnonymousClass) {
attributes.modifiers |= ModifierConstants.INIT_TO_ANON_CLASS;
}
@@ -335,19 +341,21 @@ public class ClassEntry extends ClassContentsEntry implements FilePopupEntry {
return i;
}
private void parseMethod(PsiElement child, MemberAttributes attributes, final PsiSearchHelper psh) {
private static void parseMethod(PsiElement child, MemberAttributes attributes, final PsiSearchHelper psh) {
attributes.method = (PsiMethod)child;
attributes.name = attributes.method.getName();
if (attributes.method.getReturnTypeElement() == null) {
final PsiTypeElement returnTypeElement = attributes.method.getReturnTypeElement();
if (returnTypeElement == null) {
attributes.type = "null";
}
else {
attributes.type = attributes.method.getReturnTypeElement().getText();
attributes.type = returnTypeElement.getText();
}
attributes.modifierString = attributes.method.getModifierList().getText();
attributes.modifiers = ModifierUtils.getModifierMask(attributes.modifierString);
attributes.nParameters = attributes.method.getParameterList().getParameters().length;
if (attributes.method.getContainingClass().isInterface()) {
final PsiClass containingClass = attributes.method.getContainingClass();
if (containingClass != null && containingClass.isInterface()) {
// methods in an interface are always considered public
attributes.modifiers |= Modifier.PUBLIC;
}
@@ -379,12 +387,12 @@ public class ClassEntry extends ClassContentsEntry implements FilePopupEntry {
attributes.modifiers |= ModifierConstants.OVERRIDDEN;
}
}
// determine if this method overrides another.
// Determine if this method overrides another.
final PsiMethod[] superMethods = attributes.method.findSuperMethods(false);
LOG.debug("method " + attributes.method.toString() + " has " + superMethods.length + " supermethods");
dumpMethodNames(superMethods);
if (superMethods.length > 0) {
// determine if supermethod is abstract or interface; if so, assign IMPLEMENTING attribute.
// Determine if supermethod is abstract or interface; if so, assign IMPLEMENTING attribute.
PsiMethod superMethod = superMethods[0];
boolean abztract = superMethod.getModifierList().hasModifierProperty(PsiModifier.ABSTRACT);
PsiClass superclass = superMethod.getContainingClass();
@@ -400,9 +408,8 @@ public class ClassEntry extends ClassContentsEntry implements FilePopupEntry {
if (attributes.method.isConstructor()) {
attributes.modifiers |= ModifierConstants.CONSTRUCTOR;
}
/** getter/setter cannot be determined here because definition of what a getter/setter
* is can vary from rule to rule. Do it at the time of rule matching.
*/
// Getter/setter cannot be determined here because definition of what a getter/setter
// is can vary from rule to rule. Do it at the time of rule matching.
else if ((attributes.modifiers & ModifierConstants.CANONICAL) == 0) {
attributes.modifiers |= ModifierConstants.OTHER_METHOD;
}
@@ -414,7 +421,7 @@ public class ClassEntry extends ClassContentsEntry implements FilePopupEntry {
);
}
private int isCanonicalOrInterface(PsiMethod method, MemberAttributes attributes) {
private static int isCanonicalOrInterface(PsiMethod method, MemberAttributes attributes) {
PsiElement methodParent = method.getParent();
LOG.debug("checking to see if " + method.getName() + " of " + methodParent + " is canonical");
PsiMethod[] superMethods = method.findSuperMethods();
@@ -458,7 +465,7 @@ public class ClassEntry extends ClassContentsEntry implements FilePopupEntry {
return 0;
}
private void dumpMethodNames(PsiMethod[] methods) {
private static void dumpMethodNames(PsiMethod[] methods) {
for (int j = 0; j < methods.length; j++) {
LOG.debug(
j +
@@ -487,17 +494,19 @@ public class ClassEntry extends ClassContentsEntry implements FilePopupEntry {
}
}
private void parseClassInitializer(PsiElement child, MemberAttributes attributes) {
private static void parseClassInitializer(PsiElement child, MemberAttributes attributes) {
attributes.classInitializer = (PsiClassInitializer)child;
attributes.classInitializer.getModifierList();
attributes.name = "";
attributes.modifierString = attributes.classInitializer.getModifierList().getText();
final PsiModifierList modifierList = attributes.classInitializer.getModifierList();
if (modifierList != null) {
attributes.modifierString = modifierList.getText();
}
attributes.modifiers = ModifierUtils.getModifierMask(attributes.modifierString) |
ModifierConstants.INITIALIZER;
}
public void emit(Emitter emitter) {
// first emit the text up to and including the left brace.
// First emit the text up to and including the left brace.
super.emit(emitter);
// now emit all children.
emitter.emitRuleInstances(getResultRuleInstances());
@@ -514,7 +523,7 @@ public class ClassEntry extends ClassContentsEntry implements FilePopupEntry {
return result;
}
/** rearranges the contents of this PsiClass according to supplied rules. */
/** Rearranges the contents of this PsiClass according to supplied rules. */
public void rearrangeContents() {
buildMethodCallGraph();
@@ -530,14 +539,10 @@ public class ClassEntry extends ClassContentsEntry implements FilePopupEntry {
((RelatableEntry)contentsEntry).determineExtractedMethod(mySettings.getExtractedMethodsSettings());
}
}
/**
* remove any cycles in the related method graph.
*/
// Remove any cycles in the related method graph.
MethodEntry.eliminateCycles(getContents());
/**
* check for overloaded extracted methods; if configured to be kept together, attach subsequent
* methods to the first and remove them from consideration for other alignment.
*/
// Check for overloaded extracted methods; if configured to be kept together, attach subsequent
// methods to the first and remove them from consideration for other alignment.
MethodEntry.handleOverloadedMethods(getContents(), mySettings);
final GenericRearranger classContentsRearranger =
new GenericRearranger(mySettings.getItemOrderAttributeList(),
@@ -42,6 +42,7 @@ import java.util.regex.Matcher;
* flags and special flags to mark any miscellaneous text or comments that precede or follow the item.
*/
abstract public class RangeEntry implements PopupTreeRangeEntry {
// ------------------------------ FIELDS ------------------------------
private static final Logger LOG = Logger.getInstance("#" + RangeEntry.class.getName());
@@ -267,7 +268,7 @@ abstract public class RangeEntry implements PopupTreeRangeEntry {
curr = curr.getNextSibling();
}
}
if (curr == myEnd) {
if (curr == myEnd && myEnd != null) {
emitElement(myEnd, buffer, document);
}
}
@@ -24,12 +24,13 @@ package com.wrq.rearranger.rearrangement;
import com.intellij.openapi.diagnostic.Logger;
import com.wrq.rearranger.entry.ClassContentsEntry;
import com.wrq.rearranger.entry.ClassEntry;
import com.wrq.rearranger.entry.RelatableEntry;
import com.wrq.rearranger.entry.RangeEntry;
import com.wrq.rearranger.entry.RelatableEntry;
import com.wrq.rearranger.ruleinstance.CommentRuleInstance;
import com.wrq.rearranger.ruleinstance.RuleInstance;
import com.wrq.rearranger.settings.RearrangerSettings;
import com.wrq.rearranger.settings.attributeGroups.*;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
@@ -51,7 +52,7 @@ public abstract class GenericRearranger {
final List<ClassContentsEntry> outerClasses,
final int nestingLevel,
final RearrangerSettings settings) {
this.myRules = rules;
myRules = rules;
myEntries = outerClasses;
this.myNestingLevel = nestingLevel;
this.mySettings = settings;
@@ -121,7 +122,7 @@ public abstract class GenericRearranger {
* @param prioritizedRules prioritized list of rules
*/
@SuppressWarnings({"StringContatenationInLoop"})
private void matchPrioritizedRules(List<RuleInstance> prioritizedRules) {
private void matchPrioritizedRules(@NotNull List<RuleInstance> prioritizedRules) {
for (RuleInstance ruleInstance : prioritizedRules) {
final Rule rule = ruleInstance.getRule();
final ListIterator entryIterator = myEntries.listIterator();
@@ -174,11 +175,11 @@ public abstract class GenericRearranger {
prioritizedRuleInstances.add(0, instance);
}
}
// now add a default rule to pick up all unmatched items.
// Now add a default rule to pick up all unmatched items.
RuleInstance defaultRuleInstance = new DefaultRule().createRuleInstance();
myResultRuleInstances.add(defaultRuleInstance);
prioritizedRuleInstances.add(defaultRuleInstance);
// finally, add a TrailerRuleInstance to pick up any leftover text.
// Finally, add a TrailerRuleInstance to pick up any leftover text.
RuleInstance tri = new TrailerRule().createRuleInstance();
myResultRuleInstances.add(tri);
prioritizedRuleInstances.add(tri);
@@ -74,22 +74,22 @@ public class Spacer {
myBuffer = new StringBuilder(maxSize);
}
private class AbortRespacing extends RuntimeException {
private static class AbortRespacingException extends RuntimeException {
}
private class BadPsiElement extends Exception {
BadPsiElement(String string) {
private static class BadPsiElementException extends Exception {
BadPsiElementException(String string) {
super(string);
}
}
private void handleBadPsiElementException(String desc, PsiElement element)
throws AbortRespacing
private static void handleBadPsiElementException(String desc, PsiElement element)
throws AbortRespacingException
{
JOptionPane.showMessageDialog(null,
"Spacing could not be performed due to a syntax error:\n" +
desc + element.getText(), "Spacing Error", JOptionPane.ERROR_MESSAGE);
throw new AbortRespacing();
throw new AbortRespacingException();
}
public boolean respace() {
@@ -132,7 +132,7 @@ public class Spacer {
bias
);
}
catch (BadPsiElement badPsiElement) {
catch (BadPsiElementException badPsiElement) {
handleBadPsiElementException("class " + psiClass.getName() + " missing left brace. Body follows:", psiClass);
}
log(mySettings.getAfterClassLBrace(), psiClass.getName(), oldbias, bias);
@@ -146,7 +146,7 @@ public class Spacer {
bias
);
}
catch (BadPsiElement badPsiElement) {
catch (BadPsiElementException badPsiElement) {
handleBadPsiElementException("class " + psiClass.getName() + " missing right brace. Body follows:", psiClass);
}
log(mySettings.getBeforeClassRBrace(), psiClass.getName(), oldbias, bias);
@@ -173,7 +173,7 @@ public class Spacer {
bias
);
}
catch (BadPsiElement badPsiElement) {
catch (BadPsiElementException badPsiElement) {
handleBadPsiElementException("class " + psiClass.getName() + " missing left brace. Body follows:", psiClass);
}
log(mySettings.getAfterClassRBrace(), psiClass.getName(), oldbias, bias);
@@ -231,7 +231,7 @@ public class Spacer {
bias
);
}
catch (BadPsiElement badPsiElement) {
catch (BadPsiElementException badPsiElement) {
handleBadPsiElementException("body of method " + psiMethod.getName() + " missing left brace. Body follows:", psiMethod);
}
log(mySettings.getAfterMethodLBrace(), psiMethod.getName(), oldbias, bias);
@@ -245,7 +245,7 @@ public class Spacer {
bias
);
}
catch (BadPsiElement badPsiElement) {
catch (BadPsiElementException badPsiElement) {
handleBadPsiElementException("body of method " + psiMethod.getName() + " missing right brace. Body follows:", psiMethod);
}
log(mySettings.getBeforeMethodRBrace(), psiMethod.getName(), oldbias, bias);
@@ -276,7 +276,7 @@ public class Spacer {
bias
);
}
catch (BadPsiElement badPsiElement) {
catch (BadPsiElementException badPsiElement) {
handleBadPsiElementException("body of method " + psiMethod.getName() + " missing right brace. Body follows:", psiMethod);
}
log(mySettings.getAfterMethodRBrace(), psiMethod.getName(), oldbias, bias);
@@ -300,7 +300,7 @@ public class Spacer {
bias += adjustSpacing(psiCodeBlock.getLBrace(),
psiCodeBlock.getRBrace(), false, 0, bias);
}
catch (BadPsiElement badPsiElement) {
catch (BadPsiElementException badPsiElement) {
handleBadPsiElementException("code block missing left brace. Content follows:\n", psiCodeBlock);
}
log("code block left brace", oldbias, bias);
@@ -313,7 +313,7 @@ public class Spacer {
try {
bias += adjustSpacing(psiCodeBlock.getRBrace(), psiCodeBlock.getLBrace(), true, 0, bias);
}
catch (BadPsiElement badPsiElement) {
catch (BadPsiElementException badPsiElement) {
handleBadPsiElementException("code block missing right brace. Content follows:\n", psiCodeBlock);
}
log("code block right brace", oldbias, bias);
@@ -323,7 +323,7 @@ public class Spacer {
try {
myFile.accept(visitor);
}
catch (AbortRespacing ar) {
catch (AbortRespacingException ar) {
return false;
}
if (myChangesMade) {
@@ -348,7 +348,7 @@ public class Spacer {
* @return true if the psiElement is the last syntactic item (i.e., not including comments and whitespace)
* of the owner.
*/
private boolean isLastMeaningfulElement(PsiElement owner, PsiElement psiElement) {
private static boolean isLastMeaningfulElement(PsiElement owner, PsiElement psiElement) {
boolean lastMethod;
// class is immediate parent
PsiElement[] elements = owner.getChildren();
@@ -372,7 +372,7 @@ public class Spacer {
return lastMethod;
}
private void log(ForceBlankLineSetting fbls, String name, int oldbias, int bias) {
private static void log(ForceBlankLineSetting fbls, String name, int oldbias, int bias) {
if (oldbias != bias) {
LOG.debug(
fbls.getObjectName() +
@@ -386,7 +386,7 @@ public class Spacer {
}
}
private void log(String name, int oldbias, int bias) {
private static void log(String name, int oldbias, int bias) {
if (oldbias != bias) {
LOG.debug(
name +
@@ -397,7 +397,7 @@ public class Spacer {
}
private int adjustSpacing(PsiElement brace, PsiElement matchingBrace, ForceBlankLineSetting fbls, int bias)
throws BadPsiElement
throws BadPsiElementException
{
if (fbls.isForce()) {
return adjustSpacing(brace, matchingBrace, fbls.isBefore(), fbls.getnBlankLines(), bias);
@@ -446,11 +446,11 @@ public class Spacer {
* @return bias adjustment corresponding to number of newlines inserted or deleted
*/
private int adjustSpacing(PsiElement brace, PsiElement matchingBrace, boolean before, int nBlankLines, int bias)
throws BadPsiElement
throws BadPsiElementException
{
int result = 0;
if (brace == null) {
throw new BadPsiElement(
throw new BadPsiElementException(
"adjustSpacing: illegal syntax (mismatched braces); PsiElement for brace is null"
);
}
@@ -495,9 +495,7 @@ public class Spacer {
return result;
}
}
while (whiteSpace != null &&
(!(whiteSpace instanceof PsiWhiteSpace) ||
whiteSpace.getText().indexOf('\n') < 0));
while (whiteSpace != null && (!(whiteSpace instanceof PsiWhiteSpace) || whiteSpace.getText().indexOf('\n') < 0));
VirtualElement virtualWhiteSpace = null;
if (whiteSpace != null) {
@@ -31,9 +31,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/** Base class for all boolean attributes. */
abstract public class AndNotAttribute
extends AtomicAttribute
{
abstract public class AndNotAttribute extends AtomicAttribute {
// ------------------------------ FIELDS ------------------------------
boolean value;
@@ -24,9 +24,7 @@ package com.wrq.rearranger.settings.atomicAttributes;
import com.wrq.rearranger.ModifierConstants;
import org.jdom.Element;
public final class InitToAnonClassAttribute
extends AndNotAttribute
{
public final class InitToAnonClassAttribute extends AndNotAttribute {
// -------------------------- STATIC METHODS --------------------------
@@ -72,10 +72,12 @@ public abstract class CommonAttributes implements AttributeGroup, PrioritizedRul
// --------------------- GETTER / SETTER METHODS ---------------------
@NotNull
public final NameAttribute getNameAttribute() {
return myNameAttribute;
}
@NotNull
final public ProtectionLevelAttributes getProtectionLevelAttributes() {
return myProtectionLevelAttributes;
}
@@ -88,10 +90,12 @@ public abstract class CommonAttributes implements AttributeGroup, PrioritizedRul
this.myPriority = priority;
}
@NotNull
final public StaticAttribute getStaticAttribute() {
return myStaticAttribute;
}
@NotNull
public SortOptions getSortOptions() {
return mySortOptions;
}
@@ -25,9 +25,10 @@ package com.wrq.rearranger;
import com.intellij.openapi.application.ApplicationManager
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import com.wrq.rearranger.settings.RearrangerSettings
import com.wrq.rearranger.settings.attributeGroups.FieldAttributes
import com.wrq.rearranger.settings.attributeGroups.MethodAttributes
import org.jetbrains.annotations.NotNull
import org.jetbrains.annotations.Nullable
import com.wrq.rearranger.settings.attributeGroups.FieldAttributes
/** JUnit tests for the rearranger plugin. */
class RearrangerTest extends LightCodeInsightFixtureTestCase {
@@ -62,35 +63,25 @@ class RearrangerTest extends LightCodeInsightFixtureTestCase {
}
}
// public final void testNotPublicFieldRearrangement() throws Exception {
// configureByFile("/com/wrq/rearranger/RearrangementTest.java");
// final PsiFile file = getFile();
// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file);
// final FieldAttributes fa;
// fa = new FieldAttributes();
// fa.getPlAttr().setPlPublic(true);
// fa.getPlAttr().setInvertProtectionLevel(true);
// rs.addItem(fa, 0);
// final RearrangerActionHandler rah = new RearrangerActionHandler();
// rah.rearrangeDocument(getProject(), file, rs, doc);
// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult3.java");
// }
//
// public final void testConstructorRearrangement() throws Exception {
// configureByFile("/com/wrq/rearranger/RearrangementTest.java");
// final PsiFile file = getFile();
// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file);
// final MethodAttributes ma;
// ma = new MethodAttributes();
// ma.getPlAttr().setPlPackage(true);
// ma.getPlAttr().setPlPublic(true);
// ma.setConstructorMethodType(true);
// rs.addItem(ma, 0);
// final RearrangerActionHandler rah = new RearrangerActionHandler();
// rah.rearrangeDocument(getProject(), file, rs, doc);
// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult4.java");
// }
//
public final void testNotPublicFieldRearrangement() throws Exception {
doTest('RearrangementTest', 'RearrangementResult3') {
def attributes = new FieldAttributes()
attributes.protectionLevelAttributes.plPublic = true
attributes.protectionLevelAttributes.invertProtectionLevel = true
mySettings.addItem(attributes, 0)
}
}
public final void testConstructorRearrangement() throws Exception {
doTest('RearrangementTest', 'RearrangementResult4') {
def attributes = new MethodAttributes()
attributes.protectionLevelAttributes.plPackage = true
attributes.protectionLevelAttributes.plPublic = true
attributes.constructorMethodType = true
mySettings.addItem(attributes, 0)
}
}
// public final void testClassRearrangement() throws Exception {
// configureByFile("/com/wrq/rearranger/RearrangementTest.java");
// final PsiFile file = getFile();
@@ -9,7 +9,6 @@ public class RearrangementTest {
NoRearrangementTest() {
// constructor body
}
/** field 1. */
private int field1;
private int field2;