DefaultPicoContainer.getService method — do not query parent container at all (only current container must be used), use only string key

deprecate bad/useless pico container methods

GitOrigin-RevId: 87a77b47af7489747e8209a49cad56cd5244591b
This commit is contained in:
Vladimir Krivosheev
2019-08-06 14:03:41 +03:00
committed by intellij-monorepo-bot
parent 3fbb8c21bb
commit 4eb65aaf9c
112 changed files with 1120 additions and 1932 deletions
@@ -5,10 +5,9 @@ import com.intellij.openapi.application.ApplicationStarter;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
/**
* @author max
*/
public class GenerateAntMain implements ApplicationStarter {
import java.util.List;
final class GenerateAntMain implements ApplicationStarter {
private GenerateAntApplication myApplication;
@Override
@@ -18,12 +17,12 @@ public class GenerateAntMain implements ApplicationStarter {
}
@Override
public void premain(String[] args) {
public void premain(@NotNull List<String> args) {
System.setProperty("idea.load.plugins", "false");
myApplication = new GenerateAntApplication();
myApplication.myProjectPath = args[1];
myApplication.myOutPath = args[2];
myApplication.myProjectPath = args.get(1);
myApplication.myOutPath = args.get(2);
}
@Override
@@ -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-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.
package com.intellij.core;
import com.intellij.codeInsight.ContainerProvider;
@@ -10,7 +10,6 @@ import com.intellij.ide.highlighter.ArchiveFileType;
import com.intellij.ide.highlighter.JavaClassFileType;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.lang.LanguageASTFactory;
import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.lang.folding.LanguageFolding;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.lang.java.JavaParserDefinition;
@@ -53,13 +52,13 @@ public class JavaCoreApplicationEnvironment extends CoreApplicationEnvironment {
registerFileType(PlainTextFileType.INSTANCE, "txt;sh;bat;cmd;policy;log;cgi;MF;jad;jam;htaccess");
addExplicitExtension(LanguageASTFactory.INSTANCE, PlainTextLanguage.INSTANCE, new PlainTextASTFactory());
addExplicitExtension(LanguageParserDefinitions.INSTANCE, PlainTextLanguage.INSTANCE, new PlainTextParserDefinition());
registerParserDefinition(new PlainTextParserDefinition());
addExplicitExtension(FileTypeFileViewProviders.INSTANCE, JavaClassFileType.INSTANCE, new ClassFileViewProviderFactory());
addExplicitExtension(BinaryFileStubBuilders.INSTANCE, JavaClassFileType.INSTANCE, new ClassFileStubBuilder());
addExplicitExtension(LanguageASTFactory.INSTANCE, JavaLanguage.INSTANCE, new JavaASTFactory());
addExplicitExtension(LanguageParserDefinitions.INSTANCE, JavaLanguage.INSTANCE, new JavaParserDefinition());
registerParserDefinition(new JavaParserDefinition());
addExplicitExtension(LanguageConstantExpressionEvaluator.INSTANCE, JavaLanguage.INSTANCE, new PsiExpressionEvaluator());
addExtension(ContainerProvider.EP_NAME, new JavaContainerProvider());
@@ -41,7 +41,7 @@ public class LightAdvHighlightingPerformanceTest extends LightDaemonAnalyzerTest
blockUntil(Extensions.getRootArea().getExtensionPoint(LanguageAnnotators.EP_NAME), getTestRootDisposable());
blockUntil(Extensions.getRootArea().getExtensionPoint(LineMarkerProviders.EP_NAME), getTestRootDisposable());
blockUntil(ConcatenationInjectorManager.CONCATENATION_INJECTOR_EP_NAME.getPoint(getProject()), getTestRootDisposable());
blockUntil(Extensions.getArea(getProject()).getExtensionPoint(MultiHostInjector.MULTIHOST_INJECTOR_EP_NAME), getTestRootDisposable());
blockUntil(getProject().getExtensionArea().getExtensionPoint(MultiHostInjector.MULTIHOST_INJECTOR_EP_NAME), getTestRootDisposable());
IntentionManager.getInstance().getAvailableIntentionActions(); // hack to avoid slowdowns in PyExtensionFactory
PathManagerEx.getTestDataPath(); // to cache stuff
@@ -3,7 +3,6 @@ package com.intellij.json;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
@@ -43,7 +42,7 @@ public class JsonSpellcheckerTest extends JsonTestCase {
PsiFile[] files = myFixture.configureByFiles(getTestName(false) + ".json", "Schema.json");
JsonSchemaTestServiceImpl.setProvider(new JsonSchemaTestProvider(files[1].getVirtualFile(),
getAvailabilityPredicate()));
MutablePicoContainer container = Extensions.getArea(getProject()).getPicoContainer();
MutablePicoContainer container = (MutablePicoContainer)getProject().getPicoContainer();
String key = JsonSchemaService.class.getName();
container.unregisterComponent(key);
container.registerComponentImplementation(key, JsonSchemaTestServiceImpl.class);
@@ -8,7 +8,6 @@ import com.intellij.json.JsonFileType;
import com.intellij.json.psi.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.Trinity;
@@ -236,7 +235,7 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest {
public void registerSchemes() {
final String moduleDir = getModuleDir(getProject());
MutablePicoContainer container = Extensions.getArea(getProject()).getPicoContainer();
MutablePicoContainer container = (MutablePicoContainer)getProject().getPicoContainer();
final String key = JsonSchemaMappingsProjectConfiguration.class.getName();
container.unregisterComponent(key);
container.registerComponentImplementation(key, TestJsonSchemaMappingsProjectConfiguration.class);
@@ -4,7 +4,6 @@ package com.jetbrains.jsonSchema;
import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
@@ -20,7 +19,6 @@ import java.io.File;
import java.io.IOException;
public abstract class JsonSchemaHighlightingTestBase extends DaemonAnalyzerTestCase {
protected abstract String getTestFileName();
protected abstract InspectionProfileEntry getInspectionProfile();
protected abstract Predicate<VirtualFile> getAvailabilityPredicate();
@@ -62,7 +60,7 @@ public abstract class JsonSchemaHighlightingTestBase extends DaemonAnalyzerTestC
FileUtil.writeToFile(child, schema);
VirtualFile schemaFile = getVirtualFile(child);
JsonSchemaTestServiceImpl.setProvider(new JsonSchemaTestProvider(schemaFile, getAvailabilityPredicate()));
MutablePicoContainer container = Extensions.getArea(project).getPicoContainer();
MutablePicoContainer container = (MutablePicoContainer)project.getPicoContainer();
String key = JsonSchemaService.class.getName();
container.unregisterComponent(key);
container.registerComponentImplementation(key, JsonSchemaTestServiceImpl.class);
@@ -3,6 +3,7 @@ package com.intellij.configurationStore
import com.intellij.configurationStore.schemeManager.ROOT_CONFIG
import com.intellij.openapi.application.Application
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.PathManager
import com.intellij.openapi.application.appSystemDir
import com.intellij.openapi.components.*
@@ -15,11 +16,16 @@ import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import org.jetbrains.jps.model.serialization.JpsGlobalLoader
private class ApplicationPathMacroManager : PathMacroManager(null)
internal class ApplicationPathMacroManager : PathMacroManager(null)
const val APP_CONFIG = "\$APP_CONFIG$"
class ApplicationStoreImpl(private val application: Application, pathMacroManager: PathMacroManager? = null) : ComponentStoreWithExtraComponents() {
class ApplicationStoreImpl(pathMacroManager: PathMacroManager?) : ComponentStoreWithExtraComponents() {
private val application = ApplicationManager.getApplication()
@Suppress("unused")
constructor() : this(PathMacroManager.getInstance(ApplicationManager.getApplication()))
override val storageManager = ApplicationStorageManager(application, pathMacroManager)
// number of app components require some state, so, we load default state in test mode
@@ -3,7 +3,6 @@ package com.intellij.lang;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.extensions.CustomLoadingExtensionPointBean;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.util.KeyedLazyInstance;
import com.intellij.util.xmlb.annotations.Attribute;
import org.jetbrains.annotations.NotNull;
@@ -14,6 +13,13 @@ import org.jetbrains.annotations.NotNull;
* @author yole
*/
public class LanguageExtensionPoint<T> extends CustomLoadingExtensionPointBean implements KeyedLazyInstance<T> {
public LanguageExtensionPoint() {
}
public LanguageExtensionPoint(@NotNull T instance) {
myInstance = instance;
}
// these must be public for scrambling compatibility
/**
@@ -27,13 +33,28 @@ public class LanguageExtensionPoint<T> extends CustomLoadingExtensionPointBean i
@Attribute("implementationClass")
public String implementationClass;
private final NotNullLazyValue<T> myHandler =
NotNullLazyValue.createValue(() -> instantiateExtension(implementationClass, ApplicationManager.getApplication().getPicoContainer()));
private volatile T myInstance;
@NotNull
@Override
public T getInstance() {
return myHandler.getValue();
T result = myInstance;
if (result != null) {
return result;
}
//noinspection SynchronizeOnThis
synchronized (this) {
result = myInstance;
if (result != null) {
return result;
}
//noinspection NonPrivateFieldAccessedInSynchronizedContext
result = instantiateExtension(implementationClass, ApplicationManager.getApplication().getPicoContainer());
myInstance = result;
}
return result;
}
@Override
@@ -35,7 +35,7 @@ public final class LanguageUtil {
public static Language getLanguageForPsi(@NotNull Project project, @Nullable VirtualFile file) {
Language language = getFileLanguage(file);
if (language == null) return null;
return LanguageSubstitutors.INSTANCE.substituteLanguage(language, file, project);
return LanguageSubstitutors.getInstance().substituteLanguage(language, file, project);
}
@Nullable
@@ -4,9 +4,11 @@ package com.intellij.openapi.components;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.extensions.AreaInstance;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.ExtensionsArea;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.UserDataHolder;
import com.intellij.util.messages.MessageBus;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.picocontainer.PicoContainer;
@@ -19,7 +21,7 @@ import org.picocontainer.PicoContainer;
* @see com.intellij.openapi.application.Application
* @see com.intellij.openapi.project.Project
*/
public interface ComponentManager extends UserDataHolder, Disposable {
public interface ComponentManager extends UserDataHolder, Disposable, AreaInstance {
/**
* @deprecated Use {@link #getComponent(Class)} instead.
*/
@@ -51,7 +53,7 @@ public interface ComponentManager extends UserDataHolder, Disposable {
* @return {@code true} if there is a component with the specified interface class;
* {@code false} otherwise
*/
boolean hasComponent(@NotNull Class interfaceClass);
boolean hasComponent(@NotNull Class<?> interfaceClass);
/**
* Gets all components whose implementation class is derived from {@code baseClass}.
@@ -83,7 +85,9 @@ public interface ComponentManager extends UserDataHolder, Disposable {
*/
@NotNull
@Deprecated
<T> T[] getExtensions(@NotNull ExtensionPointName<T> extensionPointName);
default <T> T[] getExtensions(@NotNull ExtensionPointName<T> extensionPointName) {
return getExtensionArea().getExtensionPoint(extensionPointName).getExtensions();
}
/**
* @return condition for this component being disposed.
@@ -94,4 +98,18 @@ public interface ComponentManager extends UserDataHolder, Disposable {
default void initializeComponent(@NotNull Object component, @Nullable ServiceDescriptor serviceDescriptor) {
}
@ApiStatus.Internal
default <T> T getService(@NotNull Class<T> serviceClass, boolean isCreate) {
// default impl to keep backward compatibility
//noinspection unchecked
return (T)getPicoContainer().getComponentInstance(serviceClass.getName());
}
@NotNull
@Override
default ExtensionsArea getExtensionArea() {
// default impl to keep backward compatibility
throw new AbstractMethodError();
}
}
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2012 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-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.
package com.intellij.openapi.components;
import org.jetbrains.annotations.NonNls;
@@ -20,7 +6,7 @@ import org.jetbrains.annotations.NonNls;
/**
* @author yole
*/
public class ExtensionAreas {
public final class ExtensionAreas {
@NonNls public static final String IDEA_PROJECT = "IDEA_PROJECT";
@NonNls public static final String IDEA_MODULE = "IDEA_MODULE";
}
@@ -1,102 +1,35 @@
// 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.
package com.intellij.openapi.components;
import com.intellij.diagnostic.LoadingPhase;
import com.intellij.diagnostic.ParallelActivity;
import com.intellij.diagnostic.StartUpMeasurer;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.NotNullLazyKey;
import com.intellij.openapi.util.Ref;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.storage.HeavyProcessLatch;
import com.intellij.util.pico.DefaultPicoContainer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.picocontainer.PicoContainer;
import java.lang.reflect.Modifier;
import java.util.concurrent.ConcurrentMap;
/**
* For old-style components, the contract specifies a lifecycle: the component gets created and notified during the project opening process.
* For services, there's no such contract, so we don't even load the class implementing the service until someone requests it.
*/
public final class ServiceManager {
private static final Logger LOG = Logger.getInstance(ServiceManager.class);
private static final ConcurrentMap<Class<?>, Object> ourAppServices = ContainerUtil.newConcurrentMap();
private ServiceManager() { }
public static <T> T getService(@NotNull Class<T> serviceClass) {
if (isLightService(serviceClass)) {
return getOrCreateLightService(serviceClass);
}
else {
return doGetService(ApplicationManager.getApplication(), serviceClass, true);
}
return ApplicationManager.getApplication().getService(serviceClass, true);
}
public static <T> T getService(@NotNull Project project, @NotNull Class<T> serviceClass) {
return doGetService(project, serviceClass, true);
return project.getService(serviceClass, true);
}
@Nullable
public static <T> T getServiceIfCreated(@NotNull Project project, @NotNull Class<T> serviceClass) {
return doGetService(project, serviceClass, false);
return project.getService(serviceClass, false);
}
@Nullable
public static <T> T getServiceIfCreated(@NotNull Class<T> serviceClass) {
if (isLightService(serviceClass)) {
//noinspection unchecked
return (T)ourAppServices.get(serviceClass);
}
return doGetService(ApplicationManager.getApplication(), serviceClass, false);
}
@Nullable
private static <T> T doGetService(@NotNull ComponentManager componentManager, @NotNull Class<T> serviceClass, boolean isCreate) {
String componentKey = serviceClass.getName();
PicoContainer picoContainer = componentManager.getPicoContainer();
if (!isCreate && picoContainer instanceof DefaultPicoContainer) {
return ((DefaultPicoContainer)picoContainer).getComponentInstanceIfInstantiated(componentKey);
}
@SuppressWarnings("unchecked") T instance = (T)picoContainer.getComponentInstance(componentKey);
if (instance == null) {
ProgressManager.checkCanceled();
instance = assertServiceNotRegisteredAsComponent(componentManager, serviceClass, componentKey);
}
return instance;
}
private static <T> T assertServiceNotRegisteredAsComponent(@NotNull ComponentManager componentManager,
@NotNull Class<T> serviceClass,
@NotNull String componentKey) {
T instance = componentManager.getComponent(serviceClass);
if (instance != null) {
Application app = ApplicationManager.getApplication();
String message = componentKey + " requested as a service, but it is a component - convert it to a service or change call to " +
(componentManager == app ? "ApplicationManager.getApplication().getComponent()" : "project.getComponent()");
if (app.isUnitTestMode()) {
LOG.error(message);
}
else {
LOG.warn(message);
}
}
return instance;
return ApplicationManager.getApplication().getService(serviceClass, false);
}
/**
@@ -110,59 +43,4 @@ public final class ServiceManager {
public static <T> NotNullLazyKey<T, Project> createLazyKey(@NotNull final Class<? extends T> serviceClass) {
return NotNullLazyKey.create("Service: " + serviceClass.getName(), project -> getService(project, serviceClass));
}
private static <T> boolean isLightService(@NotNull Class<T> serviceClass) {
return Modifier.isFinal(serviceClass.getModifiers()) && serviceClass.isAnnotationPresent(Service.class);
}
@NotNull
private static <T> T getOrCreateLightService(@NotNull Class<T> serviceClass) {
@SuppressWarnings("unchecked")
T instance = (T)ourAppServices.get(serviceClass);
if (instance != null) {
return instance;
}
LoadingPhase.COMPONENT_REGISTERED.assertAtLeast();
//noinspection SynchronizeOnThis
synchronized (serviceClass) {
//noinspection unchecked
instance = (T)ourAppServices.get(serviceClass);
if (instance != null) {
return instance;
}
ComponentManager componentManager = ApplicationManager.getApplication();
try (AccessToken ignore = HeavyProcessLatch.INSTANCE.processStarted("Creating service '" + serviceClass.getName() + "'")) {
if (ProgressIndicatorProvider.getGlobalProgressIndicator() == null) {
instance = createLightService(serviceClass, componentManager);
}
else {
Ref<T> ref = new Ref<>();
//noinspection CodeBlock2Expr
ProgressManager.getInstance().executeNonCancelableSection(() -> {
ref.set(createLightService(serviceClass, componentManager));
});
instance = ref.get();
}
}
Object prevValue = ourAppServices.put(serviceClass, instance);
LOG.assertTrue(prevValue == null);
return instance;
}
}
@NotNull
private static <T> T createLightService(@NotNull Class<T> serviceClass, @NotNull ComponentManager componentManager) {
long startTime = StartUpMeasurer.getCurrentTime();
T instance = ReflectionUtil.newInstance(serviceClass, false);
if (instance instanceof Disposable) {
Disposer.register(componentManager, (Disposable)instance);
}
componentManager.initializeComponent(instance, null);
ParallelActivity.SERVICE.record(startTime, instance.getClass(), StartUpMeasurer.Level.APPLICATION);
return instance;
}
}
@@ -1,7 +1,6 @@
// 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.
package com.intellij.openapi.extensions;
import com.intellij.diagnostic.PluginException;
import com.intellij.util.ExtensionInstantiator;
import com.intellij.util.xmlb.annotations.Attribute;
import org.jetbrains.annotations.NotNull;
@@ -1,18 +1,4 @@
/*
* 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.
*/
// 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.
package com.intellij.openapi.fileTypes;
import com.intellij.lang.Language;
@@ -14,15 +14,19 @@ import gnu.trove.THashMap;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.util.*;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
public class KeyedExtensionCollector<T, KeyT> implements ModificationTracker {
private static final Logger LOG = Logger.getInstance(KeyedExtensionCollector.class);
protected final String myLock;
@Nullable
private final Disposable myParentDisposable;
/** Guarded by {@link #myLock} */
@SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
@@ -32,32 +36,7 @@ public class KeyedExtensionCollector<T, KeyT> implements ModificationTracker {
private final String myEpName;
private final SimpleModificationTracker myTracker = new SimpleModificationTracker();
private final ExtensionPointAndAreaListener<KeyedLazyInstance<T>> myListener = new ExtensionPointAndAreaListener<KeyedLazyInstance<T>>() {
@Override
public void extensionAdded(@NotNull KeyedLazyInstance<T> bean, @NotNull PluginDescriptor pluginDescriptor) {
synchronized (myLock) {
if (bean.getKey() == null) {
throw new PluginException("No key specified for extension of class " + bean.getInstance().getClass(), pluginDescriptor.getPluginId());
}
myCache.remove(bean.getKey());
myTracker.incModificationCount();
}
}
@Override
public void extensionRemoved(@NotNull KeyedLazyInstance<T> bean, @NotNull PluginDescriptor pluginDescriptor) {
synchronized (myLock) {
myCache.remove(bean.getKey());
myTracker.incModificationCount();
}
}
@Override
public void areaReplaced(@NotNull ExtensionsArea area) {
myCache.clear();
myTracker.incModificationCount();
}
};
protected final AtomicBoolean myEpListenerAdded = new AtomicBoolean();
public KeyedExtensionCollector(@NotNull String epName) {
this(epName, null);
@@ -66,23 +45,46 @@ public class KeyedExtensionCollector<T, KeyT> implements ModificationTracker {
public KeyedExtensionCollector(@NotNull String epName, @Nullable Disposable parentDisposable) {
myEpName = epName;
myLock = "lock for KeyedExtensionCollector " + epName;
myParentDisposable = parentDisposable;
}
Extensions.getRootArea().addAvailabilityListener(epName, new ExtensionPointAvailabilityListener() {
@TestOnly
public void clearCache() {
myCache.clear();
myTracker.incModificationCount();
}
private void addExtensionPointListener(@NotNull ExtensionPoint<KeyedLazyInstance<T>> point) {
if (!myEpListenerAdded.compareAndSet(false, true)) {
return;
}
point.addExtensionPointListener(new ExtensionPointAndAreaListener<KeyedLazyInstance<T>>() {
@Override
public void extensionPointRegistered(@NotNull ExtensionPoint extensionPoint) {
if (extensionPoint.getName().equals(epName)) {
//noinspection unchecked
extensionPoint.addExtensionPointListener(myListener, false, parentDisposable);
myCache.clear();
public void extensionAdded(@NotNull KeyedLazyInstance<T> bean, @NotNull PluginDescriptor pluginDescriptor) {
synchronized (myLock) {
if (bean.getKey() == null) {
throw new PluginException("No key specified for extension of class " + bean.getInstance().getClass(), pluginDescriptor.getPluginId());
}
myCache.remove(bean.getKey());
myTracker.incModificationCount();
}
}
@Override
public void extensionPointRemoved(@NotNull ExtensionPoint extensionPoint) {
// no need to remove myListener - it should unregister automatically
public void extensionRemoved(@NotNull KeyedLazyInstance<T> bean, @NotNull PluginDescriptor pluginDescriptor) {
synchronized (myLock) {
myCache.remove(bean.getKey());
myTracker.incModificationCount();
}
}
}, parentDisposable);
@Override
public void areaReplaced(@NotNull ExtensionsArea area) {
myCache.clear();
myTracker.incModificationCount();
}
}, false, myParentDisposable);
}
public void addExplicitExtension(@NotNull KeyT key, @NotNull T t) {
@@ -163,7 +165,13 @@ public class KeyedExtensionCollector<T, KeyT> implements ModificationTracker {
@NotNull
protected final List<KeyedLazyInstance<T>> getExtensions() {
ExtensionPoint<KeyedLazyInstance<T>> point = getPoint();
return point == null ? Collections.emptyList() : point.getExtensionList();
if (point == null) {
return Collections.emptyList();
}
else {
addExtensionPointListener(point);
return point.getExtensionList();
}
}
@Nullable
@@ -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-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.
package com.intellij.psi;
@@ -12,7 +12,6 @@ import java.util.Collection;
* @author Dmitry Avdeev
*/
public abstract class FileContextProvider {
public static final ExtensionPointName<FileContextProvider> EP_NAME = new ExtensionPointName<>("com.intellij.fileContextProvider");
@Nullable
@@ -6,6 +6,7 @@ import com.intellij.lang.Language;
import com.intellij.lang.LanguageExtension;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.TransactionGuard;
import com.intellij.openapi.components.Service;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
@@ -24,13 +25,24 @@ import java.util.concurrent.atomic.AtomicBoolean;
/**
* A utility class used to query the language for PSI from {@link LanguageSubstitutor} extensions.
*/
@Service
public final class LanguageSubstitutors extends LanguageExtension<LanguageSubstitutor> {
public static final LanguageSubstitutors INSTANCE = new LanguageSubstitutors();
/**
* @deprecated Use {@link #getInstance()}
*/
@Deprecated
public static final LanguageSubstitutors INSTANCE = getInstance();
private static final Logger LOG = Logger.getInstance(LanguageSubstitutors.class);
private static final Key<Key<Language>> PROJECT_KEY_FOR_SUBSTITUTED_LANG_KEY = Key.create("PROJECT_KEY_FOR_SUBSTITUTED_LANG_KEY");
private static final AtomicBoolean REQUESTS_DRAIN_NEEDED = new AtomicBoolean(true);
private static final ConcurrentMap<VirtualFile, SubstitutionInfo> ourReparsingRequests = ContainerUtil.newConcurrentMap();
@NotNull
public static LanguageSubstitutors getInstance() {
return ApplicationManager.getApplication().getService(LanguageSubstitutors.class, true);
}
private LanguageSubstitutors() {
super("com.intellij.lang.substitutor");
}
@@ -16,7 +16,6 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.impl.CoreCommandProcessor;
import com.intellij.openapi.components.ExtensionAreas;
import com.intellij.openapi.editor.impl.DocumentImpl;
import com.intellij.openapi.extensions.*;
import com.intellij.openapi.fileEditor.FileDocumentManager;
@@ -27,7 +26,6 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.impl.CoreProgressManager;
import com.intellij.openapi.util.ClassExtension;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.StaticGetter;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.VirtualFileSystem;
import com.intellij.openapi.vfs.encoding.EncodingManager;
@@ -86,14 +84,12 @@ public class CoreApplicationEnvironment {
myApplication = createApplication(myParentDisposable);
ApplicationManager.setApplication(myApplication,
new StaticGetter<>(myFileTypeRegistry),
() -> myFileTypeRegistry,
myParentDisposable);
myLocalFileSystem = createLocalFileSystem();
myJarFileSystem = createJarFileSystem();
myJrtFileSystem = createJrtFileSystem();
Extensions.registerAreaClass(ExtensionAreas.IDEA_PROJECT, null);
final MutablePicoContainer appContainer = myApplication.getPicoContainer();
registerComponentInstance(appContainer, FileDocumentManager.class, new MockFileDocumentManagerImpl(
charSequence -> new DocumentImpl(charSequence), null));
@@ -8,7 +8,6 @@ import com.intellij.mock.MockProject;
import com.intellij.mock.MockResolveScopeManager;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.util.Disposer;
@@ -97,7 +96,7 @@ public class CoreProjectEnvironment {
public <T> void registerProjectExtensionPoint(@NotNull ExtensionPointName<T> extensionPointName,
@NotNull Class<? extends T> aClass) {
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getArea(myProject), extensionPointName, aClass);
CoreApplicationEnvironment.registerExtensionPoint(myProject.getExtensionArea(), extensionPointName, aClass);
}
public <T> void addProjectExtension(@NotNull ExtensionPointName<T> name, @NotNull final T extension) {
@@ -10,8 +10,6 @@ import com.intellij.openapi.components.ComponentConfig;
import com.intellij.openapi.components.OldComponentConfig;
import com.intellij.openapi.components.ServiceDescriptor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.ExtensionsArea;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.extensions.impl.ExtensionPointImpl;
@@ -48,6 +46,10 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class IdeaPluginDescriptorImpl implements IdeaPluginDescriptor {
public enum OS {
mac, linux, windows, unix, freebsd
}
public static final IdeaPluginDescriptorImpl[] EMPTY_ARRAY = new IdeaPluginDescriptorImpl[0];
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.plugins.PluginDescriptor");
@@ -470,16 +472,22 @@ public final class IdeaPluginDescriptorImpl implements IdeaPluginDescriptor {
return build;
}
public void registerExtensionPoints(@NotNull ExtensionsArea area) {
ContainerDescriptor containerDescriptor = getContainerDescriptorByExtensionArea(area.getAreaClass());
if (containerDescriptor == null) {
throw new IllegalStateException("Unknown area: " + area);
public void registerExtensionPoints(@NotNull ExtensionsArea area, @NotNull MutablePicoContainer picoContainer) {
ContainerDescriptor containerDescriptor;
if (picoContainer.getParent() == null) {
containerDescriptor = myAppContainerDescriptor;
}
else if (picoContainer.getParent().getParent() == null) {
containerDescriptor = myProjectContainerDescriptor;
}
else {
containerDescriptor = myModuleContainerDescriptor;
}
List<Element> extensionsPoints = containerDescriptor.extensionsPoints;
if (extensionsPoints != null) {
for (Element element : extensionsPoints) {
area.registerExtensionPoint(this, element);
area.registerExtensionPoint(this, element, picoContainer);
}
}
}
@@ -510,14 +518,6 @@ public final class IdeaPluginDescriptorImpl implements IdeaPluginDescriptor {
}
}
// made public for Upsource
public void registerExtensions(@NotNull ExtensionsArea area, @NotNull ExtensionPoint<?> extensionPoint) {
if (myExtensions == null) {
return;
}
((ExtensionPointImpl<?>)extensionPoint).createAndRegisterAdapters(myExtensions.get(extensionPoint.getName()), this, area.getPicoContainer());
}
@Override
public String getDescription() {
return myDescription.getValue();
@@ -841,19 +841,19 @@ public final class IdeaPluginDescriptorImpl implements IdeaPluginDescriptor {
return true;
}
if (os.equals(Extensions.OS.mac.name())) {
if (os.equals(OS.mac.name())) {
return SystemInfo.isMac;
}
else if (os.equals(Extensions.OS.linux.name())) {
else if (os.equals(OS.linux.name())) {
return SystemInfo.isLinux;
}
else if (os.equals(Extensions.OS.windows.name())) {
else if (os.equals(OS.windows.name())) {
return SystemInfo.isWindows;
}
else if (os.equals(Extensions.OS.unix.name())) {
else if (os.equals(OS.unix.name())) {
return SystemInfo.isUnix;
}
else if (os.equals(Extensions.OS.freebsd.name())) {
else if (os.equals(OS.freebsd.name())) {
return SystemInfo.isFreeBSD;
}
else {
@@ -13,9 +13,11 @@ import com.intellij.openapi.application.JetBrainsProtocolHandler;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.components.ExtensionAreas;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.*;
import com.intellij.openapi.extensions.ExtensionInstantiationException;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.ExtensionsArea;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.extensions.impl.ExtensionPointImpl;
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl;
import com.intellij.openapi.project.Project;
@@ -41,6 +43,7 @@ import gnu.trove.THashSet;
import gnu.trove.TObjectIntHashMap;
import org.jdom.JDOMException;
import org.jetbrains.annotations.*;
import org.picocontainer.MutablePicoContainer;
import java.io.*;
import java.lang.invoke.MethodHandle;
@@ -406,7 +409,7 @@ public class PluginManagerCore {
@ApiStatus.Internal
@NotNull
public static PluginException createPluginException(@NotNull String errorMessage, @Nullable Throwable cause,
@NotNull Class pluginClass) {
@NotNull Class<?> pluginClass) {
ClassLoader classLoader = pluginClass.getClassLoader();
PluginId pluginId = classLoader instanceof PluginClassLoader ? ((PluginClassLoader)classLoader).getPluginId()
: getPluginByClassName(pluginClass.getName());
@@ -532,11 +535,6 @@ public class PluginManagerCore {
return loadPlugins == null || Boolean.TRUE.toString().equals(loadPlugins);
}
public static void configureExtensions() {
Extensions.registerAreaClass(ExtensionAreas.IDEA_PROJECT, null);
Extensions.registerAreaClass(ExtensionAreas.IDEA_MODULE, ExtensionAreas.IDEA_PROJECT);
}
@Nullable
private static ClassLoader createPluginClassLoader(@NotNull File[] classPath,
@NotNull ClassLoader[] parentLoaders,
@@ -1496,7 +1494,6 @@ public class PluginManagerCore {
@NotNull
private static IdeaPluginDescriptorImpl[] initializePlugins(@NotNull ClassLoader coreLoader) {
Activity loadPluginsActivity = ParallelActivity.PREPARE_APP_INIT.start(ActivitySubNames.INIT_PLUGINS);
configureExtensions();
List<String> errors = new ArrayList<>();
IdeaPluginDescriptorImpl[] pluginDescriptors = loadDescriptors(errors);
@@ -1536,16 +1533,6 @@ public class PluginManagerCore {
}
loadPluginsActivity.end("plugin count: " + pluginDescriptors.length);
Activity registerExtensionsActivity = ParallelActivity.PREPARE_APP_INIT.start(ActivitySubNames.REGISTER_EXTENSIONS);
registerExtensionPointsAndExtensions((ExtensionsAreaImpl)Extensions.getRootArea(), result);
//noinspection deprecation
Extensions.AREA_LISTENER_EXTENSION_POINT.getPoint(null).registerExtension(new AreaListener() {
@Override
public void areaCreated(@NotNull String areaClass, @NotNull AreaInstance areaInstance) {
registerExtensionPointsAndExtensions((ExtensionsAreaImpl)Extensions.getArea(areaInstance), result);
}
});
registerExtensionsActivity.end();
ourLoadedPlugins = Collections.unmodifiableList(result);
ourPlugins.set(pluginDescriptors);
@@ -1634,15 +1621,17 @@ public class PluginManagerCore {
}
}
private static void registerExtensionPointsAndExtensions(@NotNull ExtensionsAreaImpl area,
@NotNull List<IdeaPluginDescriptorImpl> loadedPlugins) {
@ApiStatus.Internal
public static void registerExtensionPointsAndExtensions(@NotNull ExtensionsAreaImpl area,
@NotNull MutablePicoContainer container,
@NotNull List<IdeaPluginDescriptorImpl> loadedPlugins) {
for (IdeaPluginDescriptorImpl descriptor : loadedPlugins) {
descriptor.registerExtensionPoints(area);
descriptor.registerExtensionPoints(area, container);
}
ExtensionPointImpl[] extensionPoints = area.getExtensionPoints();
ExtensionPointImpl<?>[] extensionPoints = area.getExtensionPoints();
for (IdeaPluginDescriptorImpl descriptor : loadedPlugins) {
descriptor.registerExtensions(extensionPoints, area.getPicoContainer());
descriptor.registerExtensions(extensionPoints, container);
}
// to avoid clearing cache for each plugin on registration, cache is cleared only now
@@ -1673,7 +1662,8 @@ public class PluginManagerCore {
}
if (descriptor != null) {
registerExtensionPointsAndExtensions((ExtensionsAreaImpl)area, Collections.singletonList(descriptor));
registerExtensionPointsAndExtensions((ExtensionsAreaImpl)area,
(MutablePicoContainer)ApplicationManager.getApplication().getPicoContainer(), Collections.singletonList(descriptor));
}
else {
getLogger().error("Cannot load " + fileName + " from " + pluginRoot);
@@ -1683,7 +1673,7 @@ public class PluginManagerCore {
@NotNull
private static synchronized IdeaPluginDescriptorImpl[] initPlugins(@Nullable ClassLoader coreLoader) {
if (coreLoader == null) {
Class callerClass = ReflectionUtil.findCallerClass(1);
Class<?> callerClass = ReflectionUtil.findCallerClass(1);
assert callerClass != null;
coreLoader = callerClass.getClassLoader();
}
@@ -1,32 +1,22 @@
/*
* Copyright 2000-2016 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-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.
package com.intellij.mock;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.*;
import com.intellij.openapi.application.impl.AnyModalityState;
import com.intellij.openapi.components.Service;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.ThrowableComputable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.ide.PooledThreadExecutor;
import java.awt.*;
import java.lang.reflect.Modifier;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
@@ -35,7 +25,36 @@ public class MockApplication extends MockComponentManager implements Application
public MockApplication(@NotNull Disposable parentDisposable) {
super(null, parentDisposable);
INSTANCES_CREATED++;
//noinspection TestOnlyProblems
Extensions.setRootArea(getExtensionArea(), parentDisposable);
}
@NotNull
@TestOnly
public static MockApplication setUp(@NotNull Disposable parentDisposable) {
MockApplication app = new MockApplication(parentDisposable);
ApplicationManager.setApplication(app, parentDisposable);
return app;
}
@Override
public <T> T getService(@NotNull Class<T> serviceClass, boolean isCreate) {
T service = super.getService(serviceClass, isCreate);
if (service == null && isCreate && Modifier.isFinal(serviceClass.getModifiers()) && serviceClass.isAnnotationPresent(Service.class)) {
//noinspection SynchronizeOnThis,SynchronizationOnLocalVariableOrMethodParameter
synchronized (serviceClass) {
service = super.getService(serviceClass, true);
if (service != null) {
return service;
}
getPicoContainer().registerComponentImplementation(serviceClass.getName(), serviceClass);
return super.getService(serviceClass, true);
}
}
return service;
}
@Override
@@ -3,7 +3,6 @@ package com.intellij.mock;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
@@ -14,12 +13,8 @@ import javax.swing.*;
public class MockApplicationEx extends MockApplication implements ApplicationEx {
public MockApplicationEx(@NotNull Disposable parentDisposable) {
super(parentDisposable);
}
@NotNull
@Override
public String getName() {
return "mock";
Extensions.setRootArea(getExtensionArea());
}
@Override
@@ -73,12 +68,6 @@ public class MockApplicationEx extends MockApplication implements ApplicationEx
return false;
}
@NotNull
@Override
public <T> T[] getExtensions(@NotNull final ExtensionPointName<T> extensionPointName) {
return Extensions.getRootArea().getExtensionPoint(extensionPointName).getExtensions();
}
@Override
public void assertIsDispatchThread(@Nullable final JComponent component) {
}
@@ -4,31 +4,30 @@ package com.intellij.mock;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.BaseComponent;
import com.intellij.openapi.components.ComponentManager;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Conditions;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.messages.impl.MessageBusFactoryImpl;
import com.intellij.util.pico.DefaultPicoContainer;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.picocontainer.MutablePicoContainer;
import org.picocontainer.PicoContainer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class MockComponentManager extends UserDataHolderBase implements ComponentManager {
private final MessageBus myMessageBus = new MessageBusFactoryImpl().createMessageBus(this);
private final MutablePicoContainer myPicoContainer;
private final DefaultPicoContainer myPicoContainer;
private final ExtensionsAreaImpl myExtensionArea;
private final Map<Class<?>, Object> myComponents = new HashMap<>();
private final Map<Class<?>, Object> myComponents = new THashMap<>();
private final Set<Object> myDisposableComponents = ContainerUtil.newConcurrentSet();
private boolean myDisposed;
@@ -47,13 +46,19 @@ public class MockComponentManager extends UserDataHolderBase implements Componen
};
myPicoContainer.registerComponentInstance(this);
myExtensionArea = new ExtensionsAreaImpl(myPicoContainer);
Disposer.register(parentDisposable, this);
}
@NotNull
@Override
public ExtensionsAreaImpl getExtensionArea() {
return myExtensionArea;
}
private void registerComponentInDisposer(@Nullable Object o) {
if (o instanceof Disposable && o != this && !(o instanceof MessageBus)) {
if (myDisposableComponents.add(o))
Disposer.register(this, (Disposable)o);
if (o instanceof Disposable && o != this && !(o instanceof MessageBus) && myDisposableComponents.add(o)) {
Disposer.register(this, (Disposable)o);
}
}
@@ -89,6 +94,13 @@ public class MockComponentManager extends UserDataHolderBase implements Componen
return (T)(o != null ? o : myComponents.get(interfaceClass));
}
@Override
public <T> T getService(@NotNull Class<T> serviceClass, boolean isCreate) {
T result = myPicoContainer.getService(serviceClass, isCreate);
registerComponentInDisposer(result);
return result;
}
@Override
public <T> T getComponent(@NotNull Class<T> interfaceClass, T defaultImplementation) {
return getComponent(interfaceClass);
@@ -99,12 +111,10 @@ public class MockComponentManager extends UserDataHolderBase implements Componen
return false;
}
@SuppressWarnings("unchecked")
@Override
@NotNull
public <T> T[] getComponents(@NotNull Class<T> baseClass) {
final List<T> list = myPicoContainer.getComponentInstancesOfType(baseClass);
return list.toArray(ArrayUtil.newArray(baseClass, 0));
throw new UnsupportedOperationException();
}
@Override
@@ -130,12 +140,6 @@ public class MockComponentManager extends UserDataHolderBase implements Componen
myDisposed = true;
}
@NotNull
@Override
public <T> T[] getExtensions(@NotNull final ExtensionPointName<T> extensionPointName) {
throw new UnsupportedOperationException("getExtensions()");
}
@NotNull
@Override
public Condition<?> getDisposed() {
@@ -1,29 +1,11 @@
/*
* Copyright 2000-2017 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-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.
package com.intellij.mock;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.ExtensionAreas;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -40,13 +22,6 @@ public class MockProject extends MockComponentManager implements Project {
public MockProject(PicoContainer parent, @NotNull Disposable parentDisposable) {
super(parent, parentDisposable);
Extensions.instantiateArea(ExtensionAreas.IDEA_PROJECT, this, null);
Disposer.register(parentDisposable, new Disposable() {
@Override
public void dispose() {
Extensions.disposeArea(MockProject.this);
}
});
}
@Override
@@ -57,7 +32,7 @@ public class MockProject extends MockComponentManager implements Project {
@NotNull
@Override
public Condition<?> getDisposed() {
return (Condition)o -> isDisposed();
return o -> isDisposed();
}
@Override
@@ -121,12 +96,6 @@ public class MockProject extends MockComponentManager implements Project {
public void save() {
}
@NotNull
@Override
public <T> T[] getExtensions(@NotNull final ExtensionPointName<T> extensionPointName) {
return Extensions.getArea(this).getExtensionPoint(extensionPointName).getExtensions();
}
public void projectOpened() {
final ProjectComponent[] components = getComponents(ProjectComponent.class);
for (ProjectComponent component : components) {
@@ -38,9 +38,6 @@ public interface ApplicationEx extends Application {
return LoadingPhase.COMPONENT_LOADED.isComplete();
}
@NotNull
String getName();
/**
* @return true if this thread is inside read action.
* @see #runReadAction(Runnable)
@@ -13,8 +13,11 @@ import com.intellij.openapi.components.ComponentConfig;
import com.intellij.openapi.components.ComponentManager;
import com.intellij.openapi.components.NamedComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.ExtensionsArea;
import com.intellij.openapi.extensions.PluginDescriptor;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
@@ -50,7 +53,9 @@ import java.util.Map;
public abstract class ComponentManagerImpl extends UserDataHolderBase implements ComponentManager, Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.components.ComponentManager");
private final MutablePicoContainer myPicoContainer;
private final DefaultPicoContainer myPicoContainer;
private final ExtensionsAreaImpl myExtensionArea;
private volatile boolean myDisposed;
private volatile boolean myDisposeCompleted;
@@ -66,16 +71,19 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
private final List<BaseComponent> myBaseComponents = new SmartList<>();
private final ComponentManager myParentComponentManager;
private final ComponentManager myParent;
protected ComponentManagerImpl(@Nullable ComponentManager parentComponentManager) {
myParentComponentManager = parentComponentManager;
myPicoContainer = bootstrapPicoContainer(toString());
protected ComponentManagerImpl(@Nullable ComponentManager parent) {
this(parent, new DefaultPicoContainer(parent == null ? null : parent.getPicoContainer()));
}
protected ComponentManagerImpl(@Nullable ComponentManager parentComponentManager, @NotNull String name) {
myParentComponentManager = parentComponentManager;
myPicoContainer = bootstrapPicoContainer(name);
protected ComponentManagerImpl(@Nullable ComponentManager parent, @NotNull DefaultPicoContainer picoContainer) {
myParent = parent;
myPicoContainer = picoContainer;
myExtensionArea = new ExtensionsAreaImpl(myPicoContainer);
if (parent == null) {
Extensions.setRootArea(myExtensionArea);
}
}
@Nullable
@@ -93,7 +101,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
String activityNamePrefix = activityNamePrefix();
Activity activity = activityNamePrefix == null ? null : StartUpMeasurer.start(activityNamePrefix + Phases.CREATE_COMPONENTS_SUFFIX);
DefaultPicoContainer picoContainer = (DefaultPicoContainer)getPicoContainer();
DefaultPicoContainer picoContainer = getPicoContainer();
for (ComponentAdapter componentAdapter : picoContainer.getComponentAdapters()) {
if (componentAdapter instanceof ComponentConfigComponentAdapter) {
((ComponentConfigComponentAdapter)componentAdapter).getComponentInstance(picoContainer, indicator);
@@ -167,6 +175,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
}
myBaseComponents.clear();
//noinspection NonPrivateFieldAccessedInSynchronizedContext
myComponentConfigCount = -1;
}
@@ -226,7 +235,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
}
@Override
public boolean hasComponent(@NotNull Class interfaceClass) {
public boolean hasComponent(@NotNull Class<?> interfaceClass) {
return getPicoContainer().getComponentAdapter(interfaceClass) != null;
}
@@ -245,7 +254,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
public final <T> List<T> getComponentInstancesOfType(@NotNull Class<T> baseClass, boolean createIfNotYet) {
List<T> result = null;
// we must use instances only from our adapter (could be service or extension point or something else)
for (ComponentAdapter componentAdapter : ((DefaultPicoContainer)getPicoContainer()).getComponentAdapters()) {
for (ComponentAdapter componentAdapter : getPicoContainer().getComponentAdapters()) {
if (componentAdapter instanceof ComponentConfigComponentAdapter &&
ReflectionUtil.isAssignable(baseClass, componentAdapter.getComponentImplementation())) {
ComponentConfigComponentAdapter adapter = (ComponentConfigComponentAdapter)componentAdapter;
@@ -264,14 +273,20 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
@Override
@NotNull
public MutablePicoContainer getPicoContainer() {
MutablePicoContainer container = myPicoContainer;
public DefaultPicoContainer getPicoContainer() {
DefaultPicoContainer container = myPicoContainer;
if (container == null || myDisposeCompleted) {
throwAlreadyDisposed();
}
return container;
}
@NotNull
@Override
public ExtensionsArea getExtensionArea() {
return myExtensionArea;
}
@Contract("->fail")
private void throwAlreadyDisposed() {
ReadAction.run(() -> {
@@ -280,11 +295,6 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
});
}
@NotNull
protected MutablePicoContainer createPicoContainer() {
return myParentComponentManager == null ? new DefaultPicoContainer() : new DefaultPicoContainer(myParentComponentManager.getPicoContainer());
}
protected boolean isComponentSuitable(@NotNull ComponentConfig componentConfig) {
Map<String, String> options = componentConfig.options;
return options == null || !Boolean.parseBoolean(options.get("internal")) || ApplicationManager.getApplication().isInternal();
@@ -311,10 +321,6 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
return myDisposed;
}
protected MutablePicoContainer bootstrapPicoContainer(@NotNull String name) {
return createPicoContainer();
}
protected void logMessageBusDelivery(Topic<?> topic, String messageName, Object handler, long durationNanos) {
if (!StartUpMeasurer.isMeasuringPluginStartupCosts()) {
((MessageBusImpl) myMessageBus).setMessageDeliveryListener(null);
@@ -327,7 +333,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
}
protected final ComponentManager getParentComponentManager() {
return myParentComponentManager;
return myParent;
}
@Nullable
@@ -342,7 +348,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
@Nullable
private ComponentConfigComponentAdapter getComponentAdapter(@NotNull Class<?> componentImplementation) {
for (ComponentAdapter componentAdapter : ((DefaultPicoContainer)getPicoContainer()).getComponentAdapters()) {
for (ComponentAdapter componentAdapter : getPicoContainer().getComponentAdapters()) {
if (componentAdapter instanceof ComponentConfigComponentAdapter && componentAdapter.getComponentImplementation() == componentImplementation) {
return (ComponentConfigComponentAdapter)componentAdapter;
}
@@ -1,18 +1,4 @@
/*
* 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.
*/
// 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.
/*
* @author max
@@ -99,7 +85,7 @@ public class PsiFileFactoryImpl extends PsiFileFactory {
final LightVirtualFile virtualFile = new LightVirtualFile(name, fileType, text, modificationStamp);
if(fileType instanceof LanguageFileType){
final Language language =
LanguageSubstitutors.INSTANCE.substituteLanguage(((LanguageFileType)fileType).getLanguage(), virtualFile, myManager.getProject());
LanguageSubstitutors.getInstance().substituteLanguage(((LanguageFileType)fileType).getLanguage(), virtualFile, myManager.getProject());
final PsiFile file = trySetupPsiForFile(virtualFile, language, eventSystemEnabled, markAsCopy);
if (file != null) return 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-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.
package com.intellij.util.indexing;
import com.intellij.lang.FileASTNode;
@@ -30,7 +16,10 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.LanguageSubstitutors;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
@@ -143,7 +132,7 @@ public class FileContentImpl extends UserDataHolderBase implements PsiDependentF
public static PsiFile createFileFromText(@NotNull Project project, @NotNull CharSequence text, @NotNull LanguageFileType fileType,
@NotNull VirtualFile file, @NotNull String fileName) {
final Language language = fileType.getLanguage();
final Language substitutedLanguage = LanguageSubstitutors.INSTANCE.substituteLanguage(language, file, project);
final Language substitutedLanguage = LanguageSubstitutors.getInstance().substituteLanguage(language, file, project);
PsiFile psiFile = PsiFileFactory.getInstance(project).createFileFromText(fileName, substitutedLanguage, text, false, false, false, file);
if (psiFile == null) {
throw new IllegalStateException("psiFile is null. language = " + language.getID() +
@@ -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-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.
package com.intellij.util.indexing;
import com.intellij.lang.Language;
@@ -48,7 +34,7 @@ public class SubstitutedFileType extends LanguageFileType{
}
if (fileType instanceof LanguageFileType) {
final Language language = ((LanguageFileType)fileType).getLanguage();
final Language substitutedLanguage = LanguageSubstitutors.INSTANCE.substituteLanguage(language, file, project);
final Language substitutedLanguage = LanguageSubstitutors.getInstance().substituteLanguage(language, file, project);
LanguageFileType substFileType;
if (!substitutedLanguage.equals(language) && (substFileType = substitutedLanguage.getAssociatedFileType()) != null) {
return new SubstitutedFileType(fileType, substFileType, substitutedLanguage);
@@ -1,18 +1,4 @@
/*
* 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.
*/
// 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.
package com.intellij.diff.applications;
import com.intellij.diff.DiffDialogHints;
@@ -32,13 +18,12 @@ import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
public class DiffApplication extends DiffApplicationBase {
public DiffApplication() {
final class DiffApplication extends DiffApplicationBase {
DiffApplication() {
super("diff", 2, 3);
}
@@ -51,8 +36,8 @@ public class DiffApplication extends DiffApplicationBase {
@NotNull
@Override
public Future<CliResult> processCommand(@NotNull String[] args, @Nullable String currentDirectory) throws Exception {
List<String> filePaths = Arrays.asList(args).subList(1, args.length);
public Future<CliResult> processCommand(@NotNull List<String> args, @Nullable String currentDirectory) throws Exception {
List<String> filePaths = args.subList(1, args.size());
List<VirtualFile> files = findFiles(filePaths, currentDirectory);
Project project = guessProject(files);
@@ -22,8 +22,8 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicReference;
public class MergeApplication extends DiffApplicationBase {
public MergeApplication() {
class MergeApplication extends DiffApplicationBase {
MergeApplication() {
super("merge", 3, 4);
}
@@ -36,8 +36,8 @@ public class MergeApplication extends DiffApplicationBase {
@NotNull
@Override
public Future<CliResult> processCommand(@NotNull String[] args, @Nullable String currentDirectory) throws Exception {
List<String> filePaths = Arrays.asList(args).subList(1, args.length);
public Future<CliResult> processCommand(@NotNull List<String> args, @Nullable String currentDirectory) throws Exception {
List<String> filePaths = args.subList(1, args.size());
List<VirtualFile> files = findFiles(filePaths, currentDirectory);
Project project = guessProject(files);
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 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-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.
package com.intellij.diff.lang;
import com.intellij.diff.contents.DiffContent;
@@ -64,7 +50,7 @@ public abstract class LangDiffIgnoredRangeProvider implements DiffIgnoredRangePr
if (language != null && content instanceof DocumentContent) {
VirtualFile highlightFile = ((DocumentContent)content).getHighlightFile();
if (highlightFile != null) language = LanguageSubstitutors.INSTANCE.substituteLanguage(language, highlightFile, project);
if (highlightFile != null) language = LanguageSubstitutors.getInstance().substituteLanguage(language, highlightFile, project);
}
return language;
@@ -6,7 +6,6 @@ import com.intellij.dvcs.repo.VcsRepositoryCreator;
import com.intellij.dvcs.repo.VcsRepositoryManager;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsKey;
@@ -55,7 +54,7 @@ public class VcsRepositoryManagerTest extends VcsPlatformTest {
@NotNull
private ExtensionPoint<VcsRepositoryCreator> getExtensionPoint() {
return Extensions.getArea(myProject).getExtensionPoint(VcsRepositoryCreator.EXTENSION_POINT_NAME);
return VcsRepositoryCreator.EXTENSION_POINT_NAME.getPoint(myProject);
}
@Override
@@ -1,26 +1,10 @@
/*
* 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.
*/
// 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.
package com.intellij.openapi.fileTypes;
import com.intellij.lang.LanguageExtensionPoint;
import com.intellij.util.xmlb.annotations.Attribute;
public class SyntaxHighlighterFactoryEP extends LanguageExtensionPoint<SyntaxHighlighterFactory> {
// For backward compatibility
final class SyntaxHighlighterFactoryEP extends LanguageExtensionPoint<SyntaxHighlighterFactory> {
/**
* @deprecated use "language" attribute instead
*/
@@ -30,12 +14,7 @@ public class SyntaxHighlighterFactoryEP extends LanguageExtensionPoint<SyntaxHig
@Override
public String getKey() {
final String result = super.getKey();
if (result != null) {
return result;
}
//noinspection deprecation
return key;
String result = super.getKey();
return result == null ? key : result;
}
}
@@ -1,18 +1,4 @@
/*
* 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.
*/
// 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.
package com.intellij.openapi.editor.highlighter;
import com.intellij.lang.Language;
@@ -93,7 +79,7 @@ public class EditorHighlighterFactoryImpl extends EditorHighlighterFactory {
private static LanguageFileType substituteFileType(Language language, VirtualFile vFile, Project project) {
LanguageFileType fileType = null;
if (vFile != null && project != null) {
Language substLanguage = LanguageSubstitutors.INSTANCE.substituteLanguage(language, vFile, project);
Language substLanguage = LanguageSubstitutors.getInstance().substituteLanguage(language, vFile, project);
if (substLanguage != language) {
fileType = substLanguage.getAssociatedFileType();
}
@@ -1,22 +1,11 @@
/*
* Copyright 2000-2009 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-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.
package com.intellij.openapi.extensions;
/**
* @author akireyev
*/
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
public interface AreaInstance {
@NotNull
@ApiStatus.Internal
ExtensionsArea getExtensionArea();
}
@@ -1,15 +0,0 @@
// 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.
package com.intellij.openapi.extensions;
import org.jetbrains.annotations.NotNull;
/**
* @author akireyev
*/
public interface AreaListener {
default void areaCreated(@NotNull String areaClass, @NotNull AreaInstance areaInstance) {
}
default void areaDisposing(@NotNull String areaClass, @NotNull AreaInstance areaInstance) {
}
}
@@ -25,7 +25,7 @@ public abstract class BaseExtensionPointName {
@Nullable
protected static <T> T findExtension(@NotNull BaseExtensionPointName pointName, @NotNull Class<T> instanceOf, @Nullable AreaInstance areaInstance, boolean isRequired) {
ExtensionPointImpl<T> point = ((ExtensionsAreaImpl)Extensions.getArea(areaInstance)).getExtensionPoint(pointName.getName());
ExtensionPointImpl<T> point = ((ExtensionsAreaImpl)(areaInstance == null ? Extensions.getRootArea() : areaInstance.getExtensionArea())).getExtensionPoint(pointName.getName());
return point.findExtension(instanceOf, isRequired);
}
}
@@ -1,55 +0,0 @@
// 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.
package com.intellij.openapi.extensions;
import org.jetbrains.annotations.NotNull;
/**
* @author AKireyev
*/
public class EPAvailabilityListenerExtension implements PluginAware {
public static final String EXTENSION_POINT_NAME = "com.intellij.openapi.extensions.epAvailabilityListener";
private String myExtensionPointName;
private String myListenerClass;
private PluginDescriptor myPluginDescriptor;
public EPAvailabilityListenerExtension(@NotNull String extensionPointName, @NotNull String listenerClass) {
myExtensionPointName = extensionPointName;
myListenerClass = listenerClass;
}
@NotNull
public String getExtensionPointName() {
return myExtensionPointName;
}
public void setExtensionPointName(@NotNull String extensionPointName) {
myExtensionPointName = extensionPointName;
}
@NotNull
public String getListenerClass() {
return myListenerClass;
}
public void setListenerClass(@NotNull String listenerClass) {
myListenerClass = listenerClass;
}
@Override
public void setPluginDescriptor(@NotNull PluginDescriptor pluginDescriptor) {
myPluginDescriptor = pluginDescriptor;
}
public PluginDescriptor getPluginDescriptor() {
return myPluginDescriptor;
}
@NotNull
public Class loadListenerClass() throws ClassNotFoundException {
if (myPluginDescriptor != null && myPluginDescriptor.getPluginClassLoader() != null) {
return Class.forName(getListenerClass(), true, myPluginDescriptor.getPluginClassLoader());
}
return Class.forName(getListenerClass());
}
}
@@ -50,7 +50,7 @@ public final class ExtensionPointName<T> extends BaseExtensionPointName {
@NotNull
public List<T> getExtensionsIfPointIsRegistered(@Nullable AreaInstance areaInstance) {
ExtensionPoint<T> point = Extensions.getArea(areaInstance).getExtensionPointIfRegistered(getName());
ExtensionPoint<T> point = (areaInstance == null ? Extensions.getRootArea() : areaInstance.getExtensionArea()).getExtensionPointIfRegistered(getName());
return point == null ? Collections.emptyList() : point.getExtensionList();
}
@@ -89,7 +89,8 @@ public final class ExtensionPointName<T> extends BaseExtensionPointName {
@NotNull
public ExtensionPoint<T> getPoint(@Nullable AreaInstance areaInstance) {
return Extensions.getArea(areaInstance).getExtensionPoint(getName());
ExtensionsArea area = areaInstance == null ? Extensions.getRootArea() : areaInstance.getExtensionArea();
return area.getExtensionPoint(getName());
}
@Nullable
@@ -3,67 +3,74 @@ package com.intellij.openapi.extensions;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl;
import com.intellij.openapi.extensions.impl.InterfaceExtensionPoint;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.pico.DefaultPicoContainer;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public final class Extensions {
public static final ExtensionPointName<AreaListener> AREA_LISTENER_EXTENSION_POINT = new ExtensionPointName<>("com.intellij.arealistener");
private static final Map<AreaInstance, ExtensionsAreaImpl> ourAreaInstance2area = ContainerUtil.newConcurrentMap();
private static final Map<String, AreaClassConfiguration> ourAreaClass2Configuration = ContainerUtil.newConcurrentMap();
@NotNull
private static ExtensionsAreaImpl ourRootArea = createRootArea();
private static ExtensionsAreaImpl ourRootArea;
private Extensions() {
}
@NotNull
private static ExtensionsAreaImpl createRootArea() {
ExtensionsAreaImpl rootArea = new ExtensionsAreaImpl(null, null, null);
rootArea.registerExtensionPoint(new InterfaceExtensionPoint<>(AREA_LISTENER_EXTENSION_POINT.getName(), AreaListener.class, rootArea.getPicoContainer()));
return rootArea;
public static void setRootArea(@NotNull ExtensionsAreaImpl area) {
ourRootArea = area;
}
@TestOnly
public static void setRootArea(@NotNull ExtensionsAreaImpl area, @NotNull Disposable parentDisposable) {
ExtensionsAreaImpl oldRootArea = ourRootArea;
ourRootArea = area;
Disposer.register(parentDisposable, () -> {
ourRootArea.notifyAreaReplaced(oldRootArea);
ourRootArea = oldRootArea;
});
}
/**
* @return instance containing application-level extensions
*/
@NotNull
public static ExtensionsArea getRootArea() {
return ourRootArea;
}
/**
* If {@code areaInstance} is a project returns instance containing project-level extensions for that project
* if {@code areaInstance} is a module returns instance containing module-level extensions for that module,
* if {@code areaInstance} is {@code null} returns instance containing application-level extensions.
* @deprecated Use {@link AreaInstance#getExtensionArea()}
*/
@NotNull
@Deprecated
public static ExtensionsArea getArea(@Nullable("null means root") AreaInstance areaInstance) {
if (areaInstance == null) {
return ourRootArea;
}
ExtensionsAreaImpl area = ourAreaInstance2area.get(areaInstance);
if (area == null) {
throw new IllegalArgumentException("No area instantiated for: " + areaInstance);
}
return area;
return areaInstance == null ? ourRootArea : areaInstance.getExtensionArea();
}
@TestOnly
private static final class TestAreaInstance implements AreaInstance {
private final DefaultPicoContainer container = new DefaultPicoContainer();
private final ExtensionsAreaImpl extensionArea = new ExtensionsAreaImpl(container);
@NotNull
@Override
public ExtensionsArea getExtensionArea() {
return extensionArea;
}
}
/**
* @deprecated Extension area is a part of component manager, no need to clean extension area - dispose component manager instead.
*/
@TestOnly
@Deprecated
public static void cleanRootArea(@NotNull Disposable parentDisposable) {
final ExtensionsAreaImpl oldRootArea = (ExtensionsAreaImpl)getRootArea();
final ExtensionsAreaImpl newArea = createRootArea();
ExtensionsAreaImpl oldRootArea = ourRootArea;
TestAreaInstance areaInstance = new TestAreaInstance();
final ExtensionsAreaImpl newArea = new ExtensionsAreaImpl(areaInstance.container);
ourRootArea = newArea;
oldRootArea.notifyAreaReplaced(newArea);
if (oldRootArea != null) {
oldRootArea.notifyAreaReplaced(newArea);
}
Disposer.register(parentDisposable, () -> {
ourRootArea = oldRootArea;
newArea.notifyAreaReplaced(oldRootArea);
@@ -116,94 +123,10 @@ public final class Extensions {
}
/**
* @deprecated Use {@link ExtensionPointName#findExtensionOrFail(Class)}
* @deprecated Not needed.
*/
@SuppressWarnings("unused")
@Deprecated
@NotNull
public static <T, U extends T> U findExtension(@NotNull ExtensionPointName<T> extensionPointName, AreaInstance areaInstance, @NotNull Class<U> extClass) {
return extensionPointName.findExtensionOrFail(extClass, areaInstance);
}
public static void instantiateArea(@NonNls @NotNull String areaClass, @NotNull AreaInstance areaInstance, @Nullable("null means root") AreaInstance parentAreaInstance) {
AreaClassConfiguration configuration = ourAreaClass2Configuration.get(areaClass);
if (configuration == null) {
throw new IllegalArgumentException("Area class is not registered: " + areaClass);
}
ExtensionsArea parentArea = getArea(parentAreaInstance);
if (!Objects.equals(parentArea.getAreaClass(), configuration.getParentClassName())) {
throw new IllegalArgumentException("Wrong parent area. Expected class: " + configuration.getParentClassName() + " actual class: " + parentArea.getAreaClass());
}
ExtensionsAreaImpl area = new ExtensionsAreaImpl(areaClass, areaInstance, parentArea.getPicoContainer());
if (ourAreaInstance2area.put(areaInstance, area) != null) {
throw new IllegalArgumentException("Area already instantiated for: " + areaInstance);
}
for (AreaListener listener : getAreaListeners()) {
listener.areaCreated(areaClass, areaInstance);
}
}
@NotNull
private static List<AreaListener> getAreaListeners() {
return getRootArea().getExtensionPoint(AREA_LISTENER_EXTENSION_POINT).getExtensionList();
}
public static void registerAreaClass(@NonNls @NotNull String areaClass, @Nullable @NonNls String parentAreaClass) {
if (ourAreaClass2Configuration.containsKey(areaClass)) {
// allow duplicate area class registrations if they are the same - fixing duplicate registration in tests is much more trouble
AreaClassConfiguration configuration = ourAreaClass2Configuration.get(areaClass);
if (!Objects.equals(configuration.getParentClassName(), parentAreaClass)) {
throw new RuntimeException("Area class already registered: " + areaClass + ", "+ configuration);
}
else {
return;
}
}
AreaClassConfiguration configuration = new AreaClassConfiguration(areaClass, parentAreaClass);
ourAreaClass2Configuration.put(areaClass, configuration);
}
public static void disposeArea(@NotNull AreaInstance areaInstance) {
assert ourAreaInstance2area.containsKey(areaInstance);
String areaClass = ourAreaInstance2area.get(areaInstance).getAreaClass();
if (areaClass == null) {
throw new IllegalArgumentException("Area class is null (area never instantiated?). Instance: " + areaInstance);
}
try {
for (AreaListener listener : getAreaListeners()) {
listener.areaDisposing(areaClass, areaInstance);
}
}
finally {
ourAreaInstance2area.remove(areaInstance);
}
}
private static class AreaClassConfiguration {
private final String myClassName;
private final String myParentClassName;
private AreaClassConfiguration(@NotNull String className, String parentClassName) {
myClassName = className;
myParentClassName = parentClassName;
}
@NotNull
public String getClassName() {
return myClassName;
}
public String getParentClassName() {
return myParentClassName;
}
@Override
public String toString() {
return "AreaClassConfiguration{myClassName='" + myClassName + '\'' + ", myParentClassName='" + myParentClassName + "'}";
}
}
public enum OS {
mac, linux, windows, unix, freebsd
}
}
@@ -10,16 +10,9 @@ import org.jetbrains.annotations.TestOnly;
import org.picocontainer.MutablePicoContainer;
/**
* @see Extensions#getArea(AreaInstance)
* @see Extensions#getRootArea()
*/
public interface ExtensionsArea {
@TestOnly
void registerExtensionPoint(@NotNull BaseExtensionPointName extensionPoint,
@NotNull String extensionPointBeanClass,
@NotNull ExtensionPoint.Kind kind,
@NotNull Disposable parentDisposable);
/**
* @deprecated use {@link ExtensionsArea#registerExtensionPoint(BaseExtensionPointName, String, ExtensionPoint.Kind, Disposable)}
*/
@@ -48,28 +41,11 @@ public interface ExtensionsArea {
<T> ExtensionPoint<T> getExtensionPoint(@NotNull ExtensionPointName<T> extensionPointName);
@NotNull
ExtensionPoint[] getExtensionPoints();
ExtensionPoint<?>[] getExtensionPoints();
void addAvailabilityListener(@NotNull String extensionPointName, @NotNull ExtensionPointAvailabilityListener listener, @Nullable Disposable parentDisposable);
/**
* @deprecated use {@link #addAvailabilityListener(String, ExtensionPointAvailabilityListener, Disposable)}
*/
@Deprecated
default void addAvailabilityListener(@NotNull String extensionPointName, @NotNull ExtensionPointAvailabilityListener listener) {
addAvailabilityListener(extensionPointName, listener, null);
}
/**
* @deprecated use {@link #addAvailabilityListener(String, ExtensionPointAvailabilityListener, Disposable)}
*/
@Deprecated
void removeAvailabilityListener(@NotNull String extensionPointName, @NotNull ExtensionPointAvailabilityListener listener);
@NotNull
MutablePicoContainer getPicoContainer();
void registerExtensionPoint(@NotNull PluginDescriptor pluginDescriptor, @NotNull Element extensionPointElement);
void registerExtensionPoint(@NotNull PluginDescriptor pluginDescriptor,
@NotNull Element extensionPointElement,
@NotNull MutablePicoContainer picoContainer);
/**
* Registers a new extension.
@@ -80,7 +56,5 @@ public interface ExtensionsArea {
@TestOnly
void registerExtension(@NotNull PluginDescriptor pluginDescriptor, @NotNull Element extensionElement, @Nullable String extensionNs);
void registerExtension(@NotNull final ExtensionPoint extensionPoint, @NotNull final PluginDescriptor pluginDescriptor, @NotNull final Element extensionElement);
String getAreaClass();
void registerExtension(@NotNull ExtensionPoint<?> extensionPoint, @NotNull PluginDescriptor pluginDescriptor, @NotNull Element extensionElement);
}
@@ -14,7 +14,7 @@ public final class ProjectExtensionPointName<T> extends BaseExtensionPointName {
@NotNull
public ExtensionPoint<T> getPoint(@NotNull AreaInstance areaInstance) {
return Extensions.getArea(areaInstance).getExtensionPoint(getName());
return areaInstance.getExtensionArea().getExtensionPoint(getName());
}
@NotNull
@@ -38,6 +38,8 @@ public abstract class ExtensionPointImpl<T> implements ExtensionPoint<T>, Iterab
// test-only
private static Set<ExtensionPointImpl<?>> POINTS_IN_READONLY_MODE;
private static volatile Predicate<Class<?>> TYPE_CHECKER;
private final String myName;
private final String myClassName;
@@ -75,6 +77,20 @@ public abstract class ExtensionPointImpl<T> implements ExtensionPoint<T>, Iterab
myDescriptor = pluginDescriptor;
}
@TestOnly
public static boolean setTestTypeChecker(@NotNull Predicate<Class<?>> typeChecker, @NotNull Disposable parentDisposable) {
if (TYPE_CHECKER != null) {
return false;
}
TYPE_CHECKER = typeChecker;
Disposer.register(parentDisposable, () -> {
TYPE_CHECKER = null;
});
return true;
}
@NotNull
@Override
public String getName() {
@@ -194,6 +210,11 @@ public abstract class ExtensionPointImpl<T> implements ExtensionPoint<T>, Iterab
private synchronized void checkExtensionType(@NotNull T extension, @NotNull Class<T> extensionClass, @Nullable ExtensionComponentAdapter adapter) {
if (!extensionClass.isInstance(extension)) {
Predicate<Class<?>> checker = TYPE_CHECKER;
if (checker != null && checker.test(extensionClass)) {
return;
}
String message = "Extension " + extension.getClass() + " does not implement " + extensionClass;
if (adapter != null) {
message += ". It came from " + adapter;
@@ -686,7 +707,7 @@ public abstract class ExtensionPointImpl<T> implements ExtensionPoint<T>, Iterab
}
}
private static final ArrayFactory<ExtensionPointListener> LISTENER_ARRAY_FACTORY =
private static final ArrayFactory<ExtensionPointListener<?>> LISTENER_ARRAY_FACTORY =
n -> n == 0 ? ExtensionPointListener.EMPTY_ARRAY : new ExtensionPointListener[n];
private static <T> ArrayFactory<ExtensionPointListener<T>> listenerArrayFactory() {
//noinspection unchecked
@@ -883,7 +904,7 @@ public abstract class ExtensionPointImpl<T> implements ExtensionPoint<T>, Iterab
final synchronized void notifyAreaReplaced(@NotNull ExtensionsArea oldArea) {
for (final ExtensionPointListener<T> listener : myListeners) {
if (listener instanceof ExtensionPointAndAreaListener) {
((ExtensionPointAndAreaListener)listener).areaReplaced(oldArea);
((ExtensionPointAndAreaListener<?>)listener).areaReplaced(oldArea);
}
}
}
@@ -8,8 +8,6 @@ import com.intellij.openapi.extensions.impl.InterfaceExtensionPoint.PicoContaine
import com.intellij.openapi.util.Disposer;
import com.intellij.util.SystemProperties;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.pico.CachingConstructorInjectionComponentAdapter;
import com.intellij.util.pico.DefaultPicoContainer;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
@@ -20,10 +18,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.picocontainer.MutablePicoContainer;
import org.picocontainer.PicoContainer;
import java.util.Collection;
import java.util.Iterator;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.Set;
@@ -34,68 +30,37 @@ public final class ExtensionsAreaImpl implements ExtensionsArea {
private static final boolean DEBUG_REGISTRATION = Boolean.FALSE.booleanValue(); // not compile-time constant to avoid yellow code
private final MutablePicoContainer myPicoContainer;
private final Map<String, ExtensionPointImpl> myExtensionPoints = ContainerUtil.newConcurrentMap();
private final DefaultPicoContainer myPicoContainer;
private final Map<String, ExtensionPointImpl<?>> myExtensionPoints = ContainerUtil.newConcurrentMap();
private final Map<String,Throwable> myEPTraces = DEBUG_REGISTRATION ? new THashMap<>() : null;
private final MultiMap<String, ExtensionPointAvailabilityListener> myAvailabilityListeners = MultiMap.createSmart(); // guarded by myAvailabilityListeners
private final AreaInstance myAreaInstance;
private final String myAreaClass;
public ExtensionsAreaImpl(@Nullable String areaClass, @Nullable AreaInstance areaInstance, PicoContainer parentPicoContainer) {
myAreaClass = areaClass;
myAreaInstance = areaInstance;
myPicoContainer = new DefaultPicoContainer(parentPicoContainer);
initialize();
public ExtensionsAreaImpl(@NotNull DefaultPicoContainer picoContainer) {
myPicoContainer = picoContainer;
}
@TestOnly
public final void notifyAreaReplaced(@NotNull ExtensionsAreaImpl newArea) {
public final void notifyAreaReplaced(@Nullable ExtensionsAreaImpl newArea) {
Set<String> processedEPs = new THashSet<>();
for (final ExtensionPointImpl point : myExtensionPoints.values()) {
for (ExtensionPointImpl<?> point : myExtensionPoints.values()) {
point.notifyAreaReplaced(this);
processedEPs.add(point.getName());
}
// this code is required because we have a lot of static extensions e.g. LanguageExtension that are initialized only once
// for the extensions AvailabilityListeners will be broken if the initialization happened in a "fake" area, which doesn't have required EP
if (!myAvailabilityListeners.isEmpty()) {
for (Map.Entry<String, Collection<ExtensionPointAvailabilityListener>> entry : myAvailabilityListeners.entrySet()) {
String key = entry.getKey();
if (!processedEPs.contains(key)) {
boolean wasAdded = false;
//if listeners are "detached" for any EP we have to transfer them to the new area (otherwise it will affect area searching)
for (ExtensionPointAvailabilityListener listener : entry.getValue()) {
if (!newArea.hasAvailabilityListener(key, listener)) {
newArea.addAvailabilityListener(key, listener, null);
wasAdded = true;
}
}
if (wasAdded) {
processedEPs.add(key);
}
}
}
if (newArea == null) {
return;
}
for (ExtensionPointImpl point : newArea.myExtensionPoints.values()) {
for (ExtensionPointImpl<?> point : newArea.myExtensionPoints.values()) {
if (!processedEPs.contains(point.getName())) {
point.notifyAreaReplaced(this);
}
}
}
@NotNull
@Override
public MutablePicoContainer getPicoContainer() {
return myPicoContainer;
}
@Override
public String getAreaClass() {
return myAreaClass;
}
@Override
public void registerExtensionPoint(@NotNull PluginDescriptor pluginDescriptor, @NotNull Element extensionPointElement) {
public void registerExtensionPoint(@NotNull PluginDescriptor pluginDescriptor,
@NotNull Element extensionPointElement,
@NotNull MutablePicoContainer picoContainer) {
String pointName = extensionPointElement.getAttributeValue("qualifiedName");
if (pointName == null) {
final String name = extensionPointElement.getAttributeValue("name");
@@ -118,7 +83,7 @@ public final class ExtensionsAreaImpl implements ExtensionsArea {
ExtensionPointImpl<Object> point;
if (interfaceClassName == null) {
point = new BeanExtensionPoint<>(pointName, beanClassName, myPicoContainer, pluginDescriptor);
point = new BeanExtensionPoint<>(pointName, beanClassName, picoContainer, pluginDescriptor);
}
else {
boolean registerInPicoContainer;
@@ -134,10 +99,10 @@ public final class ExtensionsAreaImpl implements ExtensionsArea {
}
if (registerInPicoContainer) {
point = new PicoContainerAwareInterfaceExtensionPoint<>(pointName, interfaceClassName, myPicoContainer, pluginDescriptor);
point = new PicoContainerAwareInterfaceExtensionPoint<>(pointName, interfaceClassName, picoContainer, pluginDescriptor);
}
else {
point = new InterfaceExtensionPoint<>(pointName, interfaceClassName, myPicoContainer, pluginDescriptor);
point = new InterfaceExtensionPoint<>(pointName, interfaceClassName, picoContainer, pluginDescriptor);
}
}
registerExtensionPoint(point);
@@ -152,12 +117,12 @@ public final class ExtensionsAreaImpl implements ExtensionsArea {
// Used in Upsource
@Override
public void registerExtension(@NotNull final ExtensionPoint extensionPoint, @NotNull final PluginDescriptor pluginDescriptor, @NotNull final Element extensionElement) {
((ExtensionPointImpl)extensionPoint).createAndRegisterAdapter(extensionElement, pluginDescriptor, myPicoContainer);
((ExtensionPointImpl<?>)extensionPoint).createAndRegisterAdapter(extensionElement, pluginDescriptor, myPicoContainer);
}
// don't want to expose clearCache directly
public void extensionsRegistered(@NotNull ExtensionPointImpl[] points) {
for (ExtensionPointImpl point : points) {
public void extensionsRegistered(@NotNull ExtensionPointImpl<?>[] points) {
for (ExtensionPointImpl<?> point : points) {
point.clearCache();
}
}
@@ -177,85 +142,15 @@ public final class ExtensionsAreaImpl implements ExtensionsArea {
return epName;
}
private void initialize() {
InterfaceExtensionPoint<EPAvailabilityListenerExtension> point =
new InterfaceExtensionPoint<>(EPAvailabilityListenerExtension.EXTENSION_POINT_NAME, EPAvailabilityListenerExtension.class, myPicoContainer);
registerExtensionPoint(point);
point.addExtensionPointListener(new ExtensionPointListener<EPAvailabilityListenerExtension>() {
@Override
public void extensionRemoved(@NotNull EPAvailabilityListenerExtension extension, @NotNull PluginDescriptor pluginDescriptor) {
synchronized (myAvailabilityListeners) {
Collection<ExtensionPointAvailabilityListener> listeners = myAvailabilityListeners.get(extension.getExtensionPointName());
for (Iterator<ExtensionPointAvailabilityListener> iterator = listeners.iterator(); iterator.hasNext(); ) {
ExtensionPointAvailabilityListener listener = iterator.next();
if (listener.getClass().getName().equals(extension.getListenerClass())) {
iterator.remove();
return;
}
}
}
LOG.warn("Failed to find EP availability listener: " + extension.getListenerClass());
}
@Override
public void extensionAdded(@NotNull EPAvailabilityListenerExtension extension, @NotNull PluginDescriptor pluginDescriptor) {
String epName = extension.getExtensionPointName();
ExtensionPointAvailabilityListener listener;
try {
listener = (ExtensionPointAvailabilityListener)instantiate(extension.loadListenerClass());
}
catch (ClassNotFoundException e) {
throw new ExtensionInstantiationException(e, pluginDescriptor);
}
addAvailabilityListener(epName, listener, null);
}
}, false, null);
}
@NotNull
private Object instantiate(@NotNull Class clazz) {
CachingConstructorInjectionComponentAdapter adapter =
new CachingConstructorInjectionComponentAdapter(Integer.toString(System.identityHashCode(new Object())), clazz);
return adapter.getComponentInstance(getPicoContainer());
}
@Override
public void addAvailabilityListener(@NotNull String extensionPointName, @NotNull ExtensionPointAvailabilityListener listener, @Nullable Disposable parentDisposable) {
synchronized (myAvailabilityListeners) {
myAvailabilityListeners.putValue(extensionPointName, listener);
}
ExtensionPointImpl<?> ep = myExtensionPoints.get(extensionPointName);
if (ep != null) {
listener.extensionPointRegistered(ep);
}
if (parentDisposable != null) {
Disposer.register(parentDisposable, () -> removeAvailabilityListener(extensionPointName, listener));
}
}
@Override
public void removeAvailabilityListener(@NotNull String extensionPointName, @NotNull ExtensionPointAvailabilityListener listener) {
synchronized (myAvailabilityListeners) {
myAvailabilityListeners.remove(extensionPointName, listener);
}
}
private boolean hasAvailabilityListener(@NotNull String extensionPointName, @NotNull ExtensionPointAvailabilityListener listener) {
Collection<ExtensionPointAvailabilityListener> listeners = myAvailabilityListeners.get(extensionPointName);
return ContainerUtil.containsIdentity(listeners, listener);
}
@Override
@TestOnly
public void registerExtensionPoint(@NotNull @NonNls String extensionPointName,
@NotNull String extensionPointBeanClass,
@NotNull ExtensionPoint.Kind kind) {
doRegisterExtensionPoint(extensionPointName, extensionPointBeanClass, kind);
}
@Override
@TestOnly
public void registerExtensionPoint(@NotNull BaseExtensionPointName extensionPoint,
@NotNull String extensionPointBeanClass,
@NotNull ExtensionPoint.Kind kind,
@@ -277,6 +172,33 @@ public final class ExtensionsAreaImpl implements ExtensionsArea {
registerExtensionPoint(point);
}
@TestOnly
public <T> ExtensionPointImpl<T> registerPoint(@NotNull String name,
@NotNull Class<T> extensionClass,
@NotNull PluginDescriptor pluginDescriptor) {
ExtensionPointImpl<T> point;
if (extensionClass.isInterface() || (extensionClass.getModifiers() & Modifier.ABSTRACT) != 0) {
point = new PicoContainerAwareInterfaceExtensionPoint<>(name, extensionClass.getName(), myPicoContainer, pluginDescriptor);
}
else {
point = new BeanExtensionPoint<>(name, extensionClass.getName(), myPicoContainer, pluginDescriptor);
}
registerExtensionPoint(point);
return point;
}
/**
* To register extensions for {@link com.intellij.openapi.util.KeyedExtensionCollector} for test purposes, where extension instance can be KeyedLazyInstance and not a real bean class,
* because often it is not possible to use one (for example, {@link com.intellij.lang.LanguageExtensionPoint}).
*/
@TestOnly
public <T> ExtensionPointImpl<T> registerFakeBeanPoint(@NotNull String name, @NotNull PluginDescriptor pluginDescriptor) {
// any object name can be used, because EP must not create any instance
ExtensionPointImpl<T> point = new BeanExtensionPoint<>(name, Object.class.getName(), myPicoContainer, pluginDescriptor);
registerExtensionPoint(point);
return point;
}
@Nullable
private static PluginId id(@NotNull PluginDescriptor descriptor) {
return descriptor instanceof UndefinedPluginDescriptor ? null : descriptor.getPluginId();
@@ -300,28 +222,18 @@ public final class ExtensionsAreaImpl implements ExtensionsArea {
String name = point.getName();
checkThatPointNotDuplicated(name, point.getDescriptor());
myExtensionPoints.put(name, point);
notifyPointRegistered(point);
if (DEBUG_REGISTRATION) {
myEPTraces.put(name, new Throwable("Original registration for " + name));
}
}
private void notifyPointRegistered(@NotNull ExtensionPoint extensionPoint) {
Collection<ExtensionPointAvailabilityListener> listeners;
synchronized (myAvailabilityListeners) {
listeners = myAvailabilityListeners.get(extensionPoint.getName());
}
for (final ExtensionPointAvailabilityListener listener : listeners) {
listener.extensionPointRegistered(extensionPoint);
}
}
@NotNull
@Override
public <T> ExtensionPointImpl<T> getExtensionPoint(@NotNull String extensionPointName) {
@SuppressWarnings("unchecked") ExtensionPointImpl<T> extensionPoint = myExtensionPoints.get(extensionPointName);
@SuppressWarnings("unchecked")
ExtensionPointImpl<T> extensionPoint = (ExtensionPointImpl<T>)myExtensionPoints.get(extensionPointName);
if (extensionPoint == null) {
throw new IllegalArgumentException("Missing extension point: " + extensionPointName + " in area " + myAreaInstance);
throw new IllegalArgumentException("Missing extension point: " + extensionPointName + " in container " + myPicoContainer);
}
return extensionPoint;
}
@@ -329,7 +241,8 @@ public final class ExtensionsAreaImpl implements ExtensionsArea {
@Nullable
@Override
public <T> ExtensionPoint<T> getExtensionPointIfRegistered(@NotNull String extensionPointName) {
@SuppressWarnings("unchecked") ExtensionPointImpl<T> extensionPoint = myExtensionPoints.get(extensionPointName);
@SuppressWarnings("unchecked")
ExtensionPointImpl<T> extensionPoint = (ExtensionPointImpl<T>)myExtensionPoints.get(extensionPointName);
return extensionPoint;
}
@@ -341,27 +254,16 @@ public final class ExtensionsAreaImpl implements ExtensionsArea {
@NotNull
@Override
public ExtensionPointImpl[] getExtensionPoints() {
public ExtensionPointImpl<?>[] getExtensionPoints() {
return myExtensionPoints.values().toArray(new ExtensionPointImpl[0]);
}
@Override
public void unregisterExtensionPoint(@NotNull final String extensionPointName) {
ExtensionPoint extensionPoint = myExtensionPoints.get(extensionPointName);
ExtensionPoint<?> extensionPoint = myExtensionPoints.get(extensionPointName);
if (extensionPoint != null) {
extensionPoint.reset();
myExtensionPoints.remove(extensionPointName);
notifyEPRemoved(extensionPoint);
}
}
private void notifyEPRemoved(@NotNull ExtensionPoint extensionPoint) {
Collection<ExtensionPointAvailabilityListener> listeners;
synchronized (myAvailabilityListeners) {
listeners = myAvailabilityListeners.get(extensionPoint.getName());
}
for (final ExtensionPointAvailabilityListener listener : listeners) {
listener.extensionPointRemoved(extensionPoint);
}
}
@@ -377,6 +279,6 @@ public final class ExtensionsAreaImpl implements ExtensionsArea {
@Override
public String toString() {
return (myAreaClass == null ? "Root" : myAreaClass)+" Area";
return myPicoContainer.toString();
}
}
@@ -1,16 +1,15 @@
// 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.
package com.intellij.openapi.extensions.impl;
import com.intellij.openapi.extensions.*;
import com.intellij.openapi.extensions.ExtensionInstantiationException;
import com.intellij.openapi.extensions.LoadingOrder;
import com.intellij.openapi.extensions.PluginDescriptor;
import org.jdom.Attribute;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.picocontainer.ComponentAdapter;
import org.picocontainer.MutablePicoContainer;
import java.util.List;
public class InterfaceExtensionPoint<T> extends ExtensionPointImpl<T> {
public InterfaceExtensionPoint(@NotNull String name, @NotNull Class<T> clazz, @NotNull MutablePicoContainer picoContainer) {
super(name, clazz.getName(), picoContainer, new UndefinedPluginDescriptor());
@@ -63,32 +62,6 @@ public class InterfaceExtensionPoint<T> extends ExtensionPointImpl<T> {
return false;
}
@Nullable
protected static <T> T findExtension(@NotNull BaseExtensionPointName pointName,
@NotNull Class<T> instanceOf,
@Nullable AreaInstance areaInstance,
boolean isRequired) {
ExtensionPoint<T> point = Extensions.getArea(areaInstance).getExtensionPoint(pointName.getName());
List<T> list = point.getExtensionList();
//noinspection ForLoopReplaceableByForEach
for (int i = 0, size = list.size(); i < size; i++) {
T object = list.get(i);
if (instanceOf.isInstance(object)) {
return object;
}
}
if (isRequired) {
String message = "could not find extension implementation " + instanceOf;
if (((ExtensionPointImpl)point).isInReadOnlyMode()) {
message += " (point in read-only mode)";
}
throw new IllegalArgumentException(message);
}
return null;
}
static final class PicoContainerAwareInterfaceExtensionPoint<T> extends InterfaceExtensionPoint<T> {
PicoContainerAwareInterfaceExtensionPoint(@NotNull String name,
@NotNull String className,
@@ -6,6 +6,9 @@ import com.intellij.openapi.extensions.PluginId;
import org.jetbrains.annotations.NotNull;
final class UndefinedPluginDescriptor implements PluginDescriptor {
UndefinedPluginDescriptor() {
}
@NotNull
@Override
public PluginId getPluginId() {
@@ -39,7 +39,7 @@ public class DefaultPicoContainer implements MutablePicoContainer {
return componentAdapters.getImmutableSet();
}
private void appendNonAssignableAdaptersOfType(@NotNull Class componentType, @NotNull List<? super ComponentAdapter> result) {
private void appendNonAssignableAdaptersOfType(@NotNull Class<?> componentType, @NotNull List<? super ComponentAdapter> result) {
List<ComponentAdapter> comp = new ArrayList<>();
for (final ComponentAdapter componentAdapter : nonAssignableComponentAdapters.get()) {
if (ReflectionUtil.isAssignable(componentType, componentAdapter.getComponentImplementation())) {
@@ -69,7 +69,7 @@ public class DefaultPicoContainer implements MutablePicoContainer {
}
if (componentKey instanceof Class) {
return componentKeyToAdapterCache.get(((Class)componentKey).getName());
return componentKeyToAdapterCache.get(((Class<?>)componentKey).getName());
}
return null;
@@ -92,7 +92,7 @@ public class DefaultPicoContainer implements MutablePicoContainer {
return parent == null ? null : parent.getComponentAdapterOfType(componentType);
}
Class[] foundClasses = new Class[found.size()];
Class<?>[] foundClasses = new Class[found.size()];
for (int i = 0; i < foundClasses.length; i++) {
foundClasses[i] = found.get(i).getComponentImplementation();
}
@@ -165,24 +165,13 @@ public class DefaultPicoContainer implements MutablePicoContainer {
}
@Override
public List getComponentInstances() {
return getComponentInstancesOfType(Object.class);
public List<?> getComponentInstances() {
throw new UnsupportedOperationException("Do not use");
}
@Override
public List<Object> getComponentInstancesOfType(@Nullable Class componentType) {
if (componentType == null) {
return Collections.emptyList();
}
List<Object> result = new ArrayList<>();
for (ComponentAdapter componentAdapter : getComponentAdapters()) {
if (ReflectionUtil.isAssignable(componentType, componentAdapter.getComponentImplementation())) {
// may be null in the case of the "implicit" adapter representing "this".
ContainerUtil.addIfNotNull(result, getInstance(componentAdapter));
}
}
return result;
throw new UnsupportedOperationException("use ComponentManagerImpl.getComponentInstancesOfType");
}
@FunctionalInterface
@@ -190,27 +179,12 @@ public class DefaultPicoContainer implements MutablePicoContainer {
boolean isComponentInstantiated();
}
@Nullable
public <T> T getComponentInstanceIfInstantiated(@NotNull String componentKey) {
ComponentAdapter adapter = getFromCache(componentKey);
if (!(adapter instanceof LazyComponentAdapter)) {
//noinspection unchecked
return (T)getComponentInstance(componentKey);
}
if (((LazyComponentAdapter)adapter).isComponentInstantiated()) {
//noinspection unchecked
return (T)getLocalInstance(adapter);
}
return null;
}
@Override
@Nullable
public Object getComponentInstance(Object componentKey) {
ComponentAdapter adapter = getFromCache(componentKey);
if (adapter != null) {
return getLocalInstance(adapter);
return adapter.getComponentInstance(this);
}
if (parent != null) {
adapter = parent.getComponentAdapter(componentKey);
@@ -221,6 +195,22 @@ public class DefaultPicoContainer implements MutablePicoContainer {
return null;
}
@Nullable
public <T> T getService(@NotNull Class<T> serviceClass, boolean isCreate) {
ComponentAdapter adapter = componentKeyToAdapterCache.get(serviceClass.getName());
if (adapter == null) {
return null;
}
if (!isCreate && adapter instanceof LazyComponentAdapter && !((LazyComponentAdapter)adapter).isComponentInstantiated()) {
return null;
}
else {
//noinspection unchecked
return (T)adapter.getComponentInstance(this);
}
}
@Override
@Nullable
public Object getComponentInstanceOfType(Class componentType) {
@@ -231,7 +221,7 @@ public class DefaultPicoContainer implements MutablePicoContainer {
@Nullable
private Object getInstance(@NotNull ComponentAdapter componentAdapter) {
if (getComponentAdapters().contains(componentAdapter)) {
return getLocalInstance(componentAdapter);
return componentAdapter.getComponentInstance(this);
}
if (parent != null) {
return parent.getComponentInstance(componentAdapter.getComponentKey());
@@ -240,40 +230,23 @@ public class DefaultPicoContainer implements MutablePicoContainer {
return null;
}
private Object getLocalInstance(@NotNull ComponentAdapter componentAdapter) {
PicoException firstLevelException;
try {
return componentAdapter.getComponentInstance(this);
}
catch (PicoInitializationException | PicoIntrospectionException e) {
firstLevelException = e;
}
if (parent != null) {
Object instance = parent.getComponentInstance(componentAdapter.getComponentKey());
if (instance != null) {
return instance;
}
}
throw firstLevelException;
}
/**
* @deprecated Do not use.
*/
@Override
@Deprecated
@Nullable
public ComponentAdapter unregisterComponentByInstance(@NotNull Object componentInstance) {
for (ComponentAdapter adapter : getComponentAdapters()) {
Object o = getInstance(adapter);
if (componentInstance.equals(o)) {
return unregisterComponent(adapter.getComponentKey());
}
}
return null;
throw new UnsupportedOperationException("Do not use");
}
/**
* @deprecated Do not use.
*/
@Override
@Deprecated
public void verify() {
new VerifyingVisitor().traverse(this);
throw new UnsupportedOperationException("Do not use");
}
@Override
@@ -356,7 +329,7 @@ public class DefaultPicoContainer implements MutablePicoContainer {
* A linked hash set that's copied on write operations.
* @param <T>
*/
private static class LinkedHashSetWrapper<T> {
private static final class LinkedHashSetWrapper<T> {
private final Object lock = new Object();
private volatile Set<T> immutableSet;
private LinkedHashSet<T> synchronizedSet = new LinkedHashSet<>();
@@ -1,39 +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.openapi.extensions.impl;
import org.junit.Test;
import org.picocontainer.MutablePicoContainer;
import org.picocontainer.defaults.DefaultPicoContainer;
import java.util.List;
import static org.junit.Assert.assertEquals;
/**
* @author mike
*/
public class ExtensionsAreaTest {
@Test
public void testGetComponentAdapterDoesntDuplicateAdapters() {
MutablePicoContainer picoContainer =
new ExtensionsAreaImpl("foo", null, new DefaultPicoContainer()).getPicoContainer();
picoContainer.registerComponentImplementation("runnable", ExtensionsAreaTest.class);
List adapters = picoContainer.getComponentAdaptersOfType(ExtensionsAreaTest.class);
assertEquals(1, adapters.size());
}
}
@@ -5,13 +5,13 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.extensions.*;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.util.pico.DefaultPicoContainer;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Test;
import org.picocontainer.MutablePicoContainer;
import org.picocontainer.defaults.DefaultPicoContainer;
import java.io.IOException;
import java.util.Arrays;
@@ -21,9 +21,6 @@ import static org.assertj.core.api.AssertionsForClassTypes.fail;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* @author AKireyev
*/
public class ExtensionsImplTest {
static final String EXTENSION_POINT_NAME_1 = "ext.point.one";
@@ -36,7 +33,7 @@ public class ExtensionsImplTest {
@Test
public void testCreateAndAccess() {
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(null, null, null);
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(new DefaultPicoContainer());
int numEP = extensionsArea.getExtensionPoints().length;
registerInterfaceExtension(extensionsArea);
assertEquals("Additional EP available", numEP + 1, extensionsArea.getExtensionPoints().length);
@@ -49,7 +46,7 @@ public class ExtensionsImplTest {
@Test(expected = Throwable.class)
public void testInvalidActions() {
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(null, null, null);
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(new DefaultPicoContainer());
registerInterfaceExtension(extensionsArea);
extensionsArea.doRegisterExtensionPoint(EXTENSION_POINT_NAME_1, Boolean.class.getName(), ExtensionPoint.Kind.INTERFACE);
fail("Should not allow duplicate registration");
@@ -57,7 +54,7 @@ public class ExtensionsImplTest {
@Test
public void testUnregisterEP() {
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(null, null, null);
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(new DefaultPicoContainer());
int numEP = extensionsArea.getExtensionPoints().length;
registerInterfaceExtension(extensionsArea);
@@ -80,51 +77,6 @@ public class ExtensionsImplTest {
assertThat(removed[0]).withFailMessage("Extension point disposed").isTrue();
}
@Test
public void testAvailabilityListener() {
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(null, null, null);
MyListener.reset();
extensionsArea.getExtensionPoint(EPAvailabilityListenerExtension.EXTENSION_POINT_NAME).registerExtension(
new EPAvailabilityListenerExtension(EXTENSION_POINT_NAME_1, MyListener.class.getName()));
assertEquals(0, MyListener.regCount);
assertEquals(0, MyListener.remCount);
registerInterfaceExtension(extensionsArea);
assertEquals(1, MyListener.regCount);
assertEquals(0, MyListener.remCount);
MyListener.reset();
extensionsArea.unregisterExtensionPoint(EXTENSION_POINT_NAME_1);
assertEquals(1, MyListener.remCount);
assertEquals(0, MyListener.regCount);
}
@Test
public void testAvailability2Listeners() {
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(null, null, null);
MyListener.reset();
registerInterfaceExtension(extensionsArea);
extensionsArea.getExtensionPoint(EPAvailabilityListenerExtension.EXTENSION_POINT_NAME).registerExtension(
new EPAvailabilityListenerExtension(EXTENSION_POINT_NAME_1, MyListener.class.getName()));
extensionsArea.getExtensionPoint(EPAvailabilityListenerExtension.EXTENSION_POINT_NAME).registerExtension(
new EPAvailabilityListenerExtension(EXTENSION_POINT_NAME_1, MyListener.class.getName()));
assertEquals(2, MyListener.regCount);
assertEquals(0, MyListener.remCount);
MyListener.reset();
extensionsArea.unregisterExtensionPoint(EXTENSION_POINT_NAME_1);
assertEquals(2, MyListener.remCount);
assertEquals(0, MyListener.regCount);
}
@Test
public void testAvailabilityListenerAfter() {
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(null, null, null);
registerInterfaceExtension(extensionsArea);
MyListener.reset();
extensionsArea.getExtensionPoint(EPAvailabilityListenerExtension.EXTENSION_POINT_NAME).registerExtension(
new EPAvailabilityListenerExtension(EXTENSION_POINT_NAME_1, MyListener.class.getName()));
assertEquals(1, MyListener.regCount);
assertEquals(0, MyListener.remCount);
}
@Test
public void testTryPicoContainer() {
DefaultPicoContainer rootContainer = new DefaultPicoContainer();
@@ -178,7 +130,7 @@ public class ExtensionsImplTest {
@Test
public void testExtensionsNamespaces() throws IOException, JDOMException {
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(null, null, new DefaultPicoContainer());
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(new DefaultPicoContainer());
extensionsArea.doRegisterExtensionPoint("plugin.ep1", TestExtensionClassOne.class.getName(), ExtensionPoint.Kind.BEAN_CLASS);
registerExtension(extensionsArea, "plugin", JDOMUtil.load(
"<plugin:ep1 xmlns:plugin=\"plugin\" order=\"LAST\"><text>3</text></plugin:ep1>"));
@@ -186,7 +138,7 @@ public class ExtensionsImplTest {
"<ep1 xmlns=\"plugin\" order=\"FIRST\"><text>1</text></ep1>"));
registerExtension(extensionsArea, "plugin", JDOMUtil.load(
"<extension point=\"plugin.ep1\"><text>2</text></extension>"));
ExtensionPoint extensionPoint = extensionsArea.getExtensionPoint("plugin.ep1");
ExtensionPoint<?> extensionPoint = extensionsArea.getExtensionPoint("plugin.ep1");
TestExtensionClassOne[] extensions = (TestExtensionClassOne[]) extensionPoint.getExtensions();
assertEquals(3, extensions.length);
assertEquals("1", extensions[0].getText());
@@ -196,7 +148,7 @@ public class ExtensionsImplTest {
@Test
public void testExtensionsWithOrdering() throws IOException, JDOMException {
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(null, null, new DefaultPicoContainer());
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(new DefaultPicoContainer());
extensionsArea.doRegisterExtensionPoint("ep1", TestExtensionClassOne.class.getName(), ExtensionPoint.Kind.BEAN_CLASS);
registerExtension(extensionsArea, "", JDOMUtil.load(
"<extension point=\"ep1\" order=\"LAST\"><text>3</text></extension>"));
@@ -204,7 +156,7 @@ public class ExtensionsImplTest {
"<extension point=\"ep1\" order=\"FIRST\"><text>1</text></extension>"));
registerExtension(extensionsArea, "", JDOMUtil.load(
"<extension point=\"ep1\"><text>2</text></extension>"));
ExtensionPoint extensionPoint = extensionsArea.getExtensionPoint("ep1");
ExtensionPoint<?> extensionPoint = extensionsArea.getExtensionPoint("ep1");
TestExtensionClassOne[] extensions = (TestExtensionClassOne[]) extensionPoint.getExtensions();
assertEquals(3, extensions.length);
assertEquals("1", extensions[0].getText());
@@ -214,7 +166,7 @@ public class ExtensionsImplTest {
@Test
public void testExtensionsWithOrderingUpdate() throws IOException, JDOMException {
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(null, null, new DefaultPicoContainer());
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(new DefaultPicoContainer());
extensionsArea.doRegisterExtensionPoint("ep1", TestExtensionClassOne.class.getName(), ExtensionPoint.Kind.BEAN_CLASS);
registerExtension(extensionsArea, "", JDOMUtil.load("<extension point=\"ep1\" id=\"_7\" order=\"LAST\"><text>7</text></extension>"));
registerExtension(extensionsArea, "", JDOMUtil.load("<extension point=\"ep1\" id=\"fst\" order=\"FIRST\"><text>1</text></extension>"));
@@ -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-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.
package com.intellij.application.options.editor;
import com.intellij.openapi.application.ApplicationBundle;
@@ -8,10 +8,7 @@ import com.intellij.openapi.project.Project;
import javax.swing.*;
/**
* @author Sergey.Malenkov
*/
public class EditorOptionsTopHitProvider extends EditorOptionsTopHitProviderBase.NoPrefix {
final class EditorOptionsTopHitProvider extends EditorOptionsTopHitProviderBase.NoPrefix {
@Override
protected Configurable getConfigurable(Project project) {
return new EditorOptionsPanel();
@@ -1,23 +1,8 @@
/*
* 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.
*/
// 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.
package com.intellij.codeInsight.actions;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.SelectionModel;
@@ -108,7 +93,7 @@ public class RearrangeCodeProcessor extends AbstractLayoutCodeProcessor {
@NotNull
private Runnable prepareRearrangeCommand(@NotNull final PsiFile file, @NotNull final Collection<TextRange> ranges) {
final ArrangementEngine engine = ServiceManager.getService(myProject, ArrangementEngine.class);
ArrangementEngine engine = ArrangementEngine.getInstance();
return () -> {
engine.arrange(file, ranges);
if (getInfoCollector() != null) {
@@ -3,10 +3,12 @@ package com.intellij.codeInspection;
import com.intellij.execution.configurations.ParametersList;
import com.intellij.openapi.application.ApplicationStarter;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ArrayUtilRt;
import com.sampullara.cli.Args;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author Roman.Chernyatchik
*/
@@ -18,10 +20,10 @@ public abstract class AbstractInspectionToolStarter implements ApplicationStarte
protected abstract AbstractInspectionCmdlineOptions createCmdlineOptions();
@Override
public void premain(String[] args) {
public void premain(@NotNull List<String> args) {
myOptions = createCmdlineOptions();
try {
Args.parse(myOptions, args);
Args.parse(myOptions, ArrayUtilRt.toStringArray(args));
}
catch (Exception e) {
printHelpAndExit(args, myOptions);
@@ -80,17 +82,16 @@ public abstract class AbstractInspectionToolStarter implements ApplicationStarte
return opts.getVerboseLevelProperty() > 0;
}
protected void printArgs(String[] args, StringBuilder buff) {
if (args.length < 2) {
protected void printArgs(@NotNull List<String> args, @NotNull StringBuilder buff) {
if (args.size() < 2) {
buff.append(" no arguments");
}
else {
final String argString = ParametersList.join(ContainerUtil.newArrayList(args, 1, args.length));
buff.append(argString);
buff.append(ParametersList.join(args.subList(1, args.size())));
}
}
protected void printHelpAndExit(final String[] args, final InspectionToolCmdlineOptions opts) {
protected void printHelpAndExit(@NotNull List<String> args, final InspectionToolCmdlineOptions opts) {
final StringBuilder buff = new StringBuilder();
buff.append("\n");
buff.append("Invalid options or syntax:");
@@ -4,7 +4,7 @@ package com.intellij.codeInspection;
import com.intellij.openapi.application.ApplicationStarter;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
public class InspectionMain implements ApplicationStarter {
private InspectionApplication myApplication;
@@ -16,9 +16,9 @@ public class InspectionMain implements ApplicationStarter {
@Override
@SuppressWarnings({"HardCodedStringLiteral"})
public void premain(String[] args) {
if (args.length < 4) {
System.err.println("invalid args:" + Arrays.toString(args));
public void premain(@NotNull List<String> args) {
if (args.size() < 4) {
System.err.println("invalid args:" + args);
printHelp();
}
@@ -31,9 +31,9 @@ public class InspectionMain implements ApplicationStarter {
printHelp();
}
};
myApplication.myProjectPath = args[1];
myApplication.myStubProfile = args[2];
myApplication.myOutPath = args[3];
myApplication.myProjectPath = args.get(1);
myApplication.myStubProfile = args.get(2);
myApplication.myOutPath = args.get(3);
if (myApplication.myProjectPath == null
|| myApplication.myOutPath == null
@@ -43,16 +43,16 @@ public class InspectionMain implements ApplicationStarter {
}
try {
for (int i = 4; i < args.length; i++) {
String arg = args[i];
for (int i = 4; i < args.size(); i++) {
String arg = args.get(i);
if ("-profileName".equals(arg)) {
myApplication.myProfileName = args[++i];
myApplication.myProfileName = args.get(++i);
}
else if ("-profilePath".equals(arg)) {
myApplication.myProfilePath = args[++i];
myApplication.myProfilePath = args.get(++i);
}
else if ("-d".equals(arg)) {
myApplication.mySourceDirectory = args[++i];
myApplication.mySourceDirectory = args.get(++i);
}
else if ("-v0".equals(arg)) {
myApplication.setVerboseLevel(0);
@@ -187,7 +187,7 @@ public class ScratchFileServiceImpl extends ScratchFileService implements Persis
Language language = rootType.substituteLanguage(project, file);
Language adjusted = language != null ? language : getLanguageByFileName(file);
return adjusted != null && adjusted != ScratchFileType.INSTANCE.getLanguage() ?
LanguageSubstitutors.INSTANCE.substituteLanguage(adjusted, file, project) : adjusted;
LanguageSubstitutors.getInstance().substituteLanguage(adjusted, file, project) : adjusted;
}
}
@@ -68,9 +68,9 @@ public class TraverseUIStarter implements ApplicationStarter {
}
@Override
public void premain(String[] args) {
OUTPUT_PATH = args[1];
SPLIT_BY_RESOURCE_PATH = args.length > 2 && Boolean.valueOf(args[2]);
public void premain(@NotNull List<String> args) {
OUTPUT_PATH = args.get(1);
SPLIT_BY_RESOURCE_PATH = args.size() > 2 && Boolean.valueOf(args.get(2));
}
@Override
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2010 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-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.
package com.intellij.internal;
import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -41,15 +27,15 @@ public class DumpExtensionsAction extends DumbAwareAction {
areas.add(Extensions.getRootArea());
final Project project = e.getData(CommonDataKeys.PROJECT);
if (project != null) {
areas.add(Extensions.getArea(project));
areas.add(project.getExtensionArea());
final Module[] modules = ModuleManager.getInstance(project).getModules();
if (modules.length > 0) {
areas.add(Extensions.getArea(modules[0]));
areas.add(modules[0].getExtensionArea());
}
}
System.out.print(areas.size() + " extension areas: ");
for (ExtensionsArea area : areas) {
System.out.print(area.getAreaClass() + " ");
System.out.print(area.toString() + " ");
}
System.out.println("\n");
@@ -9,9 +9,6 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.*;
import com.intellij.openapi.components.impl.PlatformComponentManagerImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.AreaInstance;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleComponent;
import com.intellij.openapi.module.ModuleServiceManager;
@@ -33,7 +30,6 @@ import com.intellij.util.xmlb.annotations.Property;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.picocontainer.MutablePicoContainer;
import java.util.List;
import java.util.Map;
@@ -53,7 +49,7 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx
private final ModuleScopeProvider myModuleScopeProvider;
ModuleImpl(@NotNull String name, @NotNull Project project, @NotNull String filePath) {
super(project, "Module " + name);
super(project);
getPicoContainer().registerComponentInstance(Module.class, this);
@@ -64,12 +60,6 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx
myImlFilePointer = VirtualFilePointerManager.getInstance().create(VfsUtilCore.pathToUrl(filePath), this, null);
}
@Override
protected MutablePicoContainer bootstrapPicoContainer(@NotNull String name) {
Extensions.instantiateArea(ExtensionAreas.IDEA_MODULE, this, (AreaInstance)getParentComponentManager());
return super.bootstrapPicoContainer(name);
}
@Override
public void init(@Nullable Runnable beforeComponentCreation) {
// do not measure (activityNamePrefix method not overridden by this class)
@@ -149,7 +139,6 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx
public synchronized void dispose() {
isModuleAdded = false;
disposeComponents();
Extensions.disposeArea(this);
super.dispose();
}
@@ -307,18 +296,6 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx
return "Module: '" + getName() + "'";
}
@NotNull
@Override
public <T> T[] getExtensions(@NotNull final ExtensionPointName<T> extensionPointName) {
return Extensions.getArea(this).getExtensionPoint(extensionPointName).getExtensions();
}
@NotNull
@Override
protected MutablePicoContainer createPicoContainer() {
return Extensions.getArea(this).getPicoContainer();
}
@Override
public long getOptionsModificationCount() {
return getOptionManager().getModificationCount();
@@ -5,6 +5,8 @@ import com.intellij.application.options.CodeStyle;
import com.intellij.codeInsight.actions.FormatChangedTextUtil;
import com.intellij.lang.Language;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.Service;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.DocumentEx;
@@ -41,12 +43,15 @@ import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Se
* <p/>
* I.e. the general idea is to have a language-specific rules hidden by generic arrangement API and common arrangement
* engine which works on top of that API and performs the arrangement.
*
* @author Denis Zhdanov
*/
public class ArrangementEngine {
@Service
public final class ArrangementEngine {
private boolean myCodeChanged;
public static ArrangementEngine getInstance() {
return ServiceManager.getService(ArrangementEngine.class);
}
@Nullable
public String getUserNotificationInfo() {
if (myCodeChanged) {
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 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-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.
package com.intellij.psi.impl.source.tree.injected;
@@ -784,7 +770,8 @@ public class InjectedLanguageUtil {
.getCachedInjectedDocumentsInRange(containingFile, element.getTextRange())
.stream()
.map(documentWindow -> PsiDocumentManager.getInstance(containingFile.getProject()).getPsiFile(documentWindow))
.filter(file -> file != null && file.getLanguage() == LanguageSubstitutors.INSTANCE.substituteLanguage(language, file.getVirtualFile(), file.getProject()))
.filter(file -> file != null && file.getLanguage() == LanguageSubstitutors.getInstance()
.substituteLanguage(language, file.getVirtualFile(), file.getProject()))
.max(Comparator.comparingInt(PsiElement::getTextLength))
.orElse(null);
}
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2016 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-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.
package com.intellij.psi.impl.source.tree.injected;
@@ -370,7 +356,7 @@ class InjectionRegistrarImpl extends MultiHostRegistrarImpl implements MultiHost
resultReferences.add(Pair.create(injector, place));
clear();
}
// returns true if shreds were set, false if old ones were reused
private static boolean cacheEverything(@NotNull Place place,
@NotNull DocumentWindowImpl documentWindow,
@@ -532,7 +518,7 @@ class InjectionRegistrarImpl extends MultiHostRegistrarImpl implements MultiHost
* and corresponding injected {@code oldInjectedPsi} (along with {@code oldDocumentWindow} and {@code oldInjectedVirtualFile}) were created.
* Then the user came along and changed the host document in {@code hostVirtualFile}.
* Document commit started and produced PSI diff {@code oldRoot} -> {@code newRoot} in the host PSI.
*
*
* Now we try to produce similar diff for the injected fragment PSI.
* To do that, we:
* <pre>
@@ -665,7 +651,7 @@ class InjectionRegistrarImpl extends MultiHostRegistrarImpl implements MultiHost
@NotNull StringBuilder decodedChars,
@NotNull String fileName, @NotNull PsiDocumentManagerBase documentManager) {
VirtualFileWindowImpl virtualFile = new VirtualFileWindowImpl(fileName, hostVirtualFile, documentWindow, language, decodedChars);
Language finalLanguage = forcedLanguage == null ? LanguageSubstitutors.INSTANCE.substituteLanguage(language, virtualFile, project) : forcedLanguage;
Language finalLanguage = forcedLanguage == null ? LanguageSubstitutors.getInstance().substituteLanguage(language, virtualFile, project) : forcedLanguage;
InjectedFileViewProvider viewProvider = new InjectedFileViewProvider(PsiManager.getInstance(project), virtualFile, documentWindow, finalLanguage);
ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(finalLanguage);
assert parserDefinition != null : "Parser definition for language " + finalLanguage + " is null";
@@ -3,9 +3,11 @@ package com.intellij.openapi.application;
import com.intellij.ide.CliResult;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.util.ArrayUtilRt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.concurrent.Future;
/**
@@ -24,12 +26,21 @@ public interface ApplicationStarter {
*/
String getCommandName();
/**
* @deprecated Use {@link #premain(List)}
*/
@SuppressWarnings("DeprecatedIsStillUsed")
@Deprecated
default void premain(@SuppressWarnings("unused") @NotNull String[] args) { }
/**
* Called before application initialization. Invoked in event dispatch thread.
*
* @param args program arguments (including the selector)
*/
default void premain(String[] args) { }
default void premain(@NotNull List<String> args) {
premain(ArrayUtilRt.toStringArray(args));
}
/**
* <p>Called when application has been initialized. Invoked in event dispatch thread.</p>
@@ -67,7 +78,7 @@ public interface ApplicationStarter {
/** @see #canProcessExternalCommandLine */
@NotNull
default Future<CliResult> processExternalCommandLineAsync(@NotNull String[] args, @Nullable String currentDirectory) {
default Future<CliResult> processExternalCommandLineAsync(@NotNull List<String> args, @Nullable String currentDirectory) {
throw new UnsupportedOperationException("Class " + getClass().getName() + " must implement `processExternalCommandLineAsync()`");
}
}
@@ -2,10 +2,12 @@
package com.intellij.openapi.application;
import com.intellij.ide.CliResult;
import com.intellij.util.ArrayUtilRt;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.concurrent.Future;
/** @deprecated override {@link ApplicationStarter} instead */
@@ -14,8 +16,8 @@ import java.util.concurrent.Future;
public abstract class ApplicationStarterEx implements ApplicationStarter {
@NotNull
@Override
public final Future<CliResult> processExternalCommandLineAsync(@NotNull String[] args, @Nullable String currentDirectory) {
processExternalCommandLine(args, currentDirectory);
public final Future<CliResult> processExternalCommandLineAsync(@NotNull List<String> args, @Nullable String currentDirectory) {
processExternalCommandLine(ArrayUtilRt.toStringArray(args), currentDirectory);
return CliResult.ok();
}
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2019 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-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.
package com.intellij.openapi.fileTypes;
import com.intellij.openapi.application.Application;
@@ -21,7 +21,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.platform.CommandLineProjectOpenProcessor;
import com.intellij.util.ArrayUtilRt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -105,7 +104,7 @@ public final class CommandLineProcessor {
@NotNull
public static Pair<Project, Future<CliResult>> processExternalCommandLine(@NotNull List<String> args,
@Nullable String currentDirectory) {
@Nullable String currentDirectory) {
LOG.info("External command line:");
LOG.info("Dir: " + currentDirectory);
for (String arg : args) LOG.info(arg);
@@ -121,7 +120,7 @@ public final class CommandLineProcessor {
if (command.equals(starter.getCommandName())) {
if (starter.canProcessExternalCommandLine()) {
LOG.info("Processing command with " + starter);
return pair(null, starter.processExternalCommandLineAsync(ArrayUtilRt.toStringArray(args), currentDirectory));
return pair(null, starter.processExternalCommandLineAsync(args, currentDirectory));
}
else {
String title = "Cannot execute command '" + command + "'";
@@ -15,7 +15,6 @@ import com.intellij.ide.plugins.*
import com.intellij.ide.ui.customization.CustomActionsSchema
import com.intellij.openapi.actionSystem.IdeActions
import com.intellij.openapi.application.*
import com.intellij.openapi.application.ex.ApplicationManagerEx
import com.intellij.openapi.application.impl.ApplicationImpl
import com.intellij.openapi.components.stateStore
import com.intellij.openapi.diagnostic.Logger
@@ -51,7 +50,6 @@ import java.awt.EventQueue
import java.beans.PropertyChangeListener
import java.io.File
import java.nio.file.Paths
import java.util.*
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Future
import java.util.concurrent.atomic.AtomicReference
@@ -72,21 +70,43 @@ private fun executeInitAppInEdt(rawArgs: Array<String>,
pluginDescriptorsFuture: CompletableFuture<List<IdeaPluginDescriptor>>) {
val args = processProgramArguments(rawArgs)
StartupUtil.patchSystem(LOG)
val starter = createAppStarter(args, pluginDescriptorsFuture)
val headless = Main.isHeadless()
val app = initAppActivity.runChild("create app") {
ApplicationImpl(java.lang.Boolean.getBoolean(PluginManagerCore.IDEA_IS_INTERNAL_PROPERTY), false, headless, Main.isCommandLine(),
ApplicationManagerEx.IDEA_APPLICATION)
ApplicationImpl(java.lang.Boolean.getBoolean(PluginManagerCore.IDEA_IS_INTERNAL_PROPERTY), false, headless, Main.isCommandLine())
}
starter.premain(args)
val registerFuture = pluginDescriptorsFuture.thenAccept {
initAppActivity.runChild("app component registration") {
app.registerComponents(it)
}
}
if (args.isEmpty()) {
startApp(app, IdeStarter(), initAppActivity, registerFuture, args)
return
}
// ApplicationStarter it is extension, so, to find starter, extensions must be registered prior to that
registerFuture.thenRunOrHandleError {
val starter = findStarter(args.first()) ?: IdeStarter()
if (Main.isHeadless() && !starter.isHeadless) {
Main.showMessage("Startup Error", "Application cannot start in headless mode", true)
exitProcess(Main.NO_GRAPHICS)
}
starter.premain(args)
startApp(app, starter, initAppActivity, registerFuture, args)
}
}
private fun startApp(app: ApplicationImpl, starter: ApplicationStarter, initAppActivity: Activity, registerFuture: CompletableFuture<Void?>, args: List<String>) {
// this code is here for one simple reason - here we have application,
// and after plugin loading we don't have - ApplicationManager.getApplication() can be used, but it doesn't matter
// but it is very important to call registerRegistryAndMessageBusAndComponent immediately after application creation
// and do not place any time-consuming code in between (e.g. showLicenseeInfoOnSplash)
var future = registerRegistryAndContainerAndInitStore(pluginDescriptorsFuture, app, initAppActivity)
var future = registerRegistryAndInitStore(registerFuture, app)
val headless = app.isHeadlessEnvironment
if (!headless) {
initAppActivity.runChild("icon loader activation") {
// todo investigate why in test mode dummy icon manager is not suitable
@@ -139,7 +159,7 @@ private fun executeInitAppInEdt(rawArgs: Array<String>,
WeakFocusStackManager.getInstance()
}
future.thenRun(Runnable {
future.thenRunOrHandleError {
// this invokeLater() call is needed not only because current thread maybe not EDT, but to place the app starting code on a freshly minted IdeEventQueue instance
val placeOnEventQueueActivity = initAppActivity.startChild(Phases.PLACE_ON_EVENT_QUEUE)
EventQueue.invokeLater {
@@ -153,7 +173,7 @@ private fun executeInitAppInEdt(rawArgs: Array<String>,
}
(TransactionGuard.getInstance() as TransactionGuardImpl).performUserActivity {
starter.main(args)
starter.main(ArrayUtilRt.toStringArray(args))
}
if (PluginManagerCore.isRunningFromSources()) {
@@ -168,25 +188,19 @@ private fun executeInitAppInEdt(rawArgs: Array<String>,
ParallelActivity.PREPARE_APP_INIT.run("init system properties") {
SystemPropertyBean.initSystemProperties()
}
})
}
}
@ApiStatus.Internal
fun registerRegistryAndContainerAndInitStore(pluginDescriptorsFuture: CompletableFuture<List<IdeaPluginDescriptor>>,
app: ApplicationImpl,
initAppActivity: Activity?): CompletableFuture<Void?> {
return pluginDescriptorsFuture
.thenCompose { pluginDescriptors ->
fun registerRegistryAndInitStore(registerFuture: CompletableFuture<*>, app: ApplicationImpl): CompletableFuture<Void?> {
return registerFuture
.thenCompose {
val future = CompletableFuture.runAsync(Runnable {
ParallelActivity.PREPARE_APP_INIT.run("add registry keys") {
RegistryKeyBean.addKeysFromPlugins()
}
}, AppExecutorUtil.getAppExecutorService())
initAppActivity.runChild("app component registration") {
app.registerComponents(pluginDescriptors)
}
// yes, at this moment initSystemProperties or RegistryKeyBean.addKeysFromPlugins maybe not yet performed, but it doesn't affect because not used.
initConfigurationStore(app, null)
@@ -237,21 +251,6 @@ private fun addActivateAndWindowsCliListeners(app: ApplicationImpl) {
}
}
private fun createAppStarter(args: Array<String>, pluginsLoaded: Future<*>): ApplicationStarter {
if (args.isEmpty()) {
return IdeStarter()
}
pluginsLoaded.get()
val starter = findStarter(args[0]) ?: IdeStarter()
if (Main.isHeadless() && !starter.isHeadless) {
Main.showMessage("Startup Error", "Application cannot start in headless mode", true)
exitProcess(Main.NO_GRAPHICS)
}
return starter
}
fun initApplication(rawArgs: Array<String>) {
val initAppActivity = MainRunner.startupStart.endAndStart(Phases.INIT_APP)
val pluginDescriptorsFuture = CompletableFuture<List<IdeaPluginDescriptor>>()
@@ -272,7 +271,7 @@ fun initApplication(rawArgs: Array<String>) {
pluginDescriptorsFuture.complete(plugins)
}
fun findStarter(key: String?): ApplicationStarter? {
fun findStarter(key: String): ApplicationStarter? {
for (starter in ApplicationStarter.EP_NAME.iterable) {
if (starter == null) {
break
@@ -323,7 +322,7 @@ open class IdeStarter : ApplicationStarter {
override fun canProcessExternalCommandLine() = true
override fun processExternalCommandLineAsync(args: Array<String>, currentDirectory: String?): Future<CliResult> {
override fun processExternalCommandLineAsync(args: List<String>, currentDirectory: String?): Future<CliResult> {
LOG.info("Request to open in $currentDirectory with parameters: ${args.joinToString(separator = ",")}")
if (args.isEmpty()) {
return CliResult.ok()
@@ -470,8 +469,12 @@ open class IdeStarter : ApplicationStarter {
* @see SAFE_JAVA_ENV_PARAMETERS
*/
@Suppress("SpellCheckingInspection")
private fun processProgramArguments(args: Array<String>): Array<String> {
val arguments = ArrayList<String>()
private fun processProgramArguments(args: Array<String>): List<String> {
if (args.isEmpty()) {
return emptyList()
}
val arguments = mutableListOf<String>()
val safeKeys = SAFE_JAVA_ENV_PARAMETERS.toList()
for (arg in args) {
if (arg.startsWith("-D")) {
@@ -487,7 +490,7 @@ private fun processProgramArguments(args: Array<String>): Array<String> {
arguments.add(arg)
}
return ArrayUtilRt.toStringArray(arguments)
return arguments
}
@ApiStatus.Internal
@@ -519,4 +522,12 @@ fun preloadServices(app: ApplicationImpl): CompletableFuture<Void?> {
}
}, appExecutorService)
})
}
private fun CompletableFuture<Void?>.thenRunOrHandleError(handler: () -> Unit): CompletableFuture<Void>? {
return thenRun(handler)
.exceptionally {
MainRunner.processException(it)
null
}
}
@@ -1,23 +0,0 @@
// 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.
package com.intellij.idea;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.diagnostic.Logger;
import org.jetbrains.annotations.ApiStatus;
/** @deprecated obsolete; use {@link com.intellij.ide.impl.HeadlessDataManager} and {@code com.intellij.idea.IdeaTestApplication} instead */
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2019.3")
public class CommandLineApplication {
private static final Logger LOG = Logger.getInstance("#com.intellij.idea.CommandLineApplication");
protected static CommandLineApplication ourInstance;
protected CommandLineApplication(boolean isInternal, boolean isUnitTestMode, boolean isHeadless) {
LOG.assertTrue(ourInstance == null, "Only one instance allowed.");
//noinspection AssignmentToStaticFieldFromInstanceMethod
ourInstance = this;
new ApplicationImpl(isInternal, isUnitTestMode, isHeadless, true, ApplicationManagerEx.IDEA_APPLICATION);
}
}
@@ -17,11 +17,15 @@ import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author nik
*/
public class JpsIdePluginManagerImpl extends JpsPluginManager {
public final class JpsIdePluginManagerImpl extends JpsPluginManager {
private final List<PluginDescriptor> myExternalBuildPlugins = new CopyOnWriteArrayList<>();
public JpsIdePluginManagerImpl() {
ExtensionsArea rootArea = Extensions.getRootArea();
if (rootArea == null) {
return;
}
//todo[nik] get rid of this check: currently this class is used in intellij.platform.jps.build tests instead of JpsPluginManagerImpl because intellij.platform.ide.impl module is added to classpath via testFramework
if (rootArea.hasExtensionPoint(JpsPluginBean.EP_NAME)) {
JpsPluginBean.EP_NAME.getPoint(null).addExtensionPointListener(new ExtensionPointListener<JpsPluginBean>() {
@@ -9,6 +9,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Future;
/**
@@ -41,7 +42,7 @@ public abstract class ApplicationStarterBase implements ApplicationStarter {
@NotNull
@Override
public Future<CliResult> processExternalCommandLineAsync(@NotNull String[] args, @Nullable String currentDirectory) {
public Future<CliResult> processExternalCommandLineAsync(@NotNull List<String> args, @Nullable String currentDirectory) {
if (!checkArguments(args)) {
Messages.showMessageDialog(getUsageMessage(), StringUtil.toTitleCase(getCommandName()), Messages.getInformationIcon());
return CliResult.error(1, getUsageMessage());
@@ -64,17 +65,17 @@ public abstract class ApplicationStarterBase implements ApplicationStarter {
ApplicationManager.getApplication().saveSettings();
}
private boolean checkArguments(String[] args) {
return Arrays.binarySearch(myArgsCount, args.length - 1) != -1 && getCommandName().equals(args[0]);
private boolean checkArguments(@NotNull List<String> args) {
return Arrays.binarySearch(myArgsCount, args.size() - 1) != -1 && getCommandName().equals(args.get(0));
}
public abstract String getUsageMessage();
@NotNull
protected abstract Future<CliResult> processCommand(@NotNull String[] args, @Nullable String currentDirectory) throws Exception;
protected abstract Future<CliResult> processCommand(@NotNull List<String> args, @Nullable String currentDirectory) throws Exception;
@Override
public void premain(String[] args) {
public void premain(@NotNull List<String> args) {
if (!checkArguments(args)) {
System.err.println(getUsageMessage());
System.exit(1);
@@ -85,7 +86,7 @@ public abstract class ApplicationStarterBase implements ApplicationStarter {
public void main(@NotNull String[] args) {
int exitCode = 0;
try {
Future<CliResult> commandFuture = processCommand(args, null);
Future<CliResult> commandFuture = processCommand(Arrays.asList(args), null);
CliResult result = commandFuture.get();
if (result.getMessage() != null) {
System.out.println(result.getMessage());
@@ -5,9 +5,10 @@ import com.intellij.ide.CliResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.concurrent.Future;
public final class SaveStarter extends ApplicationStarterBase {
final class SaveStarter extends ApplicationStarterBase {
private SaveStarter() {
super("save", 0);
}
@@ -19,7 +20,7 @@ public final class SaveStarter extends ApplicationStarterBase {
@NotNull
@Override
protected Future<CliResult> processCommand(@NotNull String[] args, @Nullable String currentDirectory) {
protected Future<CliResult> processCommand(@NotNull List<String> args, @Nullable String currentDirectory) {
saveAll();
return CliResult.ok();
}
@@ -26,7 +26,7 @@ public class DecodeDefaultsUtil {
url = getResource(appendExt(componentResourcePath), requestor);
}
else {
url = getResource(appendExt('/' + ApplicationManagerEx.getApplicationEx().getName() + '/' + componentResourcePath), requestor);
url = getResource(appendExt("/idea/" + componentResourcePath), requestor);
if (url == null) {
url = getResource(appendExt('/' + componentResourcePath), requestor);
}
@@ -27,7 +27,6 @@ import com.intellij.openapi.components.impl.PlatformComponentManagerImpl;
import com.intellij.openapi.diagnostic.Attachment;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.diagnostic.RuntimeExceptionWithAttachments;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl;
import com.intellij.openapi.progress.*;
@@ -83,7 +82,6 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
private final boolean myCommandLineMode;
private final boolean myIsInternal;
private final String myName;
// contents modified in write action, read in read action
private final Stack<Class<?>> myWriteActionsStack = new Stack<>();
@@ -103,10 +101,9 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
private static final String WAS_EVER_SHOWN = "was.ever.shown";
public ApplicationImpl(boolean isInternal,
boolean isUnitTestMode,
boolean isHeadless,
boolean isCommandLine,
@NotNull String appName) {
boolean isUnitTestMode,
boolean isHeadless,
boolean isCommandLine) {
super(null);
ApplicationManager.setApplication(this, myLastDisposable); // reset back to null only when all components already disposed
@@ -121,8 +118,6 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
Disposer.setDebugMode(isInternal || isUnitTestMode || Disposer.isDebugDisposerOn());
myName = appName;
myIsInternal = isInternal;
myTestModeFlag = isUnitTestMode;
myHeadlessMode = isHeadless;
@@ -213,23 +208,11 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
return true;
}
@Override
@NotNull
public String getName() {
return myName;
}
@Override
public boolean holdsReadLock() {
return myLock.isReadLockedByThisThread();
}
@NotNull
@Override
protected MutablePicoContainer createPicoContainer() {
return Extensions.getRootArea().getPicoContainer();
}
@Override
public boolean isInternal() {
return myIsInternal;
@@ -1349,12 +1332,6 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
return mySaveAllowed;
}
@NotNull
@Override
public <T> T[] getExtensions(@NotNull final ExtensionPointName<T> extensionPointName) {
return Extensions.getRootArea().getExtensionPoint(extensionPointName).getExtensions();
}
@Override
public boolean isDisposeInProgress() {
return myDisposeInProgress || ShutDownTracker.isShutdownHookRunning();
@@ -2,17 +2,17 @@
package com.intellij.openapi.command.impl;
import com.intellij.openapi.components.BaseComponent;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.ExtensionsArea;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.pico.DefaultPicoContainer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.SystemIndependent;
import org.picocontainer.PicoContainer;
/**
* @author max
@@ -79,6 +79,11 @@ public class DummyProject extends UserDataHolderBase implements Project {
return null;
}
@Override
public <T> T getService(@NotNull Class<T> serviceClass, boolean isCreate) {
return null;
}
@Nullable
@Override
public <T> T getComponent(@NotNull Class<T> interfaceClass) {
@@ -99,10 +104,16 @@ public class DummyProject extends UserDataHolderBase implements Project {
@Override
@NotNull
public PicoContainer getPicoContainer() {
public DefaultPicoContainer getPicoContainer() {
throw new UnsupportedOperationException("getPicoContainer is not implement in : " + getClass());
}
@NotNull
@Override
public ExtensionsArea getExtensionArea() {
throw new UnsupportedOperationException("getExtensionArea is not implement in : " + getClass());
}
@Override
public <T> T getComponent(@NotNull Class<T> interfaceClass, T defaultImplementation) {
return null;
@@ -142,10 +153,4 @@ public class DummyProject extends UserDataHolderBase implements Project {
@Override
public void dispose() { }
@NotNull
@Override
public <T> T[] getExtensions(@NotNull final ExtensionPointName<T> extensionPointName) {
throw new UnsupportedOperationException("getExtensions()");
}
}
@@ -11,6 +11,7 @@ import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -30,7 +31,7 @@ public class UpdatePluginsApp implements ApplicationStarter {
}
@Override
public void premain(String[] args) {
public void premain(@NotNull List<String> args) {
System.setProperty("idea.skip.indices.initialization", "true");
}
@@ -1,36 +1,55 @@
// 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.
package com.intellij.openapi.components.impl
import com.intellij.diagnostic.ActivitySubNames
import com.intellij.diagnostic.LoadingPhase
import com.intellij.ide.plugins.ContainerDescriptor
import com.intellij.ide.plugins.IdeaPluginDescriptor
import com.intellij.ide.plugins.IdeaPluginDescriptorImpl
import com.intellij.ide.plugins.PluginManager
import com.intellij.diagnostic.ParallelActivity
import com.intellij.diagnostic.run
import com.intellij.ide.plugins.*
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.ComponentManager
import com.intellij.openapi.components.PathMacroManager
import com.intellij.openapi.components.ServiceDescriptor
import com.intellij.openapi.components.impl.stores.IComponentStore
import com.intellij.openapi.components.stateStore
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.extensions.AreaInstance
import com.intellij.openapi.extensions.PluginId
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl
import com.intellij.openapi.progress.ProgressManager
import com.intellij.serviceContainer.ServiceContainer
import com.intellij.util.SmartList
import com.intellij.util.containers.ContainerUtil
import com.intellij.util.messages.ListenerDescriptor
import com.intellij.util.messages.MessageBusFactory
import com.intellij.util.messages.impl.MessageBusImpl
import com.intellij.util.pico.DefaultPicoContainer
import org.jetbrains.annotations.ApiStatus
import java.util.concurrent.ConcurrentMap
abstract class PlatformComponentManagerImpl : ComponentManagerImpl {
private val LOG = logger<PlatformComponentManagerImpl>()
private fun createPicoContainer(parent: ComponentManager?): DefaultPicoContainer {
return when (parent) {
null -> ServiceContainer(null)
else -> DefaultPicoContainer(parent.picoContainer)
}
}
abstract class PlatformComponentManagerImpl(parent: ComponentManager?) : ComponentManagerImpl(parent, createPicoContainer(parent)), AreaInstance {
private var handlingInitComponentError = false
private val componentStore: IComponentStore
get() = this.stateStore
protected constructor(parent: ComponentManager?) : super(parent)
protected constructor(parent: ComponentManager?, name: String) : super(parent, name)
protected open fun registerComponents(plugins: List<IdeaPluginDescriptor>) {
ParallelActivity.PREPARE_APP_INIT.run(ActivitySubNames.REGISTER_EXTENSIONS) {
@Suppress("UNCHECKED_CAST")
PluginManagerCore.registerExtensionPointsAndExtensions(extensionArea as ExtensionsAreaImpl, picoContainer,
plugins as MutableList<IdeaPluginDescriptorImpl>)
}
val app = ApplicationManager.getApplication()
val headless = app == null || app.isHeadlessEnvironment
@@ -107,4 +126,27 @@ abstract class PlatformComponentManagerImpl : ComponentManagerImpl {
}
protected abstract fun getContainerDescriptor(pluginDescriptor: IdeaPluginDescriptorImpl): ContainerDescriptor
}
@ApiStatus.Internal
override fun <T> getService(serviceClass: Class<T>, isCreate: Boolean): T? {
val componentKey = serviceClass.name
var instance = picoContainer.getService(serviceClass, isCreate)
if (instance == null && isCreate) {
ProgressManager.checkCanceled()
if (parentComponentManager != null) {
instance = parentComponentManager.getService(serviceClass, isCreate)
if (instance != null) {
LOG.error("$componentKey is registered as application service, but requested as project one")
return instance
}
}
instance = getComponent(serviceClass) ?: return null
LOG.error("$componentKey requested as a service, but it is a component - convert it to a service or " +
"change call to ${if (parentComponentManager == null) "ApplicationManager.getApplication().getComponent()" else "project.getComponent()"}")
return instance
}
return instance
}
}
@@ -268,8 +268,7 @@ public final class ServiceManagerImpl implements Disposable {
}
@Override
public void verify(final PicoContainer container) throws PicoIntrospectionException {
getDelegate().verify(container);
public void verify(PicoContainer container) {
}
@Override
@@ -1,10 +1,12 @@
// 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.
package com.intellij.openapi.options.ex;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.ExtensionsArea;
import com.intellij.openapi.options.*;
import com.intellij.openapi.project.Project;
import com.intellij.util.ArrayUtil;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
@@ -87,10 +89,10 @@ public class ConfigurableWrapper implements SearchableConfigurable, Weighted {
: null;
}
private final ConfigurableEP myEp;
private final ConfigurableEP<?> myEp;
int myWeight; // see ConfigurableExtensionPointUtil.getConfigurableToReplace
private ConfigurableWrapper(@NotNull ConfigurableEP ep) {
private ConfigurableWrapper(@NotNull ConfigurableEP<?> ep) {
myEp = ep;
myWeight = ep.groupWeight;
}
@@ -202,7 +204,7 @@ public class ConfigurableWrapper implements SearchableConfigurable, Weighted {
}
@NotNull
public ConfigurableEP getExtensionPoint() {
public ConfigurableEP<?> getExtensionPoint() {
return myEp;
}
@@ -249,53 +251,57 @@ public class ConfigurableWrapper implements SearchableConfigurable, Weighted {
@NotNull
@Override
public Configurable[] getConfigurables() {
if (!isInitialized) {
long time = System.currentTimeMillis();
ArrayList<Configurable> list = new ArrayList<>();
if (super.myEp.dynamic) {
Composite composite = cast(Composite.class, this);
if (composite != null) {
Collections.addAll(list, composite.getConfigurables());
}
}
if (super.myEp.children != null) {
for (ConfigurableEP ep : super.myEp.getChildren()) {
if (ep.isAvailable()) {
list.add((Configurable)wrapConfigurable(ep));
}
}
}
if (super.myEp.childrenEPName != null) {
Object[] extensions = Extensions.getArea(super.myEp.getProject()).getExtensionPoint(super.myEp.childrenEPName).getExtensions();
if (extensions.length > 0) {
if (extensions[0] instanceof ConfigurableEP) {
for (Object object : extensions) {
list.add((Configurable)wrapConfigurable((ConfigurableEP)object));
}
}
else if (!super.myEp.dynamic) {
Composite composite = cast(Composite.class, this);
if (composite != null) {
Collections.addAll(list, composite.getConfigurables());
}
}
}
}
Collections.addAll(list, myKids);
// sort configurables is needed
for (Configurable configurable : list) {
if (configurable instanceof Weighted) {
if (((Weighted)configurable).getWeight() != 0) {
myComparator = COMPARATOR;
Collections.sort(list, myComparator);
break;
}
}
}
myKids = list.toArray(new Configurable[0]);
isInitialized = true;
ConfigurableCardPanel.warn(this, "children", time);
if (isInitialized) {
return myKids;
}
long time = System.currentTimeMillis();
ArrayList<Configurable> list = new ArrayList<>();
if (super.myEp.dynamic) {
Composite composite = cast(Composite.class, this);
if (composite != null) {
Collections.addAll(list, composite.getConfigurables());
}
}
if (super.myEp.children != null) {
for (ConfigurableEP<?> ep : super.myEp.getChildren()) {
if (ep.isAvailable()) {
list.add((Configurable)wrapConfigurable(ep));
}
}
}
if (super.myEp.childrenEPName != null) {
Project project = super.myEp.getProject();
ExtensionsArea area = project == null ? ApplicationManager.getApplication().getExtensionArea() : project.getExtensionArea();
List<Object> extensions = area.getExtensionPoint(super.myEp.childrenEPName).getExtensionList();
if (!extensions.isEmpty()) {
if (extensions.get(0) instanceof ConfigurableEP) {
for (Object object : extensions) {
list.add((Configurable)wrapConfigurable((ConfigurableEP<?>)object));
}
}
else if (!super.myEp.dynamic) {
Composite composite = cast(Composite.class, this);
if (composite != null) {
Collections.addAll(list, composite.getConfigurables());
}
}
}
}
Collections.addAll(list, myKids);
// sort configurables is needed
for (Configurable configurable : list) {
if (configurable instanceof Weighted) {
if (((Weighted)configurable).getWeight() != 0) {
myComparator = COMPARATOR;
Collections.sort(list, myComparator);
break;
}
}
}
myKids = list.toArray(new Configurable[0]);
isInitialized = true;
ConfigurableCardPanel.warn(this, "children", time);
return myKids;
}
@@ -7,7 +7,7 @@ import com.intellij.openapi.components.BaseComponent;
import com.intellij.openapi.components.ComponentConfig;
import com.intellij.openapi.components.impl.stores.IComponentStore;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.ExtensionsArea;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ex.ProjectEx;
@@ -35,18 +35,6 @@ final class DefaultProject extends UserDataHolderBase implements ProjectEx, Proj
Project compute() {
LOG.assertTrue(!ApplicationManager.getApplication().isDisposeInProgress(), "Application is being disposed!");
return new ProjectImpl() {
private MutablePicoContainer myPicoContainer;
@Override
protected MutablePicoContainer bootstrapPicoContainer(@NotNull String name) {
return null;
}
@NotNull
@Override
public MutablePicoContainer getPicoContainer() {
return myPicoContainer;
}
@Override
public boolean isDefault() {
return true;
@@ -73,7 +61,6 @@ final class DefaultProject extends UserDataHolderBase implements ProjectEx, Proj
@Override
public void init(@Nullable ProgressIndicator indicator) {
myPicoContainer = super.bootstrapPicoContainer(TEMPLATE_PROJECT_NAME);
MutablePicoContainer picoContainer = getPicoContainer();
// do not leak internal delegate, use DefaultProject everywhere instead
picoContainer.registerComponentInstance(Project.class, DefaultProject.this);
@@ -213,6 +200,11 @@ final class DefaultProject extends UserDataHolderBase implements ProjectEx, Proj
return getDelegate().getComponent(name);
}
@Override
public <T> T getService(@NotNull Class<T> serviceClass, boolean isCreate) {
return getDelegate().getService(serviceClass, isCreate);
}
@Override
public <T> T getComponent(@NotNull Class<T> interfaceClass) {
return getDelegate().getComponent(interfaceClass);
@@ -241,6 +233,12 @@ final class DefaultProject extends UserDataHolderBase implements ProjectEx, Proj
return getDelegate().getPicoContainer();
}
@NotNull
@Override
public ExtensionsArea getExtensionArea() {
return getDelegate().getExtensionArea();
}
@Override
@NotNull
public MessageBus getMessageBus() {
@@ -252,13 +250,6 @@ final class DefaultProject extends UserDataHolderBase implements ProjectEx, Proj
return ApplicationManager.getApplication().isDisposed();
}
@Override
@Deprecated
@NotNull
public <T> T[] getExtensions(@NotNull ExtensionPointName<T> extensionPointName) {
return getDelegate().getExtensions(extensionPointName);
}
@Override
@NotNull
public Condition<?> getDisposed() {
@@ -13,17 +13,12 @@ import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.openapi.components.ExtensionAreas;
import com.intellij.openapi.components.PathMacroManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.StorageScheme;
import com.intellij.openapi.components.impl.PlatformComponentManagerImpl;
import com.intellij.openapi.components.impl.ProjectPathMacroManager;
import com.intellij.openapi.components.impl.stores.IComponentStore;
import com.intellij.openapi.components.impl.stores.IProjectStore;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.impl.EditorsSplitters;
import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl;
@@ -47,7 +42,6 @@ import com.intellij.psi.impl.DebugUtil;
import com.intellij.util.PathUtil;
import com.intellij.util.TimedReference;
import org.jetbrains.annotations.*;
import org.picocontainer.MutablePicoContainer;
import javax.swing.*;
import java.nio.file.Path;
@@ -77,7 +71,7 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project
});
protected ProjectImpl(@NotNull Path filePath, @Nullable String projectName) {
super(ApplicationManager.getApplication(), "Project " + (projectName == null ? filePath.toString() : projectName));
super(ApplicationManager.getApplication());
putUserData(CREATION_TIME, System.nanoTime());
creationTrace = ApplicationManager.getApplication().isUnitTestMode() ? DebugUtil.currentStackTrace() : null;
@@ -93,7 +87,7 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project
static final String TEMPLATE_PROJECT_NAME = "Default (Template) Project";
// default project constructor
ProjectImpl() {
super(ApplicationManager.getApplication(), TEMPLATE_PROJECT_NAME);
super(ApplicationManager.getApplication());
putUserData(CREATION_TIME, System.nanoTime());
if (ApplicationManager.getApplication().isUnitTestMode()) {
@@ -144,14 +138,6 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project
}
}
@Override
protected MutablePicoContainer bootstrapPicoContainer(@NotNull String name) {
Extensions.instantiateArea(ExtensionAreas.IDEA_PROJECT, this, null);
MutablePicoContainer container = super.bootstrapPicoContainer(name);
container.registerComponentImplementation(PathMacroManager.class, ProjectPathMacroManager.class);
return container;
}
// do not call for default project
@NotNull
public final IProjectStore getStateStore() {
@@ -323,7 +309,6 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project
// we use super here, because temporarilyDisposed will be true if project closed
LOG.assertTrue(!super.isDisposed(), this + " is disposed already");
disposeComponents();
Extensions.disposeArea(this);
super.dispose();
@@ -336,18 +321,6 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project
LaterInvocator.purgeExpiredItems();
}
@NotNull
@Override
public <T> T[] getExtensions(@NotNull final ExtensionPointName<T> extensionPointName) {
return Extensions.getArea(this).getExtensionPoint(extensionPointName).getExtensions();
}
@NotNull
@Override
protected MutablePicoContainer createPicoContainer() {
return Extensions.getArea(this).getPicoContainer();
}
@Override
public boolean isDefault() {
return false;
@@ -0,0 +1,90 @@
// 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.
package com.intellij.serviceContainer
import com.intellij.diagnostic.LoadingPhase
import com.intellij.diagnostic.ParallelActivity
import com.intellij.diagnostic.StartUpMeasurer
import com.intellij.diagnostic.StartUpMeasurer.Level
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.ComponentManager
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.progress.ProgressIndicatorProvider
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.util.Disposer
import com.intellij.util.ReflectionUtil
import com.intellij.util.containers.ContainerUtil
import com.intellij.util.io.storage.HeavyProcessLatch
import com.intellij.util.pico.DefaultPicoContainer
import org.picocontainer.PicoContainer
import java.lang.reflect.Modifier
import java.util.concurrent.ConcurrentMap
private val LOG = logger<ServiceManager>()
// used only for Application for now
internal class ServiceContainer(parent: PicoContainer?) : DefaultPicoContainer(parent) {
private val lightServices: ConcurrentMap<Class<*>, Any>? = if (parent == null) ContainerUtil.newConcurrentMap() else null
override fun <T : Any> getService(serviceClass: Class<T>, isCreate: Boolean): T? {
val lightServices = lightServices
if (lightServices == null || !isLightService(serviceClass)) {
return super.getService(serviceClass, isCreate)
}
else {
@Suppress("UNCHECKED_CAST")
val result = lightServices.get(serviceClass) as T?
if (result != null || !isCreate) {
return result
}
else {
synchronized(serviceClass) {
return getOrCreateLightService(serviceClass, lightServices)
}
}
}
}
}
private fun <T : Any> getOrCreateLightService(serviceClass: Class<T>, cache: ConcurrentMap<Class<*>, Any>): T {
LoadingPhase.COMPONENT_REGISTERED.assertAtLeast()
@Suppress("UNCHECKED_CAST")
var instance = cache.get(serviceClass) as T?
if (instance != null) {
return instance
}
val componentManager = ApplicationManager.getApplication()
HeavyProcessLatch.INSTANCE.processStarted("Creating service '${serviceClass.name}'").use {
if (ProgressIndicatorProvider.getGlobalProgressIndicator() == null) {
instance = createLightService(serviceClass, componentManager)
}
else {
ProgressManager.getInstance().executeNonCancelableSection {
instance = createLightService(serviceClass, componentManager)
}
}
}
val prevValue = cache.put(serviceClass, instance)
LOG.assertTrue(prevValue == null)
return instance!!
}
private fun <T : Any> createLightService(serviceClass: Class<T>, componentManager: ComponentManager): T {
val startTime = StartUpMeasurer.getCurrentTime()
val instance = ReflectionUtil.newInstance(serviceClass, false)
if (instance is Disposable) {
Disposer.register(componentManager, instance as Disposable)
}
componentManager.initializeComponent(instance, null)
ParallelActivity.SERVICE.record(startTime, instance.javaClass, Level.APPLICATION)
return instance
}
private fun <T> isLightService(serviceClass: Class<T>): Boolean {
return Modifier.isFinal(serviceClass.modifiers) && serviceClass.isAnnotationPresent(Service::class.java)
}
@@ -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-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.
package com.intellij.ui
import com.intellij.core.CoreFileTypeRegistry
@@ -7,7 +7,6 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.fileChooser.FileChooserDescriptor
import com.intellij.openapi.fileChooser.impl.FileChooserUtil
import com.intellij.openapi.fileTypes.FileTypeRegistry
import com.intellij.openapi.fileTypes.FileTypes
import com.intellij.openapi.util.Getter
import com.intellij.openapi.util.io.FileUtilRt
import com.intellij.openapi.vfs.LocalFileSystem
@@ -11,7 +11,6 @@ import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorProvider;
import com.intellij.openapi.fileEditor.impl.*;
@@ -474,10 +473,8 @@ public final class DockManagerImpl extends DockManager implements PersistentStat
&& !(myContainer instanceof DockContainer.Dialog)
&& !UISettings.getInstance().getPresentationMode());
IdeRootPaneNorthExtension[] extensions =
Extensions.getArea(myProject).getExtensionPoint(IdeRootPaneNorthExtension.EP_NAME).getExtensions();
HashSet<String> processedKeys = new HashSet<>();
for (IdeRootPaneNorthExtension each : extensions) {
Set<String> processedKeys = new HashSet<>();
for (IdeRootPaneNorthExtension each : IdeRootPaneNorthExtension.EP_NAME.getExtensionList(myProject)) {
processedKeys.add(each.getKey());
if (myNorthExtensions.containsKey(each.getKey())) continue;
IdeRootPaneNorthExtension toInstall = each.copy();
@@ -7,13 +7,11 @@ import com.intellij.openapi.application.ApplicationStarterBase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.concurrent.Future;
/**
* @author Denis Fokin
*/
public final class RecentProjectApplication extends ApplicationStarterBase {
public RecentProjectApplication() {
final class RecentProjectApplication extends ApplicationStarterBase {
RecentProjectApplication() {
super("reopen", 1);
}
@@ -24,8 +22,8 @@ public final class RecentProjectApplication extends ApplicationStarterBase {
@NotNull
@Override
protected Future<CliResult> processCommand(@NotNull String[] args, @Nullable String currentDirectory) {
ProjectUtil.openProject(args[1], null, false);
protected Future<CliResult> processCommand(@NotNull List<String> args, @Nullable String currentDirectory) {
ProjectUtil.openProject(args.get(1), null, false);
return CliResult.ok();
}
}
@@ -183,7 +183,6 @@
<applicationService serviceInterface="com.intellij.openapi.fileEditor.UniqueVFilePathBuilder"
serviceImplementation="com.intellij.openapi.fileEditor.impl.UniqueVFilePathBuilderImpl"/>
<applicationService serviceImplementation="com.intellij.psi.codeStyle.arrangement.engine.ArrangementEngine"/>
<applicationService serviceImplementation="com.intellij.psi.codeStyle.arrangement.MemberOrderService"/>
<applicationService serviceInterface="com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceCompletion"
@@ -50,8 +50,11 @@
<applicationService serviceInterface="com.intellij.openapi.components.impl.stores.IComponentStore"
serviceImplementation="com.intellij.configurationStore.ApplicationStoreImpl"/>
<applicationService serviceInterface="com.intellij.openapi.components.PathMacroManager"
serviceImplementation="com.intellij.configurationStore.ApplicationPathMacroManager"/>
<projectService serviceInterface="com.intellij.openapi.components.PathMacroManager"
serviceImplementation="com.intellij.openapi.components.impl.ProjectPathMacroManager"/>
<applicationService serviceImplementation="com.intellij.configurationStore.DefaultProjectExportableAndSaveTrigger"/>
@@ -1,27 +1,17 @@
/*
* Copyright 2000-2017 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-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.
package com.intellij.ide.ui;
import com.intellij.ide.SearchTopHitProvider;
import com.intellij.ide.ui.search.BooleanOptionDescription;
import com.intellij.ide.ui.search.NotABooleanOptionDescription;
import com.intellij.ide.ui.search.OptionDescription;
import com.intellij.testFramework.LightPlatformTestCase;
import com.intellij.testFramework.EdtRule;
import com.intellij.testFramework.ProjectRule;
import com.intellij.testFramework.RunsInEdt;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.junit.Rule;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
@@ -30,10 +20,16 @@ import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author Konstantin Bulenkov
*/
public class TopHitProvidersTest extends LightPlatformTestCase {
import static com.intellij.testFramework.assertions.Assertions.assertThat;
@RunsInEdt
public class TopHitProvidersTest {
@Rule
public final ProjectRule projectRule = new ProjectRule();
@Rule
public final EdtRule edtRule = new EdtRule();
@Test
public void testUiSettings() {
List<String> errors = new ArrayList<>();
@@ -61,7 +57,7 @@ public class TopHitProvidersTest extends LightPlatformTestCase {
}
}
assertEmpty(errors);
assertThat(errors).isEmpty();
}
private static List<OptionsSearchTopHitProvider> getProviders() {
@@ -72,13 +68,13 @@ public class TopHitProvidersTest extends LightPlatformTestCase {
private Collection<OptionDescription> getOptions(@NotNull OptionsSearchTopHitProvider provider) {
if (provider instanceof OptionsSearchTopHitProvider.ProjectLevelProvider) {
return ((OptionsSearchTopHitProvider.ProjectLevelProvider)provider).getOptions(getProject());
return ((OptionsSearchTopHitProvider.ProjectLevelProvider)provider).getOptions(projectRule.getProject());
}
else if (provider instanceof OptionsSearchTopHitProvider.ApplicationLevelProvider) {
return ((OptionsSearchTopHitProvider.ApplicationLevelProvider)provider).getOptions();
}
else if (provider instanceof OptionsTopHitProvider) {
return ((OptionsTopHitProvider)provider).getOptions(getProject());
return ((OptionsTopHitProvider)provider).getOptions(projectRule.getProject());
}
return Collections.emptyList();
}
@@ -2,17 +2,17 @@
package com.intellij.lang
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.extensions.DefaultPluginDescriptor
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.extensions.ExtensionsArea
import com.intellij.openapi.extensions.PluginId
import com.intellij.openapi.fileTypes.PlainTextLanguage
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.JDOMUtil
import com.intellij.testFramework.LightPlatformTestCase
import org.picocontainer.MutablePicoContainer
class LanguageExtensionCacheTest : LightPlatformTestCase() {
private val myExtensionPointName = "testLangExt"
private val myExtensionPointXML = """
<extensionPoint qualifiedName="$myExtensionPointName" beanClass="com.intellij.lang.LanguageExtensionPoint">
@@ -26,8 +26,8 @@ class LanguageExtensionCacheTest : LightPlatformTestCase() {
override fun setUp() {
super.setUp()
myArea = Extensions.getRootArea()
myArea.registerExtensionPoint(myDescriptor, JDOMUtil.load(myExtensionPointXML))
myArea = ApplicationManager.getApplication().extensionArea
myArea.registerExtensionPoint(myDescriptor, JDOMUtil.load(myExtensionPointXML), ApplicationManager.getApplication ().picoContainer as MutablePicoContainer)
Disposer.register(testRootDisposable, Disposable {
myArea.unregisterExtensionPoint(myExtensionPointName)
})
@@ -1,12 +1,17 @@
// 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-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.
package com.intellij.lang
import com.intellij.openapi.extensions.*
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.extensions.DefaultPluginDescriptor
import com.intellij.openapi.extensions.ExtensionsArea
import com.intellij.openapi.extensions.PluginDescriptor
import com.intellij.openapi.extensions.PluginId
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.JDOMUtil
import com.intellij.testFramework.LightPlatformTestCase
import com.intellij.testFramework.PlatformTestUtil
import groovy.transform.CompileStatic
import org.picocontainer.MutablePicoContainer
@CompileStatic
class LanguageExtensionOrderTest extends LightPlatformTestCase {
@@ -16,7 +21,7 @@ class LanguageExtensionOrderTest extends LightPlatformTestCase {
void setUp() {
super.setUp()
myArea = Extensions.rootArea
myArea = ApplicationManager.getApplication().getExtensionArea()
myLanguageExtension = new LanguageExtension<TestLangExtension>("langExt")
registerMetaLanguage()
registerLanguageEP()
@@ -27,11 +32,11 @@ class LanguageExtensionOrderTest extends LightPlatformTestCase {
}
private void registerLanguageEP() {
myArea.registerExtensionPoint myDescriptor, JDOMUtil.load('''\
myArea.registerExtensionPoint(myDescriptor, JDOMUtil.load('''\
<extensionPoint qualifiedName="langExt" beanClass="com.intellij.lang.LanguageExtensionPoint">
<with attribute="implementationClass" implements="com.intellij.lang.TestLangExtension"/>
</extensionPoint>
''')
'''), (MutablePicoContainer)ApplicationManager.getApplication().picoContainer)
Disposer.register(testRootDisposable) {
myArea.unregisterExtensionPoint("langExt")
}
@@ -4,16 +4,13 @@ package com.intellij.openapi.components.impl;
import com.intellij.application.options.PathMacrosCollector;
import com.intellij.application.options.PathMacrosImpl;
import com.intellij.application.options.ReplacePathToMacroMap;
import com.intellij.mock.MockApplication;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.PathMacroFilter;
import com.intellij.openapi.application.PathMacros;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.ExtensionsArea;
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.ex.ProjectEx;
import com.intellij.openapi.util.Disposer;
@@ -21,12 +18,8 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.SystemProperties;
import org.hamcrest.Description;
import org.jetbrains.annotations.Nullable;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.api.Action;
import org.jmock.api.Invocation;
import org.jmock.integration.junit4.JMock;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.jmock.lib.legacy.ClassImposteriser;
@@ -37,9 +30,6 @@ import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;
/**
* @author mike
*/
@RunWith(JMock.class)
public class PathMacroManagerTest {
private static final String APP_HOME = FileUtil.toSystemIndependentName(PathManager.getHomePath());
@@ -50,41 +40,16 @@ public class PathMacroManagerTest {
private PathMacrosImpl myPathMacros;
private Mockery context;
protected ApplicationEx myApplication;
protected MockApplication myApplication;
private final Disposable myRootDisposable = Disposer.newDisposable();
@Before
public final void setupApplication() {
context = new JUnit4Mockery();
context.setImposteriser(ClassImposteriser.INSTANCE);
myApplication = context.mock(ApplicationEx.class, "application");
myApplication = MockApplication.setUp(myRootDisposable);
context.checking(new Expectations() {
{
allowing(myApplication).isUnitTestMode(); will(returnValue(false));
allowing(myApplication).getName(); will(returnValue("IDEA"));
// some tests leave invokeLater()'s after them
allowing(myApplication).invokeLater(with(any(Runnable.class)), with(any(ModalityState.class)));
allowing(myApplication).runReadAction(with(any(Runnable.class)));
will(new Action() {
@Override
public void describeTo(final Description description) {
description.appendText("runs runnable");
}
@Override
@Nullable
public Object invoke(final Invocation invocation) {
((Runnable)invocation.getParameter(0)).run();
return null;
}
});
}
});
final ExtensionsArea area = Extensions.getRootArea();
ExtensionsAreaImpl area = myApplication.getExtensionArea();
final ExtensionPointName<PathMacroFilter> epName = PathMacrosCollector.MACRO_FILTER_EXTENSION_POINT_NAME;
if (!area.hasExtensionPoint(epName)) {
area.registerExtensionPoint(epName, "com.intellij.openapi.application.PathMacroFilter", ExtensionPoint.Kind.INTERFACE, myRootDisposable);
@@ -111,7 +76,6 @@ public class PathMacroManagerTest {
final String moduleFilePath = projectPath + "/module/module.iml";
allowing(myApplication).getComponent(with(equal(PathMacros.class))); will(returnValue(myPathMacros));
allowing(myPathMacros).addMacroReplacements(with(any(ReplacePathToMacroMap.class)));
allowing(myPathMacros).getModificationCount();
@@ -11,7 +11,6 @@ import com.intellij.openapi.components.impl.ComponentManagerImpl;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorActionManager;
import com.intellij.openapi.editor.actionSystem.TypedAction;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
import com.intellij.openapi.fileEditor.impl.NonProjectFileWritingAccessExtension;
import com.intellij.openapi.fileEditor.impl.NonProjectFileWritingAccessProvider;
@@ -318,7 +317,7 @@ public class NonProjectFileAccessTest extends HeavyFileEditorManagerTestCase {
private Set<VirtualFile> registerWriteAccessProvider(final VirtualFile... filesToDeny) {
final Set<VirtualFile> requested = new LinkedHashSet<>();
PlatformTestUtil.registerExtension(Extensions.getArea(getProject()), WritingAccessProvider.EP_NAME, new WritingAccessProvider() {
PlatformTestUtil.registerExtension(getProject().getExtensionArea(), WritingAccessProvider.EP_NAME, new WritingAccessProvider() {
@NotNull
@Override
public Collection<VirtualFile> requestWriting(@NotNull Collection<? extends VirtualFile> files) {
@@ -332,7 +331,7 @@ public class NonProjectFileAccessTest extends HeavyFileEditorManagerTestCase {
}
private void registerAccessCheckExtension(Collection<VirtualFile> filesToAllow, Collection<VirtualFile> filesToDeny) {
PlatformTestUtil.registerExtension(Extensions.getArea(getProject()), NonProjectFileWritingAccessExtension.EP_NAME,
PlatformTestUtil.registerExtension(getProject().getExtensionArea(), NonProjectFileWritingAccessExtension.EP_NAME,
new NonProjectFileWritingAccessExtension() {
@Override
public boolean isWritable(@NotNull VirtualFile 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-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.
package com.intellij.usages.impl;
import com.intellij.find.FindManager;
@@ -15,6 +15,7 @@ import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.command.impl.UndoManagerImpl;
import com.intellij.openapi.command.undo.UndoManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileTypes.BinaryFileDecompiler;
import com.intellij.openapi.fileTypes.BinaryFileTypeDecompilers;
@@ -30,9 +31,10 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.testFramework.ExtensionTestUtil;
import com.intellij.testFramework.HeavyPlatformTestCase;
import com.intellij.testFramework.LeakHunter;
import com.intellij.testFramework.LightPlatformTestCase;
import com.intellij.testFramework.HeavyPlatformTestCase;
import com.intellij.testFramework.fixtures.BasePlatformTestCase;
import com.intellij.usageView.UsageInfo;
import com.intellij.usages.*;
@@ -303,7 +305,9 @@ public class UsageViewTest extends BasePlatformTestCase {
BinaryFileDecompiler decompiler = file -> {
throw new IllegalStateException("oh no");
};
BinaryFileTypeDecompilers.INSTANCE.addExplicitExtension(ArchiveFileType.INSTANCE, decompiler, getTestRootDisposable());
ExtensionTestUtil.addExtension((ExtensionsAreaImpl)ApplicationManager.getApplication().getExtensionArea(),
BinaryFileTypeDecompilers.INSTANCE, ArchiveFileType.INSTANCE.getName(), decompiler);
PsiFile psiFile = myFixture.addFileToProject("X.jar", "xxx");
assertEquals(ArchiveFileType.INSTANCE, psiFile.getFileType());
@@ -4,12 +4,9 @@ package com.intellij.core;
import com.intellij.ide.highlighter.ModuleFileType;
import com.intellij.mock.MockComponentManager;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.PathMacros;
import com.intellij.openapi.components.ExtensionAreas;
import com.intellij.openapi.components.PathMacroManager;
import com.intellij.openapi.components.impl.ModulePathMacroManager;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.impl.ModuleEx;
import com.intellij.openapi.module.impl.ModuleScopeProvider;
import com.intellij.openapi.project.Project;
@@ -43,13 +40,6 @@ public class CoreModule extends MockComponentManager implements ModuleEx {
myProject = project;
myPath = moduleFilePath;
Extensions.instantiateArea(ExtensionAreas.IDEA_MODULE, this, null);
Disposer.register(parentDisposable, new Disposable() {
@Override
public void dispose() {
Extensions.disposeArea(CoreModule.this);
}
});
initModuleExtensions();
final ModuleRootManagerImpl moduleRootManager =
@@ -82,7 +72,7 @@ public class CoreModule extends MockComponentManager implements ModuleEx {
// used by Upsource
protected PathMacroManager createModulePathMacroManager(@SuppressWarnings("unused") @NotNull Project project) {
return new ModulePathMacroManager(PathMacros.getInstance(), this);
return new ModulePathMacroManager(this);
}
protected ModuleFileIndex createModuleFileIndex(@NotNull Project project) {
@@ -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-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.
package com.intellij.openapi.components;
import com.intellij.application.options.PathMacrosCollector;
@@ -18,11 +18,12 @@ import org.jetbrains.annotations.SystemIndependent;
import org.jetbrains.jps.model.serialization.PathMacroUtil;
import java.util.Map;
import java.util.Objects;
public class PathMacroManager implements PathMacroSubstitutor {
@NotNull
public static PathMacroManager getInstance(@NotNull ComponentManager componentManager) {
return (PathMacroManager)componentManager.getPicoContainer().getComponentInstance(PathMacroManager.class);
return Objects.requireNonNull(componentManager.getService(PathMacroManager.class, true));
}
private static class Holder {
@@ -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-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.
package com.intellij.openapi.components.impl;
import com.intellij.application.options.ReplacePathToMacroMap;
@@ -7,11 +7,18 @@ import com.intellij.openapi.components.ExpandMacroToPathMap;
import com.intellij.openapi.components.PathMacroManager;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jps.model.serialization.PathMacroUtil;
public class ModulePathMacroManager extends PathMacroManager {
private final Module myModule;
public ModulePathMacroManager(@NotNull Module module) {
super(PathMacros.getInstance());
myModule = module;
}
@TestOnly
public ModulePathMacroManager(@NotNull PathMacros pathMacros, @NotNull Module module) {
super(pathMacros);
@@ -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-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.
package com.intellij.openapi.components.impl;
import com.intellij.application.options.ReplacePathToMacroMap;
@@ -7,12 +7,20 @@ import com.intellij.openapi.components.ExpandMacroToPathMap;
import com.intellij.openapi.components.PathMacroManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jps.model.serialization.PathMacroUtil;
public class ProjectPathMacroManager extends PathMacroManager {
public final class ProjectPathMacroManager extends PathMacroManager {
private final Project myProject;
public ProjectPathMacroManager(PathMacros pathMacros, Project project) {
@SuppressWarnings("unused")
public ProjectPathMacroManager(@NotNull Project project) {
super(PathMacros.getInstance());
myProject = project;
}
@TestOnly
public ProjectPathMacroManager(@NotNull PathMacros pathMacros, @NotNull Project project) {
super(pathMacros);
myProject = project;
}
@@ -11,7 +11,6 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.util.Disposer;
import com.intellij.testFramework.HeavyPlatformTestCase;
@@ -94,10 +93,10 @@ public final class IdeaTestApplication implements Disposable {
}, AppExecutorUtil.getAppExecutorService());
ApplicationImpl.patchSystem();
ApplicationImpl app = new ApplicationImpl(true, true, true, true, ApplicationManagerEx.IDEA_APPLICATION);
ApplicationImpl app = new ApplicationImpl(true, true, true, true);
IconManager.activate();
try {
ApplicationLoader.registerRegistryAndContainerAndInitStore(loadedPluginFuture, app, null)
ApplicationLoader.registerRegistryAndInitStore(loadedPluginFuture.thenAccept(it -> app.registerComponents(it)), app)
.thenCompose(aVoid -> ApplicationLoader.preloadServices(app))
.get(20, TimeUnit.SECONDS);
}
@@ -4,7 +4,6 @@ package com.intellij.psi.codeStyle.arrangement;
import com.intellij.application.options.CodeStyle;
import com.intellij.lang.Language;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.FoldRegion;
import com.intellij.openapi.editor.FoldingModel;
import com.intellij.openapi.fileTypes.FileType;
@@ -131,9 +130,9 @@ public abstract class AbstractRearrangerTest extends BasePlatformTestCase {
@SuppressWarnings("unchecked")
List<StdArrangementRuleAliasToken> aliases =
ObjectUtils.coalesce((List<StdArrangementRuleAliasToken>)args.get("aliases"), Collections.emptyList());
final StdArrangementSettings arrangementSettings = new StdArrangementExtendableSettings(groupingRules, sectionRules, aliases);
String text = (String)args.get("initial");
String expected = (String)args.get("expected");
@SuppressWarnings("unchecked") List<TextRange> ranges = (List<TextRange>)args.get("ranges");
@@ -143,7 +142,7 @@ public abstract class AbstractRearrangerTest extends BasePlatformTestCase {
protected void doTestWithSettings(@NotNull String text,
@NotNull String expected,
@Nullable ArrangementSettings arrangementSettings,
@Nullable ArrangementSettings arrangementSettings,
@Nullable List<TextRange> ranges) {
Info info = parse(text);
if (!isEmpty(ranges) && !isEmpty(info.ranges)) {
@@ -167,7 +166,7 @@ public abstract class AbstractRearrangerTest extends BasePlatformTestCase {
CommonCodeStyleSettings settings = CodeStyle.getSettings(myFixture.getProject()).getCommonSettings(language);
settings.setArrangementSettings(arrangementSettings);
}
ArrangementEngine engine = ServiceManager.getService(myFixture.getProject(), ArrangementEngine.class);
ArrangementEngine engine = ArrangementEngine.getInstance();
CommandProcessor.getInstance().executeCommand(getProject(), ()-> engine.arrange(myFixture.getEditor(), myFixture.getFile(), info.ranges), null, null);
@@ -0,0 +1,37 @@
// 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.
package com.intellij.testFramework
import com.intellij.lang.Language
import com.intellij.lang.LanguageExtension
import com.intellij.mock.MockApplication
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.extensions.impl.ExtensionPointImpl
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl
import com.intellij.openapi.util.KeyedExtensionCollector
import com.intellij.util.KeyedLazyInstance
import java.util.function.Predicate
object ExtensionTestUtil {
@JvmStatic
fun <T> addExtension(area: ExtensionsAreaImpl, collector: LanguageExtension<T>, language: Language, instance: T) {
addExtension(area, collector, language.id, instance)
}
@JvmStatic
fun <T, KeyT> addExtension(area: ExtensionsAreaImpl, collector: KeyedExtensionCollector<T, KeyT>, key: String, instance: T) {
val point = area.getExtensionPoint<KeyedLazyInstance<T>>(collector.name)
if (ApplicationManager.getApplication() !is MockApplication) {
// if not MockApplication, it means that extension point is not registered as fake bean
ExtensionPointImpl.setTestTypeChecker(Predicate { KeyedLazyInstance::class.java.isAssignableFrom(it) }, ApplicationManager.getApplication())
}
@Suppress("DEPRECATION")
point.registerExtension(object : KeyedLazyInstance<T> {
override fun getKey() = key
override fun getInstance() = instance
})
collector.clearCache()
}
}
@@ -9,8 +9,12 @@ import com.intellij.lang.injection.MultiHostInjector;
import com.intellij.mock.*;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.extensions.DefaultPluginDescriptor;
import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.PluginDescriptor;
import com.intellij.openapi.extensions.impl.ExtensionPointImpl;
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl;
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
@@ -21,7 +25,6 @@ import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.impl.ProgressManagerImpl;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.LineColumn;
@@ -37,24 +40,25 @@ import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.util.CachedValuesManagerImpl;
import com.intellij.util.KeyedLazyInstance;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBus;
import org.jetbrains.annotations.NotNull;
import org.picocontainer.*;
import org.picocontainer.defaults.AbstractComponentAdapter;
import org.picocontainer.ComponentAdapter;
import org.picocontainer.MutablePicoContainer;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import static java.util.Objects.requireNonNull;
import java.util.*;
/** @noinspection JUnitTestCaseWithNonTrivialConstructors*/
public abstract class ParsingTestCase extends PlatformLiteFixture {
public abstract class ParsingTestCase extends UsefulTestCase {
private PluginDescriptor myPluginDescriptor;
private MockApplication myApp;
protected MockProjectEx myProject;
protected String myFilePrefix = "";
protected String myFileExt;
protected final String myFullDataPath;
@@ -64,6 +68,7 @@ public abstract class ParsingTestCase extends PlatformLiteFixture {
protected Language myLanguage;
private final ParserDefinition[] myDefinitions;
private final boolean myLowercaseFirstLetter;
private ExtensionPointImpl<KeyedLazyInstance<ParserDefinition>> myLangParserDefinition;
protected ParsingTestCase(@NotNull String dataPath, @NotNull String fileExt, @NotNull ParserDefinition... definitions) {
this(dataPath, fileExt, false, definitions);
@@ -76,49 +81,52 @@ public abstract class ParsingTestCase extends PlatformLiteFixture {
myLowercaseFirstLetter = lowercaseFirstLetter;
}
@NotNull
protected MockApplication getApplication() {
return myApp;
}
@Override
protected void setUp() throws Exception {
super.setUp();
initApplication();
ComponentAdapter component = getApplication().getPicoContainer().getComponentAdapter(ProgressManager.class.getName());
if (component == null) {
getApplication().getPicoContainer().registerComponent(new AbstractComponentAdapter(ProgressManager.class.getName(), Object.class) {
@Override
public Object getComponentInstance(PicoContainer container) throws PicoInitializationException, PicoIntrospectionException {
return new ProgressManagerImpl();
}
@Override
public void verify(PicoContainer container) throws PicoIntrospectionException { }
});
MockApplication app = MockApplication.setUp(getTestRootDisposable());
myApp = app;
MutablePicoContainer appContainer = app.getPicoContainer();
ComponentAdapter component = appContainer.getComponentAdapter(ProgressManager.class.getName());
if (component == null) {
appContainer.registerComponentInstance(ProgressManager.class.getName(), new ProgressManagerImpl());
}
Extensions.registerAreaClass("IDEA_PROJECT", null);
myProject = new MockProjectEx(getTestRootDisposable());
myPsiManager = new MockPsiManager(myProject);
myFileFactory = new PsiFileFactoryImpl(myPsiManager);
MutablePicoContainer appContainer = getApplication().getPicoContainer();
registerComponentInstance(appContainer, MessageBus.class, getApplication().getMessageBus());
registerComponentInstance(appContainer, SchemeManagerFactory.class, new MockSchemeManagerFactory());
appContainer.registerComponentInstance(MessageBus.class, app.getMessageBus());
appContainer.registerComponentInstance(SchemeManagerFactory.class, new MockSchemeManagerFactory());
MockEditorFactory editorFactory = new MockEditorFactory();
registerComponentInstance(appContainer, EditorFactory.class, editorFactory);
registerComponentInstance(appContainer, FileDocumentManager.class, new MockFileDocumentManagerImpl(
charSequence -> editorFactory.createDocument(charSequence), FileDocumentManagerImpl.HARD_REF_TO_DOCUMENT_KEY));
registerComponentInstance(appContainer, PsiDocumentManager.class, new MockPsiDocumentManager());
appContainer.registerComponentInstance(EditorFactory.class, editorFactory);
appContainer.registerComponentInstance(FileDocumentManager.class, new MockFileDocumentManagerImpl(charSequence -> {
return editorFactory.createDocument(charSequence);
}, FileDocumentManagerImpl.HARD_REF_TO_DOCUMENT_KEY));
appContainer.registerComponentInstance(PsiDocumentManager.class, new MockPsiDocumentManager());
registerApplicationService(PsiBuilderFactory.class, new PsiBuilderFactoryImpl());
registerApplicationService(DefaultASTFactory.class, new DefaultASTFactoryImpl());
registerApplicationService(ReferenceProvidersRegistry.class, new ReferenceProvidersRegistryImpl());
app.registerService(PsiBuilderFactory.class, new PsiBuilderFactoryImpl());
app.registerService(DefaultASTFactory.class, new DefaultASTFactoryImpl());
app.registerService(ReferenceProvidersRegistry.class, new ReferenceProvidersRegistryImpl());
myProject.registerService(CachedValuesManager.class, new CachedValuesManagerImpl(myProject, new PsiCachedValuesFactory(myPsiManager)));
myProject.registerService(PsiManager.class, myPsiManager);
myProject.registerService(StartupManager.class, new StartupManagerImpl(myProject));
registerExtensionPoint(FileTypeFactory.FILE_TYPE_FACTORY_EP, FileTypeFactory.class);
registerExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
registerExtensionPoint(app.getExtensionArea(), FileTypeFactory.FILE_TYPE_FACTORY_EP, FileTypeFactory.class);
registerExtensionPoint(app.getExtensionArea(), MetaLanguage.EP_NAME, MetaLanguage.class);
myLangParserDefinition = app.getExtensionArea().registerFakeBeanPoint(LanguageParserDefinitions.INSTANCE.getName(), getPluginDescriptor());
for (ParserDefinition definition : myDefinitions) {
addExplicitExtension(LanguageParserDefinitions.INSTANCE, definition.getFileNodeType().getLanguage(), definition);
}
if (myDefinitions.length > 0) {
configureFromParserDefinition(myDefinitions[0], myFileExt);
// first definition is registered by configureFromParserDefinition
for (int i = 1, length = myDefinitions.length; i < length; i++) {
registerParserDefinition(myDefinitions[i]);
}
}
// That's for reparse routines
@@ -127,22 +135,82 @@ public abstract class ParsingTestCase extends PlatformLiteFixture {
new TreeAspect(pomModel);
}
public void configureFromParserDefinition(ParserDefinition definition, String extension) {
protected final void registerParserDefinition(@NotNull ParserDefinition definition) {
myLangParserDefinition.registerExtension(new KeyedLazyInstance<ParserDefinition>() {
@Override
public String getKey() {
return definition.getFileNodeType().getLanguage().getID();
}
@NotNull
@Override
public ParserDefinition getInstance() {
return definition;
}
});
LanguageParserDefinitions.INSTANCE.clearCache();
}
public void configureFromParserDefinition(@NotNull ParserDefinition definition, String extension) {
myLanguage = definition.getFileNodeType().getLanguage();
myFileExt = extension;
addExplicitExtension(LanguageParserDefinitions.INSTANCE, myLanguage, definition);
registerComponentInstance(getApplication().getPicoContainer(), FileTypeManager.class,
new MockFileTypeManager(new MockLanguageFileType(myLanguage, myFileExt)));
registerParserDefinition(definition);
myApp.getPicoContainer().registerComponentInstance(FileTypeManager.class, new MockFileTypeManager(new MockLanguageFileType(myLanguage, myFileExt)));
}
protected <T> void addExplicitExtension(LanguageExtension<T> instance, Language language, T object) {
instance.addExplicitExtension(language, object, myProject);
protected final <T> void registerExtension(@NotNull ExtensionPointName<T> name, @NotNull T extension) {
//noinspection unchecked
registerExtensions(name, (Class<T>)extension.getClass(), Collections.singletonList(extension));
}
@Override
protected <T> void registerExtensionPoint(@NotNull ExtensionPointName<T> extensionPointName, @NotNull Class<T> aClass) {
super.registerExtensionPoint(extensionPointName, aClass);
Disposer.register(getTestRootDisposable(), () -> Extensions.getRootArea().unregisterExtensionPoint(extensionPointName.getName()));
protected final <T> void registerExtensions(@NotNull ExtensionPointName<T> name, @NotNull Class<T> extensionClass, @NotNull List<T> extensions) {
ExtensionsAreaImpl area = myApp.getExtensionArea();
ExtensionPoint<T> point = area.getExtensionPointIfRegistered(name.getName());
if (point == null) {
point = registerExtensionPoint(area, name, extensionClass);
}
for (T extension : extensions) {
// no need to specify disposable because ParsingTestCase in any case clean area for each test
//noinspection deprecation
point.registerExtension(extension);
}
}
protected final <T> void addExplicitExtension(@NotNull LanguageExtension<T> collector, @NotNull Language language, @NotNull T object) {
ExtensionsAreaImpl area = myApp.getExtensionArea();
if (!area.hasExtensionPoint(collector.getName())) {
area.registerFakeBeanPoint(collector.getName(), getPluginDescriptor());
}
ExtensionTestUtil.addExtension(area, collector, language, object);
}
protected final <T> void registerExtensionPoint(@NotNull ExtensionPointName<T> extensionPointName, @NotNull Class<T> aClass) {
registerExtensionPoint(myApp.getExtensionArea(), extensionPointName, aClass);
}
protected <T> ExtensionPointImpl<T> registerExtensionPoint(@NotNull ExtensionsAreaImpl extensionArea,
@NotNull ExtensionPointName<T> extensionPointName,
@NotNull Class<T> extensionClass) {
// todo get rid of it - registerExtensionPoint should be not called several times
String name = extensionPointName.getName();
if (extensionArea.hasExtensionPoint(name)) {
return extensionArea.getExtensionPoint(name);
}
else {
return extensionArea.registerPoint(name, extensionClass, getPluginDescriptor());
}
}
@NotNull
// easy debug of not disposed extension
private PluginDescriptor getPluginDescriptor() {
PluginDescriptor pluginDescriptor = myPluginDescriptor;
if (pluginDescriptor == null) {
pluginDescriptor = new DefaultPluginDescriptor(getClass().getName() + "." + getName());
myPluginDescriptor = pluginDescriptor;
}
return pluginDescriptor;
}
@NotNull
@@ -226,7 +294,7 @@ public abstract class ParsingTestCase extends PlatformLiteFixture {
ensureParsed(myFile);
assertEquals("light virtual file text mismatch", text, ((LightVirtualFile)myFile.getVirtualFile()).getContent().toString());
assertEquals("virtual file text mismatch", text, LoadTextUtil.loadText(myFile.getVirtualFile()));
assertEquals("doc text mismatch", text, requireNonNull(myFile.getViewProvider().getDocument()).getText());
assertEquals("doc text mismatch", text, Objects.requireNonNull(myFile.getViewProvider().getDocument()).getText());
assertEquals("psi text mismatch", text, myFile.getText());
ensureCorrectReparse(myFile);
if (checkResult) {
@@ -378,9 +446,9 @@ public abstract class ParsingTestCase extends PlatformLiteFixture {
}
public void registerMockInjectedLanguageManager() {
registerExtensionPoint(Extensions.getArea(myProject), MultiHostInjector.MULTIHOST_INJECTOR_EP_NAME, MultiHostInjector.class);
registerExtensionPoint(myProject.getExtensionArea(), MultiHostInjector.MULTIHOST_INJECTOR_EP_NAME, MultiHostInjector.class);
registerExtensionPoint(LanguageInjector.EXTENSION_POINT_NAME, LanguageInjector.class);
registerExtensionPoint(myApp.getExtensionArea(), LanguageInjector.EXTENSION_POINT_NAME, LanguageInjector.class);
myProject.registerService(InjectedLanguageManager.class, new InjectedLanguageManagerImpl(myProject, new MockDumbService(myProject)));
}
}

Some files were not shown because too many files have changed in this diff Show More