Merge branch 'codeStyleExtractor'

This commit is contained in:
jamesbrain
2015-10-13 18:48:11 +03:00
26 changed files with 3063 additions and 239 deletions
@@ -0,0 +1,69 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor.differ;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaCodeFragment;
import com.intellij.psi.JavaCodeFragmentFactory;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade;
import com.intellij.psi.codeStyle.extractor.values.Value;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.LinkedList;
/**
* @author Roman.Shein
* @since 05.08.2015.
* TODO: move from debugger-impl to more meaningful location?
*
*
*/
public class JavaExtractor implements LangCodeStyleExtractor {
@NotNull
@Override
public Differ getDiffer(final Project project, PsiFile psiFile, CodeStyleSettings settings) {
return new DifferBase(project, psiFile, settings) {
@Override
public String reformattedText() {
final JavaCodeFragment file = JavaCodeFragmentFactory.getInstance(project).
createCodeBlockCodeFragment(myOrigText, myFile, false);
WriteCommandAction.runWriteCommandAction(myProject, "CodeStyleSettings extractor", "CodeStyleSettings extractor", new Runnable() {
@Override
public void run() {
final ASTNode treeElement = SourceTreeToPsiMap.psiElementToTree(file);
assert (treeElement != null);
SourceTreeToPsiMap.treeElementToPsi(new CodeFormatterFacade(mySettings, file.getLanguage()).processElement(treeElement));
}
}, file);
return file.getText();
}
};
}
@NotNull
@Override
public Collection<Value.VAR_KIND> getCustomVarKinds() {
return new LinkedList<Value.VAR_KIND>();
}
}
@@ -0,0 +1,196 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor;
import com.intellij.lang.Language;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsProvider;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
import com.intellij.psi.codeStyle.extractor.differ.Differ;
import com.intellij.psi.codeStyle.extractor.values.Generation;
import com.intellij.psi.codeStyle.extractor.values.Gens;
import com.intellij.psi.codeStyle.extractor.values.Value;
import com.intellij.psi.codeStyle.extractor.values.ValuesExtractionResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class Utils {
public static int CRITICAL_SYMBOL_WEIGHT = 100;
public static void logError(String message) {
System.out.println(message); //TODO reasonable implementation
}
public static int getTabSize(@Nullable CommonCodeStyleSettings.IndentOptions options) {
return options == null ? 4 : options.TAB_SIZE;
}
public static int getNormalizedLength(@Nullable CommonCodeStyleSettings.IndentOptions options, @NotNull String text) {
return text
.replaceAll(
"\t",
StringUtil.repeatSymbol(' ', getTabSize(options)))
.replaceAll(
"\n",
StringUtil.repeatSymbol(' ', CRITICAL_SYMBOL_WEIGHT))
.length();
}
public static boolean isSpace(char c) {
return " \t\n".indexOf(c) >= 0;
}
public static boolean isBracket(char c) {
return "(){}[]<>".indexOf(c) >= 0;
}
public static int getDiff(@Nullable CommonCodeStyleSettings.IndentOptions options, @NotNull String oldV, @NotNull String newV) {
oldV = oldV.trim();
newV = newV.trim();
int diff = 0;
int oPos = 0, nPos = 0;
int oEnd = oldV.length(), nEnd = newV.length();
StringBuilder oSp = new StringBuilder();
StringBuilder nSp = new StringBuilder();
char ch;
while (oPos < oEnd || nPos < nEnd) {
oSp.setLength(0);
nSp.setLength(0);
while (oPos < oEnd && isSpace(ch = oldV.charAt(oPos))) {
oSp.append(ch);
++oPos;
}
while (nPos < nEnd && isSpace(ch = newV.charAt(nPos))) {
nSp.append(ch);
++nPos;
}
diff += Math.abs(getNormalizedLength(options, oSp.toString())
- getNormalizedLength(options, nSp.toString())); //each time
while (oPos < oEnd && nPos < nEnd
&& (ch = oldV.charAt(oPos)) == newV.charAt(nPos)
&& !isSpace(ch)) {
++oPos;
++nPos;
}
if (oPos < oEnd && nPos < nEnd && !isSpace(oldV.charAt(oPos)) && !isSpace(newV.charAt(nPos))) {
logError("AST changed!");
return Differ.UGLY_FORMATTING;
}
}
return diff;
}
@Nullable
public static CustomCodeStyleSettings getLanguageSettings(@NotNull CodeStyleSettings settings, @NotNull Language language) {
for (CodeStyleSettingsProvider provider : CodeStyleSettingsProvider.EXTENSION_POINT_NAME.getExtensions()) {
if (language.equals(provider.getLanguage())) {
CustomCodeStyleSettings modelSettings = provider.createCustomSettings(settings);
if (modelSettings == null) continue;
CustomCodeStyleSettings customSettings = settings.getCustomSettings(modelSettings.getClass());
if (customSettings != null) {
return customSettings;
}
}
}
logError("Failed to load CustomCodeStyleSettings for " + language);
return null;
}
public static void adjustValuesMin(
@NotNull ValuesExtractionResult gens,
@NotNull Differ differ,
@Nullable ProgressIndicator indicator) {
final List<Value> values = gens.getValues();
final int length = values.size();
int i = 0;
for (Value value : values) {
if (indicator != null) {
indicator.checkCanceled();
indicator.setText2("Value:" + value.name);
indicator.setFraction(0.5 + 0.5 * i / length);
}
Object bestValue = value.value;
int bestScope = differ.getDifference(gens);
for (Object cnst : value.getPossibleValues()) {
if (cnst.equals(value.value)) {
continue;
}
value.value = cnst;
int diff = differ.getDifference(gens);
if (diff < bestScope) {
bestValue = cnst;
bestScope = diff;
value.state = Value.STATE.SELECTED;
}
else if (diff > bestScope) {
value.state = Value.STATE.SELECTED;
}
}
value.value = bestValue;
++i;
}
}
public static void adjustValuesGA(
@NotNull Gens gens,
@NotNull Differ differ,
@Nullable ProgressIndicator indicator) {
Generation generation = Generation.createZeroGeneration(gens);
while (generation.tryAgain()) {
if (indicator != null) {
indicator.checkCanceled();
}
final int age = generation.getAge();
if (indicator != null) {
indicator.setText2(" age:" + age + "/" + generation.getParentKind());
indicator.setFraction(0.5 * age / Generation.GEN_COUNT);
}
generation = Generation.createNextGeneration(differ, generation);
}
gens.copyFrom(generation.getBestGens(differ));
}
static long rseed = 0;
static final long RAND_MAX_32 = ((1L << 31L) - 1L);
static final long RAND_MAX = ((1L << 15L) - 1L);
public static void resetRandom() {
rseed = 0;
}
public static long getRandom() {
rseed = (rseed * 214013 + 2531011) & RAND_MAX_32;
return rseed >> 16;
}
public static int getRandomLess(int count) {
final int ret = (int)(getRandom() * count / RAND_MAX);
if (ret >= count) return count - 1;
if (ret < 0) return 0;
return ret;
}
}
@@ -0,0 +1,24 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor.differ;
import com.intellij.psi.codeStyle.extractor.values.ValuesExtractionResult;
public interface Differ {
int UGLY_FORMATTING = Integer.MAX_VALUE / 4;
int getDifference(ValuesExtractionResult values);
}
@@ -0,0 +1,51 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor.differ;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.extractor.Utils;
import com.intellij.psi.codeStyle.extractor.values.ValuesExtractionResult;
/**
* @author Roman.Shein
* @since 30.07.2015.
*/
public abstract class DifferBase implements Differ {
protected final Project myProject;
protected final String myOrigText;
protected final CodeStyleSettings mySettings;
protected final PsiFile myFile;
public DifferBase(Project project, PsiFile file, CodeStyleSettings settings) {
myProject = project;
myFile = file;
myOrigText = myFile.getText();
mySettings = settings;
}
public abstract String reformattedText();
@Override
public int getDifference(ValuesExtractionResult container) {
final ValuesExtractionResult orig = container.apply(true);
String newText = reformattedText();
int result = Utils.getDiff(mySettings.getCommonSettings(myFile.getLanguage()).getIndentOptions(), myOrigText, newText);
orig.apply(false);
return result;
}
}
@@ -0,0 +1,40 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor.differ;
import com.intellij.lang.LanguageExtension;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.extractor.values.Value;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
/**
* @author Roman.Shein
* @since 31.07.2015.
*/
public interface LangCodeStyleExtractor {
LanguageExtension<LangCodeStyleExtractor> EXTENSION =
new LanguageExtension<LangCodeStyleExtractor>("com.intellij.lang.formatting.extractor");
@NotNull
Differ getDiffer(Project project, PsiFile psiFile, CodeStyleSettings settings);
@NotNull
Collection<Value.VAR_KIND> getCustomVarKinds();
}
@@ -0,0 +1,62 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor.processor;
import com.intellij.lang.Language;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.extractor.Utils;
import com.intellij.psi.codeStyle.extractor.differ.Differ;
import com.intellij.psi.codeStyle.extractor.differ.LangCodeStyleExtractor;
import com.intellij.psi.codeStyle.extractor.values.Value;
import com.intellij.psi.codeStyle.extractor.values.ValuesExtractionResult;
import com.intellij.psi.codeStyle.extractor.values.ValuesExtractionResultImpl;
import java.util.List;
import java.util.Random;
/**
* @author Roman.Shein
* @since 04.08.2015.
*/
public class BruteForceProcessor extends CodeStyleDeriveProcessor {
public BruteForceProcessor(LangCodeStyleExtractor langExtractor) {
super(langExtractor);
}
@Override
public ValuesExtractionResult runWithProgress(Project project, CodeStyleSettings settings, PsiFile file, ProgressIndicator indicator) {
List<Value> values = getFormattingValues(settings, file.getLanguage());
Differ differ = myLangExtractor.getDiffer(project, file, settings);
ValuesExtractionResult container = new ValuesExtractionResultImpl(values);
Utils.adjustValuesMin(container, differ, indicator);
return container;
}
public void randomizeSettings(CodeStyleSettings settings, Language language) {
List<Value> values = getFormattingValues(settings, language);
Random rand = new Random();
for (Value value : values) {
Object[] possible = value.getPossibleValues();
int index = rand.nextInt(possible.length);
value.value = possible[index];
value.write(false);
}
}
}
@@ -0,0 +1,143 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor.processor;
import com.intellij.lang.Language;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
import com.intellij.psi.codeStyle.extractor.Utils;
import com.intellij.psi.codeStyle.extractor.differ.LangCodeStyleExtractor;
import com.intellij.psi.codeStyle.extractor.values.ClassSerializer;
import com.intellij.psi.codeStyle.extractor.values.Value;
import com.intellij.psi.codeStyle.extractor.values.ValuesExtractionResult;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
import java.util.*;
/**
* @author Roman.Shein
* @since 04.08.2015.
*/
public abstract class CodeStyleDeriveProcessor {
protected final LangCodeStyleExtractor myLangExtractor;
protected CodeStyleDeriveProcessor(LangCodeStyleExtractor langExtractor) {
myLangExtractor = langExtractor;
}
public abstract ValuesExtractionResult runWithProgress(Project project, CodeStyleSettings settings, PsiFile file,
ProgressIndicator indicator);
public Map<Value, Object> backupValues(CodeStyleSettings settings, Language language) {
List<Value> baseValues = getFormattingValues(settings, language);
Map<Value, Object> res = ContainerUtil.newHashMap();
for (Value baseValue: baseValues) {
res.put(baseValue, baseValue.value);
}
return res;
}
@NotNull
private Collection<Value.VAR_KIND> getVarKinds() {
List<Value.VAR_KIND> varKinds = new LinkedList<Value.VAR_KIND>();
varKinds.addAll(myLangExtractor.getCustomVarKinds());
varKinds.addAll(Arrays.asList(Value.VAR_KIND.defaultKinds));
return varKinds;
}
@NotNull
private Value.VAR_KIND getVarKind(@NotNull String name, @NotNull Object value) {
for (Value.VAR_KIND varKind : getVarKinds()) {
if (varKind.accepts(name, value)) {
return varKind;
}
}
return Value.VAR_KIND.NOTHING;
}
@NotNull
private List<Value> readAll(@NotNull String instanceName, @NotNull Object instance) {
Class<?> cls = instance.getClass();
List<Value> ret = new ArrayList<Value>();
ClassSerializer serializer = new ClassSerializer(instanceName, instance);
for (Field field : cls.getDeclaredFields()) {
field = ClassSerializer.getPreparedField(field);
if (field == null || field.getName().endsWith("_FORCE")) continue;
try {
ret.add(buildFValue(field, instance, serializer));
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return ret;
}
@NotNull
private Value buildFValue(@NotNull Field field,
@NotNull Object instance,
@NotNull ClassSerializer serializer) throws IllegalAccessException {
String name = field.getName();
Object value = field.get(instance);
Value.VAR_KIND varKind = getVarKind(name, value);
return new Value(name, value, serializer, varKind);
}
@NotNull
protected List<Value> getFormattingValues(CodeStyleSettings settings, Language language) {
final CommonCodeStyleSettings commonSettings = settings.getCommonSettings(language);
CommonCodeStyleSettings.IndentOptions indentOptions = commonSettings.getIndentOptions();
if (indentOptions == null) {
Utils.logError("IndentOptions from common settings are null; using indent options from settings.");
indentOptions = settings.getIndentOptions();
}
final Object languageSettings = Utils.getLanguageSettings(settings, language);
List<Value> values = readAll("commonSettings", commonSettings);
if (languageSettings != null) {
values.addAll(readAll("ocSettings", languageSettings));
}
final LanguageCodeStyleSettingsProvider provider = LanguageCodeStyleSettingsProvider.forLanguage(language);
if (provider != null) {
final Set<String> supportedFields = provider.getSupportedFields();
List<Value> cvalues = new ArrayList<Value>(values.size());
for (Value value : values) {
if (supportedFields.contains(value.name)) {
cvalues.add(value);
}
}
values = cvalues;
}
if (indentOptions != null) {
List<Value> valuesOrder = readAll("indentOptions", indentOptions);
valuesOrder.addAll(values);
return valuesOrder;
} else {
Utils.logError("Not indent options detected.");
return values;
}
}
}
@@ -0,0 +1,67 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor.processor;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.extractor.Utils;
import com.intellij.psi.codeStyle.extractor.differ.Differ;
import com.intellij.psi.codeStyle.extractor.differ.LangCodeStyleExtractor;
import com.intellij.psi.codeStyle.extractor.values.Gens;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author Roman.Shein
* @since 29.07.2015.
*/
public class GenProcessor extends CodeStyleDeriveProcessor {
private static DateFormat formatter = new SimpleDateFormat("mm:ss");
public GenProcessor(LangCodeStyleExtractor langExtractor) {
super(langExtractor);
}
@Override
public Gens runWithProgress(Project project, CodeStyleSettings settings, PsiFile file, ProgressIndicator indicator) {
final Gens origGens = new Gens(getFormattingValues(settings, file.getLanguage()));
final Gens forSelection = origGens.copy();
final Differ differ = myLangExtractor.getDiffer(project, file, settings);
forSelection.dropToInitial();
Utils.resetRandom();
long startTime = System.nanoTime();
Utils.adjustValuesGA(forSelection, differ, indicator);
reportResult("GA", forSelection, differ, startTime, file.getName());
startTime = System.nanoTime();
Utils.adjustValuesMin(forSelection, differ, indicator);
reportResult("MIN", forSelection, differ, startTime, file.getName());
return forSelection;
}
private void reportResult(String label, Gens gens, Differ differ, long startTime, String fileName) {
Date date = new Date((System.nanoTime() - startTime) / 1000000);
System.out.println(fileName + ": " + label + " range:" + differ.getDifference(gens) + " Execution Time: " + formatter.format(date));
}
}
@@ -0,0 +1,107 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor.values;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class ClassSerializer {
@NotNull
private String myInstanceName;
@NotNull
private final Object myInstance;
public ClassSerializer(@NotNull String instanceName, @NotNull Object o) {
myInstanceName = instanceName;
myInstance = o;
}
@Nullable
public Object read(@NotNull String name) {
try {
final Field field = getPreparedField(myInstance.getClass().getField(name));
if (field == null) return null;
return field.get(myInstance);
}
catch (NoSuchFieldException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
@Nullable
@Contract("_, _, false -> null")
public Object write(@NotNull String name, @NotNull Object value, boolean retPrevValue) {
try {
final Field field = getPreparedField(myInstance.getClass().getField(name));
if (field != null) {
Object ret = retPrevValue ? field.get(myInstance) : null;
field.set(myInstance, value);
return ret;
}
}
catch (NoSuchFieldException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
@Nullable
public static Field getPreparedField(Field field) {
field.setAccessible(true);
Class<?> type = field.getType();
if ((field.getModifiers() & Modifier.STATIC) != 0) {
return null;
}
if (type != int.class && type != boolean.class) {
return null;
}
if (field.getName().startsWith("my")) {
return null;
}
return field;
}
@NotNull
public String getInstanceName() {
return myInstanceName;
}
@Override
public boolean equals(Object o) {
if (o instanceof ClassSerializer) {
ClassSerializer other = (ClassSerializer) o;
return other.myInstance.equals(myInstance);
} else {
return false;
}
}
@Override
public int hashCode() {
return myInstance.hashCode();
}
}
@@ -0,0 +1,145 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor.values;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.codeStyle.extractor.Utils;
import com.intellij.psi.codeStyle.extractor.differ.Differ;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Generation {
private static int GENERATION_POOL_SIZE = 45;
private static int MUTATION_PER_GEN = 10;
public static int GEN_COUNT = 40;
private List<Gens> myGensPool;
private int myAge;
private int myParentKind;
private Generation(@NotNull final Gens bestGens) {
myParentKind = -1;
myGensPool = new ArrayList<Gens>(GENERATION_POOL_SIZE);
for (int i = 0; i < GENERATION_POOL_SIZE; ++i) {
// the best goes as is
myGensPool.add(new Gens(bestGens).mutate(i == 0 ? 0 : MUTATION_PER_GEN));
}
myAge = 0;
}
private Generation(@NotNull Generation previous, int parentKind) {
myAge = previous.myAge + 1;
myParentKind = parentKind;
myGensPool = new ArrayList<Gens>(GENERATION_POOL_SIZE);
int mutationsCount = MUTATION_PER_GEN;
//if (myAge < 30) {
// if (myAge < 5) {
// mutationsCount = 50;
// }
// else if (myAge % 5 == 0) {
// mutationsCount = 25;
// }
//}
//else if (myAge < 40) {
// mutationsCount = 10;
//}
//else if (myAge < 50) {
// mutationsCount = 5;
//}
final int prevPullSize = previous.myGensPool.size();
for (int i = 0; i < GENERATION_POOL_SIZE; i++) {
int parent1 = 0, parent2 = 0, iterations = 0;
while (parent1 == parent2) {
parent1 = Utils.getRandomLess(prevPullSize);//~ fitness?
parent2 = Utils.getRandomLess(prevPullSize);
if (++iterations > 25) break;
}
myGensPool.add(Gens.breed(
previous.myGensPool.get(parent1),
previous.myGensPool.get(parent2),
mutationsCount));
}
}
public static Generation createZeroGeneration(@NotNull Gens gens) {
return new Generation(gens);
}
public static Generation createNextGeneration(Differ differ, @NotNull Generation previous) {
final int parentKind = previous.reduceToSize(differ, (int)(0.2 * previous.myGensPool.size()));
return previous.tryAgain() ? new Generation(previous, parentKind) : previous;
}
private int reduceToSize(Differ differ, int newPoolSize) {
List<Pair<Integer, Integer>> ranges = new ArrayList<Pair<Integer, Integer>>(myGensPool.size());
int i = 0;
for (final Gens gens : myGensPool) {
int range = differ.getDifference(gens);
ranges.add(Pair.create(range, i++));
if (range == 0) {
myAge = GEN_COUNT;
newPoolSize = 1;
break;
}
}
Collections.sort(ranges, new Comparator<Pair<Integer, Integer>>() {
@Override
public int compare(Pair<Integer, Integer> o1, Pair<Integer, Integer> o2) {
return o1.first - o2.first;
}
});
final ArrayList<Gens> gensPool = new ArrayList<Gens>(newPoolSize);
int count = 0;
int worseForward = 0;
for (final Pair<Integer, Integer> pair : ranges) {
if (count >= newPoolSize) {
break;
}
Gens gens = myGensPool.get(pair.second);
gensPool.add(gens);
++count;
worseForward = pair.first;
}
myGensPool = gensPool;
return worseForward;
}
public boolean tryAgain() {
return myAge < GEN_COUNT;
}
public Gens getBestGens(Differ differ) {
reduceToSize(differ, 1);
return myGensPool.get(0);
}
public int getAge() {
return myAge;
}
public int getParentKind() {
return myParentKind;
}
}
@@ -0,0 +1,126 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor.values;
import com.intellij.psi.codeStyle.extractor.Utils;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class Gens extends ValuesExtractionResultImpl {
public Gens(@NotNull List<Value> values) {
super(values);
}
public Gens(@NotNull Gens gens) {
this(gens.copy().getValues());
}
public Gens mutate(int averageMutationCount) {
if (averageMutationCount > 0) {
// with mutation
int commonMutagen = 0;
for (Value value : myValues) {
commonMutagen += value.getMutagenFactor();
}
for (Value value : myValues) {
if (Utils.getRandomLess(commonMutagen) < value.getMutagenFactor() * averageMutationCount) {
final Object[] possibleValues = value.getPossibleValues();
value.value = possibleValues[Utils.getRandomLess(possibleValues.length)];
}
}
}
return this;
}
public Gens dropToInitial() {
final ArrayList<Value> values = new ArrayList<Value>();
for (Value value : myValues) {
final Object[] possibleValues = value.getPossibleValues();
if (possibleValues.length > 0) {
value.value = possibleValues[0];
}
}
return this;
}
@NotNull
public Gens copy() {
final ArrayList<Value> values = new ArrayList<Value>();
for (Value value : myValues) {
values.add(new Value(value));
}
return new Gens(values);
}
public Gens diff(Gens newGens) {
final List<Value> newValues = newGens.getValues();
final int size = myValues.size();
assert size == newValues.size();
final List<Value> diff = new ArrayList<Value>();
for (int i = 0; i < size; ++i) {
final Value value = myValues.get(i);
final Value newValue = newValues.get(i);
assert value.name.equals(newValue.name);
if (!value.value.equals(newValue.value)) {
diff.add(new Value(value.name, value.value + "->" + newValue.value, value.serializer, value.kind));
}
}
return new Gens(diff);
}
@NotNull
public static Gens breed(@NotNull Gens p1, @NotNull Gens p2, int averageMutationCount) {
final int size = p1.myValues.size();
assert size == p2.myValues.size();
// Crossover!
final int crossover = size / 2;//FUtils.getRandomLess(size - 6) + 3;
final List<Value> values = new ArrayList<Value>(size);
for (int i = 0; i < size; ++i) {
final Value value1 = p1.myValues.get(i);
final Value value2 = p2.myValues.get(i);
if (value1.kind == Value.VAR_KIND.INDENT) {
values.add(new Value(value1));
}
else if (value1.kind == Value.VAR_KIND.BRACE_STYLE) {
values.add(new Value(value2));
}
else if ((i & 0x1) == 1) {
values.add(new Value(value1));
}
else {
values.add(new Value(value2));
}
}
return new Gens(values).mutate(averageMutationCount);
}
public void copyFrom(Gens gens) {
if (myValues == gens.myValues) {
return;
}
myValues.clear();
myValues.addAll(gens.myValues);
}
}
@@ -0,0 +1,242 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor.values;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class Value {
public enum STATE {
INIT,
SELECTED,
ANY
}
public static abstract class VAR_KIND {
public int getMutagenFactor() {
return 1;
}
@NotNull
private Object[] myPossibleValues;
VAR_KIND(@NotNull Object[] possibleValues) {
myPossibleValues = possibleValues;
}
@NotNull
public Object[] getPossibleValues() {
return myPossibleValues;
}
public abstract boolean accepts(@NotNull String name, @NotNull Object value);
@NotNull
private static Object[] getRMValues() {
int from = 10;
int to = 120;
Object[] ret = new Object[to - from + 1];
ret[0] = -1; //any
for (int i = to; i > from; --i) ret[i - from] = i;
return ret;
}
//----------------Default var kinds go here---------------------
public static final VAR_KIND RIGHT_MARGIN = new CLASS_BASED_VAR_KIND(getRMValues(), Integer.class) {
@Override
public boolean acceptsName(@NotNull String name) {
return name.equals("RIGHT_MARGIN");
}
@Override
public int getMutagenFactor() {
return 0;
}
};
public static final VAR_KIND BLANK = new CLASS_BASED_VAR_KIND(new Object[]{0, 1, 2}, Integer.class) {
@Override
public boolean acceptsName(@NotNull String name) {
return name.contains("BLANK");
}
@Override
public int getMutagenFactor() {
return 2;
}
};
public static final VAR_KIND INDENT = new CLASS_BASED_VAR_KIND(new Object[]{0, 1, 2, 3, 4, 5, 6, 7, 8}, Integer.class) {
@Override
public boolean acceptsName(@NotNull String name) {
return name.contains("INDENT");
}
@Override
public int getMutagenFactor() {
return 7;
}
};
public static final VAR_KIND DEFAULT = new CLASS_BASED_VAR_KIND(new Object[]{0, 1, 2, 3, 4, 5, 6, 7, 8}, Integer.class) {
@Override
public boolean acceptsName(@NotNull String name) {
return true;
}
};
public static final VAR_KIND TAB_SIZE = new CLASS_BASED_VAR_KIND(new Object[]{2, 4, 8}, Integer.class) {
@Override
public boolean acceptsName(@NotNull String name) {
return name.contains("TAB_SIZE");
}
@Override
public int getMutagenFactor() {
return 2;
}
};
public static final VAR_KIND WRAP = new CLASS_BASED_VAR_KIND(new Object[]{0, 1, 2, 5}, Integer.class) {
@Override
public boolean acceptsName(@NotNull String name) {
return name.endsWith("_WRAP");
}
};
public static final VAR_KIND BRACE_STYLE = new CLASS_BASED_VAR_KIND(new Object[]{1, 2, 3, 4, 5}, Integer.class) {
@Override
public boolean acceptsName(@NotNull String name) {
return name.endsWith("BRACE_STYLE") || name.endsWith("BRACE_PLACEMENT");
}
@Override
public int getMutagenFactor() {
return 7;
}
};
public static final VAR_KIND KEEP = new CLASS_BASED_VAR_KIND(new Object[]{true, false}, Boolean.class) {
@Override
public boolean acceptsName(@NotNull String name) {
return name.contains("KEEP");
}
@Override
public int getMutagenFactor() {
return 3;
}
};
public static final VAR_KIND BOOL = new CLASS_BASED_VAR_KIND(new Object[]{true, false}, Boolean.class) {
@Override
public boolean acceptsName(@NotNull String name) {
return true;
}
};
public static final VAR_KIND NOTHING = new VAR_KIND(new Object[]{}) {
@Override
public boolean accepts(@NotNull String name, @NotNull Object value) {
return true;
}
};
public static final VAR_KIND[] defaultKinds = {RIGHT_MARGIN, WRAP, BRACE_STYLE, TAB_SIZE, INDENT, BLANK, DEFAULT,
KEEP, BOOL, NOTHING};
}
public static abstract class CLASS_BASED_VAR_KIND extends VAR_KIND {
private final Class<?> myVarClass;
public CLASS_BASED_VAR_KIND(@NotNull Object[] possibleValues, @NotNull Class<?> varClass) {
super(possibleValues);
myVarClass = varClass;
}
@Override
public boolean accepts(@NotNull String name, @NotNull Object value) {
return value.getClass().equals(myVarClass) && acceptsName(name);
}
public abstract boolean acceptsName(@NotNull String name);
}
public Object[] getPossibleValues() {
return kind.getPossibleValues();
}
public int getMutagenFactor() {
return kind.getMutagenFactor();
}
@NotNull
public final String name;
@NotNull
public Object value;
@NotNull
public STATE state;
@NotNull
public ClassSerializer serializer;
@NotNull
public final VAR_KIND kind;
public Value(@NotNull String name, @NotNull Object value, @NotNull ClassSerializer serializer, @NotNull VAR_KIND kind) {
this.kind = kind;
this.name = name;
if (value instanceof Integer && ((Integer)value) == 0 && kind == VAR_KIND.BRACE_STYLE) {
this.value = 1;
}
else {
this.value = value;
}
state = STATE.INIT;
this.serializer = serializer;
}
public Value(@NotNull Value valueZ) {
name = valueZ.name;
value = valueZ.value;
state = valueZ.state;
serializer = valueZ.serializer;
kind = valueZ.kind;
}
@Nullable
@Contract("false -> null")
public Value write(boolean retPrevValue) {
final Object orig = serializer.write(name, value, retPrevValue);
return orig == null ? null : new Value(name, orig, serializer, kind);
}
@Override
public String toString() {
return name + "=" + value + ";";
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public boolean equals(Object o) {
if (o instanceof Value) {
Value other = (Value) o;
return other.name.equals(name) && other.serializer.equals(serializer);
} else {
return false;
}
}
}
@@ -0,0 +1,38 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor.values;
import com.intellij.openapi.util.Condition;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Map;
/**
* @author Roman.Shein
* @since 04.08.2015.
*/
public interface ValuesExtractionResult {
@NotNull
List<Value> getValues();
void applySelected();
void applyConditioned(Condition<Value> c, Map<Value, Object> backup);
ValuesExtractionResult apply(boolean retPrevValue);
}
@@ -0,0 +1,81 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor.values;
import com.intellij.openapi.util.Condition;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author Roman.Shein
* @since 04.08.2015.
*/
public class ValuesExtractionResultImpl implements ValuesExtractionResult {
@NotNull
protected final List<Value> myValues;
public ValuesExtractionResultImpl(@NotNull List<Value> values) {
myValues = values;
}
@NotNull
public List<Value> getValues() {
return myValues;
}
public void applySelected() {
for (Value value : myValues) {
if (value.state == Value.STATE.SELECTED) {
value.write(false);
}
}
}
@Override
public void applyConditioned(Condition<Value> c, Map<Value, Object> backup) {
for (Value value: myValues) {
if (c.value(value)) {
value.write(false);
} else {
value.value = backup.get(value);
value.write(false);
}
}
}
@Contract("false -> null")
public ValuesExtractionResult apply(boolean retPrevValue) {
if (retPrevValue) {
final ArrayList<Value> orig = new ArrayList<Value>();
for (Value value : myValues) {
final Value old = value.write(true);
if (old != null) {
orig.add(old);
}
}
return new Gens(orig);
}
for (Value value : myValues) {
value.write(false);
}
return null;
}
}
@@ -0,0 +1,66 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.presentation;
import org.jetbrains.annotations.NotNull;
/**
* @author Roman.Shein
* @since 15.09.2015.
*/
public class CodeStyleBoundedIntegerSettingPresentation extends CodeStyleSettingPresentation {
protected int myLowerBound;
protected int myUpperBound;
protected int myDefaultValue;
protected String myDefaultValueUiName;
public CodeStyleBoundedIntegerSettingPresentation(@NotNull String fieldName,
@NotNull String uiName,
int lowerBound,
int upperBound,
int defaultValue,
String defaultValueUiName) {
super(fieldName, uiName);
myLowerBound = lowerBound;
myUpperBound = upperBound;
myDefaultValue = defaultValue;
myDefaultValueUiName = defaultValueUiName;
}
public int getLowerBound() {
return myLowerBound;
}
public int getUpperBound() {
return myUpperBound;
}
public int getDefaultValue() {
return myDefaultValue;
}
@Override
@NotNull
public String getValueUiName(@NotNull Object value) {
if (value instanceof Integer) {
int intValue = (Integer) value;
return intValue == myDefaultValue ? myDefaultValueUiName : super.getValueUiName(value);
} else {
return super.getValueUiName(value);
}
}
}
@@ -0,0 +1,84 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.presentation;
import org.jetbrains.annotations.NotNull;
/**
* @author Roman.Shein
* @since 16.09.2015.
*/
public class CodeStyleSelectSettingPresentation extends CodeStyleSettingPresentation {
@NotNull
protected int[] myValues;
@NotNull
protected String[] myValueUiNames;
protected int myLowerBound;
protected int myUpperBound;
public CodeStyleSelectSettingPresentation(@NotNull String fieldName, @NotNull String uiName,
@NotNull int[] values, @NotNull String[] valueUiNames) {
super(fieldName, uiName);
assert(values.length == valueUiNames.length);
assert(values.length > 0);
myValues = values;
myValueUiNames = valueUiNames;
//TODO get bounds more gracefully
myLowerBound = values[0];
myUpperBound = values[0];
for (int value : values) {
myLowerBound = Math.min(value, myLowerBound);
myUpperBound = Math.max(value, myUpperBound);
}
}
@Override
@NotNull
public String getValueUiName(@NotNull Object value) {
if (value instanceof Integer) {
int intValue = (Integer) value;
for (int i = 0; i < myValues.length; ++i) {
if (myValues[i] == intValue) return myValueUiNames[i];
}
return super.getValueUiName(value);
} else {
return super.getValueUiName(value);
}
}
public int getLowerBound() {
return myLowerBound;
}
public int getUpperBound() {
return myUpperBound;
}
@NotNull
public int[] getValues() {
return myValues;
}
@NotNull
public String[] getOptions() {
return myValueUiNames;
}
}
@@ -0,0 +1,525 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.presentation;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtil.ImmutableMapBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static com.intellij.psi.codeStyle.CodeStyleSettingsCustomizable.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* @author Roman.Shein
* @since 15.09.2015.
*/
public class CodeStyleSettingPresentation {
public static class SettingsGroup {
@Nullable
public final String name;
public SettingsGroup(@Nullable String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (o instanceof SettingsGroup) {
SettingsGroup other = (SettingsGroup) o;
return name != null && name.equals(other.name);
} else {
return false;
}
}
@Override
public int hashCode() {
return name == null ? 0 : name.hashCode();
}
public boolean isNull() {
return name == null;
}
}
@NotNull
protected String myFieldName;
@NotNull
protected String myUiName;
public CodeStyleSettingPresentation(@NotNull String fieldName, @NotNull String uiName) {
myFieldName = fieldName;
myUiName = uiName;
}
@NotNull
public String getFieldName() {
return myFieldName;
}
@NotNull
public String getUiName() {
return myUiName;
}
public void setUiName(@NotNull String newName) {
myUiName = newName;
}
@NotNull
public String getValueUiName(@NotNull Object value) {
return value.toString();
}
@Override
public boolean equals(Object o) {
return (o instanceof CodeStyleSettingPresentation) && ((CodeStyleSettingPresentation)o).getFieldName().equals(getFieldName());
}
@Override
public int hashCode() {
return myFieldName.hashCode();
}
protected static void putGroupTop(@NotNull Map<CodeStyleSettingPresentation.SettingsGroup, List<CodeStyleSettingPresentation>> result,
@NotNull String fieldName,
@NotNull String uiName, int[] values, String[] valueUiNames) {
result.put(new SettingsGroup(null), ContainerUtil.<CodeStyleSettingPresentation>immutableList(
new CodeStyleSelectSettingPresentation(fieldName, uiName, values, valueUiNames)
));
}
protected static final Map<SettingsGroup, List<CodeStyleSettingPresentation>> BLANK_LINES_STANDARD_SETTINGS;
protected static final Map<SettingsGroup, List<CodeStyleSettingPresentation>> SPACING_STANDARD_SETTINGS;
protected static final Map<SettingsGroup, List<CodeStyleSettingPresentation>> WRAPPING_AND_BRACES_STANDARD_SETTINGS;
protected static final Map<SettingsGroup, List<CodeStyleSettingPresentation>> INDENT_STANDARD_SETTINGS;
static {
//-----------------------------------BLANK_LINES_SETTINGS-----------------------------------------------------
Map<SettingsGroup, List<CodeStyleSettingPresentation>> result = ContainerUtil.newLinkedHashMap();
result.put(new SettingsGroup(BLANK_LINES_KEEP), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("KEEP_BLANK_LINES_IN_DECLARATIONS",
ApplicationBundle.message("editbox.keep.blanklines.in.declarations")),
new CodeStyleSettingPresentation("KEEP_BLANK_LINES_IN_CODE", ApplicationBundle.message("editbox.keep.blanklines.in.code")),
new CodeStyleSettingPresentation("KEEP_BLANK_LINES_BEFORE_RBRACE",
ApplicationBundle.message("editbox.keep.blanklines.before.rbrace"))
));
result.put(new SettingsGroup(BLANK_LINES), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("BLANK_LINES_BEFORE_PACKAGE",
ApplicationBundle.message("editbox.blanklines.before.package.statement")),
new CodeStyleSettingPresentation("BLANK_LINES_AFTER_PACKAGE",
ApplicationBundle.message("editbox.blanklines.after.package.statement")),
new CodeStyleSettingPresentation("BLANK_LINES_BEFORE_IMPORTS", ApplicationBundle.message("editbox.blanklines.before.imports")),
new CodeStyleSettingPresentation("BLANK_LINES_AFTER_IMPORTS", ApplicationBundle.message("editbox.blanklines.after.imports")),
new CodeStyleSettingPresentation("BLANK_LINES_AROUND_CLASS", ApplicationBundle.message("editbox.blanklines.around.class")),
new CodeStyleSettingPresentation("BLANK_LINES_AFTER_CLASS_HEADER",
ApplicationBundle.message("editbox.blanklines.after.class.header")),
new CodeStyleSettingPresentation("BLANK_LINES_AFTER_ANONYMOUS_CLASS_HEADER",
ApplicationBundle.message("editbox.blanklines.after.anonymous.class.header")),
new CodeStyleSettingPresentation("BLANK_LINES_AROUND_FIELD_IN_INTERFACE", "Around field in interface:"),
//TODO why is this not loaded from bundle??
new CodeStyleSettingPresentation("BLANK_LINES_AROUND_FIELD", ApplicationBundle.message("editbox.blanklines.around.field")),
new CodeStyleSettingPresentation("BLANK_LINES_AROUND_METHOD_IN_INTERFACE", "Around method in interface:"),
//TODO why is this not loaded from bundle??
new CodeStyleSettingPresentation("BLANK_LINES_AROUND_METHOD", ApplicationBundle.message("editbox.blanklines.around.method")),
new CodeStyleSettingPresentation("BLANK_LINES_BEFORE_METHOD_BODY",
ApplicationBundle.message("editbox.blanklines.before.method.body"))
));
BLANK_LINES_STANDARD_SETTINGS = Collections.unmodifiableMap(result);
//-----------------------------------SPACING_SETTINGS-----------------------------------------------------
result = ContainerUtil.newLinkedHashMap();
result.put(new SettingsGroup(SPACES_BEFORE_PARENTHESES), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("SPACE_BEFORE_METHOD_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.method.declaration.parentheses")),
new CodeStyleSettingPresentation("SPACE_BEFORE_METHOD_CALL_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.method.call.parentheses")),
new CodeStyleSettingPresentation("SPACE_BEFORE_IF_PARENTHESES", ApplicationBundle.message("checkbox.spaces.if.parentheses")),
new CodeStyleSettingPresentation("SPACE_BEFORE_FOR_PARENTHESES", ApplicationBundle.message("checkbox.spaces.for.parentheses")),
new CodeStyleSettingPresentation("SPACE_BEFORE_WHILE_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.while.parentheses")),
new CodeStyleSettingPresentation("SPACE_BEFORE_SWITCH_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.switch.parentheses")),
new CodeStyleSettingPresentation("SPACE_BEFORE_TRY_PARENTHESES", ApplicationBundle.message("checkbox.spaces.try.parentheses")),
new CodeStyleSettingPresentation("SPACE_BEFORE_CATCH_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.catch.parentheses")),
new CodeStyleSettingPresentation("SPACE_BEFORE_SYNCHRONIZED_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.synchronized.parentheses")),
new CodeStyleSettingPresentation("SPACE_BEFORE_ANOTATION_PARAMETER_LIST",
ApplicationBundle.message("checkbox.spaces.annotation.parameters"))
));
result.put(new SettingsGroup(SPACES_AROUND_OPERATORS), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("SPACE_AROUND_ASSIGNMENT_OPERATORS",
ApplicationBundle.message("checkbox.spaces.assignment.operators")),
new CodeStyleSettingPresentation("SPACE_AROUND_LOGICAL_OPERATORS",
ApplicationBundle.message("checkbox.spaces.logical.operators")),
new CodeStyleSettingPresentation("SPACE_AROUND_EQUALITY_OPERATORS",
ApplicationBundle.message("checkbox.spaces.equality.operators")),
new CodeStyleSettingPresentation("SPACE_AROUND_RELATIONAL_OPERATORS",
ApplicationBundle.message("checkbox.spaces.relational.operators")),
new CodeStyleSettingPresentation("SPACE_AROUND_BITWISE_OPERATORS",
ApplicationBundle.message("checkbox.spaces.bitwise.operators")),
new CodeStyleSettingPresentation("SPACE_AROUND_ADDITIVE_OPERATORS",
ApplicationBundle.message("checkbox.spaces.additive.operators")),
new CodeStyleSettingPresentation("SPACE_AROUND_MULTIPLICATIVE_OPERATORS",
ApplicationBundle.message("checkbox.spaces.multiplicative.operators")),
new CodeStyleSettingPresentation("SPACE_AROUND_SHIFT_OPERATORS", ApplicationBundle.message("checkbox.spaces.shift.operators")),
new CodeStyleSettingPresentation("SPACE_AROUND_UNARY_OPERATOR",
ApplicationBundle.message("checkbox.spaces.around.unary.operator")),
new CodeStyleSettingPresentation("SPACE_AROUND_LAMBDA_ARROW", ApplicationBundle.message("checkbox.spaces.around.lambda.arrow")),
new CodeStyleSettingPresentation("SPACE_AROUND_METHOD_REF_DBL_COLON",
ApplicationBundle.message("checkbox.spaces.around.method.ref.dbl.colon.arrow"))
));
result.put(new SettingsGroup(SPACES_BEFORE_LEFT_BRACE), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("SPACE_BEFORE_CLASS_LBRACE", ApplicationBundle.message("checkbox.spaces.class.left.brace")),
new CodeStyleSettingPresentation("SPACE_BEFORE_METHOD_LBRACE", ApplicationBundle.message("checkbox.spaces.method.left.brace")),
new CodeStyleSettingPresentation("SPACE_BEFORE_IF_LBRACE", ApplicationBundle.message("checkbox.spaces.if.left.brace")),
new CodeStyleSettingPresentation("SPACE_BEFORE_ELSE_LBRACE", ApplicationBundle.message("checkbox.spaces.else.left.brace")),
new CodeStyleSettingPresentation("SPACE_BEFORE_FOR_LBRACE", ApplicationBundle.message("checkbox.spaces.for.left.brace")),
new CodeStyleSettingPresentation("SPACE_BEFORE_WHILE_LBRACE", ApplicationBundle.message("checkbox.spaces.while.left.brace")),
new CodeStyleSettingPresentation("SPACE_BEFORE_DO_LBRACE", ApplicationBundle.message("checkbox.spaces.do.left.brace")),
new CodeStyleSettingPresentation("SPACE_BEFORE_SWITCH_LBRACE", ApplicationBundle.message("checkbox.spaces.switch.left.brace")),
new CodeStyleSettingPresentation("SPACE_BEFORE_TRY_LBRACE", ApplicationBundle.message("checkbox.spaces.try.left.brace")),
new CodeStyleSettingPresentation("SPACE_BEFORE_CATCH_LBRACE", ApplicationBundle.message("checkbox.spaces.catch.left.brace")),
new CodeStyleSettingPresentation("SPACE_BEFORE_FINALLY_LBRACE",
ApplicationBundle.message("checkbox.spaces.finally.left.brace")),
new CodeStyleSettingPresentation("SPACE_BEFORE_SYNCHRONIZED_LBRACE",
ApplicationBundle.message("checkbox.spaces.synchronized.left.brace")),
new CodeStyleSettingPresentation("SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE",
ApplicationBundle.message("checkbox.spaces.array.initializer.left.brace")),
new CodeStyleSettingPresentation("SPACE_BEFORE_ANNOTATION_ARRAY_INITIALIZER_LBRACE",
ApplicationBundle.message("checkbox.spaces.annotation.array.initializer.left.brace"))
));
result.put(new SettingsGroup(SPACES_BEFORE_KEYWORD), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("SPACE_BEFORE_ELSE_KEYWORD", ApplicationBundle.message("checkbox.spaces.else.keyword")),
new CodeStyleSettingPresentation("SPACE_BEFORE_WHILE_KEYWORD", ApplicationBundle.message("checkbox.spaces.while.keyword")),
new CodeStyleSettingPresentation("SPACE_BEFORE_CATCH_KEYWORD", ApplicationBundle.message("checkbox.spaces.catch.keyword")),
new CodeStyleSettingPresentation("SPACE_BEFORE_FINALLY_KEYWORD", ApplicationBundle.message("checkbox.spaces.finally.keyword"))
));
result.put(new SettingsGroup(SPACES_WITHIN), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("SPACE_WITHIN_BRACES", ApplicationBundle.message("checkbox.spaces.within.braces")),
new CodeStyleSettingPresentation("SPACE_WITHIN_BRACKETS", ApplicationBundle.message("checkbox.spaces.within.brackets")),
new CodeStyleSettingPresentation("SPACE_WITHIN_ARRAY_INITIALIZER_BRACES",
ApplicationBundle.message("checkbox.spaces.within.array.initializer.braces")),
new CodeStyleSettingPresentation("SPACE_WITHIN_EMPTY_ARRAY_INITIALIZER_BRACES",
ApplicationBundle.message("checkbox.spaces.within.empty.array.initializer.braces")),
new CodeStyleSettingPresentation("SPACE_WITHIN_PARENTHESES", ApplicationBundle.message("checkbox.spaces.within.parentheses")),
new CodeStyleSettingPresentation("SPACE_WITHIN_METHOD_CALL_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.checkbox.spaces.method.call.parentheses")),
new CodeStyleSettingPresentation("SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.checkbox.spaces.empty.method.call.parentheses")),
new CodeStyleSettingPresentation("SPACE_WITHIN_METHOD_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.checkbox.spaces.method.declaration.parentheses")),
new CodeStyleSettingPresentation("SPACE_WITHIN_EMPTY_METHOD_PARENTHESES", ApplicationBundle
.message("checkbox.spaces.checkbox.spaces.empty.method.declaration.parentheses")),
new CodeStyleSettingPresentation("SPACE_WITHIN_IF_PARENTHESES", ApplicationBundle.message("checkbox.spaces.if.parentheses")),
new CodeStyleSettingPresentation("SPACE_WITHIN_FOR_PARENTHESES", ApplicationBundle.message("checkbox.spaces.for.parentheses")),
new CodeStyleSettingPresentation("SPACE_WITHIN_WHILE_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.while.parentheses")),
new CodeStyleSettingPresentation("SPACE_WITHIN_SWITCH_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.switch.parentheses")),
new CodeStyleSettingPresentation("SPACE_WITHIN_TRY_PARENTHESES", ApplicationBundle.message("checkbox.spaces.try.parentheses")),
new CodeStyleSettingPresentation("SPACE_WITHIN_CATCH_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.catch.parentheses")),
new CodeStyleSettingPresentation("SPACE_WITHIN_SYNCHRONIZED_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.synchronized.parentheses")),
new CodeStyleSettingPresentation("SPACE_WITHIN_CAST_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.type.cast.parentheses")),
new CodeStyleSettingPresentation("SPACE_WITHIN_ANNOTATION_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.annotation.parentheses"))
));
result.put(new SettingsGroup(SPACES_IN_TERNARY_OPERATOR), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("SPACE_BEFORE_QUEST", ApplicationBundle.message("checkbox.spaces.before.question")),
new CodeStyleSettingPresentation("SPACE_AFTER_QUEST", ApplicationBundle.message("checkbox.spaces.after.question")),
new CodeStyleSettingPresentation("SPACE_BEFORE_COLON", ApplicationBundle.message("checkbox.spaces.before.colon")),
new CodeStyleSettingPresentation("SPACE_AFTER_COLON", ApplicationBundle.message("checkbox.spaces.after.colon"))
));
result.put(new SettingsGroup(SPACES_WITHIN_TYPE_ARGUMENTS), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS",
ApplicationBundle.message("checkbox.spaces.after.comma"))
));
result.put(new SettingsGroup(SPACES_IN_TYPE_ARGUMENTS), ContainerUtil.<CodeStyleSettingPresentation>immutableList());
result.put(new SettingsGroup(SPACES_IN_TYPE_PARAMETERS), ContainerUtil.<CodeStyleSettingPresentation>immutableList());
result.put(new SettingsGroup(SPACES_OTHER), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("SPACE_BEFORE_COMMA", ApplicationBundle.message("checkbox.spaces.before.comma")),
new CodeStyleSettingPresentation("SPACE_AFTER_COMMA", ApplicationBundle.message("checkbox.spaces.after.comma")),
new CodeStyleSettingPresentation("SPACE_BEFORE_SEMICOLON", ApplicationBundle.message("checkbox.spaces.before.semicolon")),
new CodeStyleSettingPresentation("SPACE_AFTER_SEMICOLON", ApplicationBundle.message("checkbox.spaces.after.semicolon")),
new CodeStyleSettingPresentation("SPACE_AFTER_TYPE_CAST", ApplicationBundle.message("checkbox.spaces.after.type.cast"))
));
SPACING_STANDARD_SETTINGS = Collections.unmodifiableMap(result);
//-----------------------------------WRAPPING_AND_BRACES_SETTINGS-----------------------------------------------------
result = ContainerUtil.newLinkedHashMap();
result.put(new SettingsGroup(null), ContainerUtil.<CodeStyleSettingPresentation>immutableList(
new CodeStyleBoundedIntegerSettingPresentation("RIGHT_MARGIN", ApplicationBundle.message("editbox.right.margin.columns"), 0, 999,
-1,
ApplicationBundle.message("settings.code.style.default.general"))
));
putGroupTop(result, "WRAP_ON_TYPING", ApplicationBundle.message("wrapping.wrap.on.typing"), WRAP_ON_TYPING_VALUES,
WRAP_ON_TYPING_OPTIONS);
result.put(new SettingsGroup(WRAPPING_KEEP), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("KEEP_LINE_BREAKS", ApplicationBundle.message("wrapping.keep.line.breaks")),
new CodeStyleSettingPresentation("KEEP_FIRST_COLUMN_COMMENT",
ApplicationBundle.message("wrapping.keep.comment.at.first.column")),
new CodeStyleSettingPresentation("KEEP_CONTROL_STATEMENT_IN_ONE_LINE",
ApplicationBundle.message("checkbox.keep.when.reformatting.control.statement.in.one.line")),
new CodeStyleSettingPresentation("KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE",
ApplicationBundle.message("wrapping.keep.multiple.expressions.in.one.line")),
new CodeStyleSettingPresentation("KEEP_SIMPLE_BLOCKS_IN_ONE_LINE",
ApplicationBundle.message("wrapping.keep.simple.blocks.in.one.line")),
new CodeStyleSettingPresentation("KEEP_SIMPLE_METHODS_IN_ONE_LINE",
ApplicationBundle.message("wrapping.keep.simple.methods.in.one.line")),
new CodeStyleSettingPresentation("KEEP_SIMPLE_CLASSES_IN_ONE_LINE",
ApplicationBundle.message("wrapping.keep.simple.classes.in.one.line"))
));
result.put(new SettingsGroup(null), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("WRAP_LONG_LINES", ApplicationBundle.message("wrapping.long.lines"))
));
result.put(new SettingsGroup(WRAPPING_COMMENTS), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("WRAP_COMMENTS", ApplicationBundle.message("wrapping.comments.wrap.at.right.margin"))
));
result.put(new SettingsGroup(WRAPPING_BRACES), ContainerUtil.<CodeStyleSettingPresentation>immutableList(
new CodeStyleSelectSettingPresentation("CLASS_BRACE_STYLE",
ApplicationBundle.message("wrapping.brace.placement.class.declaration"),
BRACE_PLACEMENT_VALUES, BRACE_PLACEMENT_OPTIONS),
new CodeStyleSelectSettingPresentation("METHOD_BRACE_STYLE",
ApplicationBundle.message("wrapping.brace.placement.method.declaration"),
BRACE_PLACEMENT_VALUES, BRACE_PLACEMENT_OPTIONS),
new CodeStyleSelectSettingPresentation("BRACE_STYLE", ApplicationBundle.message("wrapping.brace.placement.other"),
BRACE_PLACEMENT_VALUES, BRACE_PLACEMENT_OPTIONS)
));
putGroupTop(result, "EXTENDS_LIST_WRAP", WRAPPING_EXTENDS_LIST, WRAP_VALUES, WRAP_OPTIONS);
result.put(new SettingsGroup(WRAPPING_EXTENDS_LIST), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("ALIGN_MULTILINE_EXTENDS_LIST", ApplicationBundle.message("wrapping.align.when.multiline"))
));
putGroupTop(result, "EXTENDS_KEYWORD_WRAP", WRAPPING_EXTENDS_KEYWORD, WRAP_VALUES_FOR_SINGLETON, WRAP_OPTIONS_FOR_SINGLETON);
putGroupTop(result, "THROWS_LIST_WRAP", WRAPPING_THROWS_LIST, WRAP_VALUES, WRAP_OPTIONS);
result.put(new SettingsGroup(WRAPPING_THROWS_LIST), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("ALIGN_MULTILINE_THROWS_LIST", ApplicationBundle.message("wrapping.align.when.multiline")),
new CodeStyleSettingPresentation("ALIGN_THROWS_KEYWORD", ApplicationBundle.message("wrapping.align.throws.keyword"))
));
putGroupTop(result, "THROWS_KEYWORD_WRAP", WRAPPING_THROWS_KEYWORD, WRAP_VALUES_FOR_SINGLETON, WRAP_OPTIONS_FOR_SINGLETON);
putGroupTop(result, "METHOD_PARAMETERS_WRAP", WRAPPING_METHOD_PARAMETERS, WRAP_VALUES, WRAP_OPTIONS);
result.put(new SettingsGroup(WRAPPING_METHOD_PARAMETERS), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("ALIGN_MULTILINE_PARAMETERS", ApplicationBundle.message("wrapping.align.when.multiline")),
new CodeStyleSettingPresentation("METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE",
ApplicationBundle.message("wrapping.new.line.after.lpar")),
new CodeStyleSettingPresentation("METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE",
ApplicationBundle.message("wrapping.rpar.on.new.line"))
));
putGroupTop(result, "CALL_PARAMETERS_WRAP", WRAPPING_METHOD_ARGUMENTS_WRAPPING, WRAP_VALUES, WRAP_OPTIONS);
result.put(new SettingsGroup(WRAPPING_METHOD_ARGUMENTS_WRAPPING), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("ALIGN_MULTILINE_PARAMETERS_IN_CALLS",
ApplicationBundle.message("wrapping.align.when.multiline")),
new CodeStyleSettingPresentation("PREFER_PARAMETERS_WRAP",
ApplicationBundle.message("wrapping.take.priority.over.call.chain.wrapping")),
new CodeStyleSettingPresentation("CALL_PARAMETERS_LPAREN_ON_NEXT_LINE",
ApplicationBundle.message("wrapping.new.line.after.lpar")),
new CodeStyleSettingPresentation("CALL_PARAMETERS_RPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.rpar.on.new.line"))
));
result.put(new SettingsGroup(WRAPPING_METHOD_PARENTHESES), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("ALIGN_MULTILINE_METHOD_BRACKETS", ApplicationBundle.message("wrapping.align.when.multiline"))
));
putGroupTop(result, "METHOD_CALL_CHAIN_WRAP", WRAPPING_CALL_CHAIN, WRAP_VALUES, WRAP_OPTIONS);
result.put(new SettingsGroup(WRAPPING_CALL_CHAIN), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("WRAP_FIRST_METHOD_IN_CALL_CHAIN",
ApplicationBundle.message("wrapping.chained.method.call.first.on.new.line")),
new CodeStyleSettingPresentation("ALIGN_MULTILINE_CHAINED_METHODS", ApplicationBundle.message("wrapping.align.when.multiline"))
));
result.put(new SettingsGroup(WRAPPING_IF_STATEMENT), ContainerUtil.immutableList(
new CodeStyleSelectSettingPresentation("IF_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), BRACE_VALUES,
BRACE_OPTIONS),
new CodeStyleSettingPresentation("ELSE_ON_NEW_LINE", ApplicationBundle.message("wrapping.else.on.new.line")),
new CodeStyleSettingPresentation("SPECIAL_ELSE_IF_TREATMENT",
ApplicationBundle.message("wrapping.special.else.if.braces.treatment"))
));
putGroupTop(result, "FOR_STATEMENT_WRAP", WRAPPING_FOR_STATEMENT, WRAP_VALUES, WRAP_OPTIONS);
result.put(new SettingsGroup(WRAPPING_FOR_STATEMENT), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("ALIGN_MULTILINE_FOR", ApplicationBundle.message("wrapping.align.when.multiline")),
new CodeStyleSettingPresentation("FOR_STATEMENT_LPAREN_ON_NEXT_LINE",
ApplicationBundle.message("wrapping.new.line.after.lpar")),
new CodeStyleSettingPresentation("FOR_STATEMENT_RPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.rpar.on.new.line")),
new CodeStyleSelectSettingPresentation("FOR_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), BRACE_VALUES,
BRACE_OPTIONS)
));
result.put(new SettingsGroup(WRAPPING_WHILE_STATEMENT), ContainerUtil.<CodeStyleSettingPresentation>immutableList(
new CodeStyleSelectSettingPresentation("WHILE_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), BRACE_VALUES,
BRACE_OPTIONS)
));
result.put(new SettingsGroup(WRAPPING_DOWHILE_STATEMENT), ContainerUtil.immutableList(
new CodeStyleSelectSettingPresentation("DOWHILE_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), BRACE_VALUES,
BRACE_OPTIONS),
new CodeStyleSettingPresentation("WHILE_ON_NEW_LINE", ApplicationBundle.message("wrapping.while.on.new.line"))
));
result.put(new SettingsGroup(WRAPPING_SWITCH_STATEMENT), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("INDENT_CASE_FROM_SWITCH", ApplicationBundle.message("wrapping.indent.case.from.switch")),
new CodeStyleSettingPresentation("INDENT_BREAK_FROM_CASE", ApplicationBundle.message("wrapping.indent.break.from.case"))
));
putGroupTop(result, "RESOURCE_LIST_WRAP", WRAPPING_TRY_RESOURCE_LIST, WRAP_VALUES, WRAP_OPTIONS);
result.put(new SettingsGroup(WRAPPING_TRY_RESOURCE_LIST), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("ALIGN_MULTILINE_RESOURCES", ApplicationBundle.message("wrapping.align.when.multiline")),
new CodeStyleSettingPresentation("RESOURCE_LIST_LPAREN_ON_NEXT_LINE",
ApplicationBundle.message("wrapping.new.line.after.lpar")),
new CodeStyleSettingPresentation("RESOURCE_LIST_RPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.rpar.on.new.line"))
));
result.put(new SettingsGroup(WRAPPING_TRY_STATEMENT), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("CATCH_ON_NEW_LINE", ApplicationBundle.message("wrapping.catch.on.new.line")),
new CodeStyleSettingPresentation("FINALLY_ON_NEW_LINE", ApplicationBundle.message("wrapping.finally.on.new.line"))
));
putGroupTop(result, "BINARY_OPERATION_WRAP", WRAPPING_BINARY_OPERATION, WRAP_VALUES, WRAP_OPTIONS);
result.put(new SettingsGroup(WRAPPING_BINARY_OPERATION), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("ALIGN_MULTILINE_BINARY_OPERATION",
ApplicationBundle.message("wrapping.align.when.multiline")),
new CodeStyleSettingPresentation("BINARY_OPERATION_SIGN_ON_NEXT_LINE",
ApplicationBundle.message("wrapping.operation.sign.on.next.line")),
new CodeStyleSettingPresentation("ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION",
ApplicationBundle.message("wrapping.align.parenthesised.when.multiline")),
new CodeStyleSettingPresentation("PARENTHESES_EXPRESSION_LPAREN_WRAP",
ApplicationBundle.message("wrapping.new.line.after.lpar")),
new CodeStyleSettingPresentation("PARENTHESES_EXPRESSION_RPAREN_WRAP", ApplicationBundle.message("wrapping.rpar.on.new.line"))
));
putGroupTop(result, "ASSIGNMENT_WRAP", WRAPPING_ASSIGNMENT, WRAP_VALUES, WRAP_OPTIONS);
result.put(new SettingsGroup(WRAPPING_ASSIGNMENT), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("ALIGN_MULTILINE_ASSIGNMENT", ApplicationBundle.message("wrapping.align.when.multiline")),
new CodeStyleSettingPresentation("PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE",
ApplicationBundle.message("wrapping.assignment.sign.on.next.line"))
));
result.put(new SettingsGroup(WRAPPING_FIELDS_VARIABLES_GROUPS), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("ALIGN_GROUP_FIELD_DECLARATIONS",
ApplicationBundle.message("wrapping.align.fields.in.columns")),
new CodeStyleSettingPresentation("ALIGN_CONSECUTIVE_VARIABLE_DECLARATIONS",
ApplicationBundle.message("wrapping.align.variables.in.columns"))
));
putGroupTop(result, "TERNARY_OPERATION_WRAP", WRAPPING_TERNARY_OPERATION, WRAP_VALUES, WRAP_OPTIONS);
result.put(new SettingsGroup(WRAPPING_TERNARY_OPERATION), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("ALIGN_MULTILINE_TERNARY_OPERATION",
ApplicationBundle.message("wrapping.align.when.multiline")),
new CodeStyleSettingPresentation("TERNARY_OPERATION_SIGNS_ON_NEXT_LINE",
ApplicationBundle.message("wrapping.quest.and.colon.signs.on.next.line"))
));
putGroupTop(result, "ARRAY_INITIALIZER_WRAP", WRAPPING_ARRAY_INITIALIZER, WRAP_VALUES, WRAP_OPTIONS);
result.put(new SettingsGroup(WRAPPING_ARRAY_INITIALIZER), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION",
ApplicationBundle.message("wrapping.align.when.multiline")),
new CodeStyleSettingPresentation("ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE",
ApplicationBundle.message("wrapping.new.line.after.lbrace")),
new CodeStyleSettingPresentation("ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE",
ApplicationBundle.message("wrapping.rbrace.on.new.line"))
));
result.put(new SettingsGroup(WRAPPING_MODIFIER_LIST), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("MODIFIER_LIST_WRAP", ApplicationBundle.message("wrapping.after.modifier.list"))
));
putGroupTop(result, "ASSERT_STATEMENT_WRAP", WRAPPING_ASSERT_STATEMENT, WRAP_VALUES, WRAP_OPTIONS);
result.put(new SettingsGroup(WRAPPING_ASSERT_STATEMENT), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("ASSERT_STATEMENT_COLON_ON_NEXT_LINE",
ApplicationBundle.message("wrapping.colon.signs.on.next.line"))
));
putGroupTop(result, "ENUM_CONSTANTS_WRAP", ApplicationBundle.message("wrapping.enum.constants"), WRAP_VALUES, WRAP_OPTIONS);
putGroupTop(result, "CLASS_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.classes.annotation"), WRAP_VALUES, WRAP_OPTIONS);
putGroupTop(result, "METHOD_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.methods.annotation"), WRAP_VALUES, WRAP_OPTIONS);
putGroupTop(result, "FIELD_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.fields.annotation"), WRAP_VALUES, WRAP_OPTIONS);
putGroupTop(result, "PARAMETER_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.parameters.annotation"), WRAP_VALUES, WRAP_OPTIONS);
putGroupTop(result, "VARIABLE_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.local.variables.annotation"), WRAP_VALUES,
WRAP_OPTIONS);
WRAPPING_AND_BRACES_STANDARD_SETTINGS = Collections.unmodifiableMap(result);
//-----------------------------------INDENT_SETTINGS-----------------------------------------------------
result = ContainerUtil.newLinkedHashMap();
result.put(new SettingsGroup(null), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("INDENT_SIZE", ApplicationBundle.message("editbox.indent.indent"))
));
result.put(new SettingsGroup(null), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("CONTINUATION_INDENT_SIZE", ApplicationBundle.message("editbox.indent.continuation.indent"))
));
result.put(new SettingsGroup(null), ContainerUtil.immutableList(
new CodeStyleSettingPresentation("TAB_SIZE", ApplicationBundle.message("editbox.indent.tab.size"))
));
INDENT_STANDARD_SETTINGS = Collections.unmodifiableMap(result);
}
/**
* Returns an immutable map containing all standard settings in a mapping of type (group -> settings contained in the group).
* Notice that lists containing settings for a specific group are also immutable. Use copies to make modifications.
* @param settingsType type to get standard settings for
* @return mapping setting groups to contained setting presentations
*/
@NotNull
public static Map<SettingsGroup, List<CodeStyleSettingPresentation>> getStandardSettings(LanguageCodeStyleSettingsProvider.SettingsType settingsType) {
switch (settingsType) {
case BLANK_LINES_SETTINGS:
return BLANK_LINES_STANDARD_SETTINGS;
case SPACING_SETTINGS:
return SPACING_STANDARD_SETTINGS;
case WRAPPING_AND_BRACES_SETTINGS:
return WRAPPING_AND_BRACES_STANDARD_SETTINGS;
case INDENT_SETTINGS:
return INDENT_STANDARD_SETTINGS;
case LANGUAGE_SPECIFIC:
}
return ContainerUtil.newLinkedHashMap();
}
}
@@ -18,16 +18,15 @@ package com.intellij.application.options.codeStyle;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Trinity;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
import com.intellij.psi.codeStyle.*;
import com.intellij.psi.codeStyle.presentation.CodeStyleSettingPresentation;
import com.intellij.ui.OptionGroup;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.ui.UIUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -62,8 +61,11 @@ public class CodeStyleBlankLinesPanel extends CustomizableLanguageCodeStylePanel
JPanel optionsPanel = new JPanel(new GridBagLayout());
OptionGroup keepBlankLinesOptionsGroup = createKeepBlankLinesOptionsGroup();
OptionGroup blankLinesOptionsGroup = createBlankLinesOptionsGroup();
Map<CodeStyleSettingPresentation.SettingsGroup, List<CodeStyleSettingPresentation>> settings = CodeStyleSettingPresentation
.getStandardSettings(getSettingsType());
OptionGroup keepBlankLinesOptionsGroup = createOptionsGroup(BLANK_LINES_KEEP, settings.get(new CodeStyleSettingPresentation.SettingsGroup(BLANK_LINES_KEEP)));
OptionGroup blankLinesOptionsGroup = createOptionsGroup(BLANK_LINES, settings.get(new CodeStyleSettingPresentation.SettingsGroup(BLANK_LINES)));
if (keepBlankLinesOptionsGroup != null) {
keepBlankLinesOptionsGroup.setAnchor(keepBlankLinesOptionsGroup.findAnchor());
optionsPanel.add(keepBlankLinesOptionsGroup.createPanel(),
@@ -109,37 +111,13 @@ public class CodeStyleBlankLinesPanel extends CustomizableLanguageCodeStylePanel
}
@Nullable
private OptionGroup createBlankLinesOptionsGroup() {
OptionGroup optionGroup = new OptionGroup(BLANK_LINES);
private OptionGroup createOptionsGroup(@NotNull String groupName, @NotNull List<CodeStyleSettingPresentation> settings) {
OptionGroup optionGroup = new OptionGroup(groupName);
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.before.package.statement"), "BLANK_LINES_BEFORE_PACKAGE");
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.after.package.statement"), "BLANK_LINES_AFTER_PACKAGE");
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.before.imports"), "BLANK_LINES_BEFORE_IMPORTS");
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.after.imports"), "BLANK_LINES_AFTER_IMPORTS");
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.around.class"), "BLANK_LINES_AROUND_CLASS");
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.after.class.header"), "BLANK_LINES_AFTER_CLASS_HEADER");
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.after.anonymous.class.header"),
"BLANK_LINES_AFTER_ANONYMOUS_CLASS_HEADER");
createOption(optionGroup, "Around field in interface:", "BLANK_LINES_AROUND_FIELD_IN_INTERFACE");
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.around.field"), "BLANK_LINES_AROUND_FIELD");
createOption(optionGroup, "Around method in interface:", "BLANK_LINES_AROUND_METHOD_IN_INTERFACE");
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.around.method"), "BLANK_LINES_AROUND_METHOD");
createOption(optionGroup, ApplicationBundle.message("editbox.blanklines.before.method.body"), "BLANK_LINES_BEFORE_METHOD_BODY");
initCustomOptions(optionGroup, BLANK_LINES);
if (optionGroup.getComponents().length == 0) return null;
return optionGroup;
}
@Nullable
private OptionGroup createKeepBlankLinesOptionsGroup() {
OptionGroup optionGroup = new OptionGroup(BLANK_LINES_KEEP);
createOption(optionGroup, ApplicationBundle.message("editbox.keep.blanklines.in.declarations"), "KEEP_BLANK_LINES_IN_DECLARATIONS");
createOption(optionGroup, ApplicationBundle.message("editbox.keep.blanklines.in.code"), "KEEP_BLANK_LINES_IN_CODE");
createOption(optionGroup, ApplicationBundle.message("editbox.keep.blanklines.before.rbrace"), "KEEP_BLANK_LINES_BEFORE_RBRACE");
initCustomOptions(optionGroup, BLANK_LINES_KEEP);
for (CodeStyleSettingPresentation setting: settings) {
createOption(optionGroup, setting.getUiName(), setting.getFieldName());
}
initCustomOptions(optionGroup, groupName);
if (optionGroup.getComponents().length == 0) return null;
@@ -16,9 +16,13 @@
package com.intellij.application.options.codeStyle;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.psi.codeStyle.presentation.CodeStyleSettingPresentation;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
import java.util.List;
import java.util.Map;
public class CodeStyleSpacesPanel extends OptionTreeWithPreviewPanel {
public CodeStyleSpacesPanel(CodeStyleSettings settings) {
super(settings);
@@ -32,100 +36,16 @@ public class CodeStyleSpacesPanel extends OptionTreeWithPreviewPanel {
@Override
protected void initTables() {
initBooleanField("SPACE_BEFORE_METHOD_PARENTHESES", ApplicationBundle.message("checkbox.spaces.method.declaration.parentheses"), SPACES_BEFORE_PARENTHESES);
initBooleanField("SPACE_BEFORE_METHOD_CALL_PARENTHESES", ApplicationBundle.message("checkbox.spaces.method.call.parentheses"), SPACES_BEFORE_PARENTHESES);
initBooleanField("SPACE_BEFORE_IF_PARENTHESES", ApplicationBundle.message("checkbox.spaces.if.parentheses"), SPACES_BEFORE_PARENTHESES);
initBooleanField("SPACE_BEFORE_FOR_PARENTHESES", ApplicationBundle.message("checkbox.spaces.for.parentheses"), SPACES_BEFORE_PARENTHESES);
initBooleanField("SPACE_BEFORE_WHILE_PARENTHESES", ApplicationBundle.message("checkbox.spaces.while.parentheses"), SPACES_BEFORE_PARENTHESES);
initBooleanField("SPACE_BEFORE_SWITCH_PARENTHESES", ApplicationBundle.message("checkbox.spaces.switch.parentheses"), SPACES_BEFORE_PARENTHESES);
initBooleanField("SPACE_BEFORE_TRY_PARENTHESES", ApplicationBundle.message("checkbox.spaces.try.parentheses"), SPACES_BEFORE_PARENTHESES);
initBooleanField("SPACE_BEFORE_CATCH_PARENTHESES", ApplicationBundle.message("checkbox.spaces.catch.parentheses"), SPACES_BEFORE_PARENTHESES);
initBooleanField("SPACE_BEFORE_SYNCHRONIZED_PARENTHESES", ApplicationBundle.message("checkbox.spaces.synchronized.parentheses"), SPACES_BEFORE_PARENTHESES);
initBooleanField("SPACE_BEFORE_ANOTATION_PARAMETER_LIST", ApplicationBundle.message("checkbox.spaces.annotation.parameters"), SPACES_BEFORE_PARENTHESES);
initCustomOptions(SPACES_BEFORE_PARENTHESES);
Map<CodeStyleSettingPresentation.SettingsGroup, List<CodeStyleSettingPresentation>> settingsMap = CodeStyleSettingPresentation
.getStandardSettings(getSettingsType());
initBooleanField("SPACE_AROUND_ASSIGNMENT_OPERATORS", ApplicationBundle.message("checkbox.spaces.assignment.operators"), SPACES_AROUND_OPERATORS);
initBooleanField("SPACE_AROUND_LOGICAL_OPERATORS", ApplicationBundle.message("checkbox.spaces.logical.operators"), SPACES_AROUND_OPERATORS);
initBooleanField("SPACE_AROUND_EQUALITY_OPERATORS", ApplicationBundle.message("checkbox.spaces.equality.operators"), SPACES_AROUND_OPERATORS);
initBooleanField("SPACE_AROUND_RELATIONAL_OPERATORS", ApplicationBundle.message("checkbox.spaces.relational.operators"), SPACES_AROUND_OPERATORS);
initBooleanField("SPACE_AROUND_BITWISE_OPERATORS", ApplicationBundle.message("checkbox.spaces.bitwise.operators"), SPACES_AROUND_OPERATORS);
initBooleanField("SPACE_AROUND_ADDITIVE_OPERATORS", ApplicationBundle.message("checkbox.spaces.additive.operators"), SPACES_AROUND_OPERATORS);
initBooleanField("SPACE_AROUND_MULTIPLICATIVE_OPERATORS", ApplicationBundle.message("checkbox.spaces.multiplicative.operators"), SPACES_AROUND_OPERATORS);
initBooleanField("SPACE_AROUND_SHIFT_OPERATORS", ApplicationBundle.message("checkbox.spaces.shift.operators"), SPACES_AROUND_OPERATORS);
initBooleanField("SPACE_AROUND_UNARY_OPERATOR", ApplicationBundle.message("checkbox.spaces.around.unary.operator"), SPACES_AROUND_OPERATORS);
initBooleanField("SPACE_AROUND_LAMBDA_ARROW", ApplicationBundle.message("checkbox.spaces.around.lambda.arrow"), SPACES_AROUND_OPERATORS);
initBooleanField("SPACE_AROUND_METHOD_REF_DBL_COLON", ApplicationBundle.message("checkbox.spaces.around.method.ref.dbl.colon.arrow"), SPACES_AROUND_OPERATORS);
initCustomOptions(SPACES_AROUND_OPERATORS);
initBooleanField("SPACE_BEFORE_CLASS_LBRACE", ApplicationBundle.message("checkbox.spaces.class.left.brace"), SPACES_BEFORE_LEFT_BRACE);
initBooleanField("SPACE_BEFORE_METHOD_LBRACE", ApplicationBundle.message("checkbox.spaces.method.left.brace"), SPACES_BEFORE_LEFT_BRACE);
initBooleanField("SPACE_BEFORE_IF_LBRACE", ApplicationBundle.message("checkbox.spaces.if.left.brace"), SPACES_BEFORE_LEFT_BRACE);
initBooleanField("SPACE_BEFORE_ELSE_LBRACE", ApplicationBundle.message("checkbox.spaces.else.left.brace"), SPACES_BEFORE_LEFT_BRACE);
initBooleanField("SPACE_BEFORE_FOR_LBRACE", ApplicationBundle.message("checkbox.spaces.for.left.brace"), SPACES_BEFORE_LEFT_BRACE);
initBooleanField("SPACE_BEFORE_WHILE_LBRACE", ApplicationBundle.message("checkbox.spaces.while.left.brace"), SPACES_BEFORE_LEFT_BRACE);
initBooleanField("SPACE_BEFORE_DO_LBRACE", ApplicationBundle.message("checkbox.spaces.do.left.brace"), SPACES_BEFORE_LEFT_BRACE);
initBooleanField("SPACE_BEFORE_SWITCH_LBRACE", ApplicationBundle.message("checkbox.spaces.switch.left.brace"), SPACES_BEFORE_LEFT_BRACE);
initBooleanField("SPACE_BEFORE_TRY_LBRACE", ApplicationBundle.message("checkbox.spaces.try.left.brace"), SPACES_BEFORE_LEFT_BRACE);
initBooleanField("SPACE_BEFORE_CATCH_LBRACE", ApplicationBundle.message("checkbox.spaces.catch.left.brace"), SPACES_BEFORE_LEFT_BRACE);
initBooleanField("SPACE_BEFORE_FINALLY_LBRACE", ApplicationBundle.message("checkbox.spaces.finally.left.brace"), SPACES_BEFORE_LEFT_BRACE);
initBooleanField("SPACE_BEFORE_SYNCHRONIZED_LBRACE", ApplicationBundle.message("checkbox.spaces.synchronized.left.brace"), SPACES_BEFORE_LEFT_BRACE);
initBooleanField("SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE", ApplicationBundle.message("checkbox.spaces.array.initializer.left.brace"), SPACES_BEFORE_LEFT_BRACE);
initBooleanField("SPACE_BEFORE_ANNOTATION_ARRAY_INITIALIZER_LBRACE", ApplicationBundle.message("checkbox.spaces.annotation.array.initializer.left.brace"), SPACES_BEFORE_LEFT_BRACE);
initCustomOptions(SPACES_BEFORE_LEFT_BRACE);
initBooleanField("SPACE_BEFORE_ELSE_KEYWORD", ApplicationBundle.message("checkbox.spaces.else.keyword"), SPACES_BEFORE_KEYWORD);
initBooleanField("SPACE_BEFORE_WHILE_KEYWORD", ApplicationBundle.message("checkbox.spaces.while.keyword"), SPACES_BEFORE_KEYWORD);
initBooleanField("SPACE_BEFORE_CATCH_KEYWORD", ApplicationBundle.message("checkbox.spaces.catch.keyword"), SPACES_BEFORE_KEYWORD);
initBooleanField("SPACE_BEFORE_FINALLY_KEYWORD", ApplicationBundle.message("checkbox.spaces.finally.keyword"), SPACES_BEFORE_KEYWORD);
initCustomOptions(SPACES_BEFORE_KEYWORD);
initBooleanField("SPACE_WITHIN_BRACES", ApplicationBundle.message("checkbox.spaces.within.braces"), SPACES_WITHIN);
initBooleanField("SPACE_WITHIN_BRACKETS", ApplicationBundle.message("checkbox.spaces.within.brackets"), SPACES_WITHIN);
initBooleanField("SPACE_WITHIN_ARRAY_INITIALIZER_BRACES", ApplicationBundle.message("checkbox.spaces.within.array.initializer.braces"), SPACES_WITHIN);
initBooleanField("SPACE_WITHIN_EMPTY_ARRAY_INITIALIZER_BRACES", ApplicationBundle.message("checkbox.spaces.within.empty.array.initializer.braces"), SPACES_WITHIN);
initBooleanField("SPACE_WITHIN_PARENTHESES", ApplicationBundle.message("checkbox.spaces.within.parentheses"), SPACES_WITHIN);
initBooleanField("SPACE_WITHIN_METHOD_CALL_PARENTHESES", ApplicationBundle.message("checkbox.spaces.checkbox.spaces.method.call.parentheses"), SPACES_WITHIN);
initBooleanField(
"SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.checkbox.spaces.empty.method.call.parentheses"),
SPACES_WITHIN
);
initBooleanField("SPACE_WITHIN_METHOD_PARENTHESES", ApplicationBundle.message("checkbox.spaces.checkbox.spaces.method.declaration.parentheses"), SPACES_WITHIN);
initBooleanField(
"SPACE_WITHIN_EMPTY_METHOD_PARENTHESES",
ApplicationBundle.message("checkbox.spaces.checkbox.spaces.empty.method.declaration.parentheses"),
SPACES_WITHIN
);
initBooleanField("SPACE_WITHIN_IF_PARENTHESES", ApplicationBundle.message("checkbox.spaces.if.parentheses"), SPACES_WITHIN);
initBooleanField("SPACE_WITHIN_FOR_PARENTHESES", ApplicationBundle.message("checkbox.spaces.for.parentheses"), SPACES_WITHIN);
initBooleanField("SPACE_WITHIN_WHILE_PARENTHESES", ApplicationBundle.message("checkbox.spaces.while.parentheses"), SPACES_WITHIN);
initBooleanField("SPACE_WITHIN_SWITCH_PARENTHESES", ApplicationBundle.message("checkbox.spaces.switch.parentheses"), SPACES_WITHIN);
initBooleanField("SPACE_WITHIN_TRY_PARENTHESES", ApplicationBundle.message("checkbox.spaces.try.parentheses"), SPACES_WITHIN);
initBooleanField("SPACE_WITHIN_CATCH_PARENTHESES", ApplicationBundle.message("checkbox.spaces.catch.parentheses"), SPACES_WITHIN);
initBooleanField("SPACE_WITHIN_SYNCHRONIZED_PARENTHESES", ApplicationBundle.message("checkbox.spaces.synchronized.parentheses"), SPACES_WITHIN);
initBooleanField("SPACE_WITHIN_CAST_PARENTHESES", ApplicationBundle.message("checkbox.spaces.type.cast.parentheses"), SPACES_WITHIN);
initBooleanField("SPACE_WITHIN_ANNOTATION_PARENTHESES", ApplicationBundle.message("checkbox.spaces.annotation.parentheses"), SPACES_WITHIN);
initCustomOptions(SPACES_WITHIN);
initBooleanField("SPACE_BEFORE_QUEST", ApplicationBundle.message("checkbox.spaces.before.question"), SPACES_IN_TERNARY_OPERATOR);
initBooleanField("SPACE_AFTER_QUEST", ApplicationBundle.message("checkbox.spaces.after.question"), SPACES_IN_TERNARY_OPERATOR);
initBooleanField("SPACE_BEFORE_COLON", ApplicationBundle.message("checkbox.spaces.before.colon"), SPACES_IN_TERNARY_OPERATOR);
initBooleanField("SPACE_AFTER_COLON", ApplicationBundle.message("checkbox.spaces.after.colon"), SPACES_IN_TERNARY_OPERATOR);
initCustomOptions(SPACES_IN_TERNARY_OPERATOR);
initBooleanField("SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS", ApplicationBundle.message("checkbox.spaces.after.comma"), SPACES_WITHIN_TYPE_ARGUMENTS);
initCustomOptions(SPACES_WITHIN_TYPE_ARGUMENTS);
initCustomOptions(SPACES_IN_TYPE_ARGUMENTS);
initCustomOptions(SPACES_IN_TYPE_PARAMETERS);
initBooleanField("SPACE_BEFORE_COMMA", ApplicationBundle.message("checkbox.spaces.before.comma"), SPACES_OTHER);
initBooleanField("SPACE_AFTER_COMMA", ApplicationBundle.message("checkbox.spaces.after.comma"), SPACES_OTHER);
initBooleanField("SPACE_BEFORE_SEMICOLON", ApplicationBundle.message("checkbox.spaces.before.semicolon"), SPACES_OTHER);
initBooleanField("SPACE_AFTER_SEMICOLON", ApplicationBundle.message("checkbox.spaces.after.semicolon"), SPACES_OTHER);
initBooleanField("SPACE_AFTER_TYPE_CAST", ApplicationBundle.message("checkbox.spaces.after.type.cast"), SPACES_OTHER);
initCustomOptions(SPACES_OTHER);
for (Map.Entry<CodeStyleSettingPresentation.SettingsGroup, List<CodeStyleSettingPresentation>> entry: settingsMap.entrySet()) {
String groupName = entry.getKey().name;
for (CodeStyleSettingPresentation setting: entry.getValue()) {
initBooleanField(setting.getFieldName(), setting.getUiName(), groupName);
}
initCustomOptions(groupName);
}
}
@Override
@@ -16,9 +16,7 @@
package com.intellij.application.options.codeStyle;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
import com.intellij.psi.codeStyle.*;
import com.intellij.ui.SpeedSearchComparator;
import com.intellij.ui.TreeTableSpeedSearch;
import com.intellij.ui.components.JBCheckBox;
@@ -283,7 +281,7 @@ public abstract class OptionTableWithPreviewPanel extends CustomizableLanguageCo
return result == null ? defaultName : result;
}
private static void expandTree(final JTree tree) {
public static void expandTree(final JTree tree) {
int oldRowCount = 0;
do {
int rowCount = tree.getRowCount();
@@ -16,14 +16,17 @@
package com.intellij.application.options.codeStyle;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
import com.intellij.psi.codeStyle.*;
import com.intellij.psi.codeStyle.presentation.CodeStyleBoundedIntegerSettingPresentation;
import com.intellij.psi.codeStyle.presentation.CodeStyleSelectSettingPresentation;
import com.intellij.psi.codeStyle.presentation.CodeStyleSettingPresentation;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -60,110 +63,26 @@ public class WrappingAndBracesPanel extends OptionTableWithPreviewPanel {
@Override
protected void initTables() {
addOption("RIGHT_MARGIN", ApplicationBundle.message("editbox.right.margin.columns"), null, 0, 999, -1, ApplicationBundle.message("settings.code.style.default.general"));
addOption("WRAP_ON_TYPING", ApplicationBundle.message("wrapping.wrap.on.typing"), null, WRAP_ON_TYPING_OPTIONS, WRAP_ON_TYPING_VALUES);
addOption("KEEP_LINE_BREAKS", ApplicationBundle.message("wrapping.keep.line.breaks"), WRAPPING_KEEP);
addOption("KEEP_FIRST_COLUMN_COMMENT", ApplicationBundle.message("wrapping.keep.comment.at.first.column"), WRAPPING_KEEP);
addOption("KEEP_CONTROL_STATEMENT_IN_ONE_LINE", ApplicationBundle.message("checkbox.keep.when.reformatting.control.statement.in.one.line"), WRAPPING_KEEP);
addOption("KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE", ApplicationBundle.message("wrapping.keep.multiple.expressions.in.one.line"), WRAPPING_KEEP);
addOption("KEEP_SIMPLE_BLOCKS_IN_ONE_LINE", ApplicationBundle.message("wrapping.keep.simple.blocks.in.one.line"), WRAPPING_KEEP);
addOption("KEEP_SIMPLE_METHODS_IN_ONE_LINE", ApplicationBundle.message("wrapping.keep.simple.methods.in.one.line"), WRAPPING_KEEP);
addOption("KEEP_SIMPLE_CLASSES_IN_ONE_LINE", ApplicationBundle.message("wrapping.keep.simple.classes.in.one.line"), WRAPPING_KEEP);
addOption("WRAP_LONG_LINES", ApplicationBundle.message("wrapping.long.lines"), null);
addOption("WRAP_COMMENTS", ApplicationBundle.message("wrapping.comments.wrap.at.right.margin"), WRAPPING_COMMENTS);
addOption("CLASS_BRACE_STYLE", ApplicationBundle.message("wrapping.brace.placement.class.declaration"), WRAPPING_BRACES, BRACE_PLACEMENT_OPTIONS, BRACE_PLACEMENT_VALUES);
addOption("METHOD_BRACE_STYLE", ApplicationBundle.message("wrapping.brace.placement.method.declaration"), WRAPPING_BRACES, BRACE_PLACEMENT_OPTIONS, BRACE_PLACEMENT_VALUES);
addOption("BRACE_STYLE", ApplicationBundle.message("wrapping.brace.placement.other"), WRAPPING_BRACES, BRACE_PLACEMENT_OPTIONS, BRACE_PLACEMENT_VALUES);
addOption("EXTENDS_LIST_WRAP", WRAPPING_EXTENDS_LIST, WRAP_OPTIONS, WRAP_VALUES);
addOption("ALIGN_MULTILINE_EXTENDS_LIST", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_EXTENDS_LIST);
addOption("EXTENDS_KEYWORD_WRAP", WRAPPING_EXTENDS_KEYWORD, WRAP_OPTIONS_FOR_SINGLETON, WRAP_VALUES_FOR_SINGLETON);
addOption("THROWS_LIST_WRAP", WRAPPING_THROWS_LIST, WRAP_OPTIONS, WRAP_VALUES);
addOption("ALIGN_MULTILINE_THROWS_LIST", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_THROWS_LIST);
addOption("ALIGN_THROWS_KEYWORD", ApplicationBundle.message("wrapping.align.throws.keyword"), WRAPPING_THROWS_LIST);
addOption("THROWS_KEYWORD_WRAP", WRAPPING_THROWS_KEYWORD, WRAP_OPTIONS_FOR_SINGLETON, WRAP_VALUES_FOR_SINGLETON);
addOption("METHOD_PARAMETERS_WRAP", WRAPPING_METHOD_PARAMETERS, WRAP_OPTIONS, WRAP_VALUES);
addOption("ALIGN_MULTILINE_PARAMETERS", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_METHOD_PARAMETERS);
addOption("METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.new.line.after.lpar"), WRAPPING_METHOD_PARAMETERS);
addOption("METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.rpar.on.new.line"), WRAPPING_METHOD_PARAMETERS);
addOption("CALL_PARAMETERS_WRAP", WRAPPING_METHOD_ARGUMENTS_WRAPPING, WRAP_OPTIONS, WRAP_VALUES);
addOption("ALIGN_MULTILINE_PARAMETERS_IN_CALLS", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_METHOD_ARGUMENTS_WRAPPING);
addOption("PREFER_PARAMETERS_WRAP", ApplicationBundle.message("wrapping.take.priority.over.call.chain.wrapping"), WRAPPING_METHOD_ARGUMENTS_WRAPPING);
addOption("CALL_PARAMETERS_LPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.new.line.after.lpar"), WRAPPING_METHOD_ARGUMENTS_WRAPPING);
addOption("CALL_PARAMETERS_RPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.rpar.on.new.line"), WRAPPING_METHOD_ARGUMENTS_WRAPPING);
addOption("ALIGN_MULTILINE_METHOD_BRACKETS", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_METHOD_PARENTHESES);
addOption("METHOD_CALL_CHAIN_WRAP", WRAPPING_CALL_CHAIN, WRAP_OPTIONS, WRAP_VALUES);
addOption("WRAP_FIRST_METHOD_IN_CALL_CHAIN", ApplicationBundle.message("wrapping.chained.method.call.first.on.new.line"), WRAPPING_CALL_CHAIN);
addOption("ALIGN_MULTILINE_CHAINED_METHODS", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_CALL_CHAIN);
addOption("IF_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), WRAPPING_IF_STATEMENT, BRACE_OPTIONS, BRACE_VALUES);
addOption("ELSE_ON_NEW_LINE", ApplicationBundle.message("wrapping.else.on.new.line"), WRAPPING_IF_STATEMENT);
addOption("SPECIAL_ELSE_IF_TREATMENT", ApplicationBundle.message("wrapping.special.else.if.braces.treatment"), WRAPPING_IF_STATEMENT);
addOption("FOR_STATEMENT_WRAP", WRAPPING_FOR_STATEMENT, WRAP_OPTIONS, WRAP_VALUES);
addOption("ALIGN_MULTILINE_FOR", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_FOR_STATEMENT);
addOption("FOR_STATEMENT_LPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.new.line.after.lpar"), WRAPPING_FOR_STATEMENT);
addOption("FOR_STATEMENT_RPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.rpar.on.new.line"), WRAPPING_FOR_STATEMENT);
addOption("FOR_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), WRAPPING_FOR_STATEMENT, BRACE_OPTIONS, BRACE_VALUES);
addOption("WHILE_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), WRAPPING_WHILE_STATEMENT, BRACE_OPTIONS, BRACE_VALUES);
addOption("DOWHILE_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), WRAPPING_DOWHILE_STATEMENT, BRACE_OPTIONS, BRACE_VALUES);
addOption("WHILE_ON_NEW_LINE", ApplicationBundle.message("wrapping.while.on.new.line"), WRAPPING_DOWHILE_STATEMENT);
addOption("INDENT_CASE_FROM_SWITCH", ApplicationBundle.message("wrapping.indent.case.from.switch"), WRAPPING_SWITCH_STATEMENT);
addOption("INDENT_BREAK_FROM_CASE", ApplicationBundle.message("wrapping.indent.break.from.case"), WRAPPING_SWITCH_STATEMENT);
addOption("RESOURCE_LIST_WRAP", WRAPPING_TRY_RESOURCE_LIST, WRAP_OPTIONS, WRAP_VALUES);
addOption("ALIGN_MULTILINE_RESOURCES", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_TRY_RESOURCE_LIST);
addOption("RESOURCE_LIST_LPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.new.line.after.lpar"), WRAPPING_TRY_RESOURCE_LIST);
addOption("RESOURCE_LIST_RPAREN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.rpar.on.new.line"), WRAPPING_TRY_RESOURCE_LIST);
addOption("CATCH_ON_NEW_LINE", ApplicationBundle.message("wrapping.catch.on.new.line"), WRAPPING_TRY_STATEMENT);
addOption("FINALLY_ON_NEW_LINE", ApplicationBundle.message("wrapping.finally.on.new.line"), WRAPPING_TRY_STATEMENT);
addOption("BINARY_OPERATION_WRAP", WRAPPING_BINARY_OPERATION, WRAP_OPTIONS, WRAP_VALUES);
addOption("ALIGN_MULTILINE_BINARY_OPERATION", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_BINARY_OPERATION);
addOption("BINARY_OPERATION_SIGN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.operation.sign.on.next.line"), WRAPPING_BINARY_OPERATION);
addOption("ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION", ApplicationBundle.message("wrapping.align.parenthesised.when.multiline"), WRAPPING_BINARY_OPERATION);
addOption("PARENTHESES_EXPRESSION_LPAREN_WRAP", ApplicationBundle.message("wrapping.new.line.after.lpar"), WRAPPING_BINARY_OPERATION);
addOption("PARENTHESES_EXPRESSION_RPAREN_WRAP", ApplicationBundle.message("wrapping.rpar.on.new.line"), WRAPPING_BINARY_OPERATION);
addOption("ASSIGNMENT_WRAP", WRAPPING_ASSIGNMENT, WRAP_OPTIONS, WRAP_VALUES);
addOption("ALIGN_MULTILINE_ASSIGNMENT", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_ASSIGNMENT);
addOption("PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE", ApplicationBundle.message("wrapping.assignment.sign.on.next.line"), WRAPPING_ASSIGNMENT);
addOption("ALIGN_GROUP_FIELD_DECLARATIONS", ApplicationBundle.message("wrapping.align.fields.in.columns"), WRAPPING_FIELDS_VARIABLES_GROUPS);
addOption("ALIGN_CONSECUTIVE_VARIABLE_DECLARATIONS", ApplicationBundle.message("wrapping.align.variables.in.columns"), WRAPPING_FIELDS_VARIABLES_GROUPS);
addOption("TERNARY_OPERATION_WRAP", WRAPPING_TERNARY_OPERATION, WRAP_OPTIONS, WRAP_VALUES);
addOption("ALIGN_MULTILINE_TERNARY_OPERATION", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_TERNARY_OPERATION);
addOption("TERNARY_OPERATION_SIGNS_ON_NEXT_LINE", ApplicationBundle.message("wrapping.quest.and.colon.signs.on.next.line"), WRAPPING_TERNARY_OPERATION);
addOption("ARRAY_INITIALIZER_WRAP", WRAPPING_ARRAY_INITIALIZER, WRAP_OPTIONS, WRAP_VALUES);
addOption("ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_ARRAY_INITIALIZER);
addOption("ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE", ApplicationBundle.message("wrapping.new.line.after.lbrace"), WRAPPING_ARRAY_INITIALIZER);
addOption("ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE", ApplicationBundle.message("wrapping.rbrace.on.new.line"), WRAPPING_ARRAY_INITIALIZER);
addOption("MODIFIER_LIST_WRAP", ApplicationBundle.message("wrapping.after.modifier.list"), WRAPPING_MODIFIER_LIST);
addOption("ASSERT_STATEMENT_WRAP", WRAPPING_ASSERT_STATEMENT, WRAP_OPTIONS, WRAP_VALUES);
addOption("ASSERT_STATEMENT_COLON_ON_NEXT_LINE", ApplicationBundle.message("wrapping.colon.signs.on.next.line"), WRAPPING_ASSERT_STATEMENT);
addOption("ENUM_CONSTANTS_WRAP", ApplicationBundle.message("wrapping.enum.constants"), WRAP_OPTIONS, WRAP_VALUES);
addOption("CLASS_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.classes.annotation"), WRAP_OPTIONS, WRAP_VALUES);
addOption("METHOD_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.methods.annotation"), WRAP_OPTIONS, WRAP_VALUES);
addOption("FIELD_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.fields.annotation"), WRAP_OPTIONS, WRAP_VALUES);
addOption("PARAMETER_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.parameters.annotation"), WRAP_OPTIONS, WRAP_VALUES);
addOption("VARIABLE_ANNOTATION_WRAP", ApplicationBundle.message("wrapping.local.variables.annotation"), WRAP_OPTIONS, WRAP_VALUES);
for (Map.Entry<CodeStyleSettingPresentation.SettingsGroup, List<CodeStyleSettingPresentation>> entry:
CodeStyleSettingPresentation.getStandardSettings(getSettingsType()).entrySet()) {
CodeStyleSettingPresentation.SettingsGroup group = entry.getKey();
for (CodeStyleSettingPresentation setting: entry.getValue()) {
//TODO this is ugly, but is the fastest way to make Options UI API and settings representation API connect
String fieldName = setting.getFieldName();
String uiName = setting.getUiName();
if (setting instanceof CodeStyleBoundedIntegerSettingPresentation) {
CodeStyleBoundedIntegerSettingPresentation intSetting = (CodeStyleBoundedIntegerSettingPresentation) setting;
int defaultValue = intSetting.getDefaultValue();
addOption(fieldName, uiName, group.name, intSetting.getLowerBound(), intSetting.getUpperBound(), defaultValue, intSetting.getValueUiName(
defaultValue));
} else if (setting instanceof CodeStyleSelectSettingPresentation) {
CodeStyleSelectSettingPresentation selectSetting = (CodeStyleSelectSettingPresentation) setting;
addOption(fieldName, uiName, group.name, selectSetting.getOptions(), selectSetting.getValues());
} else {
addOption(fieldName, uiName, group.name);
}
}
}
}
protected SettingsGroup getAssociatedSettingsGroup(String fieldName) {
@@ -0,0 +1,212 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageFormatting;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.*;
import com.intellij.psi.codeStyle.extractor.differ.LangCodeStyleExtractor;
import com.intellij.psi.codeStyle.extractor.ui.ExtractedSettingsDialog;
import com.intellij.psi.impl.source.codeStyle.CodeStyleSchemesImpl;
import com.intellij.ui.BalloonLayout;
import com.intellij.psi.codeStyle.extractor.processor.CodeStyleDeriveProcessor;
import com.intellij.psi.codeStyle.extractor.processor.GenProcessor;
import com.intellij.psi.codeStyle.extractor.ui.CodeStyleSettingsNameProvider;
import com.intellij.psi.codeStyle.extractor.values.Value;
import com.intellij.psi.codeStyle.extractor.values.ValuesExtractionResult;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import java.awt.*;
import java.util.List;
import java.util.Map;
public class ExtractCodeStyleAction extends AnAction implements DumbAware {
@Override
public void actionPerformed(AnActionEvent e) {
DataContext dataContext = e.getDataContext();
final Project project = CommonDataKeys.PROJECT.getData(dataContext);
if (project == null) return;
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext);
PsiFile file = null;
if (editor == null && files != null && files.length == 1 && !files[0].isDirectory()) {
file = PsiManager.getInstance(project).findFile(files[0]);
} else if (editor != null) {
file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
}
if (file == null) return;
Language language = file.getLanguage();
final LangCodeStyleExtractor extractor = LangCodeStyleExtractor.EXTENSION.forLanguage(language);
if (extractor == null) return;
final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project);
final CodeStyleDeriveProcessor genProcessor = new GenProcessor(extractor);
final PsiFile finalFile = file;
final Task.Backgroundable task = new Task.Backgroundable(project, "Code style extractor", true) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
try {
CodeStyleSettings cloneSettings = settings.clone();
Map<Value, Object> backup = genProcessor.backupValues(cloneSettings, finalFile.getLanguage());
ValuesExtractionResult res = genProcessor.runWithProgress(project, cloneSettings, finalFile, indicator);
reportResult(res, project, cloneSettings, finalFile, backup);
}
catch (ProcessCanceledException e) {
Utils.logError("Code extraction was canceled");
}
catch (Throwable t) {
Utils.logError("Unexpected exception:\n" + t);
}
}
};
ProgressManager.getInstance().run(task);
}
public void reportResult(final ValuesExtractionResult forSelection, final Project project,
final CodeStyleSettings cloneSettings, final PsiFile file, final Map<Value, Object> backup) {
final Balloon balloon = JBPopupFactory.getInstance()
.createHtmlTextBalloonBuilder(
"Formatting Options were extracted<br/><a href=\"apply\">Apply</a> <a href=\"details\">Details...</a>",
MessageType.INFO,
new HyperlinkListener() {
@Override
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
boolean apply = "apply".equals(e.getDescription());
ExtractedSettingsDialog myDialog = null;
if (!apply) {
final List<Value> values = forSelection.getValues();
final LanguageCodeStyleSettingsProvider[] providers = Extensions.getExtensions(
LanguageCodeStyleSettingsProvider.EP_NAME);
Language language = file.getLanguage();
CodeStyleSettingsNameProvider nameProvider = new CodeStyleSettingsNameProvider();
for (final LanguageCodeStyleSettingsProvider provider : providers) {
Language target = provider.getLanguage();
if (target.equals(language)) {
//this is our language
nameProvider.addSettings(provider);
myDialog = new ExtractedSettingsDialog(project, nameProvider, values);
apply = myDialog.showAndGet();
break;
}
}
}
if (apply && myDialog != null) {
//create new settings named after the file
final ExtractedSettingsDialog finalMyDialog = myDialog;
forSelection.applyConditioned(new Condition<Value>() {
@Override
public boolean value(Value value) {
return finalMyDialog.valueIsSelectedInTree(value);
}
}, backup);
CodeStyleScheme derivedScheme = CodeStyleSchemes.getInstance().createNewScheme("Derived from " + file.getName(), null);
derivedScheme.getCodeStyleSettings().copyFrom(cloneSettings);
CodeStyleSchemes.getInstance().addScheme(derivedScheme);
((CodeStyleSchemesImpl) CodeStyleSchemes.getInstance()).getSchemeManager().setCurrent(derivedScheme);
CodeStyleSettingsManager.getInstance(project).PREFERRED_PROJECT_CODE_STYLE = derivedScheme.getName();
}
}
}
}
).setDisposable(ApplicationManager.getApplication()).setShowCallout(false).setFadeoutTime(0).
setShowCallout(false).setAnimationCycle(0).setHideOnClickOutside(false).setHideOnKeyOutside(false).
setCloseButtonEnabled(true).setHideOnLinkClick(true).createBalloon();
ApplicationManager.getApplication().
invokeLater(new Runnable() {
@Override
public void run () {
Window window = WindowManager.getInstance().getFrame(project);
if (window == null) {
window = JOptionPane.getRootFrame();
}
if (window instanceof IdeFrame) {
BalloonLayout layout = ((IdeFrame) window).getBalloonLayout();
if (layout != null) {
layout.add(balloon);
}
}
}
}
);
}
@Override
public void update(AnActionEvent event){
Presentation presentation = event.getPresentation();
DataContext dataContext = event.getDataContext();
Project project = CommonDataKeys.PROJECT.getData(dataContext);
if (project == null){
presentation.setEnabled(false);
return;
}
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
PsiFile file = null;
if (editor != null){
file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
} else {
final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext);
if (files != null && files.length == 1 && !files[0].isDirectory()) {
file = PsiManager.getInstance(project).findFile(files[0]);
}
}
if (file == null || file.getVirtualFile() == null) {
presentation.setEnabled(false);
return;
}
if (LanguageFormatting.INSTANCE.forContext(file) != null) {
presentation.setEnabled(true);
}
}
}
@@ -0,0 +1,248 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor.ui;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.codeStyle.*;
import com.intellij.psi.codeStyle.extractor.values.Value;
import com.intellij.psi.codeStyle.presentation.CodeStyleSelectSettingPresentation;
import com.intellij.psi.codeStyle.presentation.CodeStyleSettingPresentation;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.psi.codeStyle.presentation.CodeStyleSettingPresentation.SettingsGroup;
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider.SettingsType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
/**
* @author Roman.Shein
* @since 03.08.2015.
*/
public class CodeStyleSettingsNameProvider implements CodeStyleSettingsCustomizable {
protected Map<SettingsType, Map<SettingsGroup, List<CodeStyleSettingPresentation>>> mySettings =
ContainerUtil.newHashMap();
private Map<SettingsType, Map<SettingsGroup, List<CodeStyleSettingPresentation>>> standardSettings =
ContainerUtil.newHashMap();
public CodeStyleSettingsNameProvider() {
for (SettingsType settingsType : SettingsType.values()) {
standardSettings.put(settingsType, CodeStyleSettingPresentation.getStandardSettings(settingsType));
}
}
protected void addSetting(@NotNull SettingsGroup group, @NotNull CodeStyleSettingPresentation setting, @Nullable OptionAnchor anchor,
@Nullable String anchorFieldName) {
for (Map.Entry<SettingsType, Map<SettingsGroup, List<CodeStyleSettingPresentation>>> entry: mySettings.entrySet()) {
if (entry.getValue().containsKey(group)) {
addSetting(entry.getKey(), group, setting, anchor, anchorFieldName);
return;
}
}
addSetting(SettingsType.LANGUAGE_SPECIFIC, group, setting, anchor, anchorFieldName);
}
protected void addSetting(@NotNull SettingsType settingsType, @NotNull SettingsGroup group, @NotNull CodeStyleSettingPresentation setting,
@Nullable OptionAnchor anchor, @Nullable String anchorFieldName) {
Map<CodeStyleSettingPresentation.SettingsGroup, List<CodeStyleSettingPresentation>> groups = mySettings.get(settingsType);
if (groups == null) {
groups = ContainerUtil.newLinkedHashMap();
}
List<CodeStyleSettingPresentation> settingsList = groups.get(group);
if (settingsList == null) {
settingsList = ContainerUtil.newLinkedList();
}
if (settingsList.contains(setting)) return;
if (anchor != null && anchorFieldName != null) {
CodeStyleSettingPresentation anchorSettingRepresentation = new CodeStyleSettingPresentation(anchorFieldName, anchorFieldName);
int insertIndex = settingsList.indexOf(anchorSettingRepresentation);
if (insertIndex < 0) {
insertIndex = settingsList.size();
} else {
switch (anchor) {
case BEFORE:
break;
case AFTER:
insertIndex++;
break;
case NONE:
insertIndex = settingsList.size();
}
}
settingsList.add(insertIndex, setting);
} else {
settingsList.add(setting);
}
groups.put(group, settingsList);
}
@Override
public void showAllStandardOptions() {
for (SettingsType settingsType : SettingsType.values()) {
Map<SettingsGroup, List<CodeStyleSettingPresentation>> standardGroups = standardSettings.get(settingsType);
for (Map.Entry<SettingsGroup, List<CodeStyleSettingPresentation>> entry : standardGroups.entrySet()) {
for (CodeStyleSettingPresentation setting: entry.getValue()) {
addSetting(settingsType, entry.getKey(), setting, null, null);
}
}
}
}
@Override
public void showStandardOptions(String... optionNames) {
List<String> options = Arrays.asList(optionNames);
for (SettingsType settingsType : SettingsType.values()) {
Map<SettingsGroup, List<CodeStyleSettingPresentation>> standardGroups = standardSettings.get(settingsType);
for (Map.Entry<SettingsGroup, List<CodeStyleSettingPresentation>> entry : standardGroups.entrySet()) {
for (CodeStyleSettingPresentation setting: entry.getValue()) {
if (options.contains(setting.getFieldName())) {
addSetting(settingsType, entry.getKey(), setting, null, null);
}
}
}
}
}
@Override
public void showCustomOption(Class<? extends CustomCodeStyleSettings> settingsClass, @NotNull String fieldName, @NotNull String title, @Nullable String groupName, Object... options) {
showCustomOption(settingsClass, fieldName, title, groupName, null, null, options);
}
@Override
public void showCustomOption(Class<? extends CustomCodeStyleSettings> settingsClass, @NotNull String fieldName, @NotNull String title,
@Nullable String groupName, @Nullable OptionAnchor anchor, @Nullable String anchorFieldName, Object... options) {
if (options.length == 2) {
addSetting(new SettingsGroup(groupName), new CodeStyleSelectSettingPresentation(fieldName, title, (int[])options[1],
(String[])options[0]), anchor, anchorFieldName);
} else {
addSetting(new SettingsGroup(groupName), new CodeStyleSettingPresentation(fieldName, title), anchor, anchorFieldName);
}
}
@Override
public void renameStandardOption(String fieldName, String newTitle) {
for (SettingsType settingsType : SettingsType.values()) {
Map<SettingsGroup, List<CodeStyleSettingPresentation>> standardGroups = mySettings.get(settingsType);
if (standardGroups == null) {
continue;
}
for (Map.Entry<SettingsGroup, List<CodeStyleSettingPresentation>> entry : standardGroups.entrySet()) {
for (CodeStyleSettingPresentation setting: entry.getValue()) {
if (setting.getFieldName().equals(fieldName)) {
setting.setUiName(newTitle);
return;
}
}
}
}
}
@Override
public void moveStandardOption(String fieldName, String newGroup) {
for (SettingsType settingsType : SettingsType.values()) {
Map<SettingsGroup, List<CodeStyleSettingPresentation>> standardGroups = mySettings.get(settingsType);
if (standardGroups == null) {
standardGroups = ContainerUtil.newLinkedHashMap();
mySettings.put(settingsType, standardGroups);
}
for (Map.Entry<SettingsGroup, List<CodeStyleSettingPresentation>> entry : standardGroups.entrySet()) {
CodeStyleSettingPresentation moveSetting = null;
for (CodeStyleSettingPresentation setting: entry.getValue()) {
if (setting.getFieldName().equals(fieldName)) {
moveSetting = setting;
break;
}
}
if (moveSetting != null) {
entry.getValue().remove(moveSetting);
addSetting(new SettingsGroup(newGroup), moveSetting, null, null);
}
}
}
}
public static String getSettingsTypeName(LanguageCodeStyleSettingsProvider.SettingsType settingsType) {
switch (settingsType) {
case BLANK_LINES_SETTINGS: return ApplicationBundle.message("title.blank.lines");
case SPACING_SETTINGS: return ApplicationBundle.message("title.spaces");
case WRAPPING_AND_BRACES_SETTINGS: return ApplicationBundle.message("wrapping.and.braces");
case INDENT_SETTINGS: return ApplicationBundle.message("title.tabs.and.indents");
case LANGUAGE_SPECIFIC: return "Language-specific"; //TODO should load from ApplciationBundle here
default: throw new IllegalArgumentException("Unknown settings type: " + settingsType);
}
}
public void addSettings(LanguageCodeStyleSettingsProvider provider) {
for (SettingsType settingsType : LanguageCodeStyleSettingsProvider.SettingsType.values()) {
provider.customizeSettings(this, settingsType);
}
}
public static Value getValue(final CodeStyleSettingPresentation representation, List<Value> values) {
Value myValue = ContainerUtil.find(values, new Condition<Value>() {
@Override
public boolean value(Value value) {
return value.state == Value.STATE.SELECTED && value.name.equals(representation.getFieldName());
//return value.name.equals(representation.getFieldName()); //TODO this is here only to test the UI!!
}
});
return myValue;
}
public String getSettings(List<Value> values) {
StringBuilder builder = new StringBuilder();
for (SettingsType settingsType : LanguageCodeStyleSettingsProvider.SettingsType.values()) {
builder.append("<br><b><u>").append(getSettingsTypeName(settingsType)).append("</u></b>");
Map<SettingsGroup, List<CodeStyleSettingPresentation>> groups = mySettings.get(settingsType);
if (groups != null) {
for (Map.Entry<SettingsGroup, List<CodeStyleSettingPresentation>> entry : groups.entrySet()) {
boolean firstSettingGroupTop = entry.getKey().isNull();
boolean groupReported = false;
for (final CodeStyleSettingPresentation setting : entry.getValue()) {
Value myValue = ContainerUtil.find(values, new Condition<Value>() {
@Override
public boolean value(Value value) {
return value.state == Value.STATE.SELECTED && value.name.equals(setting.getFieldName());
}
});
if (myValue == null) {
continue;
}
if (!groupReported) {
if (firstSettingGroupTop) {
builder.append("<b>");
} else {
builder.append("<br><b>").append(entry.getKey().name).append("</b>");
}
}
builder.append("<br>");
String postNameSign = setting.getUiName().endsWith(":") ? " " : ": ";
builder.append(setting.getUiName()).append(postNameSign).append(setting.getValueUiName(myValue.value));
if (!groupReported) {
if (firstSettingGroupTop) {
builder.append("</b>");
}
}
groupReported = true;
}
}
}
}
return builder.toString();
}
}
@@ -0,0 +1,479 @@
/*
* Copyright 2000-2015 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 com.intellij.psi.codeStyle.extractor.ui;
import com.intellij.application.options.codeStyle.OptionTableWithPreviewPanel;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.codeStyle.presentation.CodeStyleSettingPresentation;
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
import com.intellij.psi.codeStyle.extractor.values.Value;
import com.intellij.ui.SpeedSearchComparator;
import com.intellij.ui.TreeTableSpeedSearch;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.panels.HorizontalLayout;
import com.intellij.ui.treeStructure.treetable.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.AbstractTableCellEditor;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.List;
/**
* @author Roman.Shein
* @since 28.09.2015.
*/
public class ExtractedSettingsDialog extends DialogWrapper {
protected CodeStyleSettingsNameProvider myNameProvider;
protected List<Value> myValues;
protected DefaultMutableTreeNode myRoot;
public ExtractedSettingsDialog(@Nullable Project project,
@NotNull CodeStyleSettingsNameProvider nameProvider,
@NotNull List<Value> values) {
super(project, false);
myNameProvider = nameProvider;
myValues = values;
setModal(true);
init();
setTitle("Extracted Code Style Settings");
}
@Nullable
@Override
protected JComponent createCenterPanel() {
JComponent result = buildExtractedSettingsTree();
return result;
}
public boolean valueIsSelectedInTree(@NotNull Value value) {
if (myRoot == null) return false;
return valueIsSelectedInTree(myRoot, value);
}
protected boolean valueIsSelectedInTree(@NotNull TreeNode startNode, @NotNull Value value) {
for (Enumeration children = startNode.children(); children.hasMoreElements();) {
Object child = children.nextElement();
if (child instanceof SettingsTreeNode) {
SettingsTreeNode settingsChild = (SettingsTreeNode) child;
if (settingsChild.accepted && value.equals(settingsChild.myValue)) {
return true;
}
if (valueIsSelectedInTree(settingsChild, value)) return true;
} else if (child instanceof TreeNode) {
if (valueIsSelectedInTree((TreeNode) child, value)) return true;
}
}
return false;
}
public static class SettingsTreeNode extends DefaultMutableTreeNode {
protected CodeStyleSettingPresentation myRepresentation;
protected boolean accepted = true;
protected final String valueString;
protected final boolean isGroupNode;
protected final String customTitle;
protected Value myValue;
public SettingsTreeNode(String valueString, CodeStyleSettingPresentation representation, boolean isGroupNode, Value value) {
this(valueString, representation, isGroupNode, null, value);
}
public SettingsTreeNode(String valueString, CodeStyleSettingPresentation representation, boolean isGroupNode, String customTitle,
Value value) {
this.valueString = valueString;
this.myRepresentation = representation;
this.isGroupNode = isGroupNode;
this.customTitle = customTitle;
this.myValue = value;
}
public SettingsTreeNode(String title) {
this(title, null, true, null);
}
public boolean isGroupOrTypeNode() {
return isGroupNode;
}
@NotNull
public String getTitle() {
return customTitle != null ? customTitle : (myRepresentation == null ? valueString : myRepresentation.getUiName());
}
@Nullable
public String getValueString() {
return myRepresentation == null ? null : valueString;
}
}
protected static ColumnInfo getTitleColumnInfo() {
return new ColumnInfo("TITLE") {
@Nullable
@Override
public Object valueOf(Object o) {
if (o instanceof SettingsTreeNode) {
return ((SettingsTreeNode) o).getTitle();
} else {
return o.toString();
}
}
@Override
public Class getColumnClass() {
return TreeTableModel.class;
}
};
}
protected static class ValueRenderer implements TableCellRenderer {
private final JLabel myLabel = new JLabel();
private final JCheckBox myCheckBox = new JCheckBox();
private final JPanel myPanel = new JPanel(new HorizontalLayout(0));
{
myPanel.add(myLabel);
myPanel.add(myCheckBox);
}
@NotNull
@Override
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
if (table instanceof TreeTable) {
table.setEnabled(true);
DefaultMutableTreeNode valueNode = (DefaultMutableTreeNode)((TreeTable) table).getTree().getPathForRow(row).getLastPathComponent();
if (valueNode instanceof SettingsTreeNode) {
SettingsTreeNode settingsNode = (SettingsTreeNode) valueNode;
myLabel.setText(settingsNode.getValueString());
myCheckBox.setEnabled(true);
myCheckBox.setSelected(settingsNode.accepted);
} else {
myLabel.setBackground(table.getBackground());
myCheckBox.setEnabled(false);
}
}
return myPanel;
}
}
protected static class ValueEditor extends AbstractTableCellEditor {
private final JLabel myLabel = new JLabel();
private final JCheckBox myCheckBox = new JCheckBox();
private final JPanel myPanel = new JPanel(new HorizontalLayout(0));
{
myPanel.add(myLabel);
myPanel.add(myCheckBox);
}
private SettingsTreeNode myCurrentNode;
private TreeTable myCurrentTree;
final ActionListener itemChoiceListener = new ActionListener() {
@Override
public void actionPerformed(@NotNull ActionEvent e) {
if (myCurrentNode != null) {
boolean wasChanged = myCurrentNode.accepted != myCheckBox.isSelected();
myCurrentNode.accepted = myCheckBox.isSelected();
if (wasChanged) {
updateAncestorsUi(myCurrentNode.accepted, myCurrentNode);
updateChildrenUi(myCurrentNode);
}
if (myCurrentTree != null) {
myCurrentTree.repaint();
}
}
}
};
protected void updateAncestorsUi(boolean accepted, SettingsTreeNode node) {
TreeNode parent = node.getParent();
if (parent != null && parent instanceof SettingsTreeNode) {
SettingsTreeNode settingsParent = (SettingsTreeNode) parent;
settingsParent.accepted = false;
if (!accepted) {
//propagate disabled settings upwards
updateAncestorsUi(false, settingsParent);
} else {
for (Enumeration children = parent.children(); children.hasMoreElements(); ) {
Object child = children.nextElement();
if ((child instanceof SettingsTreeNode) && !((SettingsTreeNode) child).accepted) return;
}
settingsParent.accepted = true;
updateAncestorsUi(true, settingsParent);
}
}
}
protected void updateChildrenUi(SettingsTreeNode node) {
for (Enumeration children = node.children(); children.hasMoreElements(); ) {
Object child = children.nextElement();
if (child instanceof SettingsTreeNode) {
SettingsTreeNode settingsChild = (SettingsTreeNode) child;
settingsChild.accepted = node.accepted;
updateChildrenUi(settingsChild);
}
}
}
public ValueEditor() {
myCheckBox.addActionListener(itemChoiceListener);
}
@Override
public Object getCellEditorValue() {
return myCheckBox.isSelected();
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) ((TreeTable) table).getTree().getPathForRow(row).getLastPathComponent();
if (treeNode instanceof SettingsTreeNode) {
myCurrentTree = (TreeTable) table;
myCurrentNode = (SettingsTreeNode) treeNode;
myLabel.setText(myCurrentNode.getValueString());
myCheckBox.setSelected(myCurrentNode.accepted);
}
return myPanel;
}
}
private static ValueRenderer myValueRenderer = new ValueRenderer();
private static ValueEditor myValueEditor = new ValueEditor();
protected static ColumnInfo getValueColumnInfo() {
return new ColumnInfo("VALUE") {
@Nullable
@Override
public Object valueOf(Object o) {
if (o instanceof SettingsTreeNode) {
return ((SettingsTreeNode) o).getValueString();
} else {
return null;
}
}
@Override
public TableCellRenderer getRenderer(Object o) {
return myValueRenderer;
}
public TableCellEditor getEditor(Object o) {
return myValueEditor;
}
@Override
public boolean isCellEditable(Object o) {
return o instanceof SettingsTreeNode;
}
};
}
protected JComponent buildExtractedSettingsTree() {
Collection<Value> unusedValues = ContainerUtil.newHashSet(myValues);
myRoot = new DefaultMutableTreeNode();
for (Map.Entry<LanguageCodeStyleSettingsProvider.SettingsType,
Map<CodeStyleSettingPresentation.SettingsGroup, List<CodeStyleSettingPresentation>>> typeEntry : myNameProvider.mySettings.entrySet()) {
DefaultMutableTreeNode settingsNode = null;
for (Map.Entry<CodeStyleSettingPresentation.SettingsGroup, List<CodeStyleSettingPresentation>> groupEntry: typeEntry.getValue().entrySet()) {
CodeStyleSettingPresentation.SettingsGroup group = groupEntry.getKey();
List<CodeStyleSettingPresentation> representations = groupEntry.getValue();
List<CodeStyleSettingPresentation> children = ContainerUtil.emptyList();
DefaultMutableTreeNode groupNode = null;
if (group.name == null && !representations.isEmpty()) {
//there is a setting with name coinciding with group name
if (representations.size() > 1) {
children = representations.subList(1, representations.size());
}
CodeStyleSettingPresentation headRep = representations.get(0);
Value myValue = CodeStyleSettingsNameProvider.getValue(headRep, myValues);
if (myValue == null) {
//value was not found (was not selected)
groupNode = new SettingsTreeNode(headRep.getUiName());
} else {
groupNode = new SettingsTreeNode(headRep.getUiName());
groupNode.add(new SettingsTreeNode(headRep.getValueUiName(myValue.value), headRep, true, myValue));
unusedValues.remove(myValue);
}
} else {
children = representations;
}
for (CodeStyleSettingPresentation representation: children) {
Value myValue = CodeStyleSettingsNameProvider.getValue(representation, myValues);
if (myValue != null) {
if (groupNode == null) {
groupNode = new SettingsTreeNode(group.name);
}
groupNode.add(new SettingsTreeNode(representation.getValueUiName(myValue.value), representation, false, myValue));
unusedValues.remove(myValue);
}
}
if (groupNode != null && !groupNode.isLeaf()) {
if (settingsNode == null) {
settingsNode = new SettingsTreeNode(CodeStyleSettingsNameProvider.getSettingsTypeName(typeEntry.getKey()));
}
settingsNode.add(groupNode);
}
}
if (settingsNode != null) {
myRoot.add(settingsNode);
}
}
//TODO: for now, settings without UI presentation are not displayed. Do something about it.
//unusedValues = ContainerUtil.filter(unusedValues, new Condition<Value>(){
// @Override
// public boolean value(Value value) {
// return value.state == Value.STATE.SELECTED;
// }
//});
//
//DefaultMutableTreeNode unnamedNode = null;
//for (Value value: unusedValues) {
// if (unnamedNode == null) {
// unnamedNode = new SettingsTreeNode("Settings without UI representation");
// }
// unnamedNode.add(new SettingsTreeNode(value.value.toString(), null, false, value.name, value));
//}
//
//if (unnamedNode != null) {
// myRoot.add(unnamedNode);
//}
final ColumnInfo[] COLUMNS = new ColumnInfo[]{getTitleColumnInfo(), getValueColumnInfo()};
ListTreeTableModel model = new ListTreeTableModel(myRoot, COLUMNS);
final TreeTable treeTable = new TreeTable(model) {
@Override
public TreeTableCellRenderer createTableRenderer(TreeTableModel treeTableModel) {
TreeTableCellRenderer tableRenderer = super.createTableRenderer(treeTableModel);
UIUtil.setLineStyleAngled(tableRenderer);
tableRenderer.setRootVisible(false);
tableRenderer.setShowsRootHandles(true);
return tableRenderer;
}
@Override
public TableCellRenderer getCellRenderer(int row, int column) {
TreePath treePath = getTree().getPathForRow(row);
if (treePath == null) return super.getCellRenderer(row, column);
Object node = treePath.getLastPathComponent();
TableCellRenderer renderer = COLUMNS[column].getRenderer(node);
return renderer == null ? super.getCellRenderer(row, column) : renderer;
}
@Override
public TableCellEditor getCellEditor(int row, int column) {
TreePath treePath = getTree().getPathForRow(row);
if (treePath == null) return super.getCellEditor(row, column);
Object node = treePath.getLastPathComponent();
TableCellEditor editor = COLUMNS[column].getEditor(node);
return editor == null ? super.getCellEditor(row, column) : editor;
}
};
new TreeTableSpeedSearch(treeTable).setComparator(new SpeedSearchComparator(false));
treeTable.setRootVisible(false);
final JTree tree = treeTable.getTree();
tree.setCellRenderer(myTitleRenderer);
tree.setShowsRootHandles(true);
treeTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
treeTable.setTableHeader(null);
OptionTableWithPreviewPanel.expandTree(tree);
treeTable.getColumnModel().getSelectionModel().setAnchorSelectionIndex(1);
treeTable.getColumnModel().getSelectionModel().setLeadSelectionIndex(1);
int maxWidth = tree.getPreferredScrollableViewportSize().width + 10;
final TableColumn titleColumn = treeTable.getColumnModel().getColumn(0);
titleColumn.setPreferredWidth(maxWidth);
titleColumn.setMinWidth(maxWidth);
titleColumn.setMaxWidth(maxWidth);
titleColumn.setResizable(false);
final Dimension valueSize = new JLabel(ApplicationBundle.message("option.table.sizing.text")).getPreferredSize();
treeTable.setPreferredScrollableViewportSize(new Dimension(maxWidth + valueSize.width + 10, 20));
treeTable.setBackground(UIUtil.getPanelBackground());
treeTable.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10));
final Dimension screenSize = treeTable.getToolkit().getScreenSize();
JBScrollPane scroller = new JBScrollPane(treeTable) {
@Override
public Dimension getMinimumSize() {
return super.getPreferredSize();
}
};
final Dimension preferredSize = new Dimension(Math.min(screenSize.width / 2, treeTable.getPreferredSize().width),
Math.min(screenSize.height / 2, treeTable.getPreferredSize().height));
getRootPane().setPreferredSize(preferredSize);
return scroller;
}
final TreeCellRenderer myTitleRenderer = new CellRenderer();
public static class CellRenderer implements TreeCellRenderer {
private final JLabel myLabel = new JLabel();
@NotNull
@Override
public Component getTreeCellRendererComponent(JTree tree,
Object value,
boolean selected,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus) {
if (value instanceof SettingsTreeNode) {
SettingsTreeNode node = (SettingsTreeNode) value;
myLabel.setText(node.getTitle());
myLabel.setFont(node.isGroupOrTypeNode() ? myLabel.getFont().deriveFont(Font.BOLD) : myLabel.getFont().deriveFont(Font.PLAIN));
} else {
myLabel.setText(value.toString());
myLabel.setFont(myLabel.getFont().deriveFont(Font.BOLD));
}
Color foreground = selected ? UIUtil.getTableSelectionForeground() : UIUtil.getTableForeground();
myLabel.setForeground(foreground);
return myLabel;
}
}
}
@@ -209,6 +209,9 @@
<extensionPoint name="lang.rearranger" beanClass="com.intellij.lang.LanguageExtensionPoint">
<with attribute="implementationClass" implements="com.intellij.psi.codeStyle.arrangement.Rearranger"/>
</extensionPoint>
<extensionPoint name="lang.formatting.extractor" beanClass="com.intellij.lang.LanguageExtensionPoint">
<with attribute="implementationClass" implements="com.intellij.psi.codeStyle.extractor.differ.LangCodeStyleExtractor"/>
</extensionPoint>
<extensionPoint name="rearranger.ui" interface="com.intellij.psi.codeStyle.arrangement.std.ArrangementUiComponent$Factory"/>
<extensionPoint name="lang.surroundDescriptor" beanClass="com.intellij.lang.LanguageExtensionPoint">
+1
View File
@@ -1031,6 +1031,7 @@
<lang.whiteSpaceFormattingStrategy language="JAVA"
implementationClass="com.intellij.psi.formatter.JavadocWhiteSpaceFormattingStrategy"/>
<lang.rearranger language="JAVA" implementationClass="com.intellij.psi.codeStyle.arrangement.JavaRearranger"/>
<lang.formatting.extractor language="JAVA" implementationClass="com.intellij.psi.codeStyle.extractor.differ.JavaExtractor"/>
<lang.documentationProvider language="JAVA" implementationClass="com.intellij.lang.java.JavaDocumentationProvider"/>
<documentationProvider implementation="com.intellij.lang.java.FileDocumentationProvider" order="last"/>