diff --git a/build/scripts/libLicenses.gant b/build/scripts/libLicenses.gant index f7c62a02dc4d..333c8135687b 100644 --- a/build/scripts/libLicenses.gant +++ b/build/scripts/libLicenses.gant @@ -278,6 +278,7 @@ libraryLicense(name: "json-smart", libraryName: "json-smart-1.1.1.jar", version: libraryLicense(name: "fxg-utils", libraryName: "fxg-utils", version: "4.9.1", license: "Apache 2.0", url: "http://flex.apache.org", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0") libraryLicense(name: "jayatana", libraryName: "jayatana", version: "1.2.4", license: "MIT License", url: "https://code.google.com/p/java-swing-ayatana/", licenseUrl: "http://opensource.org/licenses/mit-license.php") libraryLicense(name: "ForkJoin", version: "", license: "Creative Commons Public Domain Dedication", url: "http://gee.cs.oswego.edu/dl/concurrency-interest/index.html", licenseUrl: "http://creativecommons.org/publicdomain/zero/1.0/") +libraryLicense(name: "ANTLR 4 Runtime", libraryName: "antlr-runtime-4.1.jar", version: "4.1", license: "BSD", url: "http://www.antlr.org", licenseUrl: "http://www.antlr.org/license.html") libraryLicense(name: "minlog", libraryName: "minlog-1.2.jar", version: "1.2", license: "BSD", url: "https://github.com/EsotericSoftware/minlog", licenseUrl: "http://opensource.org/licenses/BSD-3-Clause") libraryLicense(name: "ReflectASM", libraryName: "reflectasm-1.0.7.jar", version: "1.0.7", license: "BSD", url: "https://github.com/EsotericSoftware/reflectasm", licenseUrl: "http://opensource.org/licenses/BSD-3-Clause") libraryLicense(name: "Objenesis", libraryName: "objenesis-1.2.jar", version: "1.2", license: "Apache 2.0", url: "http://objenesis.org/", licenseUrl: "http://apache.org/licenses/LICENSE-2.0") diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java index 51ab95efc0da..48ddfdcaa851 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java @@ -132,7 +132,7 @@ class JavaClassNameInsertHandler implements InsertHandler} + */ + Super aSuper = new Super(); + + } +} +''' + myFixture.configureByText "a.java", text + myFixture.completeBasic() + myFixture.type('\t') + myFixture.checkResult ''' +public class Test { + + public static void main(String[] args) { + class Super { + } + + /** + * {@link Super} + */ + Super aSuper = new Super(); + + } +} +''' + + } public void testShortNameIfImplicitlyImported() { javaSettings.CLASS_NAMES_IN_JAVADOC = JavaCodeStyleSettings.FULLY_QUALIFY_NAMES_IF_NOT_IMPORTED diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/EditorNotificationInfo.java b/platform/lang-api/src/com/intellij/psi/codeStyle/EditorNotificationInfo.java index 59315c245631..8455382bf1e6 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/EditorNotificationInfo.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/EditorNotificationInfo.java @@ -15,53 +15,33 @@ */ package com.intellij.psi.codeStyle; -import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; -import java.util.Collections; +import javax.swing.Icon; import java.util.List; -public class EditorNotificationInfo { - - private String myTitle; - private Icon myIcon; - private List myLabelsWithActions = ContainerUtil.newArrayList(); - - public EditorNotificationInfo(@NotNull String title, - @NotNull LabelWithAction firstLabel, - @Nullable LabelWithAction... otherLabels) - { - myTitle = title; - myLabelsWithActions.add(firstLabel); - if (otherLabels != null) { - Collections.addAll(myLabelsWithActions, otherLabels); - } - } - - public EditorNotificationInfo(@NotNull String title, - @NotNull Icon icon, - @NotNull LabelWithAction firstLabel, - @Nullable LabelWithAction... otherLabels) - { - this(title, firstLabel, otherLabels); - myIcon = icon; - } +public abstract class EditorNotificationInfo { @NotNull - public List getLabelAndActions() { - return myLabelsWithActions; - } + public abstract List getLabelAndActions(); + + @NotNull + public abstract String getTitle(); @Nullable public Icon getIcon() { - return myIcon; + return null; } - @NotNull - public String getTitle() { - return myTitle; + public static class ActionLabelData { + public final String label; + public final Runnable action; + + public ActionLabelData(@NotNull String label, @NotNull Runnable action) { + this.label = label; + this.action = action; + } } } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/LabelWithAction.java b/platform/lang-api/src/com/intellij/psi/codeStyle/LabelWithAction.java deleted file mode 100644 index b39afc320102..000000000000 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/LabelWithAction.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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; - -import org.jetbrains.annotations.NotNull; - -public class LabelWithAction { - - public final String label; - public final Runnable action; - - public LabelWithAction(@NotNull String label, @NotNull Runnable action) { - this.label = label; - this.action = action; - } -} diff --git a/platform/lang-impl/src/com/intellij/internal/statistic/editor/EditorSettingsStatisticsCollector.java b/platform/lang-impl/src/com/intellij/internal/statistic/editor/EditorSettingsStatisticsCollector.java new file mode 100644 index 000000000000..f2591af1689f --- /dev/null +++ b/platform/lang-impl/src/com/intellij/internal/statistic/editor/EditorSettingsStatisticsCollector.java @@ -0,0 +1,122 @@ +/* + * 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.internal.statistic.editor; + +import com.intellij.codeInsight.CodeInsightSettings; +import com.intellij.codeInsight.editorActions.SmartBackspaceMode; +import com.intellij.internal.statistic.CollectUsagesException; +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; +import com.intellij.openapi.editor.impl.softwrap.SoftWrapAppliancePlaces; +import com.intellij.openapi.editor.richcopy.settings.RichCopySettings; +import com.intellij.openapi.util.Comparing; +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.Set; + +class EditorSettingsStatisticsCollector extends UsagesCollector { + @NotNull + @Override + public GroupDescriptor getGroupId() { + return GroupDescriptor.create("Editor"); + } + + @NotNull + @Override + public Set getUsages() throws CollectUsagesException { + Set set = new HashSet(); + + EditorSettingsExternalizable es = EditorSettingsExternalizable.getInstance(); + addIfDiffers(set, es.isVirtualSpace(), false, "caretAfterLineEnd"); + addIfDiffers(set, es.isCaretInsideTabs(), false, "caretInsideTabs"); + addIfDiffers(set, es.isAdditionalPageAtBottom(), false, "virtualSpaceAtFileBottom"); + addIfDiffers(set, es.isUseSoftWraps(SoftWrapAppliancePlaces.MAIN_EDITOR), false, "softWraps"); + addIfDiffers(set, es.isUseSoftWraps(SoftWrapAppliancePlaces.CONSOLE), false, "softWraps.console"); + addIfDiffers(set, es.isUseCustomSoftWrapIndent(), false, "softWraps.relativeIndent"); + addIfDiffers(set, es.isAllSoftWrapsShown(), false, "softWraps.showAll"); + addIfDiffers(set, es.getStripTrailingSpaces(), EditorSettingsExternalizable.STRIP_TRAILING_SPACES_CHANGED, "stripTrailingSpaces"); + addIfDiffers(set, es.isEnsureNewLineAtEOF(), false, "ensureNewlineAtEOF"); + addIfDiffers(set, es.isShowQuickDocOnMouseOverElement(), false, "quickDocOnMouseHover"); + addIfDiffers(set, es.isBlinkCaret(), true, "nonBlinkingCaret"); + addIfDiffers(set, es.isBlockCursor(), false, "blockCaret"); + addIfDiffers(set, es.isRightMarginShown(), true, "noRightMargin"); + addIfDiffers(set, es.isLineNumbersShown(), false, "lineNumbers"); + addIfDiffers(set, es.isFoldingOutlineShown(), true, "noFoldingOutline"); + addIfDiffers(set, es.isWhitespacesShown() && es.isLeadingWhitespacesShown(), false, "showLeadingWhitespace"); + addIfDiffers(set, es.isWhitespacesShown() && es.isInnerWhitespacesShown(), false, "showInnerWhitespace"); + addIfDiffers(set, es.isWhitespacesShown() && es.isTrailingWhitespacesShown(), false, "showTrailingWhitespace"); + addIfDiffers(set, es.isIndentGuidesShown(), true, "noIndentGuides"); + addIfDiffers(set, es.isSmoothScrolling(), true, "noAnimatedScroll"); + addIfDiffers(set, es.isDndEnabled(), false, "dragNDrop"); + addIfDiffers(set, es.isWheelFontChangeEnabled(), false, "wheelZoom"); + addIfDiffers(set, es.isMouseClickSelectionHonorsCamelWords(), true, "mouseNoCamel"); + addIfDiffers(set, es.isVariableInplaceRenameEnabled(), true, "noInplaceRename"); + addIfDiffers(set, es.isPreselectRename(), true, "noPreselectOnRename"); + addIfDiffers(set, es.isShowInlineLocalDialog(), true, "noInlineDialog"); + addIfDiffers(set, es.isRefrainFromScrolling(), false, "minimizeScrolling"); + addIfDiffers(set, es.getOptions().SHOW_REFORMAT_DIALOG, true, "noReformatDialog"); + addIfDiffers(set, es.getOptions().SHOW_OPIMIZE_IMPORTS_DIALOG, true, "noOptimizeImportsDialog"); + addIfDiffers(set, es.isSmartHome(), true, "noSmartHome"); + addIfDiffers(set, es.isCamelWords(), false, "camelWords"); + + RichCopySettings rcs = RichCopySettings.getInstance(); + addIfDiffers(set, rcs.isEnabled(), true, "noRichCopy"); + + CodeInsightSettings cis = CodeInsightSettings.getInstance(); + addIfDiffers(set, cis.AUTO_POPUP_PARAMETER_INFO, true, "noParameterAutoPopup"); + addIfDiffers(set, cis.AUTO_POPUP_JAVADOC_INFO, false, "javadocAutoPopup"); + addIfDiffers(set, cis.AUTO_POPUP_COMPLETION_LOOKUP, true, "noCompletionAutoPopup"); + addIfDiffers(set, cis.COMPLETION_CASE_SENSITIVE, CodeInsightSettings.FIRST_LETTER, "completionCaseSensitivity"); + addIfDiffers(set, cis.SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS, false, "autoPopupCharComplete"); + addIfDiffers(set, cis.AUTOCOMPLETE_ON_CODE_COMPLETION, true, "noAutoCompleteBasic"); + addIfDiffers(set, cis.AUTOCOMPLETE_ON_SMART_TYPE_COMPLETION, true, "noAutoCompleteSmart"); + addIfDiffers(set, cis.SHOW_FULL_SIGNATURES_IN_PARAMETER_INFO, false, "parameterInfoFullSignature"); + addIfDiffers(set, cis.getBackspaceMode(), SmartBackspaceMode.AUTOINDENT, "smartBackspace"); + addIfDiffers(set, cis.SMART_INDENT_ON_ENTER, true, "noIndentOnEnter"); + addIfDiffers(set, cis.INSERT_BRACE_ON_ENTER, true, "noBraceOnEnter"); + addIfDiffers(set, cis.JAVADOC_STUB_ON_ENTER, true, "noJavadocOnEnter"); + addIfDiffers(set, cis.SMART_END_ACTION, true, "noSmartEnd"); + addIfDiffers(set, cis.JAVADOC_GENERATE_CLOSING_TAG, true, "noAutoCloseJavadocTags"); + addIfDiffers(set, cis.SURROUND_SELECTION_ON_QUOTE_TYPED, false, "surroundByQuoteOrBrace"); + addIfDiffers(set, cis.AUTOINSERT_PAIR_BRACKET, true, "noPairBracketAutoInsert"); + addIfDiffers(set, cis.AUTOINSERT_PAIR_QUOTE, true, "noPairQuoteAutoInsert"); + addIfDiffers(set, cis.REFORMAT_BLOCK_ON_RBRACE, true, "noReformatOnRBrace"); + addIfDiffers(set, cis.REFORMAT_ON_PASTE, CodeInsightSettings.INDENT_EACH_LINE, "reformatOnPaste"); + addIfDiffers(set, cis.ADD_IMPORTS_ON_PASTE, CodeInsightSettings.ASK, "importsOnPaste"); + addIfDiffers(set, cis.HIGHLIGHT_BRACES, true, "noBracesHighlight"); + addIfDiffers(set, cis.HIGHLIGHT_SCOPE, false, "scopeHighlight"); + addIfDiffers(set, cis.HIGHLIGHT_IDENTIFIER_UNDER_CARET, true, "noIdentifierUnderCaretHighlight"); + addIfDiffers(set, cis.OPTIMIZE_IMPORTS_ON_THE_FLY, false, "autoOptimizeImports"); + addIfDiffers(set, cis.ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY, false, "autoAddImports"); + + return set; + } + + private static void addIfDiffers(Set set, boolean value, boolean defaultValue, String featureId) { + if (value != defaultValue) { + set.add(new UsageDescriptor(featureId, 1)); + } + } + + private static void addIfDiffers(Set set, Object value, Object defaultValue, String featureIdPrefix) { + if (!Comparing.equal(value, defaultValue)) { + set.add(new UsageDescriptor(featureIdPrefix + "." + value, 1)); + } + } +} diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/DetectableIndentOptionsProvider.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/DetectableIndentOptionsProvider.java index 1687817f5a22..7dc8bdbd2dd3 100644 --- a/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/DetectableIndentOptionsProvider.java +++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/DetectableIndentOptionsProvider.java @@ -27,7 +27,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.*; import com.intellij.testFramework.LightVirtualFile; -import com.intellij.ui.EditorNotifications; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.WeakList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,6 +35,8 @@ import org.jetbrains.annotations.TestOnly; import java.util.List; +import static com.intellij.psi.codeStyle.EditorNotificationInfo.*; + /** * @author Rustam Vishnyakov */ @@ -82,22 +84,21 @@ public class DetectableIndentOptionsProvider extends FileIndentOptionsProvider { @NotNull CommonCodeStyleSettings.IndentOptions userOptions, @NotNull CommonCodeStyleSettings.IndentOptions detectedOptions) { - NotificationLabels labels = getNotificationLabels(userOptions, detectedOptions); + final NotificationLabels labels = getNotificationLabels(userOptions, detectedOptions); final Editor editor = fileEditor instanceof TextEditor ? ((TextEditor)fileEditor).getEditor() : null; if (labels == null || editor == null) return null; - LabelWithAction okAction = new LabelWithAction( + ActionLabelData okAction = new ActionLabelData( ApplicationBundle.message("code.style.indents.detector.accept"), new Runnable() { @Override public void run() { setAccepted(file); - EditorNotifications.getInstance(project).updateAllNotifications(); } } ); - LabelWithAction disableForSingleFile = new LabelWithAction( + ActionLabelData disableForSingleFile = new ActionLabelData( labels.revertToOldSettingsLabel, new Runnable() { @Override @@ -106,24 +107,35 @@ public class DetectableIndentOptionsProvider extends FileIndentOptionsProvider { if (editor instanceof EditorEx) { ((EditorEx)editor).reinitSettings(); } - EditorNotifications.getInstance(project).updateAllNotifications(); } } ); - LabelWithAction showSettings = new LabelWithAction( + ActionLabelData showSettings = new ActionLabelData( ApplicationBundle.message("code.style.indents.detector.show.settings"), new Runnable() { @Override public void run() { ShowSettingsUtilImpl.showSettingsDialog(project, "preferences.sourceCode", ApplicationBundle.message("settings.code.style.general.autodetect.indents")); - EditorNotifications.getInstance(project).updateAllNotifications(); } } ); - return new EditorNotificationInfo(labels.title, okAction, disableForSingleFile, showSettings); + final List actions = ContainerUtil.newArrayList(okAction, disableForSingleFile, showSettings); + return new EditorNotificationInfo() { + @NotNull + @Override + public List getLabelAndActions() { + return actions; + } + + @NotNull + @Override + public String getTitle() { + return labels.title; + } + }; } @Nullable diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/DetectedIndentOptionsNotificationProvider.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/DetectedIndentOptionsNotificationProvider.java index b0be0cee284f..078d8f5eff0f 100644 --- a/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/DetectedIndentOptionsNotificationProvider.java +++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/DetectedIndentOptionsNotificationProvider.java @@ -32,6 +32,8 @@ import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static com.intellij.psi.codeStyle.EditorNotificationInfo.*; + /** * @author Rustam Vishnyakov */ @@ -77,8 +79,15 @@ public class DetectedIndentOptionsNotificationProvider extends EditorNotificatio if (info.getIcon() != null) { panel.icon(info.getIcon()); } - for (LabelWithAction action : info.getLabelAndActions()) { - panel.createActionLabel(action.label, action.action); + for (final ActionLabelData actionLabelData : info.getLabelAndActions()) { + Runnable onClickAction = new Runnable() { + @Override + public void run() { + actionLabelData.action.run(); + EditorNotifications.getInstance(project).updateAllNotifications(); + } + }; + panel.createActionLabel(actionLabelData.label, onClickAction); } return panel; } diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 65f8821d530a..091211c6d028 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -813,6 +813,7 @@ + diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java index 6758d5e9b356..43f159e5b6db 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * 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. @@ -127,8 +127,8 @@ public class DebuggerUIUtil { JComponent component, @Nullable final FullValueEvaluationCallbackImpl callback) { ComponentPopupBuilder builder = JBPopupFactory.getInstance().createComponentPopupBuilder(component, null); - builder.setResizable(true).setAlpha(1) - .setMovable(true) + builder.setResizable(true)/*.setAlpha(1)*/ // alpha disabled because of IDEA-136331 + .setMovable(true) .setDimensionServiceKey(project, FULL_VALUE_POPUP_DIMENSION_KEY, false) .setRequestFocus(false); if (callback != null) { diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/PropertiesFile.java b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/PropertiesFile.java index 2b9a3743631e..b269e1a6fdb4 100644 --- a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/PropertiesFile.java +++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/psi/PropertiesFile.java @@ -89,18 +89,9 @@ public interface PropertiesFile { */ @NotNull PsiElement addPropertyAfter(@NotNull Property property, @Nullable Property anchor) throws IncorrectOperationException; - /** - * delegates call to {@link PropertiesFile#addPropertyLast()} method - */ - @Deprecated IProperty addProperty(String key, String value); - IProperty addPropertyFirst(String key, String value); - - IProperty addPropertyLast(String key, String value); - IProperty addPropertyAfter(String key, String value, Property anchor); - /** * @return Property key to the property value map. * Do not modify this map. It's no use anyway. @@ -116,4 +107,6 @@ public interface PropertiesFile { Project getProject(); String getText(); + + boolean isAlphaSorted(); } 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 360d9ce86dda..60ad79f7e1b3 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 @@ -17,7 +17,6 @@ package com.intellij.codeInspection.unsorted; import com.intellij.codeInspection.*; import com.intellij.lang.properties.IProperty; -import com.intellij.lang.properties.PropertiesBundle; import com.intellij.lang.properties.PropertiesImplUtil; import com.intellij.lang.properties.ResourceBundle; import com.intellij.lang.properties.psi.PropertiesElementFactory; @@ -30,11 +29,8 @@ import com.intellij.openapi.util.Comparing; import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.NullableFunction; -import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collections; @@ -68,7 +64,7 @@ public class AlphaUnsortedPropertiesFileInspection extends LocalInspectionTool { holder.registerProblem(file, String.format(MESSAGE_TEMPLATE_WHOLE_RESOURCE_BUNDLE, resourceBundleBaseName), ProblemHighlightType.INFO, new PropertiesSorterQuickFix(true, propertiesFile)); return; } - if (!isAlphaSorted(propertiesFile)) { + if (!propertiesFile.isAlphaSorted()) { holder.registerProblem(file, "Properties file is unsorted", ProblemHighlightType.INFO, new PropertiesSorterQuickFix(true, propertiesFile)); } } @@ -81,32 +77,9 @@ public class AlphaUnsortedPropertiesFileInspection extends LocalInspectionTool { if (!(file instanceof PropertiesFileImpl)) { return true; } - if (!file.equals(exceptedFile)) { - if (!isAlphaSorted(file)) { - return false; - } - } - } - return true; - } - - private static boolean isAlphaSorted(final @NotNull PropertiesFile propertiesFile) { - return isAlphaSorted(ContainerUtil.mapNotNull(propertiesFile.getProperties(), new NullableFunction() { - @Nullable - @Override - public String fun(IProperty property) { - return property.getKey(); - } - })); - } - - private static boolean isAlphaSorted(final List keys) { - String prevKey = null; - for (String key : keys) { - if (prevKey != null && prevKey.compareTo(key) > 0) { + if (!file.equals(exceptedFile) && !file.isAlphaSorted()) { return false; } - prevKey = key; } return true; } @@ -137,7 +110,7 @@ public class AlphaUnsortedPropertiesFileInspection extends LocalInspectionTool { public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final boolean force = myFilesToSort.length == 1; for (PropertiesFile file : myFilesToSort) { - if (!force && isAlphaSorted(file)) { + if (!force && file.isAlphaSorted()) { continue; } sortPropertiesFile(file); diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java index 47569143b922..00feb42ba56e 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java @@ -33,10 +33,7 @@ import com.intellij.util.indexing.FileBasedIndex; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; /** * @author Konstantin Bulenkov @@ -162,4 +159,19 @@ public class PropertiesImplUtil extends PropertiesUtil { } return getResourceBundle(baseName, baseDirectory); } + + public static boolean isAlphaSorted(final Collection properties) { + String previousKey = null; + for (IProperty property : properties) { + final String key = property.getKey(); + if (key == null) { + return false; + } + if (previousKey != null && previousKey.compareTo(key) > 0) { + return false; + } + previousKey = key; + } + return true; + } } \ No newline at end of file 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 9d04b993b6ca..7c77848a47ba 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 @@ -25,6 +25,7 @@ import com.intellij.lang.properties.parsing.PropertiesElementTypes; import com.intellij.lang.properties.psi.PropertiesElementFactory; import com.intellij.lang.properties.psi.PropertiesFile; import com.intellij.lang.properties.psi.Property; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileType; import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiElement; @@ -44,9 +45,11 @@ import org.jetbrains.annotations.Nullable; import java.util.*; public class PropertiesFileImpl extends PsiFileBase implements PropertiesFile { + private static final Logger LOG = Logger.getInstance(PropertiesFileImpl.class); private static final TokenSet PROPERTIES_LIST_SET = TokenSet.create(PropertiesElementTypes.PROPERTIES_LIST); private volatile MostlySingularMultiMap myPropertiesMap; //guarded by lock private volatile List myProperties; //guarded by lock + private volatile boolean myAlphaSorted; private final Object lock = new Object(); public PropertiesFileImpl(FileViewProvider viewProvider) { @@ -87,10 +90,12 @@ public class PropertiesFileImpl extends PsiFileBase implements PropertiesFile { propertiesMap.add(key, property); properties.add(property); } + final boolean isAlphaSorted = PropertiesImplUtil.isAlphaSorted(properties); synchronized (lock) { if (myPropertiesMap != null) return; myProperties = properties; myPropertiesMap = propertiesMap; + myAlphaSorted = isAlphaSorted; } } @@ -135,12 +140,30 @@ public class PropertiesFileImpl extends PsiFileBase implements PropertiesFile { @Override @NotNull public PsiElement addProperty(@NotNull IProperty property) throws IncorrectOperationException { - if (haveToAddNewLine()) { - insertLineBreakBefore(null); + final IProperty position = findInsertionPosition(property); + return addPropertyAfter((Property)property, (Property)position); + } + + private IProperty findInsertionPosition(@NotNull IProperty property) { + synchronized (lock) { + ensurePropertiesLoaded(); + if (myProperties.isEmpty()) { + return null; + } + if (myAlphaSorted) { + final int insertIndex = Collections.binarySearch(myProperties, property, new Comparator() { + @Override + public int compare(IProperty p1, IProperty p2) { + final String k1 = p1.getKey(); + final String k2 = p2.getKey(); + LOG.assertTrue(k1 != null && k2 != null); + return k1.compareTo(k2); + } + }); + return insertIndex == -1 ? null :myProperties.get(insertIndex < 0 ? - insertIndex - 2 : insertIndex); + } + return myProperties.get(myProperties.size() - 1); } - final TreeElement copy = ChangeUtil.copyToElement(property.getPsiElement()); - getPropertiesList().addChild(copy); - return copy.getPsi(); } @Override @@ -171,18 +194,6 @@ public class PropertiesFileImpl extends PsiFileBase implements PropertiesFile { return (IProperty)addProperty(PropertiesElementFactory.createProperty(getProject(), key, value)); } - @NotNull - @Override - public IProperty addPropertyFirst(String key, String value) { - return (IProperty)addPropertyAfter((Property) PropertiesElementFactory.createProperty(getProject(), key, value), null); - } - - @NotNull - @Override - public IProperty addPropertyLast(String key, String value) { - return addProperty(key, value); - } - @NotNull @Override public IProperty addPropertyAfter(String key, String value, @Nullable Property anchor) { @@ -208,6 +219,14 @@ public class PropertiesFileImpl extends PsiFileBase implements PropertiesFile { return result; } + @Override + public boolean isAlphaSorted() { + synchronized (lock) { + ensurePropertiesLoaded(); + return myAlphaSorted; + } + } + @Override public void clearCaches() { super.clearCaches(); diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java index b110dc429d74..a3a94c8f7f18 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java @@ -120,16 +120,6 @@ public class XmlPropertiesFileImpl extends XmlPropertiesFile { return null; } - @Override - public IProperty addPropertyFirst(String key, String value) { - return null; - } - - @Override - public IProperty addPropertyLast(String key, String value) { - return null; - } - @Override public IProperty addPropertyAfter(String key, String value, Property anchor) { return null; @@ -202,6 +192,11 @@ public class XmlPropertiesFileImpl extends XmlPropertiesFile { return getContainingFile().getText(); } + @Override + public boolean isAlphaSorted() { + return PropertiesImplUtil.isAlphaSorted(getProperties()); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesInsertManagerImpl.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesInsertManagerImpl.java index 213b0f2c47cc..fa1ac625769c 100644 --- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesInsertManagerImpl.java +++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesInsertManagerImpl.java @@ -65,17 +65,9 @@ public class ResourceBundlePropertiesInsertManagerImpl implements ResourceBundle } final PropertiesFile propertiesFile = myResourceBundle.getDefaultPropertiesFile(); if (myAlphaSorted) { - final Pair propertyAndPosition = findExistedPrevSiblingProperty(key, propertiesFile); - if (propertyAndPosition == null) { - propertiesFile.addPropertyFirst(key, value); - myKeysOrder.add(0, key); - } else { - propertiesFile.addPropertyAfter(key, value, (Property)propertyAndPosition.getFirst()); - final Integer position = propertyAndPosition.getSecond(); - myKeysOrder.add(position, key); - } + propertiesFile.addProperty(key, value); } else { - propertiesFile.addPropertyLast(key, value); + insertPropertyLast(key, value, propertiesFile); if (myOrdered) { myKeysOrder.add(key); } @@ -85,14 +77,14 @@ public class ResourceBundlePropertiesInsertManagerImpl implements ResourceBundle @Override public void insertTranslation(String key, String value, final PropertiesFile propertiesFile) { if (myOrdered) { - final Pair propertyAndPosition = findExistedPrevSiblingProperty(key, propertiesFile); - if (propertyAndPosition == null) { - propertiesFile.addPropertyFirst(key, value); - } else { - propertiesFile.addPropertyAfter(key, value, (Property)propertyAndPosition.getFirst()); + if (myAlphaSorted) { + propertiesFile.addProperty(key, value); + return; } + final Pair propertyAndPosition = findExistedPrevSiblingProperty(key, propertiesFile); + propertiesFile.addPropertyAfter(key, value, propertyAndPosition == null ? null :(Property)propertyAndPosition.getFirst()); } else { - propertiesFile.addPropertyLast(key, value); + insertPropertyLast(key, value, propertiesFile); } } @@ -100,13 +92,7 @@ public class ResourceBundlePropertiesInsertManagerImpl implements ResourceBundle if (myKeysOrder.isEmpty()) { return null; } - final int prevPosition; - if (myAlphaSorted) { - final int rawInsertionPosition = Collections.binarySearch(myKeysOrder, key); - prevPosition = rawInsertionPosition < 0 ? - rawInsertionPosition - 2 : rawInsertionPosition - 1; - } else { - prevPosition = myKeysOrder.indexOf(key); - } + final int prevPosition = myKeysOrder.indexOf(key); for (int i = prevPosition; i >= 0 ; i--) { final String prevKey = myKeysOrder.get(i); final IProperty property = file.findPropertyByKey(prevKey); @@ -117,6 +103,12 @@ public class ResourceBundlePropertiesInsertManagerImpl implements ResourceBundle return null; } + public void insertPropertyLast(String key, String value, PropertiesFile propertiesFile) { + final List properties = propertiesFile.getProperties(); + final IProperty lastProperty = properties.isEmpty() ? null : properties.get(properties.size() - 1); + propertiesFile.addPropertyAfter(key, value, (Property)lastProperty); + } + @Override public void reload() { final List keysOrder = keysOrder(myResourceBundle); @@ -124,7 +116,7 @@ public class ResourceBundlePropertiesInsertManagerImpl implements ResourceBundle if (myOrdered) { Collections.reverse(keysOrder); myAlphaSorted = isAlphaSorted(keysOrder); - myKeysOrder = keysOrder; + myKeysOrder = myAlphaSorted ? null : keysOrder; } else { myKeysOrder = null; } diff --git a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic index 55a6c61237b4..99657468b768 100644 --- a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic +++ b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic @@ -601,6 +601,7 @@ unboxing unbuffered uncomment uncommented +uncommenting undef underwave undoable