mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
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:
committed by
intellij-monorepo-bot
parent
3fbb8c21bb
commit
4eb65aaf9c
@@ -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());
|
||||
|
||||
+1
-1
@@ -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
@@ -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)
|
||||
|
||||
+30
-24
@@ -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
|
||||
|
||||
+4
-25
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-16
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
-55
@@ -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);
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+23
-2
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+57
-155
@@ -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();
|
||||
}
|
||||
}
|
||||
+3
-30
@@ -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,
|
||||
|
||||
+3
@@ -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<>();
|
||||
|
||||
-39
@@ -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());
|
||||
}
|
||||
}
|
||||
+9
-57
@@ -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>"));
|
||||
|
||||
+2
-5
@@ -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();
|
||||
|
||||
+2
-17
@@ -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) {
|
||||
|
||||
+9
-8
@@ -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();
|
||||
|
||||
+8
-3
@@ -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) {
|
||||
|
||||
+3
-16
@@ -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);
|
||||
}
|
||||
|
||||
+4
-18
@@ -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()`");
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -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>() {
|
||||
|
||||
+7
-6
@@ -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();
|
||||
}
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
+3
-26
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
+52
-10
@@ -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
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -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
|
||||
|
||||
+56
-50
@@ -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)
|
||||
})
|
||||
|
||||
+10
-5
@@ -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")
|
||||
}
|
||||
|
||||
+5
-41
@@ -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();
|
||||
|
||||
|
||||
+2
-3
@@ -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) {
|
||||
|
||||
+3
-2
@@ -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 {
|
||||
|
||||
+8
-1
@@ -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);
|
||||
|
||||
|
||||
+11
-3
@@ -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
-5
@@ -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
Reference in New Issue
Block a user