diff --git a/spellchecker/src/com/intellij/spellchecker/DictionaryLevel.kt b/spellchecker/src/com/intellij/spellchecker/DictionaryLevel.kt index 4b9d8fbcb289..e9b10679f955 100644 --- a/spellchecker/src/com/intellij/spellchecker/DictionaryLevel.kt +++ b/spellchecker/src/com/intellij/spellchecker/DictionaryLevel.kt @@ -7,23 +7,26 @@ import com.intellij.openapi.extensions.ExtensionPointName import com.intellij.openapi.project.Project import com.intellij.spellchecker.dictionary.EditableDictionary import com.intellij.spellchecker.dictionary.ProjectDictionary -import com.intellij.spellchecker.settings.DictionaryLayerChangesSubscriber +import com.intellij.spellchecker.settings.DictionaryLayerChangesListener import com.intellij.spellchecker.settings.DictionaryLayersChangesDispatcher import com.intellij.spellchecker.state.AppDictionaryState import com.intellij.spellchecker.state.ProjectDictionaryState import com.intellij.spellchecker.util.SpellCheckerBundle import org.jetbrains.annotations.Nls +import java.util.concurrent.ConcurrentMap -abstract class DictionaryLayersProvider { - abstract fun getLayers(project: Project): List - open fun startWatchingChanges(project: Project) { } +interface DictionaryLayersProvider { + fun getLayers(project: Project): List + fun startWatchingChanges(project: Project) { } companion object { val EP_NAME = ExtensionPointName.create("com.intellij.spellchecker.dictionaryLayersProvider") - fun getAllLayers(project: Project): List { + @JvmStatic + fun getAllLayers(project: Project): Collection { return project.service().getAllLayers() } + @JvmStatic fun getLayer(project: Project, layerName: String): DictionaryLayer? { return project.service().getLayer(layerName) } @@ -32,12 +35,11 @@ abstract class DictionaryLayersProvider { @Service(Service.Level.PROJECT) class PerProjectDictionaryLayersHolder(private val project: Project) { - private lateinit var layersMap: Map - private lateinit var layers: List + private var layersMap: Map = mapOf() init { project.service() - .register(object : DictionaryLayerChangesSubscriber { + .register(object : DictionaryLayerChangesListener { override fun layersChanged() { rebuild() } @@ -49,28 +51,28 @@ class PerProjectDictionaryLayersHolder(private val project: Project) { } fun rebuild() { - layers = DictionaryLayersProvider.EP_NAME.extensionList.flatMap { it.getLayers(project) }.toList() - layersMap = layers.associateBy { it.name } + layersMap = DictionaryLayersProvider.EP_NAME.extensionList + .flatMap { it.getLayers(project) } + .associateBy { it.name } } fun getLayer(layerName: String): DictionaryLayer? { return layersMap[layerName] } - fun getAllLayers(): List { - return layers + fun getAllLayers(): Collection { + return layersMap.values } } interface DictionaryLayer { val dictionary: EditableDictionary - @get:Nls - val name: String + val name: @Nls String } -class PlatformSettingsDictionaryLayersProvider : DictionaryLayersProvider() { +class PlatformSettingsDictionaryLayersProvider : DictionaryLayersProvider { override fun getLayers(project: Project): List { - return listOf(ApplicationDictionaryLayer.INSTANCE, ProjectDictionaryLayer(project)) + return listOf(ApplicationDictionaryLayer, ProjectDictionaryLayer(project)) } } @@ -83,12 +85,7 @@ class ProjectDictionaryLayer(val project: Project) : DictionaryLayer { override val dictionary: ProjectDictionary = project.service().projectDictionary } -class ApplicationDictionaryLayer : DictionaryLayer { - companion object { - val name = SpellCheckerBundle.message("dictionary.name.application.level") - val INSTANCE = ApplicationDictionaryLayer() - } - - override val name = Companion.name +object ApplicationDictionaryLayer : DictionaryLayer { + override val name = SpellCheckerBundle.message("dictionary.name.application.level") override val dictionary: EditableDictionary by lazy { AppDictionaryState.getInstance().dictionary } } \ No newline at end of file diff --git a/spellchecker/src/com/intellij/spellchecker/quickfixes/SaveTo.java b/spellchecker/src/com/intellij/spellchecker/quickfixes/SaveTo.java index 8b8a40e5788f..5b94d30e394c 100644 --- a/spellchecker/src/com/intellij/spellchecker/quickfixes/SaveTo.java +++ b/spellchecker/src/com/intellij/spellchecker/quickfixes/SaveTo.java @@ -28,20 +28,20 @@ import javax.swing.*; public final class SaveTo implements SpellCheckerQuickFix, LowPriorityAction { private static final String DICTIONARY = " dictionary"; private static final String DOTS = "..."; - @Nullable private DictionaryLayer myLevel = null; + @Nullable private DictionaryLayer myLayer = null; private String myWord; - public SaveTo(@NotNull DictionaryLayer level) { - myLevel = level; + public SaveTo(@NotNull DictionaryLayer layer) { + myLayer = layer; } public SaveTo(String word) { myWord = word; } - public SaveTo(String word, @NotNull DictionaryLayer level) { + public SaveTo(String word, @NotNull DictionaryLayer layer) { myWord = word; - myLevel = level; + myLayer = layer; } @Override @@ -51,7 +51,7 @@ public final class SaveTo implements SpellCheckerQuickFix, LowPriorityAction { @Override public @NotNull String getFamilyName() { - final String dictionary = myLevel != null ? myLevel.getName() + DICTIONARY : DOTS; + final String dictionary = myLayer != null ? myLayer.getName() + DICTIONARY : DOTS; return SpellCheckerBundle.message("save.0.to.1", "", dictionary); } @@ -66,9 +66,9 @@ public final class SaveTo implements SpellCheckerQuickFix, LowPriorityAction { .getDataContextFromFocusAsync() .onSuccess(context -> { final String wordToSave = myWord != null ? myWord : ProblemDescriptorUtil.extractHighlightedText(descriptor, descriptor.getPsiElement()); - if (myLevel == null) { + if (myLayer == null) { final JBList dictList = new JBList<>( - ContainerUtil.map(DictionaryLayersProvider.Companion.getAllLayers(project), it -> it.getName()) + ContainerUtil.map(DictionaryLayersProvider.getAllLayers(project), it -> it.getName()) ); JBPopupFactory.getInstance() @@ -78,7 +78,7 @@ public final class SaveTo implements SpellCheckerQuickFix, LowPriorityAction { () -> CommandProcessor.getInstance().executeCommand( project, - () -> acceptWord(wordToSave, DictionaryLayersProvider.Companion.getLayer(project, dictList.getSelectedValue()), descriptor), + () -> acceptWord(wordToSave, DictionaryLayersProvider.getLayer(project, dictList.getSelectedValue()), descriptor), getName(), null ) @@ -87,18 +87,18 @@ public final class SaveTo implements SpellCheckerQuickFix, LowPriorityAction { .showInBestPositionFor(context); } else { - acceptWord(wordToSave, myLevel, descriptor); + acceptWord(wordToSave, myLayer, descriptor); } }); } - private static void acceptWord(String word, @Nullable DictionaryLayer level, ProblemDescriptor descriptor) { + private static void acceptWord(String word, @Nullable DictionaryLayer layer, ProblemDescriptor descriptor) { SideEffectGuard.checkSideEffectAllowed(SideEffectGuard.EffectType.SETTINGS); PsiElement psi = descriptor.getPsiElement(); PsiFile file = psi.getContainingFile(); Project project = file.getProject(); - SpellCheckerManager.getInstance(project).acceptWordAsCorrect$intellij_spellchecker(word, file.getViewProvider().getVirtualFile(), project, level); + SpellCheckerManager.getInstance(project).acceptWordAsCorrect$intellij_spellchecker(word, file.getViewProvider().getVirtualFile(), project, layer); TextRange range = descriptor.getTextRangeInElement().shiftRight(psi.getTextRange().getStartOffset()); UpdateHighlightersUtil.removeHighlightersWithExactRange(file.getViewProvider().getDocument(), project, range); diff --git a/spellchecker/src/com/intellij/spellchecker/settings/BuiltInDictionariesProvider.kt b/spellchecker/src/com/intellij/spellchecker/settings/BuiltInDictionariesProvider.kt index d613e8bf26ce..05f38bf5bf48 100644 --- a/spellchecker/src/com/intellij/spellchecker/settings/BuiltInDictionariesProvider.kt +++ b/spellchecker/src/com/intellij/spellchecker/settings/BuiltInDictionariesProvider.kt @@ -3,12 +3,13 @@ package com.intellij.spellchecker.settings import com.intellij.openapi.extensions.ExtensionPointName -abstract class BuiltInDictionariesProvider { - abstract fun getDictionaries(): List +interface BuiltInDictionariesProvider { + fun getDictionaries(): List companion object { val EP_NAME = ExtensionPointName.create("com.intellij.spellchecker.builtInDictionariesProvider") + @JvmStatic fun getAll(): List { return EP_NAME.extensionList } diff --git a/spellchecker/src/com/intellij/spellchecker/settings/BuiltInDictionary.kt b/spellchecker/src/com/intellij/spellchecker/settings/BuiltInDictionary.kt index f1060dac1dcc..b05bf0dd01e7 100644 --- a/spellchecker/src/com/intellij/spellchecker/settings/BuiltInDictionary.kt +++ b/spellchecker/src/com/intellij/spellchecker/settings/BuiltInDictionary.kt @@ -2,8 +2,9 @@ package com.intellij.spellchecker.settings import com.intellij.openapi.project.Project +import org.jetbrains.annotations.Nls interface BuiltInDictionary { fun openDictionaryInEditor(project: Project) - val name: String + val name: @Nls String } \ No newline at end of file diff --git a/spellchecker/src/com/intellij/spellchecker/settings/CustomDictionariesPanel.java b/spellchecker/src/com/intellij/spellchecker/settings/CustomDictionariesPanel.java index 61795a3595da..2a4636d11529 100644 --- a/spellchecker/src/com/intellij/spellchecker/settings/CustomDictionariesPanel.java +++ b/spellchecker/src/com/intellij/spellchecker/settings/CustomDictionariesPanel.java @@ -43,7 +43,7 @@ public final class CustomDictionariesPanel extends JPanel { defaultDictionaries = project.isDefault() ? new ArrayList<>() : asList(SpellCheckerBundle.message("app.dictionary"), SpellCheckerBundle .message("project.dictionary")); builtInDictionaries = new HashMap<>(); - BuiltInDictionariesProvider.Companion.getAll().stream() + BuiltInDictionariesProvider.getAll().stream() .map(BuiltInDictionariesProvider::getDictionaries).flatMap(List::stream) .forEach(dictionary -> builtInDictionaries.put(dictionary.getName(), dictionary)); myCustomDictionariesTableView = new CustomDictionariesTableView(new ArrayList<>(settings.getCustomDictionariesPaths()), diff --git a/spellchecker/src/com/intellij/spellchecker/settings/DictionaryLayerChangesSubscriber.kt b/spellchecker/src/com/intellij/spellchecker/settings/DictionaryLayerChangesListener.kt similarity index 53% rename from spellchecker/src/com/intellij/spellchecker/settings/DictionaryLayerChangesSubscriber.kt rename to spellchecker/src/com/intellij/spellchecker/settings/DictionaryLayerChangesListener.kt index 3b48a70c4f26..b90f1b2734bf 100644 --- a/spellchecker/src/com/intellij/spellchecker/settings/DictionaryLayerChangesSubscriber.kt +++ b/spellchecker/src/com/intellij/spellchecker/settings/DictionaryLayerChangesListener.kt @@ -8,19 +8,21 @@ import com.intellij.util.messages.Topic @Service(Service.Level.PROJECT) class DictionaryLayersChangesDispatcher { - @Topic.ProjectLevel - private val topic = Topic(DictionaryLayerChangesSubscriber::class.java) + val publisher: DictionaryLayerChangesListener + get() = application.messageBus.syncPublisher(DictionaryLayerChangesListener.topic) - val publisher: DictionaryLayerChangesSubscriber - get() = application.messageBus.syncPublisher(topic) - - fun register(subscriber: DictionaryLayerChangesSubscriber): MessageBusConnection { + fun register(subscriber: DictionaryLayerChangesListener): MessageBusConnection { val connection = application.messageBus.connect() - connection.subscribe(topic, subscriber) + connection.subscribe(DictionaryLayerChangesListener.topic, subscriber) return connection } } -interface DictionaryLayerChangesSubscriber { +interface DictionaryLayerChangesListener { + companion object { + @Topic.ProjectLevel + val topic = Topic(DictionaryLayerChangesListener::class.java) + } + fun layersChanged() } \ No newline at end of file diff --git a/spellchecker/src/com/intellij/spellchecker/settings/SpellCheckerSettingsPane.java b/spellchecker/src/com/intellij/spellchecker/settings/SpellCheckerSettingsPane.java index deb1f18acc4e..7186bc478fcc 100644 --- a/spellchecker/src/com/intellij/spellchecker/settings/SpellCheckerSettingsPane.java +++ b/spellchecker/src/com/intellij/spellchecker/settings/SpellCheckerSettingsPane.java @@ -77,7 +77,7 @@ public final class SpellCheckerSettingsPane implements Disposable { myDictionariesComboBox.setEnabled(myUseSingleDictionary.isSelected()); } }); - DictionaryLayersProvider.Companion.getAllLayers(project).forEach(it -> myDictionariesComboBox.addItem(it.getName())); + DictionaryLayersProvider.getAllLayers(project).forEach(it -> myDictionariesComboBox.addItem(it.getName())); linkContainer.setLayout(new BorderLayout()); linkContainer.add(link); diff --git a/spellchecker/src/com/intellij/spellchecker/tokenizer/SpellcheckingStrategy.java b/spellchecker/src/com/intellij/spellchecker/tokenizer/SpellcheckingStrategy.java index 279f6c4152d5..061d241a7bb1 100644 --- a/spellchecker/src/com/intellij/spellchecker/tokenizer/SpellcheckingStrategy.java +++ b/spellchecker/src/com/intellij/spellchecker/tokenizer/SpellcheckingStrategy.java @@ -143,7 +143,7 @@ public class SpellcheckingStrategy { final SpellCheckerSettings settings = SpellCheckerSettings.getInstance(element.getProject()); if (settings.isUseSingleDictionaryToSave()) { - result.add(new SaveTo(typo, Objects.requireNonNull(DictionaryLayersProvider.Companion.getLayer(element.getProject(), settings.getDictionaryToSave())))); + result.add(new SaveTo(typo, Objects.requireNonNull(DictionaryLayersProvider.getLayer(element.getProject(), settings.getDictionaryToSave())))); return result.toArray(LocalQuickFix.EMPTY_ARRAY); } @@ -152,7 +152,7 @@ public class SpellcheckingStrategy { } public static SpellCheckerQuickFix[] getDefaultBatchFixes(PsiElement element) { - return DictionaryLayersProvider.Companion.getAllLayers(element.getProject()) + return DictionaryLayersProvider.getAllLayers(element.getProject()) .stream().map(it -> new SaveTo(it)) .toArray(SpellCheckerQuickFix[]::new); }