Support for code style value lists

This commit is contained in:
Rustam Vishnyakov
2019-01-23 15:57:32 +03:00
parent e52abb1894
commit eb0b5ff158
17 changed files with 137 additions and 86 deletions
@@ -1,13 +1,15 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.psi.codeStyle;
import com.intellij.application.options.codeStyle.properties.CodeStylePropertyAccessor;
import com.intellij.application.options.codeStyle.properties.ValueListPropertyAccessor;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
import java.util.List;
public class JavaPackageEntryTableAccessor extends CodeStylePropertyAccessor<PackageEntryTable> {
public class JavaPackageEntryTableAccessor extends ValueListPropertyAccessor<PackageEntryTable> {
public static final String BLANK_LINE_ENTRY = "blank_line";
public static final String STATIC_PREFIX = "static";
@@ -18,11 +20,10 @@ public class JavaPackageEntryTableAccessor extends CodeStylePropertyAccessor<Pac
@Nullable
@Override
protected PackageEntryTable parseString(@NotNull String str) {
protected PackageEntryTable fromExternal(@NotNull List<String> strList) {
PackageEntryTable entryTable = new PackageEntryTable();
String[] parts = str.split(",");
for (String part : parts) {
String parseStr = part.trim();
for (String strValue : strList) {
String parseStr = strValue.trim();
if (BLANK_LINE_ENTRY.equals(parseStr)) {
entryTable.addEntry(PackageEntry.BLANK_LINE_ENTRY);
}
@@ -51,28 +52,29 @@ public class JavaPackageEntryTableAccessor extends CodeStylePropertyAccessor<Pac
@NotNull
@Override
protected String asString(@NotNull PackageEntryTable value) {
StringBuilder sb = new StringBuilder();
protected List<String> toExternal(@NotNull PackageEntryTable value) {
List<String> externalList = ContainerUtil.newArrayList();
for (PackageEntry entry : value.getEntries()) {
if (sb.length() > 0) sb.append(",");
if (entry == PackageEntry.BLANK_LINE_ENTRY) {
sb.append(BLANK_LINE_ENTRY);
externalList.add(BLANK_LINE_ENTRY);
}
else {
StringBuilder entryBuilder = new StringBuilder();
if (entry.isStatic()) {
sb.append(STATIC_PREFIX + " ");
entryBuilder.append(STATIC_PREFIX + " ");
}
if (entry.isSpecial()) {
sb.append("*");
entryBuilder.append("*");
}
else {
sb.append(entry.getPackageName()).append(".*");
entryBuilder.append(entry.getPackageName()).append(".*");
if (entry.isWithSubpackages()) {
sb.append("*");
entryBuilder.append("*");
}
}
externalList.add(entryBuilder.toString());
}
}
return sb.toString();
return externalList;
}
}
@@ -16,11 +16,13 @@
package com.intellij.java.psi.codeStyle;
import com.intellij.application.options.codeStyle.properties.AbstractCodeStylePropertyMapper;
import com.intellij.application.options.codeStyle.properties.CodeStylePropertyAccessor;
import com.intellij.ide.codeStyleSettings.CodeStyleTestCase;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.options.SchemeImportException;
import com.intellij.psi.codeStyle.*;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@@ -28,6 +30,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@SuppressWarnings("SameParameterValue")
public class JavaCodeStyleSettingsTest extends CodeStyleTestCase {
public void testSettingsClone() {
@@ -65,6 +68,7 @@ public class JavaCodeStyleSettingsTest extends CodeStyleTestCase {
CommonCodeStyleSettings commonSettings = imported.getCommonSettings(JavaLanguage.INSTANCE);
assertEquals("testprefix", imported.getCustomSettings(JavaCodeStyleSettings.class).FIELD_NAME_PREFIX);
assertTrue(commonSettings.WRAP_COMMENTS);
//noinspection deprecation
assertFalse(imported.WRAP_COMMENTS);
}
@@ -84,7 +88,8 @@ public class JavaCodeStyleSettingsTest extends CodeStyleTestCase {
CommonCodeStyleSettings.class,
CommonCodeStyleSettings.IndentOptions.class)
) {
String value = mapper.getProperty(property);
CodeStylePropertyAccessor accessor = mapper.getAccessor(property);
Object value = accessor.get();
if (value != null) {
builder.append(property).append(" = ").append(value).append('\n');
}
@@ -179,7 +184,7 @@ public class JavaCodeStyleSettingsTest extends CodeStyleTestCase {
"generate_final_locals = false\n" +
"generate_final_parameters = false\n" +
"if_brace_force = never\n" +
"imports_layout = *,blank_line,javax.**,java.**,blank_line,static *\n" +
"imports_layout = [*, blank_line, javax.**, java.**, blank_line, static *]\n" +
"indent_case_from_switch = true\n" +
"indent_size = 4\n" +
"indent_style = space\n" +
@@ -210,7 +215,7 @@ public class JavaCodeStyleSettingsTest extends CodeStyleTestCase {
"method_parameters_wrap = normal\n" +
"modifier_list_wrap = false\n" +
"names_count_to_use_import_on_demand = 3\n" +
"packages_to_use_import_on_demand = java.awt.*,javax.swing.*\n" +
"packages_to_use_import_on_demand = [java.awt.*, javax.swing.*]\n" +
"parameter_annotation_wrap = off\n" +
"parentheses_expression_new_line_after_left_paren = false\n" +
"parentheses_expression_right_paren_on_new_line = false\n" +
@@ -325,12 +330,13 @@ public class JavaCodeStyleSettingsTest extends CodeStyleTestCase {
final CodeStyleSettings settings = getCurrentCodeStyleSettings();
AbstractCodeStylePropertyMapper mapper =
LanguageCodeStyleSettingsProvider.forLanguage(JavaLanguage.INSTANCE).getPropertyMapper(settings);
mapper.setProperty("align_group_field_declarations", "true");
mapper.setProperty("blank_lines_after_class_header", "1");
mapper.setProperty("brace_style", "next_line");
mapper.setProperty("indent_size", "2");
mapper.setProperty("javadoc_align_param_comments", "true");
mapper.setProperty("imports_layout", "com.jetbrains.*,blank_line, org.eclipse.bar , static ** , static org.eclipse.foo.**");
setSimple(mapper, "align_group_field_declarations", "true");
setSimple(mapper, "blank_lines_after_class_header", "1");
setSimple(mapper, "brace_style", "next_line");
setSimple(mapper, "indent_size", "2");
setSimple(mapper, "doc_align_param_comments", "true");
setList(mapper, "imports_layout",
Arrays.asList("com.jetbrains.*", "blank_line", "org.eclipse.bar", "static **", "static org.eclipse.foo.**"));
final CommonCodeStyleSettings commonJavaSettings = settings.getCommonSettings(JavaLanguage.INSTANCE);
final JavaCodeStyleSettings javaSettings = settings.getCustomSettings(JavaCodeStyleSettings.class);
assertTrue(commonJavaSettings.ALIGN_GROUP_FIELD_DECLARATIONS);
@@ -345,6 +351,20 @@ public class JavaCodeStyleSettingsTest extends CodeStyleTestCase {
assertEquals(PackageEntry.ALL_OTHER_STATIC_IMPORTS_ENTRY, importsTable.getEntryAt(3));
assertEquals(new PackageEntry(true, "org.eclipse.foo", true), importsTable.getEntryAt(4));
}
private static void setSimple(@NotNull AbstractCodeStylePropertyMapper mapper, @NotNull String name, @NotNull String value) {
CodeStylePropertyAccessor accessor = mapper.getAccessor(name);
assertNotNull(name + " not found", accessor);
//noinspection unchecked
accessor.set(value);
}
private static void setList(@NotNull AbstractCodeStylePropertyMapper mapper, @NotNull String name, @NotNull List<String> value) {
CodeStylePropertyAccessor accessor = mapper.getAccessor(name);
assertNotNull(name + " not found", accessor);
//noinspection unchecked
accessor.set(value);
}
private static boolean isPrimitiveOrString(Class type) {
return type.isPrimitive() || type.equals(String.class);
@@ -24,21 +24,6 @@ public abstract class AbstractCodeStylePropertyMapper {
myAccessorMap = AtomicNotNullLazyValue.createValue(() -> createMap());
}
public boolean setProperty(@NotNull String name, @NotNull String value) {
if (getAccessorMap().containsKey(name)) {
return myAccessorMap.getValue().get(name).set(value);
}
return false;
}
@Nullable
public String getProperty(@NotNull String name) {
if (getAccessorMap().containsKey(name)) {
return getAccessorMap().get(name).get();
}
return null;
}
public List<String> enumProperties() {
return getAccessorMap().keySet().stream().sorted().collect(Collectors.toList());
}
@@ -8,7 +8,7 @@ import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
public class BooleanAccessor extends CodeStylePropertyAccessor<Boolean> implements CodeStyleChoiceList {
public class BooleanAccessor extends CodeStylePropertyAccessor<Boolean,String> implements CodeStyleChoiceList {
private final static List<String> BOOLEAN_VALS = Arrays.asList("false", "true");
@@ -18,13 +18,13 @@ public class BooleanAccessor extends CodeStylePropertyAccessor<Boolean> implemen
@Nullable
@Override
protected Boolean parseString(@NotNull String str) {
return str.equalsIgnoreCase("true");
protected Boolean fromExternal(@NotNull String extVal) {
return extVal.equalsIgnoreCase("true");
}
@NotNull
@Override
protected String asString(@NotNull Boolean value) {
protected String toExternal(@NotNull Boolean value) {
return value.toString();
}
@@ -10,7 +10,7 @@ import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
class BraceStyleAccessor extends CodeStylePropertyAccessor<Integer> implements CodeStyleChoiceList {
class BraceStyleAccessor extends CodeStylePropertyAccessor<Integer,String> implements CodeStyleChoiceList {
private final static BidirectionalMap<Integer, String> BRACE_STYLE_MAP = new BidirectionalMap<>();
public static final String VALUE_END_OF_LINE = "end_of_line";
@@ -33,14 +33,14 @@ class BraceStyleAccessor extends CodeStylePropertyAccessor<Integer> implements C
@Nullable
@Override
protected Integer parseString(@NotNull String str) {
protected Integer fromExternal(@NotNull String str) {
List<Integer> keys = BRACE_STYLE_MAP.getKeysByValue(str);
return keys != null && keys.size() > 0 ? keys.get(0) : null;
}
@NotNull
@Override
protected String asString(@NotNull Integer value) {
protected String toExternal(@NotNull Integer value) {
return BRACE_STYLE_MAP.get(value);
}
@@ -11,7 +11,7 @@ import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
@ApiStatus.Experimental
public abstract class CodeStylePropertyAccessor<T> {
public abstract class CodeStylePropertyAccessor<T,V> {
private final Object myObject;
private final Field myField;
@@ -20,9 +20,9 @@ public abstract class CodeStylePropertyAccessor<T> {
myField = field;
}
public boolean set(@NotNull String str) {
public boolean set(@NotNull V extVal) {
try {
T value = parseString(str);
T value = fromExternal(extVal);
if (value != null) {
myField.set(myObject, value);
return true;
@@ -35,11 +35,11 @@ public abstract class CodeStylePropertyAccessor<T> {
}
@Nullable
public String get() {
public V get() {
try {
//noinspection unchecked
T value = (T)myField.get(myObject);
return value != null && !isEmpty(value) ? asString(value) : null;
return value != null && !isEmpty(value) ? toExternal(value) : null;
}
catch (IllegalAccessException e) {
// Ignore and return null
@@ -57,10 +57,10 @@ public abstract class CodeStylePropertyAccessor<T> {
}
@Nullable
protected abstract T parseString(@NotNull String str);
protected abstract T fromExternal(@NotNull V extVal);
@NotNull
protected abstract String asString(@NotNull T value);
protected abstract V toExternal(@NotNull T value);
public String getPropertyName() {
Property descriptor = myField.getAnnotation(Property.class);
@@ -10,7 +10,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class EnumPropertyAccessor extends CodeStylePropertyAccessor<Enum> implements CodeStyleChoiceList{
public class EnumPropertyAccessor extends CodeStylePropertyAccessor<Enum,String> implements CodeStyleChoiceList{
private final Class myEnumClass;
private final BidirectionalMap<String,Enum> myEnumMap = new BidirectionalMap<>();
@@ -38,13 +38,13 @@ public class EnumPropertyAccessor extends CodeStylePropertyAccessor<Enum> implem
@Nullable
@Override
protected Enum parseString(@NotNull String str) {
protected Enum fromExternal(@NotNull String str) {
return myEnumMap.get(str);
}
@NotNull
@Override
protected String asString(@NotNull Enum value) {
protected String toExternal(@NotNull Enum value) {
List<String> names = myEnumMap.getKeysByValue(value);
assert names != null && names.size() > 0 : "Unexpected value " + value.toString();
return names.get(0);
@@ -10,7 +10,7 @@ import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
class ForceBracesAccessor extends CodeStylePropertyAccessor<Integer> implements CodeStyleChoiceList {
class ForceBracesAccessor extends CodeStylePropertyAccessor<Integer,String> implements CodeStyleChoiceList {
private final static BidirectionalMap<Integer, String> FORCE_BRACES_MAP = new BidirectionalMap<>();
@@ -32,14 +32,14 @@ class ForceBracesAccessor extends CodeStylePropertyAccessor<Integer> implements
@Nullable
@Override
protected Integer parseString(@NotNull String str) {
protected Integer fromExternal(@NotNull String str) {
List<Integer> keys = FORCE_BRACES_MAP.getKeysByValue(str);
return keys != null && keys.size() > 0 ? keys.get(0) : null;
}
@NotNull
@Override
protected String asString(@NotNull Integer value) {
protected String toExternal(@NotNull Integer value) {
return FORCE_BRACES_MAP.get(value);
}
@@ -68,7 +68,7 @@ public class GeneralCodeStylePropertyMapper extends AbstractCodeStylePropertyMap
@Nullable
@Override
protected String parseString(@NotNull String str) {
protected String fromExternal(@NotNull String str) {
if (str.equals("lf")) {
return "\n";
}
@@ -83,7 +83,7 @@ public class GeneralCodeStylePropertyMapper extends AbstractCodeStylePropertyMap
@NotNull
@Override
protected String asString(@NotNull String value) {
protected String toExternal(@NotNull String value) {
if ("\n".equals(value)) {
return "lf";
}
@@ -5,13 +5,13 @@ import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public class IntegerAccessor extends CodeStylePropertyAccessor<Integer> {
public class IntegerAccessor extends CodeStylePropertyAccessor<Integer,String> {
IntegerAccessor(@NotNull Object object, @NotNull Field field) {
super(object, field);
}
@Override
protected Integer parseString(@NotNull String str) {
protected Integer fromExternal(@NotNull String str) {
try {
return Integer.parseInt(str);
}
@@ -22,7 +22,7 @@ public class IntegerAccessor extends CodeStylePropertyAccessor<Integer> {
@NotNull
@Override
protected String asString(@NotNull Integer value) {
protected String toExternal(@NotNull Integer value) {
return value.toString();
}
@@ -96,13 +96,13 @@ class PropertyAccessorFactory {
@Nullable
@Override
protected Boolean parseString(@NotNull String str) {
protected Boolean fromExternal(@NotNull String str) {
return "tab".equalsIgnoreCase(str);
}
@NotNull
@Override
protected String asString(@NotNull Boolean value) {
protected String toExternal(@NotNull Boolean value) {
return value ? "tab" : "space";
}
@@ -7,7 +7,7 @@ import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
class StringAccessor extends CodeStylePropertyAccessor<String> {
class StringAccessor extends CodeStylePropertyAccessor<String,String> {
StringAccessor(@NotNull Object object, @NotNull Field field) {
super(object, field);
@@ -15,13 +15,13 @@ class StringAccessor extends CodeStylePropertyAccessor<String> {
@Nullable
@Override
protected String parseString(@NotNull String str) {
protected String fromExternal(@NotNull String str) {
return str;
}
@NotNull
@Override
protected String asString(@NotNull String value) {
protected String toExternal(@NotNull String value) {
return value;
}
@@ -0,0 +1,22 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.application.options.codeStyle.properties;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
import java.util.List;
public abstract class ValueListPropertyAccessor<T> extends CodeStylePropertyAccessor<T, List<String>> {
public ValueListPropertyAccessor(@NotNull Object object, @NotNull Field field) {
super(object, field);
}
@Nullable
@Override
protected abstract T fromExternal(@NotNull List<String> extVal);
@NotNull
@Override
protected abstract List<String> toExternal(@NotNull T value);
}
@@ -10,7 +10,7 @@ import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
class WrappingAccessor extends CodeStylePropertyAccessor<Integer> implements CodeStyleChoiceList {
class WrappingAccessor extends CodeStylePropertyAccessor<Integer,String> implements CodeStyleChoiceList {
private final static BidirectionalMap<Integer, String> WRAPPING_MAP = new BidirectionalMap<>();
public static final String VALUE_OFF = "off";
@@ -34,14 +34,14 @@ class WrappingAccessor extends CodeStylePropertyAccessor<Integer> implements Cod
@Nullable
@Override
protected Integer parseString(@NotNull String str) {
protected Integer fromExternal(@NotNull String str) {
List<Integer> keys = WRAPPING_MAP.getKeysByValue(str);
return keys != null && keys.size() > 0 ? keys.get(0) : null;
}
@NotNull
@Override
protected String asString(@NotNull Integer value) {
protected String toExternal(@NotNull Integer value) {
return WRAPPING_MAP.get(value);
}
@@ -2,11 +2,7 @@
package com.intellij.psi.impl.source.codeStyle.json;
import com.google.gson.*;
import com.google.gson.annotations.Expose;
import com.intellij.application.options.codeStyle.properties.AbstractCodeStylePropertyMapper;
import com.intellij.application.options.codeStyle.properties.CodeStylePropertiesUtil;
import com.intellij.application.options.codeStyle.properties.GeneralCodeStylePropertyMapper;
import com.intellij.application.options.codeStyle.properties.LanguageCodeStylePropertyMapper;
import com.intellij.application.options.codeStyle.properties.*;
import com.intellij.lang.Language;
import com.intellij.openapi.options.SchemeExporter;
import com.intellij.psi.codeStyle.CodeStyleScheme;
@@ -18,10 +14,11 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class CodeStyleSchemeJsonExporter extends SchemeExporter<CodeStyleScheme> {
@@ -42,15 +39,26 @@ public class CodeStyleSchemeJsonExporter extends SchemeExporter<CodeStyleScheme>
public JsonElement serialize(AbstractCodeStylePropertyMapper src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject o = new JsonObject();
for (String name : src.enumProperties()) {
String value = src.getProperty(name);
o.addProperty(name, value);
CodeStylePropertyAccessor accessor = src.getAccessor(name);
if (accessor != null) {
Object externalized = accessor.get();
if (externalized instanceof String) {
o.addProperty(name, (String)externalized);
}
else if (externalized != null && accessor instanceof ValueListPropertyAccessor){
@SuppressWarnings("unchecked") List<String> listValues = (List<String>)externalized;
final JsonArray array = new JsonArray();
listValues.forEach(s -> array.add(s));
o.add(name, array);
}
}
}
return o;
}
});
Gson gson = builder.create();
String json = gson.toJson(getOptionDescriptors(scheme.getCodeStyleSettings(), languageNames));
try (PrintWriter writer = new PrintWriter(outputStream)) {
try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8))) {
writer.write(json);
}
}
@@ -1,6 +1,8 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.editorconfig.configmanagement.extended;
import com.intellij.application.options.codeStyle.properties.CodeStylePropertyAccessor;
import com.intellij.application.options.codeStyle.properties.ValueListPropertyAccessor;
import com.intellij.psi.codeStyle.modifier.CodeStyleSettingsModifier;
import com.intellij.application.options.codeStyle.properties.AbstractCodeStylePropertyMapper;
import com.intellij.openapi.project.Project;
@@ -78,8 +80,14 @@ public class EditorConfigCodeStyleSettingsModifier implements CodeStyleSettingsM
for (OutPair option : editorConfigOptions) {
if (!languageSpecific || option.getKey().startsWith(ideLangPrefix)) {
String intellijName = EditorConfigIntellijNameUtil.toIntellijName(mapper, option.getKey());
if (intellijName != null && mapper.setProperty(intellijName, option.getVal())) {
isModified = true;
if (intellijName != null) {
CodeStylePropertyAccessor accessor = mapper.getAccessor(intellijName);
if (!(accessor instanceof ValueListPropertyAccessor)) {
//noinspection unchecked
if (accessor != null && accessor.set(option.getVal())) {
isModified = true;
}
}
}
}
}
@@ -9,6 +9,7 @@ import org.editorconfig.language.extensions.EditorConfigOptionDescriptorProvider
import org.editorconfig.language.schema.descriptors.EditorConfigDescriptor;
import org.editorconfig.language.schema.descriptors.impl.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@@ -39,8 +40,10 @@ public class IntellijConfigOptionDescriptorProvider implements EditorConfigOptio
for (String property : mapper.enumProperties()) {
List<String> ecNames = EditorConfigIntellijNameUtil.toEditorConfigNames(mapper, property);
final EditorConfigDescriptor descriptor = createValueDescriptor(property, mapper);
for (String ecName : ecNames) {
propertyMap.put(ecName, descriptor);
if (descriptor != null) {
for (String ecName : ecNames) {
propertyMap.put(ecName, descriptor);
}
}
}
}
@@ -54,7 +57,7 @@ public class IntellijConfigOptionDescriptorProvider implements EditorConfigOptio
return descriptors;
}
@NotNull
@Nullable
private static EditorConfigDescriptor createValueDescriptor(@NotNull String property, @NotNull AbstractCodeStylePropertyMapper mapper) {
CodeStylePropertyAccessor accessor = mapper.getAccessor(property);
if (accessor instanceof CodeStyleChoiceList) {
@@ -63,6 +66,9 @@ public class IntellijConfigOptionDescriptorProvider implements EditorConfigOptio
else if (accessor instanceof IntegerAccessor) {
return new EditorConfigNumberDescriptor(null, null);
}
else if (accessor instanceof ValueListPropertyAccessor) {
return null; // No support yet
}
return new EditorConfigStringDescriptor(null, null);
}