mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 05:21:29 +07:00
cleanup, getByKey - add value mapper
GitOrigin-RevId: 4a6356dc2cb9f1a1834d64a524f824dab7af10a0
This commit is contained in:
committed by
intellij-monorepo-bot
parent
8ff880e707
commit
0532f2be19
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.module.impl;
|
||||
|
||||
import com.intellij.openapi.module.ModuleType;
|
||||
@@ -14,12 +14,12 @@ final class JavaAwareModuleTypeManagerImpl extends ModuleTypeManagerImpl{
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleType<?> findByID(final String moduleTypeID) {
|
||||
if (moduleTypeID != null) {
|
||||
if (JAVA_MODULE_ID_OLD.equals(moduleTypeID)) {
|
||||
public ModuleType<?> findByID(final String moduleTypeId) {
|
||||
if (moduleTypeId != null) {
|
||||
if (JAVA_MODULE_ID_OLD.equals(moduleTypeId)) {
|
||||
return StdModuleTypes.JAVA; // for compatibility with the previous ID that Java modules had
|
||||
}
|
||||
}
|
||||
return super.findByID(moduleTypeID);
|
||||
return super.findByID(moduleTypeId);
|
||||
}
|
||||
}
|
||||
@@ -60,6 +60,7 @@ public final class ExtensionPointName<T> extends BaseExtensionPointName<T> {
|
||||
}
|
||||
|
||||
public @NotNull List<T> getExtensionsIfPointIsRegistered(@Nullable AreaInstance areaInstance) {
|
||||
@SuppressWarnings("deprecation")
|
||||
ExtensionsArea area = areaInstance == null ? Extensions.getRootArea() : areaInstance.getExtensionArea();
|
||||
ExtensionPoint<T> point = area == null ? null : area.getExtensionPointIfRegistered(getName());
|
||||
return point == null ? Collections.emptyList() : point.getExtensionList();
|
||||
@@ -148,23 +149,34 @@ public final class ExtensionPointName<T> extends BaseExtensionPointName<T> {
|
||||
getPointImpl(null).addExtensionPointListener(listener, false, parentDisposable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build cache by arbitrary key using provided key to value mapper. Return value by key.
|
||||
* <p>
|
||||
* To exclude extension from cache, return null key.
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public final @NotNull <@NotNull K> List<T> getByGroupingKey(@NotNull K key, @NotNull Function<@NotNull T, @Nullable K> keyMapper) {
|
||||
return ExtensionProcessingHelper.getByGroupingKey(getPointImpl(null), key, keyMapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build cache by arbitrary key using provided key to value mapper. Values with the same key merge into list. Return values by key.
|
||||
* <p>
|
||||
* To exclude extension from cache, return null key.
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public final @Nullable <@NotNull K> T getByKey(@NotNull K key, @NotNull Function<@NotNull T, @Nullable K> keyMapper) {
|
||||
public final <@NotNull K> @NotNull List<T> getByGroupingKey(@NotNull K key, @NotNull Function<@NotNull T, @Nullable K> keyMapper) {
|
||||
return ExtensionProcessingHelper.getByGroupingKey(getPointImpl(null), key, keyMapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build cache by arbitrary key using provided key to value mapper. Return value by key.
|
||||
* <p>
|
||||
* To exclude extension from cache, return null key.
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public final <@NotNull K> @Nullable T getByKey(@NotNull K key, @NotNull Function<@NotNull T, @Nullable K> keyMapper) {
|
||||
return ExtensionProcessingHelper.getByKey(getPointImpl(null), key, keyMapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build cache by arbitrary key using provided key to value mapper. Return value by key.
|
||||
* <p>
|
||||
* To exclude extension from cache, return null key.
|
||||
*/
|
||||
public final <@NotNull K, @NotNull V> @Nullable V getByKey(@NotNull K key,
|
||||
@NotNull Function<@NotNull T, @Nullable K> keyMapper,
|
||||
@NotNull Function<@NotNull T, @Nullable V> valueMapper) {
|
||||
return ExtensionProcessingHelper.getByKey(getPointImpl(null), key, keyMapper, valueMapper);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import com.intellij.openapi.extensions.*;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.EmptyRunnable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.ArrayFactory;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
@@ -25,11 +24,15 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.util.AbstractMap.SimpleImmutableEntry;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@SuppressWarnings("SynchronizeOnThis")
|
||||
@@ -71,7 +74,7 @@ public abstract class ExtensionPointImpl<@NotNull T> implements ExtensionPoint<T
|
||||
|
||||
private final boolean isDynamic;
|
||||
|
||||
private final AtomicReference<ConcurrentMap<Function<T, ?>, Map<?, ?>>> keyMapperToCacheRef = new AtomicReference<>();
|
||||
private final AtomicReference<ConcurrentMap<?, Map<?, ?>>> keyMapperToCacheRef = new AtomicReference<>();
|
||||
|
||||
ExtensionPointImpl(@NotNull String name,
|
||||
@NotNull String className,
|
||||
@@ -87,14 +90,13 @@ public abstract class ExtensionPointImpl<@NotNull T> implements ExtensionPoint<T
|
||||
componentManager = value;
|
||||
}
|
||||
|
||||
final @NotNull <@NotNull K, @NotNull V> ConcurrentMap<Function<@NotNull T, @Nullable K>, Map<@NotNull K, @NotNull V>> getCacheMap() {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ConcurrentMap keyMapperToCache = keyMapperToCacheRef.get();
|
||||
final <@NotNull CACHE_KEY, @NotNull K, @NotNull V> @NotNull ConcurrentMap<@NotNull CACHE_KEY, Map<@NotNull K, @NotNull V>> getCacheMap() {
|
||||
ConcurrentMap<?, ?> keyMapperToCache = keyMapperToCacheRef.get();
|
||||
if (keyMapperToCache == null) {
|
||||
keyMapperToCache = keyMapperToCacheRef.updateAndGet(prev -> prev == null ? new ConcurrentHashMap<>() : prev);
|
||||
}
|
||||
//noinspection unchecked
|
||||
return (ConcurrentMap<Function<T, K>, Map<K, V>>)keyMapperToCache;
|
||||
return (ConcurrentMap<CACHE_KEY, Map<K, V>>)keyMapperToCache;
|
||||
}
|
||||
|
||||
public final @NotNull String getName() {
|
||||
@@ -535,11 +537,9 @@ public abstract class ExtensionPointImpl<@NotNull T> implements ExtensionPoint<T
|
||||
|
||||
if (fireEvents && myListeners.length > 0) {
|
||||
if (oldList != null) {
|
||||
notifyListeners(ExtensionEvent.REMOVED, () -> ContainerUtil.map(oldList, extension -> new Pair<>(extension, getPluginDescriptor())), myListeners);
|
||||
notifyListeners(ExtensionEvent.REMOVED, () -> ContainerUtil.map(oldList, extension -> new SimpleImmutableEntry<>(extension, getPluginDescriptor())), myListeners);
|
||||
}
|
||||
notifyListeners(ExtensionEvent.ADDED, () -> ContainerUtil.map(list, extension -> {
|
||||
return new Pair<>(extension, getPluginDescriptor());
|
||||
}), myListeners);
|
||||
notifyListeners(ExtensionEvent.ADDED, () -> ContainerUtil.map(list, extension -> new SimpleImmutableEntry<>(extension, getPluginDescriptor())), myListeners);
|
||||
}
|
||||
|
||||
Disposer.register(parentDisposable, new Disposable() {
|
||||
@@ -550,14 +550,14 @@ public abstract class ExtensionPointImpl<@NotNull T> implements ExtensionPoint<T
|
||||
myExtensionsCache = oldList;
|
||||
myExtensionsCacheAsArray = oldArray;
|
||||
|
||||
if (fireEvents && myListeners.length > 0) {
|
||||
notifyListeners(ExtensionEvent.REMOVED, () -> ContainerUtil.map(list, extension ->
|
||||
new Pair<>(extension, getPluginDescriptor())), myListeners);
|
||||
if (!fireEvents || myListeners.length <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (oldList != null) {
|
||||
notifyListeners(ExtensionEvent.ADDED, () -> ContainerUtil.map(oldList, extension ->
|
||||
new Pair<>(extension, getPluginDescriptor())), myListeners);
|
||||
}
|
||||
notifyListeners(ExtensionEvent.REMOVED, () -> ContainerUtil.map(list, extension -> new SimpleImmutableEntry<>(extension, getPluginDescriptor())), myListeners);
|
||||
|
||||
if (oldList != null) {
|
||||
notifyListeners(ExtensionEvent.ADDED, () -> ContainerUtil.map(oldList, extension -> new SimpleImmutableEntry<>(extension, getPluginDescriptor())), myListeners);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -651,21 +651,21 @@ public abstract class ExtensionPointImpl<@NotNull T> implements ExtensionPoint<T
|
||||
@NotNull T extensionObject,
|
||||
@NotNull PluginDescriptor pluginDescriptor,
|
||||
@NotNull ExtensionPointListener<T> @NotNull [] listeners) {
|
||||
notifyListeners(event, () -> Collections.singletonList(new Pair<>(extensionObject, pluginDescriptor)), listeners);
|
||||
notifyListeners(event, () -> Collections.singletonList(new SimpleImmutableEntry<>(extensionObject, pluginDescriptor)), listeners);
|
||||
}
|
||||
|
||||
private void notifyListeners(@NotNull ExtensionEvent event,
|
||||
@NotNull List<? extends ExtensionComponentAdapter> adapters,
|
||||
@NotNull ExtensionPointListener<T> @NotNull [] listeners) {
|
||||
notifyListeners(event, () -> ContainerUtil.mapNotNull(adapters, adapter ->
|
||||
adapter.isInstanceCreated() ? new Pair<>(adapter.createInstance(componentManager), adapter.getPluginDescriptor()) : null
|
||||
adapter.isInstanceCreated() ? new SimpleImmutableEntry<>(adapter.createInstance(componentManager), adapter.getPluginDescriptor()) : null
|
||||
), listeners);
|
||||
}
|
||||
|
||||
private void notifyListeners(@NotNull ExtensionEvent event,
|
||||
@NotNull Supplier<List<Pair<T, PluginDescriptor>>> extensions,
|
||||
@NotNull Supplier<List<SimpleImmutableEntry<T, PluginDescriptor>>> extensions,
|
||||
@NotNull ExtensionPointListener<T> @NotNull [] listeners) {
|
||||
List<Pair<T, PluginDescriptor>> extensionList = null;
|
||||
List<SimpleImmutableEntry<T, PluginDescriptor>> extensionList = null;
|
||||
for (ExtensionPointListener<T> listener : listeners) {
|
||||
if (listener instanceof ExtensionPointAdapter) {
|
||||
try {
|
||||
@@ -683,14 +683,14 @@ public abstract class ExtensionPointImpl<@NotNull T> implements ExtensionPoint<T
|
||||
if (extensionList == null) {
|
||||
extensionList = extensions.get();
|
||||
}
|
||||
for (Pair<? extends T, PluginDescriptor> extension : extensionList) {
|
||||
for (SimpleImmutableEntry<? extends T, PluginDescriptor> extension : extensionList) {
|
||||
try {
|
||||
switch (event) {
|
||||
case REMOVED:
|
||||
listener.extensionRemoved(extension.first, extension.second);
|
||||
listener.extensionRemoved(extension.getKey(), extension.getValue());
|
||||
break;
|
||||
case ADDED:
|
||||
listener.extensionAdded(extension.first, extension.second);
|
||||
listener.extensionAdded(extension.getKey(), extension.getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -815,7 +815,7 @@ public abstract class ExtensionPointImpl<@NotNull T> implements ExtensionPoint<T
|
||||
}
|
||||
|
||||
final void clearUserCache() {
|
||||
ConcurrentMap<Function<T, ?>, Map<?, ?>> map = keyMapperToCacheRef.get();
|
||||
ConcurrentMap<?, Map<?, ?>> map = keyMapperToCacheRef.get();
|
||||
if (map != null) {
|
||||
map.clear();
|
||||
}
|
||||
@@ -882,7 +882,7 @@ public abstract class ExtensionPointImpl<@NotNull T> implements ExtensionPoint<T
|
||||
listenerCallbacks.add(() -> {
|
||||
notifyListeners(ExtensionEvent.ADDED, () -> {
|
||||
return ContainerUtil.map(myAdapters.subList(oldSize, newSize),
|
||||
adapter -> new Pair<>(processAdapter(adapter), pluginDescriptor));
|
||||
adapter -> new SimpleImmutableEntry<>(processAdapter(adapter), pluginDescriptor));
|
||||
}, myListeners);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.AbstractMap.SimpleImmutableEntry;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.function.Consumer;
|
||||
@@ -69,7 +70,9 @@ public final class ExtensionProcessingHelper {
|
||||
/**
|
||||
* See {@link com.intellij.openapi.extensions.ExtensionPointName#getByGroupingKey}.
|
||||
*/
|
||||
public static @NotNull <@NotNull K, @NotNull T> List<T> getByGroupingKey(@NotNull ExtensionPointImpl<T> point, @NotNull K key, @NotNull Function<@NotNull T, @Nullable K> keyMapper) {
|
||||
public static <@NotNull K, @NotNull T> @NotNull List<T> getByGroupingKey(@NotNull ExtensionPointImpl<T> point,
|
||||
@NotNull K key,
|
||||
@NotNull Function<@NotNull T, @Nullable K> keyMapper) {
|
||||
ConcurrentMap<Function<T, K>, Map<K, List<T>>> keyMapperToCache = point.getCacheMap();
|
||||
Map<K, List<T>> cache = keyMapperToCache.get(keyMapper);
|
||||
if (cache == null) {
|
||||
@@ -88,12 +91,34 @@ public final class ExtensionProcessingHelper {
|
||||
* See {@link com.intellij.openapi.extensions.ExtensionPointName#getByKey}.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static <@NotNull K, @NotNull T> @Nullable T getByKey(@NotNull ExtensionPointImpl<T> point, @NotNull K key, @NotNull Function<@NotNull T, @Nullable K> keyMapper) {
|
||||
ConcurrentMap<Function<T, K>, Map<K, T>> keyMapperToCache = point.getCacheMap();
|
||||
Map<K, T> cache = keyMapperToCache.get(keyMapper);
|
||||
public static <@NotNull K, @NotNull T, @NotNull V> @Nullable V getByKey(@NotNull ExtensionPointImpl<T> point,
|
||||
@NotNull K key,
|
||||
@NotNull Function<@NotNull T, @Nullable K> keyMapper,
|
||||
@NotNull Function<@NotNull T, @Nullable V> valueMapper) {
|
||||
SimpleImmutableEntry<Function<T, K>, Function<T, V>> cacheKey = new SimpleImmutableEntry<>(keyMapper, valueMapper);
|
||||
return doGetByKey(point, cacheKey, key, keyMapper, valueMapper, point.getCacheMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link com.intellij.openapi.extensions.ExtensionPointName#getByKey}.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static <@NotNull K, @NotNull T> @Nullable T getByKey(@NotNull ExtensionPointImpl<T> point,
|
||||
@NotNull K key,
|
||||
@NotNull Function<@NotNull T, @Nullable K> keyMapper) {
|
||||
return doGetByKey(point, keyMapper, key, keyMapper, Function.identity(), point.getCacheMap());
|
||||
}
|
||||
|
||||
private static <CACHE_KEY, K, T, V> @Nullable V doGetByKey(@NotNull ExtensionPointImpl<T> point,
|
||||
@NotNull CACHE_KEY cacheKey,
|
||||
@NotNull K key,
|
||||
@NotNull Function<T, K> keyMapper,
|
||||
@NotNull Function<@NotNull T, @Nullable V> valueMapper,
|
||||
@NotNull ConcurrentMap<CACHE_KEY, Map<K, V>> keyMapperToCache) {
|
||||
Map<K, V> cache = keyMapperToCache.get(cacheKey);
|
||||
if (cache == null) {
|
||||
cache = buildCacheForKeyMapper(keyMapper, point);
|
||||
Map<K, T> prev = keyMapperToCache.putIfAbsent(keyMapper, cache);
|
||||
cache = buildCacheForKeyMapper(keyMapper, valueMapper, point);
|
||||
Map<K, V> prev = keyMapperToCache.putIfAbsent(cacheKey, cache);
|
||||
if (prev != null) {
|
||||
cache = prev;
|
||||
}
|
||||
@@ -101,7 +126,8 @@ public final class ExtensionProcessingHelper {
|
||||
return cache.get(key);
|
||||
}
|
||||
|
||||
private static @NotNull <K, T> Map<K, List<T>> buildCacheForGroupingKeyMapper(@NotNull Function<T, K> keyMapper, @NotNull ExtensionPointImpl<T> point) {
|
||||
private static <K, T> @NotNull Map<K, List<T>> buildCacheForGroupingKeyMapper(@NotNull Function<T, K> keyMapper,
|
||||
@NotNull ExtensionPointImpl<T> point) {
|
||||
// use HashMap instead of THashMap - a lot of keys not expected, nowadays HashMap is a more optimized (e.g. computeIfAbsent implemented in an efficient manner)
|
||||
Map<K, List<T>> cache = new HashMap<>();
|
||||
for (T extension : point.getExtensionList()) {
|
||||
@@ -114,14 +140,22 @@ public final class ExtensionProcessingHelper {
|
||||
return cache;
|
||||
}
|
||||
|
||||
private static @NotNull <K, T> Map<K, T> buildCacheForKeyMapper(@NotNull Function<T, K> keyMapper, @NotNull ExtensionPointImpl<T> point) {
|
||||
private static @NotNull <K, T, V> Map<K, V> buildCacheForKeyMapper(@NotNull Function<T, K> keyMapper,
|
||||
@NotNull Function<@NotNull T, @Nullable V> valueMapper,
|
||||
@NotNull ExtensionPointImpl<T> point) {
|
||||
List<T> extensions = point.getExtensionList();
|
||||
Map<K, T> cache = new THashMap<>(extensions.size());
|
||||
Map<K, V> cache = new THashMap<>(extensions.size());
|
||||
for (T extension : extensions) {
|
||||
K key = keyMapper.apply(extension);
|
||||
if (key != null) {
|
||||
cache.put(key, extension);
|
||||
if (key == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
V value = valueMapper.apply(extension);
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
cache.put(key, value);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
@@ -291,11 +291,13 @@ public class ExtensionPointImplTest {
|
||||
assertThat(extensionPoint.getExtensionList()).containsExactly(4, 2);
|
||||
|
||||
assertThat(ExtensionProcessingHelper.getByGroupingKey(extensionPoint, "foo", it -> "foo")).isEqualTo(extensionPoint.getExtensionList());
|
||||
assertThat(ExtensionProcessingHelper.getByKey(extensionPoint, 2, Function.identity())).isEqualTo(2);
|
||||
assertThat(ExtensionProcessingHelper.getByKey(extensionPoint, 2, Function.identity(), Function.identity())).isEqualTo(2);
|
||||
assertThat(ExtensionProcessingHelper.getByKey(extensionPoint, 2, Function.identity(), (Integer it) -> it * 2)).isEqualTo(4);
|
||||
|
||||
Function<@NotNull Integer, @Nullable Integer> filteringKeyMapper = it -> it < 3 ? it : null;
|
||||
assertThat(ExtensionProcessingHelper.getByKey(extensionPoint, 2, filteringKeyMapper)).isEqualTo(2);
|
||||
assertThat(ExtensionProcessingHelper.getByKey(extensionPoint, 4, filteringKeyMapper)).isNull();
|
||||
assertThat(ExtensionProcessingHelper.getByKey(extensionPoint, 2, filteringKeyMapper, Function.identity())).isEqualTo(2);
|
||||
assertThat(ExtensionProcessingHelper.getByKey(extensionPoint, 4, filteringKeyMapper, Function.identity())).isNull();
|
||||
assertThat(ExtensionProcessingHelper.getByKey(extensionPoint, 4, Function.identity(), (Integer it) -> (Integer)null)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.module;
|
||||
|
||||
import com.intellij.ide.util.frameworkSupport.FrameworkRole;
|
||||
@@ -36,8 +36,7 @@ import javax.swing.*;
|
||||
public abstract class ModuleType<T extends ModuleBuilder> {
|
||||
public static final ModuleType<?> EMPTY;
|
||||
|
||||
@NotNull
|
||||
private final String myId;
|
||||
private final @NotNull String myId;
|
||||
private final FrameworkRole myFrameworkRole;
|
||||
|
||||
protected ModuleType(@NotNull @NonNls String id) {
|
||||
@@ -45,41 +44,31 @@ public abstract class ModuleType<T extends ModuleBuilder> {
|
||||
myFrameworkRole = new FrameworkRole(id);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract T createModuleBuilder();
|
||||
public abstract @NotNull T createModuleBuilder();
|
||||
|
||||
@NotNull
|
||||
@Nls(capitalization = Nls.Capitalization.Title)
|
||||
public abstract String getName();
|
||||
public abstract @NotNull @Nls(capitalization = Nls.Capitalization.Title) String getName();
|
||||
|
||||
@NotNull
|
||||
@Nls(capitalization = Nls.Capitalization.Sentence)
|
||||
public abstract String getDescription();
|
||||
public abstract @NotNull @Nls(capitalization = Nls.Capitalization.Sentence) String getDescription();
|
||||
|
||||
@NotNull
|
||||
public Icon getIcon() {
|
||||
public @NotNull Icon getIcon() {
|
||||
return getNodeIcon(false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract Icon getNodeIcon(@Deprecated boolean isOpened);
|
||||
public abstract @NotNull Icon getNodeIcon(@Deprecated boolean isOpened);
|
||||
|
||||
public ModuleWizardStep @NotNull [] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull T moduleBuilder, @NotNull ModulesProvider modulesProvider) {
|
||||
return ModuleWizardStep.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ModuleWizardStep modifySettingsStep(@NotNull SettingsStep settingsStep, @NotNull ModuleBuilder moduleBuilder) {
|
||||
public @Nullable ModuleWizardStep modifySettingsStep(@NotNull SettingsStep settingsStep, @NotNull ModuleBuilder moduleBuilder) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ModuleWizardStep modifyProjectTypeStep(@NotNull SettingsStep settingsStep, @NotNull ModuleBuilder moduleBuilder) {
|
||||
public @Nullable ModuleWizardStep modifyProjectTypeStep(@NotNull SettingsStep settingsStep, @NotNull ModuleBuilder moduleBuilder) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final String getId() {
|
||||
public final @NotNull String getId() {
|
||||
return myId;
|
||||
}
|
||||
|
||||
@@ -104,17 +93,16 @@ public abstract class ModuleType<T extends ModuleBuilder> {
|
||||
EMPTY = instantiate("com.intellij.openapi.module.EmptyModuleType");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ModuleType instantiate(String className) {
|
||||
private static @NotNull ModuleType<?> instantiate(String className) {
|
||||
try {
|
||||
return (ModuleType)Class.forName(className).newInstance();
|
||||
return (ModuleType<?>)Class.forName(className).newInstance();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isValidSdk(@NotNull Module module, @Nullable final Sdk projectSdk) {
|
||||
public boolean isValidSdk(@NotNull Module module, final @Nullable Sdk projectSdk) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -126,8 +114,7 @@ public abstract class ModuleType<T extends ModuleBuilder> {
|
||||
return get(module) instanceof InternalModuleType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ModuleType get(@NotNull Module module) {
|
||||
public static @NotNull ModuleType<?> get(@NotNull Module module) {
|
||||
final ModuleTypeManager instance = ModuleTypeManager.getInstance();
|
||||
if (instance == null) {
|
||||
return EMPTY;
|
||||
@@ -135,12 +122,11 @@ public abstract class ModuleType<T extends ModuleBuilder> {
|
||||
return instance.findByID(module.getModuleTypeName());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FrameworkRole getDefaultAcceptableRole() {
|
||||
public @NotNull FrameworkRole getDefaultAcceptableRole() {
|
||||
return myFrameworkRole;
|
||||
}
|
||||
|
||||
public boolean isSupportedRootType(JpsModuleSourceRootType type) {
|
||||
public boolean isSupportedRootType(JpsModuleSourceRootType<?> type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import com.intellij.openapi.extensions.PluginDescriptor;
|
||||
import com.intellij.serviceContainer.LazyExtensionInstance;
|
||||
import com.intellij.util.xmlb.annotations.Attribute;
|
||||
import com.intellij.util.xmlb.annotations.Transient;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -21,16 +20,14 @@ public final class ModuleTypeEP extends LazyExtensionInstance<ModuleType<?>> imp
|
||||
@Attribute("classpathProvider")
|
||||
public boolean classpathProvider;
|
||||
|
||||
@ApiStatus.Internal
|
||||
@Transient
|
||||
public PluginDescriptor pluginDescriptor;
|
||||
private PluginDescriptor pluginDescriptor;
|
||||
|
||||
@Override
|
||||
protected @Nullable String getImplementationClassName() {
|
||||
return implementationClass;
|
||||
}
|
||||
|
||||
public ModuleType<?> getModuleType() {
|
||||
public @NotNull ModuleType<?> getModuleType() {
|
||||
return getInstance(ApplicationManager.getApplication(), pluginDescriptor);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.module;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class ModuleTypeManager {
|
||||
public static ModuleTypeManager getInstance() {
|
||||
return ServiceManager.getService(ModuleTypeManager.class);
|
||||
return ApplicationManager.getApplication().getService(ModuleTypeManager.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -26,7 +27,7 @@ public abstract class ModuleTypeManager {
|
||||
|
||||
public abstract void registerModuleType(ModuleType<?> type, boolean classpathProvider);
|
||||
|
||||
public abstract boolean isClasspathProvider(ModuleType<?> moduleType);
|
||||
public abstract boolean isClasspathProvider(@NotNull ModuleType<?> moduleType);
|
||||
|
||||
public abstract ModuleType<?> getDefaultModuleType();
|
||||
}
|
||||
@@ -6,6 +6,8 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.module.*;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -14,17 +16,17 @@ import java.util.List;
|
||||
public class ModuleTypeManagerImpl extends ModuleTypeManager {
|
||||
private static final Logger LOG = Logger.getInstance(ModuleTypeManagerImpl.class);
|
||||
@ApiStatus.Internal
|
||||
public static final ExtensionPointName<ModuleTypeEP> EP_NAME = ExtensionPointName.create("com.intellij.moduleType");
|
||||
public static final ExtensionPointName<ModuleTypeEP> EP_NAME = new ExtensionPointName<>("com.intellij.moduleType");
|
||||
|
||||
private final LinkedHashMap<ModuleType<?>, Boolean> myModuleTypes = new LinkedHashMap<>();
|
||||
|
||||
public ModuleTypeManagerImpl() {
|
||||
registerModuleType(getDefaultModuleType(), true);
|
||||
for (ModuleTypeEP ep : EP_NAME.getExtensions()) {
|
||||
EP_NAME.processWithPluginDescriptor((ep, pluginDescriptor) -> {
|
||||
if (ep.id == null) {
|
||||
LOG.error(new PluginException("'id' attribute isn't specified for <moduleType implementationClass='" + ep.implementationClass + "'> extension", ep.pluginDescriptor.getPluginId()));
|
||||
LOG.error(new PluginException("'id' attribute isn't specified for <moduleType implementationClass='" + ep.implementationClass + "'> extension", pluginDescriptor.getPluginId()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,31 +64,33 @@ public class ModuleTypeManagerImpl extends ModuleTypeManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleType<?> findByID(String moduleTypeID) {
|
||||
if (moduleTypeID == null) return getDefaultModuleType();
|
||||
public ModuleType<?> findByID(@Nullable String moduleTypeId) {
|
||||
if (moduleTypeId == null) {
|
||||
return getDefaultModuleType();
|
||||
}
|
||||
|
||||
for (ModuleType<?> type : myModuleTypes.keySet()) {
|
||||
if (type.getId().equals(moduleTypeID)) {
|
||||
if (type.getId().equals(moduleTypeId)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
for (ModuleTypeEP ep : EP_NAME.getExtensionList()) {
|
||||
if (moduleTypeID.equals(ep.id)) {
|
||||
return ep.getModuleType();
|
||||
}
|
||||
}
|
||||
|
||||
return new UnknownModuleType(moduleTypeID, getDefaultModuleType());
|
||||
ModuleTypeEP result = EP_NAME.getByKey(moduleTypeId, it -> it.id);
|
||||
if (result != null) {
|
||||
return result.getModuleType();
|
||||
}
|
||||
return new UnknownModuleType(moduleTypeId, getDefaultModuleType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClasspathProvider(ModuleType moduleType) {
|
||||
public boolean isClasspathProvider(@NotNull ModuleType moduleType) {
|
||||
for (ModuleTypeEP ep : EP_NAME.getExtensionList()) {
|
||||
if (moduleType.getId().equals(ep.id)) {
|
||||
return ep.classpathProvider;
|
||||
}
|
||||
}
|
||||
|
||||
final Boolean provider = myModuleTypes.get(moduleType);
|
||||
Boolean provider = myModuleTypes.get(moduleType);
|
||||
return provider != null && provider;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ package com.intellij.openapi.module
|
||||
import com.intellij.ide.util.projectWizard.ModuleBuilder
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.extensions.DefaultPluginDescriptor
|
||||
import com.intellij.openapi.module.impl.ModuleTypeManagerImpl
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.io.systemIndependentPath
|
||||
@@ -15,18 +16,19 @@ import javax.swing.Icon
|
||||
class ModuleTypeRegistrationTest : HeavyPlatformTestCase() {
|
||||
fun `test unregister module type and register again`() {
|
||||
val moduleTypeManager = ModuleTypeManager.getInstance()
|
||||
val moduleManager = ModuleManager.getInstance(myProject)
|
||||
runWithRegisteredType {
|
||||
val moduleType = moduleTypeManager.findByID(MockModuleType.ID)
|
||||
assertInstanceOf(moduleType, MockModuleType::class.java)
|
||||
val module = runWriteAction {
|
||||
ModuleManager.getInstance(myProject).newModule(File(createTempDirectory(), "test.iml").systemIndependentPath, MockModuleType.ID)
|
||||
moduleManager.newModule(File(createTempDirectory(), "test.iml").systemIndependentPath, MockModuleType.ID)
|
||||
}
|
||||
assertSame(moduleType, ModuleType.get(module))
|
||||
}
|
||||
|
||||
val unknownType = moduleTypeManager.findByID(MockModuleType.ID)
|
||||
assertInstanceOf(unknownType, UnknownModuleType::class.java)
|
||||
val module = ModuleManager.getInstance(myProject).findModuleByName("test")!!
|
||||
val module = moduleManager.findModuleByName("test")!!
|
||||
assertInstanceOf(ModuleType.get(module), UnknownModuleType::class.java)
|
||||
|
||||
registerModuleType(testRootDisposable)
|
||||
@@ -54,6 +56,7 @@ class ModuleTypeRegistrationTest : HeavyPlatformTestCase() {
|
||||
}
|
||||
})
|
||||
val extension = ModuleTypeEP()
|
||||
extension.setPluginDescriptor(DefaultPluginDescriptor("test"))
|
||||
extension.id = MockModuleType.ID
|
||||
extension.implementationClass = MockModuleType::class.qualifiedName
|
||||
ModuleTypeManagerImpl.EP_NAME.getPoint(null).registerExtension(extension, moduleTypeDisposable)
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.
|
||||
*/
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.jetbrains.python;
|
||||
|
||||
import com.intellij.ide.util.projectWizard.EmptyModuleBuilder;
|
||||
@@ -25,9 +11,8 @@ import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
|
||||
* @author yole
|
||||
*/
|
||||
public class PlatformPythonModuleType extends PythonModuleTypeBase<EmptyModuleBuilder> {
|
||||
@NotNull
|
||||
@Override
|
||||
public EmptyModuleBuilder createModuleBuilder() {
|
||||
public @NotNull EmptyModuleBuilder createModuleBuilder() {
|
||||
return new EmptyModuleBuilder() {
|
||||
@Override
|
||||
public ModuleType getModuleType() {
|
||||
@@ -37,7 +22,7 @@ public class PlatformPythonModuleType extends PythonModuleTypeBase<EmptyModuleBu
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedRootType(JpsModuleSourceRootType type) {
|
||||
public boolean isSupportedRootType(JpsModuleSourceRootType<?> type) {
|
||||
return type == JavaSourceRootType.SOURCE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.jetbrains.python.module;
|
||||
|
||||
import com.jetbrains.python.PythonModuleTypeBase;
|
||||
@@ -7,8 +7,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PythonModuleType extends PythonModuleTypeBase<PythonModuleBuilderBase> {
|
||||
|
||||
public final class PythonModuleType extends PythonModuleTypeBase<PythonModuleBuilderBase> {
|
||||
@Override
|
||||
@NotNull
|
||||
public PythonModuleBuilder createModuleBuilder() {
|
||||
|
||||
Reference in New Issue
Block a user