mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-08-25 19:29:30 +07:00
Supported "initializer block" arrangement entry (IDEA-95115)
Previous behaviour was to treat initializer block as field and stick it with previous field, now it's eliminated with matching and rearranging according to matching rules. See comments also in [CR-IC-6618]
This commit is contained in:
@@ -35,4 +35,6 @@ public class JavaCodeStyleSettings extends CustomCodeStyleSettings {
|
||||
public int ANNOTATION_PARAMETER_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP;
|
||||
public boolean ALIGN_MULTILINE_ANNOTATION_PARAMETERS = false;
|
||||
|
||||
public int BLANK_LINES_AROUND_INITIALIZER = 1;
|
||||
|
||||
}
|
||||
|
||||
+2
-22
@@ -341,31 +341,11 @@ public class JavaArrangementVisitor extends JavaRecursiveElementVisitor {
|
||||
|
||||
@Override
|
||||
public void visitClassInitializer(PsiClassInitializer initializer) {
|
||||
JavaElementArrangementEntry entry = createNewEntry(initializer, initializer.getTextRange(), FIELD, null, true);
|
||||
JavaElementArrangementEntry entry = createNewEntry(initializer, initializer.getTextRange(), INIT_BLOCK, null, true);
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
PsiElement classLBrace = null;
|
||||
PsiClass clazz = initializer.getContainingClass();
|
||||
if (clazz != null) {
|
||||
classLBrace = clazz.getLBrace();
|
||||
}
|
||||
for (PsiElement e = initializer.getPrevSibling(); e != null; e = e.getPrevSibling()) {
|
||||
JavaElementArrangementEntry prevEntry;
|
||||
if (e == classLBrace) {
|
||||
prevEntry = myEntries.get(clazz);
|
||||
}
|
||||
else {
|
||||
prevEntry = myEntries.get(e);
|
||||
}
|
||||
if (prevEntry != null) {
|
||||
entry.addDependency(prevEntry);
|
||||
}
|
||||
if (!(e instanceof PsiWhiteSpace)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
parseModifiers(initializer.getModifierList(), entry);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.arrangement.engine.ArrangementEngine;
|
||||
import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingRule;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher;
|
||||
@@ -36,6 +37,7 @@ import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchConditio
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementCompositeMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import com.intellij.psi.codeStyle.arrangement.std.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -62,7 +64,7 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
|
||||
// Type
|
||||
@NotNull private static final Set<ArrangementSettingsToken> SUPPORTED_TYPES =
|
||||
ContainerUtilRt.newLinkedHashSet(
|
||||
FIELD, CONSTRUCTOR, METHOD, CLASS, INTERFACE, ENUM, GETTER, SETTER, OVERRIDDEN
|
||||
FIELD, INIT_BLOCK, CONSTRUCTOR, METHOD, CLASS, INTERFACE, ENUM, GETTER, SETTER, OVERRIDDEN
|
||||
);
|
||||
// Modifier
|
||||
@NotNull private static final Set<ArrangementSettingsToken> SUPPORTED_MODIFIERS =
|
||||
@@ -79,6 +81,9 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
|
||||
@NotNull private static final Collection<Set<ArrangementSettingsToken>> MUTEXES =
|
||||
ContainerUtilRt.newArrayList();
|
||||
|
||||
private static final Set<ArrangementSettingsToken> TYPES_WITH_DISABLED_ORDER = ContainerUtil.newHashSet();
|
||||
private static final Set<ArrangementSettingsToken> TYPES_WITH_DISABLED_NAME_MATCH = ContainerUtil.newHashSet();
|
||||
|
||||
static {
|
||||
Set<ArrangementSettingsToken> visibilityModifiers = ContainerUtilRt.newHashSet(PUBLIC, PROTECTED, PACKAGE_PRIVATE, PRIVATE);
|
||||
MUTEXES.add(visibilityModifiers);
|
||||
@@ -96,6 +101,11 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
|
||||
MODIFIERS_BY_TYPE.put(GETTER, ContainerUtilRt.<ArrangementSettingsToken>newHashSet());
|
||||
MODIFIERS_BY_TYPE.put(SETTER, ContainerUtilRt.<ArrangementSettingsToken>newHashSet());
|
||||
MODIFIERS_BY_TYPE.put(OVERRIDDEN, ContainerUtilRt.<ArrangementSettingsToken>newHashSet());
|
||||
MODIFIERS_BY_TYPE.put(INIT_BLOCK, ContainerUtilRt.newHashSet(STATIC));
|
||||
|
||||
TYPES_WITH_DISABLED_ORDER.add(INIT_BLOCK);
|
||||
|
||||
TYPES_WITH_DISABLED_NAME_MATCH.add(INIT_BLOCK);
|
||||
}
|
||||
|
||||
private static final Map<ArrangementSettingsToken, List<ArrangementSettingsToken>> GROUPING_RULES = ContainerUtilRt.newLinkedHashMap();
|
||||
@@ -129,6 +139,8 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
|
||||
for (ArrangementSettingsToken modifier : visibility) {
|
||||
and(matchRules, FIELD, STATIC, modifier);
|
||||
}
|
||||
and(matchRules, INIT_BLOCK, STATIC);
|
||||
|
||||
for (ArrangementSettingsToken modifier : visibility) {
|
||||
and(matchRules, FIELD, FINAL, modifier);
|
||||
}
|
||||
@@ -136,6 +148,7 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
|
||||
and(matchRules, FIELD, modifier);
|
||||
}
|
||||
and(matchRules, FIELD);
|
||||
and(matchRules, INIT_BLOCK);
|
||||
and(matchRules, CONSTRUCTOR);
|
||||
and(matchRules, METHOD, STATIC);
|
||||
and(matchRules, METHOD);
|
||||
@@ -304,10 +317,14 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
|
||||
}
|
||||
|
||||
CommonCodeStyleSettings commonSettings = settings.getCommonSettings(JavaLanguage.INSTANCE);
|
||||
JavaCodeStyleSettings javaSettings = settings.getCustomSettings(JavaCodeStyleSettings.class);
|
||||
if (FIELD.equals(target.getType())) {
|
||||
if (parent != null && parent.getType() == INTERFACE) {
|
||||
return commonSettings.BLANK_LINES_AROUND_FIELD_IN_INTERFACE;
|
||||
}
|
||||
else if (INIT_BLOCK.equals(previous.getType())) {
|
||||
return javaSettings.BLANK_LINES_AROUND_INITIALIZER;
|
||||
}
|
||||
else {
|
||||
return commonSettings.BLANK_LINES_AROUND_FIELD;
|
||||
}
|
||||
@@ -323,6 +340,9 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
|
||||
else if (CLASS.equals(target.getType())) {
|
||||
return commonSettings.BLANK_LINES_AROUND_CLASS;
|
||||
}
|
||||
else if (INIT_BLOCK.equals(target.getType())) {
|
||||
return javaSettings.BLANK_LINES_AROUND_INITIALIZER;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
@@ -363,9 +383,10 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(@NotNull ArrangementSettingsToken token, @Nullable ArrangementMatchCondition current) {
|
||||
if (SUPPORTED_TYPES.contains(token) || SUPPORTED_ORDERS.contains(token) || StdArrangementTokens.Regexp.NAME.equals(token)) {
|
||||
if (SUPPORTED_TYPES.contains(token)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ArrangementSettingsToken type = null;
|
||||
if (current != null) {
|
||||
type = ArrangementUtil.parseType(current);
|
||||
@@ -373,6 +394,15 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
|
||||
if (type == null) {
|
||||
type = NO_TYPE;
|
||||
}
|
||||
|
||||
if (SUPPORTED_ORDERS.contains(token)) {
|
||||
return !TYPES_WITH_DISABLED_ORDER.contains(type);
|
||||
}
|
||||
|
||||
if (StdArrangementTokens.Regexp.NAME.equals(token)) {
|
||||
return !TYPES_WITH_DISABLED_NAME_MATCH.contains(type);
|
||||
}
|
||||
|
||||
Set<ArrangementSettingsToken> modifiers = MODIFIERS_BY_TYPE.get(type);
|
||||
return modifiers != null && modifiers.contains(token);
|
||||
}
|
||||
|
||||
@@ -425,13 +425,8 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
|
||||
myResult = Spacing.createSpacing(0, 0, 1, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE);
|
||||
}
|
||||
else if (myRole1 == ChildRole.FIELD) {
|
||||
int lines = Math.max(getLinesAroundField(), getLinesAroundMethod()) + 1;
|
||||
// IJ has been keeping initialization block which starts at the same line as a field for a while.
|
||||
// However, it's not convenient for a situation when particular code is created via PSI - it's easier to not bothering
|
||||
// with whitespace elements when inserting, say, new initialization blocks. That's why we don't enforce new line
|
||||
// only during explicit reformatting ('Reformat' action).
|
||||
//int minLineFeeds = FormatterUtil.isFormatterCalledExplicitly() ? 0 : 1;
|
||||
myResult = Spacing.createSpacing(0, mySettings.SPACE_BEFORE_CLASS_LBRACE ? 1 : 0, 1, true, mySettings.KEEP_BLANK_LINES_BEFORE_RBRACE, lines);
|
||||
int blankLines = myJavaSettings.BLANK_LINES_AROUND_INITIALIZER + 1;
|
||||
myResult = Spacing.createSpacing(0, mySettings.SPACE_BEFORE_CLASS_LBRACE ? 1 : 0, blankLines, true, mySettings.KEEP_BLANK_LINES_BEFORE_RBRACE);
|
||||
}
|
||||
else if (myRole1 == ChildRole.CLASS) {
|
||||
setAroundClassSpacing();
|
||||
@@ -450,7 +445,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
|
||||
setAroundClassSpacing();
|
||||
}
|
||||
else {
|
||||
final int blankLines = getLinesAroundMethod() + 1;
|
||||
final int blankLines = myJavaSettings.BLANK_LINES_AROUND_INITIALIZER + 1;
|
||||
myResult = Spacing.createSpacing(0, Integer.MAX_VALUE, blankLines, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_DECLARATIONS);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -83,9 +83,10 @@ class Test {
|
||||
expected: '''\
|
||||
class Test {
|
||||
public int j;
|
||||
{ j = 1; }
|
||||
protected int k;
|
||||
private int i;
|
||||
|
||||
{ j = 1; }
|
||||
}''',
|
||||
rules: [rule(FIELD, PUBLIC), rule(FIELD, PROTECTED), rule(FIELD, PRIVATE)])
|
||||
}
|
||||
@@ -101,10 +102,11 @@ class Test {
|
||||
}''',
|
||||
expected: '''\
|
||||
class Test {
|
||||
{ j = 1; }
|
||||
public int j;
|
||||
protected int k;
|
||||
private int i;
|
||||
|
||||
{ j = 1; }
|
||||
}''',
|
||||
rules: [rule(FIELD, PUBLIC), rule(FIELD, PROTECTED), rule(FIELD, PRIVATE)])
|
||||
}
|
||||
|
||||
+81
@@ -569,4 +569,85 @@ class B extends A {
|
||||
rules: [rule(PUBLIC, METHOD), rule(PRIVATE, METHOD)]
|
||||
)
|
||||
}
|
||||
|
||||
void "test initializer block after fields"() {
|
||||
doTest(
|
||||
initial: '''\
|
||||
public class NewOneClass {
|
||||
|
||||
{
|
||||
a = 1;
|
||||
}
|
||||
|
||||
int a;
|
||||
|
||||
{
|
||||
b = 5;
|
||||
}
|
||||
|
||||
int b;
|
||||
|
||||
}
|
||||
''',
|
||||
expected: '''\
|
||||
public class NewOneClass {
|
||||
|
||||
int a;
|
||||
int b;
|
||||
|
||||
{
|
||||
a = 1;
|
||||
}
|
||||
|
||||
{
|
||||
b = 5;
|
||||
}
|
||||
|
||||
}
|
||||
''',
|
||||
rules: [rule(FIELD), rule(INIT_BLOCK)]
|
||||
)
|
||||
}
|
||||
|
||||
void "test static initializer block"() {
|
||||
doTest(
|
||||
initial: '''\
|
||||
public class NewOneClass {
|
||||
|
||||
static {
|
||||
a = 1;
|
||||
}
|
||||
|
||||
static int a;
|
||||
|
||||
{
|
||||
b = 5;
|
||||
}
|
||||
|
||||
int b;
|
||||
|
||||
}
|
||||
''',
|
||||
expected: '''\
|
||||
public class NewOneClass {
|
||||
|
||||
static int a;
|
||||
|
||||
static {
|
||||
a = 1;
|
||||
}
|
||||
|
||||
int b;
|
||||
|
||||
{
|
||||
b = 5;
|
||||
}
|
||||
|
||||
}
|
||||
''',
|
||||
rules: [rule(STATIC, FIELD), rule(STATIC, INIT_BLOCK), rule(FIELD), rule(INIT_BLOCK)]
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+1
@@ -25,6 +25,7 @@ public class JavaFormatterBlankLinesTest extends AbstractJavaFormatterTest {
|
||||
|
||||
public void testBlankLinesAroundClassInitializationBlock() throws Exception {
|
||||
getSettings().BLANK_LINES_AROUND_METHOD = 3;
|
||||
getJavaSettings().BLANK_LINES_AROUND_INITIALIZER = 3;
|
||||
doTextTest(
|
||||
"class T {\n" +
|
||||
" private final DecimalFormat fmt = new DecimalFormat();\n" +
|
||||
|
||||
+1
@@ -164,6 +164,7 @@ public class StdArrangementTokens {
|
||||
@NotNull public static final ArrangementSettingsToken PROPERTY = invertible("PROPERTY", StdArrangementTokenType.ENTRY_TYPE);
|
||||
@NotNull public static final ArrangementSettingsToken EVENT_HANDLER = invertible("EVENT_HANDLER", StdArrangementTokenType.ENTRY_TYPE);
|
||||
@NotNull public static final ArrangementSettingsToken STATIC_INIT = invertible("STATIC_INIT", StdArrangementTokenType.ENTRY_TYPE);
|
||||
@NotNull public static final ArrangementSettingsToken INIT_BLOCK = invertible("INITIALIZER BLOCK", StdArrangementTokenType.ENTRY_TYPE);
|
||||
@NotNull public static final ArrangementSettingsToken NAMESPACE = invertible("NAMESPACE", StdArrangementTokenType.ENTRY_TYPE);
|
||||
@NotNull public static final ArrangementSettingsToken TRAIT = invertible("TRAIT", StdArrangementTokenType.ENTRY_TYPE);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user