diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java index 9f16a2ab6e12..3050cae6faa6 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java @@ -21,6 +21,177 @@ import org.jetbrains.annotations.Nullable; public interface CodeStyleSettingsCustomizable { enum OptionAnchor {NONE, BEFORE, AFTER} + enum SpacingOption { + INSERT_FIRST_SPACE_IN_LINE, + SPACE_AROUND_ASSIGNMENT_OPERATORS, + SPACE_AROUND_LOGICAL_OPERATORS, + SPACE_AROUND_EQUALITY_OPERATORS, + SPACE_AROUND_RELATIONAL_OPERATORS, + SPACE_AROUND_BITWISE_OPERATORS, + SPACE_AROUND_ADDITIVE_OPERATORS, + SPACE_AROUND_MULTIPLICATIVE_OPERATORS, + SPACE_AROUND_SHIFT_OPERATORS, + SPACE_AROUND_UNARY_OPERATOR, + SPACE_AFTER_COMMA, + SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS, + SPACE_BEFORE_COMMA, + SPACE_AFTER_SEMICOLON, + SPACE_BEFORE_SEMICOLON, + SPACE_WITHIN_PARENTHESES, + SPACE_WITHIN_METHOD_CALL_PARENTHESES, + SPACE_WITHIN_METHOD_PARENTHESES, + SPACE_WITHIN_IF_PARENTHESES, + SPACE_WITHIN_WHILE_PARENTHESES, + SPACE_WITHIN_FOR_PARENTHESES, + SPACE_WITHIN_TRY_PARENTHESES, + SPACE_WITHIN_CATCH_PARENTHESES, + SPACE_WITHIN_SWITCH_PARENTHESES, + SPACE_WITHIN_SYNCHRONIZED_PARENTHESES, + SPACE_WITHIN_CAST_PARENTHESES, + SPACE_WITHIN_BRACKETS, + SPACE_WITHIN_BRACES, + SPACE_WITHIN_ARRAY_INITIALIZER_BRACES, + SPACE_AFTER_TYPE_CAST, + SPACE_BEFORE_METHOD_CALL_PARENTHESES, + SPACE_BEFORE_METHOD_PARENTHESES, + SPACE_BEFORE_IF_PARENTHESES, + SPACE_BEFORE_WHILE_PARENTHESES, + SPACE_BEFORE_FOR_PARENTHESES, + SPACE_BEFORE_TRY_PARENTHESES, + SPACE_BEFORE_CATCH_PARENTHESES, + SPACE_BEFORE_SWITCH_PARENTHESES, + SPACE_BEFORE_SYNCHRONIZED_PARENTHESES, + SPACE_BEFORE_CLASS_LBRACE, + SPACE_BEFORE_METHOD_LBRACE, + SPACE_BEFORE_IF_LBRACE, + SPACE_BEFORE_ELSE_LBRACE, + SPACE_BEFORE_WHILE_LBRACE, + SPACE_BEFORE_FOR_LBRACE, + SPACE_BEFORE_DO_LBRACE, + SPACE_BEFORE_SWITCH_LBRACE, + SPACE_BEFORE_TRY_LBRACE, + SPACE_BEFORE_CATCH_LBRACE, + SPACE_BEFORE_FINALLY_LBRACE, + SPACE_BEFORE_SYNCHRONIZED_LBRACE, + SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE, + SPACE_BEFORE_ANNOTATION_ARRAY_INITIALIZER_LBRACE, + SPACE_BEFORE_ELSE_KEYWORD, + SPACE_BEFORE_WHILE_KEYWORD, + SPACE_BEFORE_CATCH_KEYWORD, + SPACE_BEFORE_FINALLY_KEYWORD, + SPACE_BEFORE_QUEST, + SPACE_AFTER_QUEST, + SPACE_BEFORE_COLON, + SPACE_AFTER_COLON, + SPACE_BEFORE_TYPE_PARAMETER_LIST, + SPACE_BEFORE_ANOTATION_PARAMETER_LIST, + SPACE_WITHIN_ANNOTATION_PARENTHESES, + } + + enum BlankLinesOption { + KEEP_BLANK_LINES_IN_DECLARATIONS, + KEEP_BLANK_LINES_IN_CODE, + KEEP_BLANK_LINES_BEFORE_RBRACE, + BLANK_LINES_BEFORE_PACKAGE, + BLANK_LINES_AFTER_PACKAGE, + BLANK_LINES_BEFORE_IMPORTS, + BLANK_LINES_AFTER_IMPORTS, + BLANK_LINES_AROUND_CLASS, + BLANK_LINES_AROUND_FIELD, + BLANK_LINES_AROUND_METHOD, + BLANK_LINES_BEFORE_METHOD_BODY, + BLANK_LINES_AROUND_FIELD_IN_INTERFACE, + BLANK_LINES_AROUND_METHOD_IN_INTERFACE, + BLANK_LINES_AFTER_CLASS_HEADER, + BLANK_LINES_AFTER_ANONYMOUS_CLASS_HEADER + } + + enum WrappingOrBraceOption { + KEEP_CONTROL_STATEMENT_IN_ONE_LINE, + LINE_COMMENT_AT_FIRST_COLUMN, + BLOCK_COMMENT_AT_FIRST_COLUMN, + KEEP_LINE_BREAKS, + KEEP_FIRST_COLUMN_COMMENT, + CALL_PARAMETERS_WRAP, + PREFER_PARAMETERS_WRAP, + CALL_PARAMETERS_LPAREN_ON_NEXT_LINE, + CALL_PARAMETERS_RPAREN_ON_NEXT_LINE, + METHOD_PARAMETERS_WRAP, + METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE, + METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE, + RESOURCE_LIST_WRAP, + RESOURCE_LIST_LPAREN_ON_NEXT_LINE, + RESOURCE_LIST_RPAREN_ON_NEXT_LINE, + EXTENDS_LIST_WRAP, + THROWS_LIST_WRAP, + EXTENDS_KEYWORD_WRAP, + THROWS_KEYWORD_WRAP, + METHOD_CALL_CHAIN_WRAP, + PARENTHESES_EXPRESSION_LPAREN_WRAP, + PARENTHESES_EXPRESSION_RPAREN_WRAP, + BINARY_OPERATION_WRAP, + BINARY_OPERATION_SIGN_ON_NEXT_LINE, + TERNARY_OPERATION_WRAP, + TERNARY_OPERATION_SIGNS_ON_NEXT_LINE, + MODIFIER_LIST_WRAP, + KEEP_SIMPLE_BLOCKS_IN_ONE_LINE, + KEEP_SIMPLE_METHODS_IN_ONE_LINE, + KEEP_SIMPLE_CLASSES_IN_ONE_LINE, + KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE, + FOR_STATEMENT_WRAP, + FOR_STATEMENT_LPAREN_ON_NEXT_LINE, + FOR_STATEMENT_RPAREN_ON_NEXT_LINE, + ARRAY_INITIALIZER_WRAP, + ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE, + ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE, + ASSIGNMENT_WRAP, + PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE, + LABELED_STATEMENT_WRAP, + WRAP_COMMENTS, + ASSERT_STATEMENT_WRAP, + ASSERT_STATEMENT_COLON_ON_NEXT_LINE, + IF_BRACE_FORCE, + DOWHILE_BRACE_FORCE, + WHILE_BRACE_FORCE, + FOR_BRACE_FORCE, + WRAP_LONG_LINES, + METHOD_ANNOTATION_WRAP, + CLASS_ANNOTATION_WRAP, + FIELD_ANNOTATION_WRAP, + PARAMETER_ANNOTATION_WRAP, + VARIABLE_ANNOTATION_WRAP, + ALIGN_MULTILINE_CHAINED_METHODS, + ALIGN_MULTILINE_PARAMETERS, + ALIGN_MULTILINE_PARAMETERS_IN_CALLS, + ALIGN_MULTILINE_RESOURCES, + ALIGN_MULTILINE_FOR, + INDENT_WHEN_CASES, + ALIGN_MULTILINE_BINARY_OPERATION, + ALIGN_MULTILINE_ASSIGNMENT, + ALIGN_MULTILINE_TERNARY_OPERATION, + ALIGN_MULTILINE_THROWS_LIST, + ALIGN_THROWS_KEYWORD, + ALIGN_MULTILINE_EXTENDS_LIST, + ALIGN_MULTILINE_METHOD_BRACKETS, + ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION, + ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION, + ALIGN_GROUP_FIELD_DECLARATIONS, + BRACE_STYLE, + CLASS_BRACE_STYLE, + METHOD_BRACE_STYLE, + USE_FLYING_GEESE_BRACES, + FLYING_GEESE_BRACES_GAP, + DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS, + ELSE_ON_NEW_LINE, + WHILE_ON_NEW_LINE, + CATCH_ON_NEW_LINE, + FINALLY_ON_NEW_LINE, + INDENT_CASE_FROM_SWITCH, + SPECIAL_ELSE_IF_TREATMENT + } + + + String SPACES_AROUND_OPERATORS = ApplicationBundle.message("group.spaces.around.operators"); String SPACES_BEFORE_PARENTHESES = ApplicationBundle.message("group.spaces.before.parentheses"); String SPACES_BEFORE_LEFT_BRACE = ApplicationBundle.message("group.spaces.before.left.brace"); diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java index 9ebd146fdfc6..10f38b4018fc 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java @@ -27,6 +27,7 @@ import org.jetbrains.annotations.Nullable; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.util.Set; /** * Common code style settings can be used by several programming languages. Each language may have its own @@ -40,7 +41,7 @@ public class CommonCodeStyleSettings { private CodeStyleSettings myRootSettings; private IndentOptions myIndentOptions; private FileType myFileType; - + private final static String INDENT_OPTIONS_TAG = "indentOptions"; public CommonCodeStyleSettings(Language language, FileType fileType) { @@ -54,7 +55,7 @@ public class CommonCodeStyleSettings { myFileType = language.getAssociatedFileType(); } } - + void setRootSettings(CodeStyleSettings rootSettings) { myRootSettings = rootSettings; } @@ -73,7 +74,7 @@ public class CommonCodeStyleSettings { } } } - + @NotNull public IndentOptions initIndentOptions() { myIndentOptions = new IndentOptions(); @@ -91,7 +92,7 @@ public class CommonCodeStyleSettings { return null; } - + @Nullable public FileType getFileType() { return myFileType; @@ -127,7 +128,7 @@ public class CommonCodeStyleSettings { void copyNonDefaultValuesFrom(CommonCodeStyleSettings from) { CommonCodeStyleSettings defaultSettings = new CommonCodeStyleSettings(null); PARENT_SETTINGS_INSTALLED = - copyFields(this.getClass().getFields(), from, this, new DifferenceFilter(from, defaultSettings)); + copyFields(this.getClass().getFields(), from, this, new DifferenceFilter(from, defaultSettings)); } private static void copyFields(Field[] fields, Object from, Object to) { @@ -190,8 +191,18 @@ public class CommonCodeStyleSettings { } public void writeExternal(Element element) throws WriteExternalException { - CommonCodeStyleSettings defaultSettings = getDefaultSettings(); - DefaultJDOMExternalizer.writeExternal(this, element, new DifferenceFilter(this, defaultSettings)); + CommonCodeStyleSettings defaultSettings = getDefaultSettings(); + final LanguageCodeStyleSettingsProvider provider = LanguageCodeStyleSettingsProvider.forLanguage(myLanguage); + final Set fieldNames = provider == null ? null : provider.getSupportedFields(); + DefaultJDOMExternalizer.writeExternal(this, element, new DifferenceFilter(this, defaultSettings) { + @Override + public boolean isAccept(Field field) { + if (fieldNames == null || "PARENT_SETTINGS_INSTALLED".equals(field.getName()) || fieldNames.contains(field.getName())) { + return super.isAccept(field); + } + return false; + } + }); if (myIndentOptions != null) { IndentOptions defaultIndentOptions = defaultSettings != null ? defaultSettings.getIndentOptions() : null; Element indentOptionsElement = new Element(INDENT_OPTIONS_TAG); @@ -731,7 +742,7 @@ public class CommonCodeStyleSettings { public boolean SPACE_BEFORE_TYPE_PARAMETER_LIST = false; //----------------- WRAPPING --------------------------- - + public static final int DO_NOT_WRAP = 0x00; public static final int WRAP_AS_NEEDED = 0x01; public static final int WRAP_ALWAYS = 0x02; @@ -820,13 +831,13 @@ public class CommonCodeStyleSettings { //-------------------------Enums---------------------------------------------------------- public int ENUM_CONSTANTS_WRAP = DO_NOT_WRAP; - + // // The flag telling that original default settings were overwritten with non-default // values from shared code style settings (happens upon the very first initialization). // - public boolean PARENT_SETTINGS_INSTALLED = false; - + public boolean PARENT_SETTINGS_INSTALLED = false; + //-------------------------Indent options------------------------------------------------- public static class IndentOptions implements JDOMExternalizable, Cloneable { public int INDENT_SIZE = 4; @@ -856,7 +867,7 @@ public class CommonCodeStyleSettings { } }); } - + public void deserialize(Element indentOptionsElement) { XmlSerializer.deserializeInto(this, indentOptionsElement); } @@ -907,7 +918,4 @@ public class CommonCodeStyleSettings { copyPublicFields(other, this); } } - - - } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java b/platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java index 7e477c6c3464..b303650d3fdf 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java @@ -21,10 +21,15 @@ import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; +import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.reflect.Array; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Set; /** * Base class and extension point for code style settings shared between multiple languages @@ -201,5 +206,80 @@ public abstract class LanguageCodeStyleSettingsProvider { public IndentOptionsEditor getIndentOptionsEditor() { return null; } + + public Set getSupportedFields() { + SupportedFieldCollector fieldCollector = new SupportedFieldCollector(); + fieldCollector.collectFields(); + return fieldCollector.getCollectedFields(); + } + + private final class SupportedFieldCollector implements CodeStyleSettingsCustomizable { + private Set myCollectedFields = new HashSet(); + private SettingsType myCurrSettingsType; + + public void collectFields() { + for (SettingsType settingsType : SettingsType.values()) { + myCurrSettingsType = settingsType; + LanguageCodeStyleSettingsProvider.this.customizeSettings(this, settingsType); + } + } + + @Override + public void showAllStandardOptions() { + switch (myCurrSettingsType) { + case BLANK_LINES_SETTINGS: + for (BlankLinesOption blankLinesOption : BlankLinesOption.values()) { + myCollectedFields.add(blankLinesOption.name()); + } + break; + case SPACING_SETTINGS: + for (SpacingOption spacingOption : SpacingOption.values()) { + myCollectedFields.add(spacingOption.name()); + } + break; + case WRAPPING_AND_BRACES_SETTINGS: + for (WrappingOrBraceOption wrappingOrBraceOption : WrappingOrBraceOption.values()) { + myCollectedFields.add(wrappingOrBraceOption.name()); + } + break; + default: + // ignore + } + } + + @Override + public void showStandardOptions(String... optionNames) { + myCollectedFields.addAll(Arrays.asList(optionNames)); + } + + @Override + public void showCustomOption(Class settingsClass, + String fieldName, + String title, + @Nullable String groupName, + Object... options) { + myCollectedFields.add(fieldName); + } + + @Override + public void showCustomOption(Class settingsClass, + String fieldName, + String title, + @Nullable String groupName, + @Nullable OptionAnchor anchor, + @Nullable String anchorFieldName, + Object... options) { + myCollectedFields.add(fieldName); + } + + @Override + public void renameStandardOption(String fieldName, String newTitle) { + // Ignore + } + + public Set getCollectedFields() { + return myCollectedFields; + } + } }