From af7424eff92c8e5122ad2bfe20e1e2d9850d573a Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Thu, 5 Mar 2015 14:59:10 +0300 Subject: [PATCH] resource bundles: customization of key/value delimiters in code style (IDEA-137241). --- .../WrongPropertyKeyValueDelimiter.html | 5 + .../properties-psi-api/properties-psi-api.iml | 5 +- .../messages/PropertiesBundle.properties | 1 + .../psi/PropertiesElementFactory.java | 14 ++- .../PropertiesCodeStyleSettings.java | 39 ++++++ .../PropertiesCodeStyleSettingsPanel.form | 37 ++++++ .../PropertiesCodeStyleSettingsPanel.java | 111 ++++++++++++++++++ .../PropertiesCodeStyleSettingsProvider.java | 60 ++++++++++ .../properties-psi-impl.iml | 1 + ...ngPropertyKeyValueDelimiterInspection.java | 78 ++++++++++++ ...AlphaUnsortedPropertiesFileInspection.java | 5 +- .../psi/impl/PropertiesFileImpl.java | 10 ++ .../properties/psi/impl/PropertyImpl.java | 20 ++++ plugins/properties/src/META-INF/plugin.xml | 6 + .../wrongPropertyKeyDelimiter/expected.xml | 13 ++ .../src/Test1.properties | 4 + .../lang/properties/PropertiesFileTest.java | 18 ++- ...opertyKeyValueDelimiterInspectionTest.java | 37 ++++++ 18 files changed, 455 insertions(+), 9 deletions(-) create mode 100644 platform/platform-resources-en/src/inspectionDescriptions/WrongPropertyKeyValueDelimiter.html create mode 100644 plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/codeStyle/PropertiesCodeStyleSettings.java create mode 100644 plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/codeStyle/PropertiesCodeStyleSettingsPanel.form create mode 100644 plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/codeStyle/PropertiesCodeStyleSettingsPanel.java create mode 100644 plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/codeStyle/PropertiesCodeStyleSettingsProvider.java create mode 100644 plugins/properties/properties-psi-impl/src/com/intellij/codeInspection/WrongPropertyKeyValueDelimiterInspection.java create mode 100644 plugins/properties/testData/wrongPropertyKeyDelimiter/expected.xml create mode 100644 plugins/properties/testData/wrongPropertyKeyDelimiter/src/Test1.properties create mode 100644 plugins/properties/testSrc/com/intellij/lang/properties/WrongPropertyKeyValueDelimiterInspectionTest.java diff --git a/platform/platform-resources-en/src/inspectionDescriptions/WrongPropertyKeyValueDelimiter.html b/platform/platform-resources-en/src/inspectionDescriptions/WrongPropertyKeyValueDelimiter.html new file mode 100644 index 000000000000..949a0108e642 --- /dev/null +++ b/platform/platform-resources-en/src/inspectionDescriptions/WrongPropertyKeyValueDelimiter.html @@ -0,0 +1,5 @@ + + +This inspection reports on properties in which key/value delimiter doesn't corresponds to code style settings. + + \ No newline at end of file diff --git a/plugins/properties/properties-psi-api/properties-psi-api.iml b/plugins/properties/properties-psi-api/properties-psi-api.iml index fa09be36a180..bfbb8149469f 100644 --- a/plugins/properties/properties-psi-api/properties-psi-api.iml +++ b/plugins/properties/properties-psi-api/properties-psi-api.iml @@ -15,6 +15,7 @@ + + - - + \ No newline at end of file diff --git a/plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties b/plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties index 1a58d5b832a4..19be683fa99a 100644 --- a/plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties +++ b/plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties @@ -66,3 +66,4 @@ dissociate.resource.bundle.quick.fix.name=Dissociate Resource Bundle dissociate.resource.bundle.quick.fix.options.label=Additional language codes\: dissociate.resource.bundle.quick.fix.options.input.text=Inter language code dissociate.resource.bundle.quick.fix.options.input.title=Additional Locale Languages +wrong.property.key.value.delimiter.inspection.display.name=Property key/value delimiter doesn't correspond to code style \ No newline at end of file diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/PropertiesElementFactory.java b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/PropertiesElementFactory.java index c114506ec4aa..ebafb102010d 100644 --- a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/PropertiesElementFactory.java +++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/PropertiesElementFactory.java @@ -18,12 +18,14 @@ package com.intellij.lang.properties.psi; import com.intellij.lang.properties.IProperty; import com.intellij.lang.properties.PropertiesFileType; +import com.intellij.lang.properties.psi.codeStyle.PropertiesCodeStyleSettings; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.UserDataCache; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiFileFactory; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -42,14 +44,20 @@ public class PropertiesElementFactory { @NotNull public static IProperty createProperty(@NotNull Project project, @NonNls @NotNull String name, @NonNls @NotNull String value) { - String text = getPropertyText(name, value); + String text = getPropertyText(name, value, null, project); final PropertiesFile dummyFile = createPropertiesFile(project, text); return dummyFile.getProperties().get(0); } @NotNull - public static String getPropertyText(@NonNls @NotNull String name, @NonNls @NotNull String value) { - return escape(name) + "=" + escapeValue(value); + public static String getPropertyText(@NonNls @NotNull String name, + @NonNls @NotNull String value, + @NonNls @Nullable Character delimiter, + @Nullable Project project) { + if (delimiter == null) { + delimiter = project == null ? PropertiesCodeStyleSettings.DEFAULT_KEY_VALUE_DELIMITER : PropertiesCodeStyleSettings.getInstance(project).KEY_VALUE_DELIMITER; + } + return escape(name) + String.valueOf(delimiter) + escapeValue(value); } @NotNull diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/codeStyle/PropertiesCodeStyleSettings.java b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/codeStyle/PropertiesCodeStyleSettings.java new file mode 100644 index 000000000000..1ba1422ff3a4 --- /dev/null +++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/codeStyle/PropertiesCodeStyleSettings.java @@ -0,0 +1,39 @@ +/* + * 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.lang.properties.psi.codeStyle; + +import com.intellij.lang.properties.PropertiesLanguage; +import com.intellij.openapi.project.Project; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.codeStyle.CustomCodeStyleSettings; + +/** + * @author Dmitry Batkovich + */ +public class PropertiesCodeStyleSettings extends CustomCodeStyleSettings { + public final static char DEFAULT_KEY_VALUE_DELIMITER = '='; + + public PropertiesCodeStyleSettings(CodeStyleSettings container) { + super(PropertiesLanguage.INSTANCE.getID(), container); + } + + public static PropertiesCodeStyleSettings getInstance(final Project project) { + return CodeStyleSettingsManager.getSettings(project).getCustomSettings(PropertiesCodeStyleSettings.class); + } + + public char KEY_VALUE_DELIMITER = DEFAULT_KEY_VALUE_DELIMITER; +} diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/codeStyle/PropertiesCodeStyleSettingsPanel.form b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/codeStyle/PropertiesCodeStyleSettingsPanel.form new file mode 100644 index 000000000000..1c2c50f97d1b --- /dev/null +++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/codeStyle/PropertiesCodeStyleSettingsPanel.form @@ -0,0 +1,37 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/codeStyle/PropertiesCodeStyleSettingsPanel.java b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/codeStyle/PropertiesCodeStyleSettingsPanel.java new file mode 100644 index 000000000000..6c9819b77695 --- /dev/null +++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/codeStyle/PropertiesCodeStyleSettingsPanel.java @@ -0,0 +1,111 @@ +/* + * 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.lang.properties.psi.codeStyle; + +import com.intellij.application.options.CodeStyleAbstractPanel; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.highlighter.EditorHighlighter; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.ui.ComboBox; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +/** + * @author Dmitry Batkovich + */ +public class PropertiesCodeStyleSettingsPanel extends CodeStyleAbstractPanel { + private final static String WHITESPACE_ELEMENT = "Whitespace symbol"; + + private ComboBox myDelimiterCombo; + private JPanel myPanel; + + public PropertiesCodeStyleSettingsPanel(CodeStyleSettings settings) { + super(settings); + final DefaultComboBoxModel model = new DefaultComboBoxModel(); + model.addElement(':'); + model.addElement('='); + model.addElement(WHITESPACE_ELEMENT); + myDelimiterCombo.setModel(model); + selectChar(settings.getCustomSettings(PropertiesCodeStyleSettings.class)); + } + + private void selectChar(PropertiesCodeStyleSettings settings) { + myDelimiterCombo.setSelectedItem(settings.KEY_VALUE_DELIMITER == ' ' ? WHITESPACE_ELEMENT : settings.KEY_VALUE_DELIMITER); + } + + private char getSelectedChar() { + final Object item = myDelimiterCombo.getModel().getSelectedItem(); + if (item instanceof Character) { + return (Character)item; + } + assert item == WHITESPACE_ELEMENT; + return ' '; + } + + private void createUIComponents() { + } + + @Override + protected int getRightMargin() { + return 0; + } + + @Nullable + @Override + protected EditorHighlighter createHighlighter(EditorColorsScheme scheme) { + return null; + } + + @NotNull + @Override + protected FileType getFileType() { + return StdFileTypes.PROPERTIES; + } + + @Nullable + @Override + protected String getPreviewText() { + return null; + } + + @Override + public void apply(CodeStyleSettings settings) throws ConfigurationException { + final PropertiesCodeStyleSettings propertiesCodeStyleSettings = settings.getCustomSettings(PropertiesCodeStyleSettings.class); + propertiesCodeStyleSettings.KEY_VALUE_DELIMITER = getSelectedChar(); + } + + @Override + public boolean isModified(CodeStyleSettings settings) { + final PropertiesCodeStyleSettings propertiesCodeStyleSettings = settings.getCustomSettings(PropertiesCodeStyleSettings.class); + return propertiesCodeStyleSettings.KEY_VALUE_DELIMITER != getSelectedChar(); + } + + @Nullable + @Override + public JComponent getPanel() { + return myPanel; + } + + @Override + protected void resetImpl(CodeStyleSettings settings) { + selectChar(settings.getCustomSettings(PropertiesCodeStyleSettings.class)); + } +} diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/codeStyle/PropertiesCodeStyleSettingsProvider.java b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/codeStyle/PropertiesCodeStyleSettingsProvider.java new file mode 100644 index 000000000000..7746d66f670d --- /dev/null +++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/codeStyle/PropertiesCodeStyleSettingsProvider.java @@ -0,0 +1,60 @@ +/* + * 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.lang.properties.psi.codeStyle; + +import com.intellij.application.options.CodeStyleAbstractConfigurable; +import com.intellij.application.options.CodeStyleAbstractPanel; +import com.intellij.lang.properties.PropertiesLanguage; +import com.intellij.openapi.options.Configurable; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsProvider; +import com.intellij.psi.codeStyle.CustomCodeStyleSettings; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Dmitry Batkovich + */ +public class PropertiesCodeStyleSettingsProvider extends CodeStyleSettingsProvider { + @NotNull + @Override + public Configurable createSettingsPage(CodeStyleSettings settings, CodeStyleSettings originalSettings) { + return new CodeStyleAbstractConfigurable(settings, originalSettings, "Properties Files") { + @Nullable + @Override + public String getHelpTopic() { + return "reference.settingsdialog.codestyle.properties"; + } + + @Override + protected CodeStyleAbstractPanel createPanel(CodeStyleSettings settings) { + return new PropertiesCodeStyleSettingsPanel(settings); + } + }; + } + + @Nullable + @Override + public CustomCodeStyleSettings createCustomSettings(CodeStyleSettings settings) { + return new PropertiesCodeStyleSettings(settings); + } + + @Nullable + @Override + public String getConfigurableDisplayName() { + return PropertiesLanguage.INSTANCE.getDisplayName(); + } +} \ No newline at end of file diff --git a/plugins/properties/properties-psi-impl/properties-psi-impl.iml b/plugins/properties/properties-psi-impl/properties-psi-impl.iml index d297116cb114..e40048fbfeb1 100644 --- a/plugins/properties/properties-psi-impl/properties-psi-impl.iml +++ b/plugins/properties/properties-psi-impl/properties-psi-impl.iml @@ -16,6 +16,7 @@ + diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/codeInspection/WrongPropertyKeyValueDelimiterInspection.java b/plugins/properties/properties-psi-impl/src/com/intellij/codeInspection/WrongPropertyKeyValueDelimiterInspection.java new file mode 100644 index 000000000000..b8ead119072f --- /dev/null +++ b/plugins/properties/properties-psi-impl/src/com/intellij/codeInspection/WrongPropertyKeyValueDelimiterInspection.java @@ -0,0 +1,78 @@ +/* + * 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.codeInspection; + +import com.intellij.codeInsight.intention.HighPriorityAction; +import com.intellij.lang.properties.PropertiesBundle; +import com.intellij.lang.properties.PropertySuppressableInspectionBase; +import com.intellij.lang.properties.psi.codeStyle.PropertiesCodeStyleSettings; +import com.intellij.lang.properties.psi.impl.PropertiesFileImpl; +import com.intellij.lang.properties.psi.impl.PropertyImpl; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; + +/** + * @author Dmitry Batkovich + */ +public class WrongPropertyKeyValueDelimiterInspection extends PropertySuppressableInspectionBase { + + @NotNull + @Override + public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { + if (!(holder.getFile() instanceof PropertiesFileImpl)) { + return PsiElementVisitor.EMPTY_VISITOR; + } + final PropertiesCodeStyleSettings codeStyleSettings = PropertiesCodeStyleSettings.getInstance(holder.getProject()); + final char codeStyleKeyValueDelimiter = codeStyleSettings.KEY_VALUE_DELIMITER; + return new PsiElementVisitor() { + @Override + public void visitElement(PsiElement element) { + if (element instanceof PropertyImpl) { + final Character delimiter = ((PropertyImpl)element).getKeyValueDelimiter(); + if (delimiter != null && !delimiter.equals(codeStyleKeyValueDelimiter)) { + holder.registerProblem(element, PropertiesBundle.message("wrong.property.key.value.delimiter.inspection.display.name"), new ReplaceKeyValueDelimiterQuickFix(element)); + } + } + } + }; + } + + private static final class ReplaceKeyValueDelimiterQuickFix extends LocalQuickFixOnPsiElement implements HighPriorityAction { + public ReplaceKeyValueDelimiterQuickFix(@NotNull PsiElement element) { + super(element); + } + + @NotNull + @Override + public String getText() { + return getFamilyName(); + } + + @Override + public void invoke(@NotNull Project project, @NotNull PsiFile file, @NotNull PsiElement element, @NotNull PsiElement endElement) { + ((PropertyImpl) element).replaceKeyValueDelimiterWithDefault(); + } + + @NotNull + @Override + public String getFamilyName() { + return "Replace Property Key/Value Delimiter According Code Style"; + } + } +} diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/codeInspection/unsorted/AlphaUnsortedPropertiesFileInspection.java b/plugins/properties/properties-psi-impl/src/com/intellij/codeInspection/unsorted/AlphaUnsortedPropertiesFileInspection.java index 60ad79f7e1b3..28d36a0af23e 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/codeInspection/unsorted/AlphaUnsortedPropertiesFileInspection.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/codeInspection/unsorted/AlphaUnsortedPropertiesFileInspection.java @@ -22,6 +22,7 @@ import com.intellij.lang.properties.ResourceBundle; import com.intellij.lang.properties.psi.PropertiesElementFactory; import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.lang.properties.psi.PropertiesList; +import com.intellij.lang.properties.psi.codeStyle.PropertiesCodeStyleSettings; import com.intellij.lang.properties.psi.impl.PropertiesFileImpl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -127,12 +128,12 @@ public class AlphaUnsortedPropertiesFileInspection extends LocalInspectionTool { return Comparing.compare(p1.getKey(), p2.getKey()); } }); - + final char delimiter = PropertiesCodeStyleSettings.getInstance(file.getProject()).KEY_VALUE_DELIMITER; final StringBuilder rawText = new StringBuilder(); for (int i = 0; i < properties.size(); i++) { IProperty property = properties.get(i); final String value = property.getValue(); - rawText.append(PropertiesElementFactory.getPropertyText(property.getName(), value != null ? value : "")); + rawText.append(PropertiesElementFactory.getPropertyText(property.getName(), value != null ? value : "", delimiter, null)); if (i != properties.size() - 1) { rawText.append("\n"); } diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java index 7c77848a47ba..b839ff919e15 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java @@ -99,6 +99,16 @@ public class PropertiesFileImpl extends PsiFileBase implements PropertiesFile { } } + public Character findFirstKeyValueDelimiter() { + for (IProperty property : myProperties) { + final Character separator = ((PropertyImpl)property).getKeyValueDelimiter(); + if (separator != null) { + return separator; + } + } + return null; + } + @Override public IProperty findPropertyByKey(@NotNull String key) { ensurePropertiesLoaded(); diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java index 0d34b1e74126..2bce158b7069 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java @@ -441,4 +441,24 @@ public class PropertyImpl extends PropertiesStubElementImpl implem public LiteralTextEscaper createLiteralTextEscaper() { return new PropertyImplEscaper(this); } + + @Nullable + public Character getKeyValueDelimiter() { + final PsiElement delimiter = findChildByType(PropertiesTokenTypes.KEY_VALUE_SEPARATOR); + if (delimiter == null) { + return null; + } + final String separatorText = delimiter.getText(); + LOG.assertTrue(separatorText.length() == 1); + return separatorText.charAt(0); + } + + public void replaceKeyValueDelimiterWithDefault() { + PropertyImpl property = (PropertyImpl)PropertiesElementFactory.createProperty(getProject(), "yyy", "xxx"); + final ASTNode oldDelimiter = getNode().findChildByType(PropertiesTokenTypes.KEY_VALUE_SEPARATOR); + LOG.assertTrue(oldDelimiter != null); + final ASTNode newDelimiter = property.getNode().findChildByType(PropertiesTokenTypes.KEY_VALUE_SEPARATOR); + LOG.assertTrue(newDelimiter != null); + getNode().replaceChild(oldDelimiter, newDelimiter); + } } diff --git a/plugins/properties/src/META-INF/plugin.xml b/plugins/properties/src/META-INF/plugin.xml index d928df37ea79..dbe1091741a4 100644 --- a/plugins/properties/src/META-INF/plugin.xml +++ b/plugins/properties/src/META-INF/plugin.xml @@ -81,6 +81,10 @@ key="alpha.unsorted.properties.file.inspection.display.name" groupKey="properties.files.inspection.group.display.name" enabledByDefault="false" level="INFO" implementationClass="com.intellij.codeInspection.unsorted.AlphaUnsortedPropertiesFileInspection"/> + @@ -99,6 +103,8 @@ + + diff --git a/plugins/properties/testData/wrongPropertyKeyDelimiter/expected.xml b/plugins/properties/testData/wrongPropertyKeyDelimiter/expected.xml new file mode 100644 index 000000000000..245d7fe84930 --- /dev/null +++ b/plugins/properties/testData/wrongPropertyKeyDelimiter/expected.xml @@ -0,0 +1,13 @@ + + + + Test1.properties + 2 + Property key/value delimiter doesn't correspond to code style + + + Test1.properties + 3 + Property key/value delimiter doesn't correspond to code style + + \ No newline at end of file diff --git a/plugins/properties/testData/wrongPropertyKeyDelimiter/src/Test1.properties b/plugins/properties/testData/wrongPropertyKeyDelimiter/src/Test1.properties new file mode 100644 index 000000000000..3759b7d43ff9 --- /dev/null +++ b/plugins/properties/testData/wrongPropertyKeyDelimiter/src/Test1.properties @@ -0,0 +1,4 @@ +a=1 +c:123 +z 123123 +zxc=zxc \ No newline at end of file diff --git a/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesFileTest.java b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesFileTest.java index b0d0c5e162f2..ee61d7ba27f0 100644 --- a/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesFileTest.java +++ b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesFileTest.java @@ -18,6 +18,8 @@ package com.intellij.lang.properties; import com.intellij.lang.properties.psi.PropertiesElementFactory; import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.lang.properties.psi.Property; +import com.intellij.lang.properties.psi.codeStyle.PropertiesCodeStyleSettings; +import com.intellij.lang.properties.psi.impl.PropertyImpl; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.testFramework.LightPlatformTestCase; @@ -97,8 +99,9 @@ public class PropertiesFileTest extends LightPlatformCodeInsightFixtureTestCase PropertiesFile propertiesFile = PropertiesElementFactory.createPropertiesFile(getProject(), "xxx=yyy\nxxx2=tyrt\nxxx3=ttt\n\n"); final Property property = (Property)propertiesFile.findPropertyByKey("xxx2"); - WriteCommandAction.runWriteCommandAction(null, new Runnable(){public void run() { - property.delete(); + WriteCommandAction.runWriteCommandAction(null, new Runnable() { + public void run() { + property.delete(); } }); @@ -177,4 +180,15 @@ public class PropertiesFileTest extends LightPlatformCodeInsightFixtureTestCase assertEquals(" e=f", properties.get(2).getUnescapedKey()); assertEquals("\u1234\\uxyzt", properties.get(3).getUnescapedKey()); } + + public void testNonDefaultKeyValueDelimiter() { + final PropertiesCodeStyleSettings codeStyleSettings = PropertiesCodeStyleSettings.getInstance(getProject()); + codeStyleSettings.KEY_VALUE_DELIMITER = ':'; + final PropertyImpl property = (PropertyImpl)PropertiesElementFactory.createProperty(getProject(), "xxx", "yyy"); + final Character delimiter = property.getKeyValueDelimiter(); + assertNotNull(delimiter); + assertEquals(':', (char)delimiter); + assertEquals("xxx:yyy", property.getPsiElement().getText()); + codeStyleSettings.KEY_VALUE_DELIMITER = PropertiesCodeStyleSettings.DEFAULT_KEY_VALUE_DELIMITER; + } } diff --git a/plugins/properties/testSrc/com/intellij/lang/properties/WrongPropertyKeyValueDelimiterInspectionTest.java b/plugins/properties/testSrc/com/intellij/lang/properties/WrongPropertyKeyValueDelimiterInspectionTest.java new file mode 100644 index 000000000000..afb0a79343fd --- /dev/null +++ b/plugins/properties/testSrc/com/intellij/lang/properties/WrongPropertyKeyValueDelimiterInspectionTest.java @@ -0,0 +1,37 @@ +/* + * 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.lang.properties; + +import com.intellij.codeInspection.WrongPropertyKeyValueDelimiterInspection; +import com.intellij.openapi.application.PluginPathManager; +import com.intellij.testFramework.InspectionTestCase; +import org.jetbrains.annotations.NotNull; + +/** + * @author Dmitry Batkovich + */ +public class WrongPropertyKeyValueDelimiterInspectionTest extends InspectionTestCase { + + @NotNull + @Override + protected String getTestDataPath() { + return PluginPathManager.getPluginHomePath("properties") + "/testData"; + } + + public void testSimple() throws Exception { + doTest("wrongPropertyKeyDelimiter/", new WrongPropertyKeyValueDelimiterInspection()); + } +}