cleanup, getByKey - add value mapper

GitOrigin-RevId: 4a6356dc2cb9f1a1834d64a524f824dab7af10a0
This commit is contained in:
Vladimir Krivosheev
2020-04-21 09:49:26 +02:00
committed by intellij-monorepo-bot
parent 8ff880e707
commit 0532f2be19
12 changed files with 157 additions and 134 deletions

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
});
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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;
}
}

View File

@@ -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() {