more async start-up, do not activate icon loader explicitly

GitOrigin-RevId: dc43aca428d16c3a1b41b439a5f2f3be91a88743
This commit is contained in:
Vladimir Krivosheev
2021-04-05 09:30:15 +00:00
committed by intellij-monorepo-bot
parent 32b9d6a38c
commit a2ef29db78
61 changed files with 780 additions and 766 deletions
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.debugger.settings;
import com.intellij.CommonBundle;
@@ -267,7 +267,7 @@ public class CaptureConfigurable implements SearchableConfigurable, NoScroll {
}
});
try {
JDOMUtil.write(rootElement, wrapper.getFile());
JDOMUtil.write(rootElement, wrapper.getFile().toPath());
}
catch (Exception ex) {
final String msg = ex.getLocalizedMessage();
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.openapi.command.WriteCommandAction;
@@ -11,6 +11,10 @@ import com.intellij.util.ui.UIUtil;
import javax.swing.*;
public class DeferredIconTest extends LightJavaCodeInsightFixtureTestCase {
@Override
protected boolean isIconRequired() {
return true;
}
public void test_icons_before_and_after_computation_are_equal() {
PsiFile file = myFixture.addFileToProject("a.java", "class C {}");
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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;
import com.intellij.icons.AllIcons;
@@ -27,45 +27,44 @@ import javax.swing.*;
final class JavaDirectoryIconProvider extends IconProvider implements DumbAware {
@Override
@Nullable
public Icon getIcon(@NotNull PsiElement element, int flags) {
if (element instanceof PsiDirectory) {
final PsiDirectory psiDirectory = (PsiDirectory)element;
final VirtualFile vFile = psiDirectory.getVirtualFile();
final Project project = psiDirectory.getProject();
SourceFolder sourceFolder;
Icon symbolIcon;
if (vFile.getParent() == null && vFile.getFileSystem() instanceof ArchiveFileSystem) {
symbolIcon = PlatformIcons.JAR_ICON;
}
else if (ProjectRootsUtil.isModuleContentRoot(vFile, project)) {
Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(vFile);
symbolIcon = module == null || module.isDisposed() ? PlatformIcons.CONTENT_ROOT_ICON_CLOSED : ModuleType.get(module).getIcon();
}
else if (ProjectRootsUtil.findUnloadedModuleByContentRoot(vFile, project) != null) {
symbolIcon = AllIcons.Modules.UnloadedModule;
}
else if ((sourceFolder = ProjectRootsUtil.getModuleSourceRoot(vFile, project)) != null) {
symbolIcon = SourceRootPresentation.getSourceRootIcon(sourceFolder);
}
else if (JrtFileSystem.isModuleRoot(vFile)) {
symbolIcon = AllIcons.Nodes.Module;
}
else if (isValidPackage(psiDirectory)) {
symbolIcon = IconManager.getInstance().tooltipOnlyIfComposite(PlatformIcons.PACKAGE_ICON);
}
else if (!Registry.is("ide.hide.excluded.files") && ProjectRootManager.getInstance(project).getFileIndex().isExcluded(vFile)) {
symbolIcon = AllIcons.Modules.ExcludeRoot;
}
else {
symbolIcon = PlatformIcons.FOLDER_ICON;
}
return IconManager.getInstance().createLayeredIcon(element, symbolIcon, 0);
public @Nullable Icon getIcon(@NotNull PsiElement element, int flags) {
if (!(element instanceof PsiDirectory)) {
return null;
}
return null;
final PsiDirectory psiDirectory = (PsiDirectory)element;
final VirtualFile vFile = psiDirectory.getVirtualFile();
final Project project = psiDirectory.getProject();
SourceFolder sourceFolder;
Icon symbolIcon;
if (vFile.getParent() == null && vFile.getFileSystem() instanceof ArchiveFileSystem) {
symbolIcon = PlatformIcons.JAR_ICON;
}
else if (ProjectRootsUtil.isModuleContentRoot(vFile, project)) {
Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(vFile);
symbolIcon = module == null || module.isDisposed() ? PlatformIcons.CONTENT_ROOT_ICON_CLOSED : ModuleType.get(module).getIcon();
}
else if (ProjectRootsUtil.findUnloadedModuleByContentRoot(vFile, project) != null) {
symbolIcon = AllIcons.Modules.UnloadedModule;
}
else if ((sourceFolder = ProjectRootsUtil.getModuleSourceRoot(vFile, project)) != null) {
symbolIcon = SourceRootPresentation.getSourceRootIcon(sourceFolder);
}
else if (JrtFileSystem.isModuleRoot(vFile)) {
symbolIcon = AllIcons.Nodes.Module;
}
else if (isValidPackage(psiDirectory)) {
IconManager iconManager = IconManager.getInstance();
symbolIcon = iconManager.createLayeredIcon(element, iconManager.tooltipOnlyIfComposite(PlatformIcons.PACKAGE_ICON), 0);
}
else if (!Registry.is("ide.hide.excluded.files") && ProjectRootManager.getInstance(project).getFileIndex().isExcluded(vFile)) {
symbolIcon = AllIcons.Modules.ExcludeRoot;
}
else {
symbolIcon = PlatformIcons.FOLDER_ICON;
}
return IconManager.getInstance().createLayeredIcon(element, symbolIcon, 0);
}
/**
@@ -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.
// Copyright 2000-2021 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.daemon.impl
import com.intellij.codeInsight.daemon.DaemonBundle
import com.intellij.codeInsight.daemon.LineMarkerInfo
import com.intellij.codeInsight.daemon.impl.JavaServiceUtil.ServiceNavigationHandler
import com.intellij.icons.AllIcons
@@ -10,10 +9,9 @@ import com.intellij.psi.*
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.testFramework.LightProjectDescriptor
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
import com.intellij.ui.IconTestUtil
import org.assertj.core.api.Assertions.assertThat
/**
* @author Pavel.Dolgov
*/
class ServiceLineMarkerTest : LightJavaCodeInsightFixtureTestCase() {
override fun getProjectDescriptor(): LightProjectDescriptor = JAVA_9
@@ -30,40 +28,45 @@ class ServiceLineMarkerTest : LightJavaCodeInsightFixtureTestCase() {
@Override public void doWork() {}
}""".trimIndent())
fun testProvidesWithMethod() =
fun testProvidesWithMethod() {
doTestImplementer("""
public class MyServiceImpl {
public static MyService <caret>provider() {
return new MyService() { @Override public void doWork() {} };
}
}""".trimIndent())
public class MyServiceImpl {
public static MyService <caret>provider() {
return new MyService() { @Override public void doWork() {} };
}
}""".trimIndent())
}
fun testLoadWithLiteral() =
fun testLoadWithLiteral() {
doTestLoader("""
void foo() {
ServiceLoader<MyService> loader = <caret>ServiceLoader.load(MyService.class);
}""".trimIndent())
void foo() {
ServiceLoader<MyService> loader = <caret>ServiceLoader.load(MyService.class);
}""".trimIndent())
}
fun testLoadWithVariable() =
fun testLoadWithVariable() {
doTestLoader("""
void foo() {
Class<MyService> service = MyService.class;
ServiceLoader<MyService> loader = <caret>ServiceLoader.load(service);
}""".trimIndent())
void foo() {
Class<MyService> service = MyService.class;
ServiceLoader<MyService> loader = <caret>ServiceLoader.load(service);
}""".trimIndent())
}
fun testLoadWithClassForName() =
fun testLoadWithClassForName() {
doTestLoader("""
void foo() throws ClassNotFoundException {
ServiceLoader<MyService> loader =
<caret>ServiceLoader.load(Class.forName("foo.bar.MyService"), Main.class.getClassLoader());
}""".trimIndent())
void foo() throws ClassNotFoundException {
ServiceLoader<MyService> loader =
<caret>ServiceLoader.load(Class.forName("foo.bar.MyService"), Main.class.getClassLoader());
}""".trimIndent())
}
fun testLoadWithConstant() =
fun testLoadWithConstant() {
doTestLoader("""
static final Class<MyService> SERVICE = MyService.class;
void foo() {
ServiceLoader<MyService> loader = <caret>ServiceLoader.load(SERVICE);
}""".trimIndent())
static final Class<MyService> SERVICE = MyService.class;
void foo() {
ServiceLoader<MyService> loader = <caret>ServiceLoader.load(SERVICE);
}""".trimIndent())
}
private fun doTestLoader(text: String) {
val module = addModule("module foo.bar { uses foo.bar.MyService; provides foo.bar.MyService with foo.bar.impl.MyServiceImpl; }")
@@ -83,10 +86,10 @@ class ServiceLineMarkerTest : LightJavaCodeInsightFixtureTestCase() {
private fun doTest(file: PsiFile, module: PsiJavaModule, message: String, fqn: String, parentType: Class<out PsiElement>) {
myFixture.configureFromExistingVirtualFile(file.virtualFile!!)
val atCaret = myFixture.findGuttersAtCaret().filter { it.icon === AllIcons.Gutter.Java9Service }
assertEquals("atCaret", 1, atCaret.size)
val all = myFixture.findAllGutters().filter { it.icon === AllIcons.Gutter.Java9Service }
assertEquals("all", atCaret, all)
val atCaret = myFixture.findGuttersAtCaret().filter { IconTestUtil.unwrapIcon(it.icon) == AllIcons.Gutter.Java9Service }
assertThat(atCaret).hasSize(1)
val all = myFixture.findAllGutters().filter { IconTestUtil.unwrapIcon(it.icon) == AllIcons.Gutter.Java9Service }
assertThat(all).isEqualTo(atCaret)
val mark = atCaret[0]
assertEquals(message, mark.tooltipText)
@@ -99,18 +102,21 @@ class ServiceLineMarkerTest : LightJavaCodeInsightFixtureTestCase() {
assertEquals(fqn, targetReference.qualifiedName)
}
private fun addModule(text: String): PsiJavaModule =
(myFixture.addFileToProject("module-info.java", text) as PsiJavaFile).moduleDeclaration!!
private fun addModule(text: String): PsiJavaModule {
return (myFixture.addFileToProject("module-info.java", text) as PsiJavaFile).moduleDeclaration!!
}
private fun addImplementer(text: String) =
myFixture.addFileToProject("foo/bar/impl/MyServiceImpl.java", "package foo.bar.impl;\nimport foo.bar.MyService;\n${text}")
private fun addImplementer(text: String): PsiFile {
return myFixture.addFileToProject("foo/bar/impl/MyServiceImpl.java", "package foo.bar.impl;\nimport foo.bar.MyService;\n${text}")
}
private fun addMain(method: String) =
myFixture.addFileToProject("foo/bar/main/Main.java", """
package foo.bar.main;
import foo.bar.MyService;
import java.util.ServiceLoader;
public class Main {
[METHOD]
}""".trimIndent().replace("[METHOD]", method.prependIndent(" ")))
private fun addMain(method: String): PsiFile {
return myFixture.addFileToProject("foo/bar/main/Main.java", """
package foo.bar.main;
import foo.bar.MyService;
import java.util.ServiceLoader;
public class Main {
[METHOD]
}""".trimIndent().replace("[METHOD]", method.prependIndent(" ")))
}
}
@@ -1,6 +1,7 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.java;
import com.intellij.icons.AllIcons;
import com.intellij.ide.projectView.impl.nodes.AbstractPsiBasedNode;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.util.Iconable;
@@ -9,28 +10,32 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaFile;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import com.intellij.ui.IconTestUtil;
import com.intellij.util.PlatformIcons;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import javax.swing.*;
import java.io.IOException;
import java.util.List;
public class JavaIconTest extends LightJavaCodeInsightFixtureTestCase {
@Override
protected boolean isIconRequired() {
return true;
}
public void testOnlyOneIconForLockedJavaClass() throws IOException {
PsiFile psiFile = myFixture.configureByText("a.java", "class A {}");
VirtualFile file = myFixture.getFile().getVirtualFile();
setFileWritable(file, false);
UIUtil.dispatchAllInvocationEvents(); // write actions
UIUtil.dispatchAllInvocationEvents();
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue(); // write actions
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue();
try {
PsiClass psiClass = ((PsiJavaFile) psiFile).getClasses()[0];
Icon icon = AbstractPsiBasedNode.patchIcon(getProject(), psiClass.getIcon(Iconable.ICON_FLAG_READ_STATUS), file);
List<Icon> icons = IconTestUtil.renderDeferredIcon(icon);
assertOneElement(ContainerUtil.filter(icons, ic -> ic == IconTestUtil.unwrapRetrievableIcon(PlatformIcons.LOCKED_ICON)));
assertOneElement(ContainerUtil.filter(icons, ic -> IconTestUtil.unwrapIcon(ic) == AllIcons.Nodes.Locked));
}
finally {
setFileWritable(file, true);
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.projectView
import com.intellij.ide.projectView.ProjectViewNode
@@ -16,6 +16,8 @@ import com.intellij.util.io.directoryContent
import com.intellij.util.io.generateInVirtualTempDir
class CustomScopePaneTest : AbstractProjectViewTest() {
override fun isIconRequired() = true
override fun tearDown() {
NamedScopeManager.getInstance(project).removeAllSets()
super.tearDown()
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.lookup;
@@ -405,7 +405,8 @@ public final class LookupElementBuilder extends LookupElement {
}
else if (myHardcodedPresentation != null) {
presentation.copyFrom(myHardcodedPresentation);
} else {
}
else {
presentation.setItemText(myLookupString);
}
}
@@ -5,8 +5,10 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.ProjectExtensionPointName;
import com.intellij.openapi.extensions.impl.ExtensionPointImpl;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.*;
@@ -19,10 +21,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.*;
/**
* A service managing the IDE's 'dumb' mode: when indexes are updated in the background, and the functionality is very much limited.
@@ -60,13 +59,23 @@ public abstract class DumbService {
}
public static @NotNull <T> List<T> getDumbAwareExtensions(@NotNull Project project, @NotNull ExtensionPointName<T> extensionPoint) {
List<T> list = extensionPoint.getExtensionList();
if (list.isEmpty()) {
return list;
ExtensionPoint<T> point = extensionPoint.getPoint();
int size = point.size();
if (size == 0) {
return Collections.emptyList();
}
DumbService dumbService = getInstance(project);
return dumbService.filterByDumbAwareness(list);
if (!getInstance(project).isDumb()) {
return point.getExtensionList();
}
List<T> result = new ArrayList<>(size);
for (T element : ((ExtensionPointImpl<T>)point)) {
if (isDumbAware(element)) {
result.add(element);
}
}
return result;
}
public static @NotNull <T> List<T> getDumbAwareExtensions(@NotNull Project project, @NotNull ProjectExtensionPointName<T> extensionPoint) {
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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;
import com.intellij.icons.AllIcons;
@@ -70,11 +70,6 @@ public interface PlatformIcons {
Icon CHECK_ICON_SMALL = AllIcons.Actions.Checked;
Icon CHECK_ICON_SMALL_SELECTED = AllIcons.Actions.Checked_selected;
/** @deprecated to be removed in IDEA 2021.1 (use expandable text field instead, see https://jetbrains.design/intellij/controls/built_in_button/) */
@SuppressWarnings("unused")
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2021.1")
Icon OPEN_EDIT_DIALOG_ICON = AllIcons.Actions.ShowViewer;
Icon FLATTEN_PACKAGES_ICON = AllIcons.ObjectBrowser.FlattenPackages;
Icon EDIT_IN_SECTION_ICON = AllIcons.Actions.Edit;
Icon CLASS_INITIALIZER = AllIcons.Nodes.ClassInitializer;
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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;
import com.intellij.ide.IconProvider;
@@ -11,11 +11,17 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public final class PsiIconUtil {
@Nullable
public static Icon getProvidersIcon(@NotNull PsiElement element, @Iconable.IconFlags int flags) {
for (IconProvider provider : DumbService.getDumbAwareExtensions(element.getProject(), IconProvider.EXTENSION_POINT_NAME)) {
public static @Nullable Icon getProvidersIcon(@NotNull PsiElement element, @Iconable.IconFlags int flags) {
boolean isDumb = DumbService.getInstance(element.getProject()).isDumb();
for (IconProvider provider : IconProvider.EXTENSION_POINT_NAME.getIterable()) {
if (isDumb && !DumbService.isDumbAware(provider)) {
continue;
}
Icon icon = provider.getIcon(element, flags);
if (icon != null) return icon;
if (icon != null) {
return icon;
}
}
return null;
}
@@ -379,18 +379,38 @@ object PluginDescriptorLoader {
bundledPluginDir: Path?,
isRunningFromSources: Boolean) {
val classLoader = PluginDescriptorLoader::class.java.classLoader
val urlsFromClassPath = LinkedHashMap<URL, String>()
var activity = StartUpMeasurer.startActivity("platform plugin collecting", ActivityCategory.APP_INIT)
val platformPluginURL = computePlatformPluginUrlAndCollectPluginUrls(classLoader, urlsFromClassPath, isRunningFromSources)
val pool = ForkJoinPool.commonPool()
var activity = StartUpMeasurer.startActivity("platform plugin collecting", ActivityCategory.APP_INIT)
val platformPrefix = System.getProperty(PlatformUtils.PLATFORM_PREFIX_KEY)
// should be the only plugin in lib (only for Ultimate and WebStorm for now)
val pathResolver = ClassPathXmlPathResolver(classLoader)
if ((platformPrefix == null || platformPrefix == PlatformUtils.IDEA_PREFIX || platformPrefix == PlatformUtils.WEB_PREFIX) &&
(java.lang.Boolean.getBoolean("idea.use.dev.build.server") || !isRunningFromSources)) {
val factory = context.xmlFactory
val element = JDOMUtil.load(classLoader.getResourceAsStream(PluginManagerCore.PLUGIN_XML_PATH)!!, factory)
if (urlsFromClassPath.isNotEmpty()) {
activity = activity.endAndStart("plugin from classpath loading")
pool.invoke(LoadDescriptorsFromClassPathAction(urls = urlsFromClassPath,
context = context,
platformPluginURL = platformPluginURL,
pathResolver = ClassPathXmlPathResolver(classLoader)))
val descriptor = IdeaPluginDescriptorImpl(Paths.get(PathManager.getLibPath()), true)
descriptor.readExternal(element, pathResolver, context, descriptor, object : DataLoader {
override val pool: ZipFilePool
get() = throw IllegalStateException("must be not called")
override fun load(path: String) = throw IllegalStateException("must be not called")
override fun toString() = "product classpath"
})
descriptor.setUseCoreClassLoader()
context.result.add(descriptor, /* overrideUseIfCompatible = */false)
}
else {
val urlsFromClassPath = LinkedHashMap<URL, String>()
val platformPluginURL = computePlatformPluginUrlAndCollectPluginUrls(classLoader, urlsFromClassPath, platformPrefix)
if (!urlsFromClassPath.isEmpty()) {
activity = activity.endAndStart("plugin from classpath loading")
pool.invoke(LoadDescriptorsFromClassPathAction(urls = urlsFromClassPath,
context = context,
platformPluginURL = platformPluginURL,
pathResolver = pathResolver))
}
}
activity = activity.endAndStart("plugin from user dir loading")
@@ -404,16 +424,7 @@ object PluginDescriptorLoader {
private fun computePlatformPluginUrlAndCollectPluginUrls(loader: ClassLoader,
urls: MutableMap<URL, String>,
isRunningFromSources: Boolean): URL? {
val platformPrefix = System.getProperty(PlatformUtils.PLATFORM_PREFIX_KEY)
// should be the only plugin in lib (only for Ultimate and WebStorm for now)
if ((platformPrefix == null || platformPrefix == PlatformUtils.IDEA_PREFIX || platformPrefix == PlatformUtils.WEB_PREFIX) &&
(java.lang.Boolean.getBoolean("idea.use.dev.build.server") || !isRunningFromSources)) {
urls.put(loader.getResource(PluginManagerCore.PLUGIN_XML_PATH)!!, PluginManagerCore.PLUGIN_XML)
return null
}
platformPrefix: String?): URL? {
var result: URL? = null
if (platformPrefix != null) {
val fileName = "${platformPrefix}Plugin.xml"
+12 -22
View File
@@ -43,9 +43,8 @@ public final class CoreIconManager implements IconManager, CoreAwareIconManager
return AllIcons.Actions.Stub;
}
@NotNull
@Override
public Icon getIcon(@NotNull String path, @NotNull Class<?> aClass) {
public @NotNull Icon getIcon(@NotNull String path, @NotNull Class<?> aClass) {
Icon icon = IconLoader.getIcon(path, aClass);
Supplier<String> tooltip = new IconDescriptionLoader(path);
if (icon instanceof ScalableIcon) {
@@ -103,16 +102,14 @@ public final class CoreIconManager implements IconManager, CoreAwareIconManager
}
}
@NotNull
@Override
public Icon createEmptyIcon(@NotNull Icon icon) {
public @NotNull Icon createEmptyIcon(@NotNull Icon icon) {
return EmptyIcon.create(icon);
}
@NotNull
@Override
public <T> Icon createDeferredIcon(@Nullable Icon base, T param, @NotNull Function<? super T, ? extends Icon> f) {
return IconDeferrer.getInstance().defer(base, param, f);
public @NotNull <T> Icon createDeferredIcon(@Nullable Icon base, T param, @NotNull Function<? super T, ? extends Icon> iconProducer) {
return IconDeferrer.getInstance().defer(base, param, iconProducer);
}
@Override
@@ -130,24 +127,21 @@ public final class CoreIconManager implements IconManager, CoreAwareIconManager
return new IconWrapperWithToolTipComposite(icon);
}
@NotNull
@Override
public com.intellij.ui.icons.RowIcon createRowIcon(int iconCount, com.intellij.ui.icons.RowIcon.Alignment alignment) {
public @NotNull com.intellij.ui.icons.RowIcon createRowIcon(int iconCount, com.intellij.ui.icons.RowIcon.Alignment alignment) {
return new RowIcon(iconCount, alignment);
}
@NotNull
@Override
public com.intellij.ui.icons.RowIcon createRowIcon(Icon @NotNull ... icons) {
public @NotNull com.intellij.ui.icons.RowIcon createRowIcon(Icon @NotNull ... icons) {
return new RowIcon(icons);
}
@NotNull
@Override
public RowIcon createLayeredIcon(@NotNull Iconable instance, Icon icon, int flags) {
public @NotNull RowIcon createLayeredIcon(@NotNull Iconable instance, Icon icon, int flags) {
List<Icon> layersFromProviders = new ArrayList<>();
for (IconLayerProvider provider : IconLayerProvider.EP_NAME.getExtensionList()) {
final Icon layerIcon = provider.getLayerIcon(instance, BitUtil.isSet(flags, FLAGS_LOCKED));
Icon layerIcon = provider.getLayerIcon(instance, BitUtil.isSet(flags, FLAGS_LOCKED));
if (layerIcon != null) {
layersFromProviders.add(layerIcon);
}
@@ -174,21 +168,18 @@ public final class CoreIconManager implements IconManager, CoreAwareIconManager
return baseIcon;
}
@NotNull
@Override
public Icon createOffsetIcon(@NotNull Icon icon) {
public @NotNull Icon createOffsetIcon(@NotNull Icon icon) {
return new OffsetIcon(icon);
}
@NotNull
@Override
public Icon colorize(Graphics2D g, @NotNull Icon source, @NotNull Color color) {
public @NotNull Icon colorize(Graphics2D g, @NotNull Icon source, @NotNull Color color) {
return IconUtil.colorize(g, source, color);
}
@NotNull
@Override
public Icon createLayered(Icon @NotNull ... icons) {
public @NotNull Icon createLayered(Icon @NotNull ... icons) {
return new LayeredIcon(icons);
}
@@ -204,8 +195,7 @@ public final class CoreIconManager implements IconManager, CoreAwareIconManager
private static final class IconLayer {
private final int flagMask;
@NotNull
private final Icon icon;
private final @NotNull Icon icon;
private IconLayer(final int flagMask, @NotNull Icon icon) {
BitUtil.assertOneBitMask(flagMask);
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.ui.icons.CopyableIcon;
@@ -9,10 +9,10 @@ import javax.swing.*;
import java.awt.*;
import java.util.Objects;
public class IconWrapperWithToolTipComposite implements IconWithToolTip, CopyableIcon, RetrievableIcon {
final class IconWrapperWithToolTipComposite implements IconWithToolTip, CopyableIcon, RetrievableIcon {
private final Icon myIcon;
public IconWrapperWithToolTipComposite(Icon icon) {
IconWrapperWithToolTipComposite(Icon icon) {
myIcon = icon;
}
+19 -48
View File
@@ -1,35 +1,24 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.openapi.util.IconLoader;
import com.intellij.util.ArrayUtil;
import com.intellij.ui.scale.ScaleType;
import com.intellij.util.IconUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.JBCachingScalableIcon;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.intellij.ui.scale.ScaleType.OBJ_SCALE;
import static java.lang.Math.ceil;
public class RowIcon extends JBCachingScalableIcon<RowIcon> implements com.intellij.ui.icons.RowIcon, IconWithToolTip {
private final com.intellij.ui.icons.RowIcon.Alignment myAlignment;
private final Alignment myAlignment;
private int myWidth;
private int myHeight;
/**
* @use {@link com.intellij.ui.icons.RowIcon.Alignment instead}
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2021.2")
public enum Alignment {TOP, CENTER, BOTTOM}
private final Icon @NotNull [] myIcons;
private Icon[] myScaledIcons;
@@ -39,30 +28,10 @@ public class RowIcon extends JBCachingScalableIcon<RowIcon> implements com.intel
}
public RowIcon(int iconCount/*, int orientation*/) {
this(iconCount, com.intellij.ui.icons.RowIcon.Alignment.TOP);
this(iconCount, Alignment.TOP);
}
/**
* @deprecated use {@link #RowIcon(int, com.intellij.ui.icons.RowIcon.Alignment)} instead
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2021.2")
public RowIcon(int iconCount, Alignment alignment) {
com.intellij.ui.icons.RowIcon.Alignment a = null;
if (alignment == Alignment.TOP) {
a = com.intellij.ui.icons.RowIcon.Alignment.TOP;
}
else if (alignment == Alignment.BOTTOM) {
a = com.intellij.ui.icons.RowIcon.Alignment.BOTTOM;
}
else if (alignment == Alignment.CENTER) {
a = com.intellij.ui.icons.RowIcon.Alignment.CENTER;
}
myAlignment = a;
myIcons = new Icon[iconCount];
}
public RowIcon(int iconCount, com.intellij.ui.icons.RowIcon.Alignment alignment) {
myAlignment = alignment;
myIcons = new Icon[iconCount];
}
@@ -79,19 +48,17 @@ public class RowIcon extends JBCachingScalableIcon<RowIcon> implements com.intel
myAlignment = icon.myAlignment;
myWidth = icon.myWidth;
myHeight = icon.myHeight;
myIcons = ArrayUtil.copyOf(icon.myIcons);
myIcons = icon.myIcons.clone();
myScaledIcons = null;
}
@NotNull
@Override
public RowIcon copy() {
public @NotNull RowIcon copy() {
return new RowIcon(this);
}
@NotNull
@Override
public com.intellij.ui.icons.RowIcon deepCopy() {
public @NotNull com.intellij.ui.icons.RowIcon deepCopy() {
RowIcon icon = new RowIcon(this);
for (int i = 0; i < icon.myIcons.length; i++) {
icon.myIcons[i] = IconUtil.copy(icon.myIcons[i], null);
@@ -119,8 +86,13 @@ public class RowIcon extends JBCachingScalableIcon<RowIcon> implements com.intel
@Override
public Icon @NotNull [] getAllIcons() {
List<Icon> icons = ContainerUtil.packNullables(myIcons);
return icons.toArray(new Icon[0]);
List<Icon> list = new ArrayList<>(myIcons.length);
for (Icon element : myIcons) {
if (element != null) {
list.add(element);
}
}
return list.toArray(new Icon[0]);
}
public int hashCode() {
@@ -128,7 +100,7 @@ public class RowIcon extends JBCachingScalableIcon<RowIcon> implements com.intel
}
public boolean equals(Object obj) {
return obj instanceof RowIcon && Arrays.equals(((RowIcon)obj).myIcons, myIcons);
return obj == this || (obj instanceof RowIcon && Arrays.equals(((RowIcon)obj).myIcons, myIcons));
}
@Override
@@ -172,13 +144,13 @@ public class RowIcon extends JBCachingScalableIcon<RowIcon> implements com.intel
@Override
public int getIconWidth() {
getScaleContext().update();
return (int)ceil(scaleVal(myWidth, OBJ_SCALE));
return (int)Math.ceil(scaleVal(myWidth, ScaleType.OBJ_SCALE));
}
@Override
public int getIconHeight() {
getScaleContext().update();
return (int)ceil(scaleVal(myHeight, OBJ_SCALE));
return (int)Math.ceil(scaleVal(myHeight, ScaleType.OBJ_SCALE));
}
private void updateSize() {
@@ -194,9 +166,8 @@ public class RowIcon extends JBCachingScalableIcon<RowIcon> implements com.intel
myHeight = height;
}
@NotNull
@Override
public Icon getDarkIcon(boolean isDark) {
public @NotNull Icon getDarkIcon(boolean isDark) {
RowIcon newIcon = copy();
for (int i=0; i<newIcon.myIcons.length; i++) {
newIcon.myIcons[i] = newIcon.myIcons[i] == null ? null : IconLoader.getDarkIcon(newIcon.myIcons[i], isDark);
+3 -1
View File
@@ -1,5 +1,7 @@
# 29
* Add `splash preparation (in queue)` and `splash initialization (in queue)`.
* Add `splash preparation (in queue)` and `splash initialization (in queue)`.
* Add `pre app class running`, `repaint manager set`, `linux wm set`. Existing`event queue replacing` doesn't include added metrics anymore.
* Remove `icon loader activation`.
# 28
* Add `platform plugin collecting`, `plugin from classpath loading`, `plugin from user dir loading`, `plugin from bundled dir loading`.
@@ -38,7 +38,7 @@ class StartUpPerformanceReporter : StartupActivity, StartUpPerformanceService {
companion object {
internal val LOG = logger<StartUpMeasurer>()
internal const val VERSION = "28"
internal const val VERSION = "29"
internal fun sortItems(items: MutableList<ActivityImpl>) {
items.sortWith(Comparator { o1, o2 ->
@@ -92,13 +92,11 @@ public class ModuleImpl extends ComponentManagerImpl implements ModuleEx {
public void init(@Nullable Runnable beforeComponentCreation) {
// do not measure (activityNamePrefix method not overridden by this class)
// because there are a lot of modules and no need to measure each one
//noinspection unchecked
registerComponents((List<IdeaPluginDescriptorImpl>)PluginManagerCore.getLoadedPlugins(), null);
registerComponents(PluginManagerCore.getLoadedPlugins(null), ApplicationManager.getApplication(), null);
if (!isPersistent()) {
registerService(IComponentStore.class,
NonPersistentModuleStore.class,
Objects.requireNonNull(PluginManagerCore.getPlugin(PluginManagerCore.CORE_ID),
"Could not find plugin by id: " + PluginManagerCore.CORE_ID),
ComponentManagerImpl.getFakeCorePluginDescriptor(),
true);
}
if (beforeComponentCreation != null) {
@@ -5,6 +5,7 @@ import com.intellij.facet.FacetFromExternalSourcesStorage
import com.intellij.facet.FacetManager
import com.intellij.ide.plugins.IdeaPluginDescriptorImpl
import com.intellij.ide.plugins.PluginManagerCore
import com.intellij.openapi.application.Application
import com.intellij.openapi.application.WriteAction
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.impl.ModuleImpl
@@ -63,8 +64,8 @@ internal class ModuleBridgeImpl(
super<ModuleImpl>.rename(newName, notifyStorage)
}
override fun registerComponents(plugins: List<IdeaPluginDescriptorImpl>, listenerCallbacks: MutableList<Runnable>?) {
super.registerComponents(plugins, null)
override fun registerComponents(plugins: List<IdeaPluginDescriptorImpl>, app: Application?, listenerCallbacks: MutableList<Runnable>?) {
super.registerComponents(plugins, app, null)
val corePlugin = plugins.find { it.pluginId == PluginManagerCore.CORE_ID } ?: return
registerComponent(ModuleRootManager::class.java, ModuleRootComponentBridge::class.java, corePlugin, true)
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.icons.AllIcons;
@@ -7,19 +7,17 @@ import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.Key;
import com.intellij.util.concurrency.EdtScheduledExecutorService;
import com.intellij.util.ui.UIUtil;
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Set;
import static com.intellij.util.containers.ContainerUtil.immutableList;
import static java.awt.AlphaComposite.SrcAtop;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.concurrent.TimeUnit;
public class AnimatedIcon implements Icon {
private static final Logger LOG = Logger.getInstance(AnimatedIcon.class);
@@ -50,7 +48,7 @@ public class AnimatedIcon implements Icon {
}
public static final int DELAY = 130;
public static final List<Icon> ICONS = immutableList(
public static final List<Icon> ICONS = List.of(
AllIcons.Process.Step_1,
AllIcons.Process.Step_2,
AllIcons.Process.Step_3,
@@ -69,7 +67,7 @@ public class AnimatedIcon implements Icon {
}
public static final int DELAY = 130;
public static final List<Icon> ICONS = immutableList(
public static final List<Icon> ICONS = List.of(
AllIcons.Process.Big.Step_1,
AllIcons.Process.Big.Step_2,
AllIcons.Process.Big.Step_3,
@@ -82,13 +80,13 @@ public class AnimatedIcon implements Icon {
public static final AnimatedIcon INSTANCE = new Big();
}
public static class Recording extends AnimatedIcon {
public static final class Recording extends AnimatedIcon {
public Recording() {
super(DELAY, ICONS.toArray(new Icon[0]));
}
public static final int DELAY = 250;
public static final List<Icon> ICONS = immutableList(
public static final List<Icon> ICONS = List.of(
AllIcons.Ide.Macro.Recording_1,
AllIcons.Ide.Macro.Recording_2,
AllIcons.Ide.Macro.Recording_3,
@@ -96,13 +94,13 @@ public class AnimatedIcon implements Icon {
}
@ApiStatus.Internal
public static class FS extends AnimatedIcon {
public static final class FS extends AnimatedIcon {
public FS() {
super(DELAY, ICONS.toArray(new Icon[0]));
}
public static final int DELAY = 50;
public static final List<Icon> ICONS = immutableList(
public static final List<Icon> ICONS = List.of(
AllIcons.Process.FS.Step_1,
AllIcons.Process.FS.Step_2,
AllIcons.Process.FS.Step_3,
@@ -124,7 +122,7 @@ public class AnimatedIcon implements Icon {
}
@ApiStatus.Internal
public static class Blinking extends AnimatedIcon {
public static final class Blinking extends AnimatedIcon {
public Blinking(@NotNull Icon icon) {
this(1000, icon);
}
@@ -135,7 +133,7 @@ public class AnimatedIcon implements Icon {
}
@ApiStatus.Internal
public static class Fading extends AnimatedIcon {
public static final class Fading extends AnimatedIcon {
public Fading(@NotNull Icon icon) {
this(1000, icon);
}
@@ -163,7 +161,7 @@ public class AnimatedIcon implements Icon {
if (alpha < 1 && g instanceof Graphics2D) {
Graphics2D g2d = (Graphics2D)g.create();
try {
g2d.setComposite(SrcAtop.derive(alpha));
g2d.setComposite(AlphaComposite.SrcAtop.derive(alpha));
icon.paintIcon(c, g2d, x, y);
}
finally {
@@ -181,7 +179,7 @@ public class AnimatedIcon implements Icon {
private final Frame[] frames;
private final Set<Component> requested = new ReferenceOpenHashSet<>();
private final Set<Component> requested = Collections.newSetFromMap(new IdentityHashMap<>());
private long time;
private int index;
@@ -239,21 +237,23 @@ public class AnimatedIcon implements Icon {
}
private void requestRefresh(@Nullable Component c) {
if (c != null && !requested.contains(c) && canRefresh(c)) {
Frame frame = frames[index];
int delay = frame.getDelay();
if (delay > 0) {
requested.add(c);
EdtScheduledExecutorService.getInstance().schedule(() -> {
requested.remove(c);
if (canRefresh(c)) {
doRefresh(c);
}
}, delay, MILLISECONDS);
}
else {
doRefresh(c);
}
if (c == null || requested.contains(c) || !canRefresh(c)) {
return;
}
Frame frame = frames[index];
int delay = frame.getDelay();
if (delay > 0) {
requested.add(c);
EdtScheduledExecutorService.getInstance().schedule(() -> {
requested.remove(c);
if (canRefresh(c)) {
doRefresh(c);
}
}, delay, TimeUnit.MILLISECONDS);
}
else {
doRefresh(c);
}
}
@@ -285,12 +285,12 @@ public class AnimatedIcon implements Icon {
}
protected void doRefresh(@NotNull Component component) {
Runnable delegate = UIUtil.getClientProperty(component, REFRESH_DELEGATE);
if (delegate != null) {
delegate.run();
Runnable delegate = component instanceof JComponent ? (Runnable)((JComponent)component).getClientProperty(REFRESH_DELEGATE) : null;
if (delegate == null) {
component.repaint();
}
else {
component.repaint();
delegate.run();
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.colors;
@@ -1260,7 +1260,7 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
metaInfo = JDOMUtil.load(JDOMUtil.writeElement(metaInfo));
scheme.addContent(0, metaInfo);
}
JDOMUtil.write(scheme, path.toFile());
JDOMUtil.write(scheme, path);
VirtualFileManager.getInstance().syncRefresh();
}
catch (Exception e) {
@@ -82,8 +82,7 @@ public final class IdeEventQueue extends EventQueue {
private static final Logger TYPEAHEAD_LOG = Logger.getInstance(IdeEventQueue.class.getName() + ".typeahead");
private static final Logger FOCUS_AWARE_RUNNABLES_LOG = Logger.getInstance(IdeEventQueue.class.getName() + ".runnables");
private static final boolean ourActionAwareTypeaheadEnabled = !SystemInfoRt.isMac && Boolean.getBoolean("action.aware.typeAhead");
private static final boolean ourTypeAheadSearchEverywhereEnabled =
SystemProperties.getBooleanProperty("action.aware.typeAhead.searchEverywhere", false);
private static final boolean ourTypeAheadSearchEverywhereEnabled = Boolean.getBoolean("action.aware.typeAhead.searchEverywhere");
private static final boolean ourSkipMetaPressOnLinux = Boolean.getBoolean("keymap.skip.meta.press.on.linux");
private static TransactionGuardImpl ourTransactionGuard;
private static ProgressManager ourProgressManager;
@@ -1146,11 +1146,11 @@ private fun loadPluginDescriptor(pluginDescriptor: IdeaPluginDescriptorImpl,
updateDependenciesStatus(pluginDescriptor, pluginStateChecker)
val list = listOf(pluginDescriptor)
app.registerComponents(list, listenerCallbacks)
app.registerComponents(list, ApplicationManager.getApplication(), listenerCallbacks)
for (openProject in ProjectUtil.getOpenProjects()) {
(openProject as ComponentManagerImpl).registerComponents(list, listenerCallbacks)
(openProject as ComponentManagerImpl).registerComponents(list, ApplicationManager.getApplication(), listenerCallbacks)
for (module in ModuleManager.getInstance(openProject).modules) {
(module as ComponentManagerImpl).registerComponents(list, listenerCallbacks)
(module as ComponentManagerImpl).registerComponents(list, ApplicationManager.getApplication(), listenerCallbacks)
}
}
@@ -1,5 +1,6 @@
// Copyright 2000-2021 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.
@file:JvmName("ApplicationLoader")
@file:ApiStatus.Internal
package com.intellij.idea
import com.intellij.diagnostic.*
@@ -41,6 +42,7 @@ import java.awt.Font
import java.awt.GraphicsEnvironment
import java.awt.dnd.DragSource
import java.io.IOException
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Path
import java.util.concurrent.*
@@ -55,19 +57,56 @@ private fun executeInitAppInEdt(args: List<String>,
initAppActivity: Activity,
pluginDescriptorFuture: CompletableFuture<List<IdeaPluginDescriptorImpl>>) {
StartupUtil.patchSystem(LOG)
val registerComponentFuture = CompletableFuture<List<IdeaPluginDescriptorImpl>>()
val app = runActivity("create app") {
ApplicationImpl(java.lang.Boolean.getBoolean(PluginManagerCore.IDEA_IS_INTERNAL_PROPERTY), false, Main.isHeadless(),
Main.isCommandLine())
Main.isCommandLine()) { app ->
ForkJoinPool.commonPool().execute {
pluginDescriptorFuture
.thenApply {
if (!app.isHeadlessEnvironment) {
ForkJoinPool.commonPool().execute {
runActivity("icons preloading") {
if (app.isInternal) {
IconLoader.setStrictGlobally(true)
}
AsyncProcessIcon("")
AnimatedIcon.Blinking(AllIcons.Ide.FatalError)
AnimatedIcon.FS()
}
runActivity("migLayout") {
// IDEA-170295
PlatformDefaults.setLogicalPixelBase(PlatformDefaults.BASE_FONT_SIZE)
}
}
}
runMainActivity("app component registration") {
app.registerComponents(it, app, null)
}
it
}
.whenComplete { result, error ->
if (error == null) {
registerComponentFuture.complete(result)
}
else {
registerComponentFuture.completeExceptionally(error)
}
}
}
}
}
val registerFuture = registerAppComponents(pluginDescriptorFuture, app)
if (args.isEmpty()) {
startApp(app, IdeStarter(), initAppActivity, registerFuture, args)
startApp(app, IdeStarter(), initAppActivity, registerComponentFuture, args)
return
}
// `ApplicationStarter` is an extension, so to find a starter extensions must be registered first
registerFuture
registerComponentFuture
.thenRun {
val starter = findStarter(args.first()) ?: IdeStarter()
if (Main.isHeadless() && !starter.isHeadless) {
@@ -89,7 +128,7 @@ private fun executeInitAppInEdt(args: List<String>,
}
starter.premain(args)
startApp(app, starter, initAppActivity, registerFuture, args)
startApp(app, starter, initAppActivity, registerComponentFuture, args)
}
.exceptionally {
StartupAbortedException.processException(it)
@@ -97,59 +136,35 @@ private fun executeInitAppInEdt(args: List<String>,
}
}
@ApiStatus.Internal
fun registerAppComponents(pluginFuture: CompletableFuture<List<IdeaPluginDescriptorImpl>>,
app: ApplicationImpl): CompletableFuture<List<IdeaPluginDescriptorImpl>> {
return pluginFuture.thenApply {
runMainActivity("app component registration") {
app.registerComponents(it, null)
}
it
}
}
private fun startApp(app: ApplicationImpl,
starter: ApplicationStarter,
initAppActivity: Activity,
registerFuture: CompletableFuture<List<IdeaPluginDescriptorImpl>>,
registerComponentFuture: CompletableFuture<List<IdeaPluginDescriptorImpl>>,
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
val registerRegistryAndInitStoreFuture = registerRegistryAndInitStore(registerFuture, app)
val headless = app.isHeadlessEnvironment
if (!headless) {
runActivity("icon loader activation") {
// todo investigate why in test mode dummy icon manager is not suitable
IconLoader.activate()
IconLoader.setStrictGlobally(app.isInternal)
}
val initStoreFuture = registerComponentFuture.thenApply { plugins ->
// initSystemProperties or RegistryKeyBean.addKeysFromPlugins maybe not yet performed,
// but it is ok because registry is not and should be not used
initConfigurationStore(app)
plugins
}
val nonEdtExecutor = Executor {
if (app.isDispatchThread) {
ForkJoinPool.commonPool().execute(it)
}
else {
it.run()
}
val preloadSyncServiceFuture = initStoreFuture.thenAccept {
preloadServices(it, app, activityPrefix = "")
}
// preload services only after icon activation
val preloadSyncServiceFuture = registerRegistryAndInitStoreFuture
.thenComposeAsync({
preloadServices(it, app, activityPrefix = "")
}, nonEdtExecutor)
initStoreFuture.thenRunAsync({
runActivity("add registry keys") {
RegistryKeyBean.addKeysFromPlugins()
}
}, ForkJoinPool.commonPool())
if (!headless) {
if (!app.isHeadlessEnvironment) {
if (SystemInfoRt.isMac) {
runActivity("mac app init") {
MacOSApplicationProvider.initApplication()
}
registerFuture.thenRunAsync(Runnable {
initStoreFuture.thenRunAsync(Runnable {
// ensure that TouchBarsManager is loaded before WelcomeFrame/project
// do not wait completion - it is thread safe and not required for application start
runActivity("mac touchbar") {
@@ -167,69 +182,47 @@ private fun startApp(app: ApplicationImpl,
}
WeakFocusStackManager.getInstance()
ForkJoinPool.commonPool().execute {
runActivity("migLayout") {
// IDEA-170295
PlatformDefaults.setLogicalPixelBase(PlatformDefaults.BASE_FONT_SIZE)
}
}
ForkJoinPool.commonPool().execute {
runActivity("icons preloading") {
AsyncProcessIcon("")
AnimatedIcon.Blinking(AllIcons.Ide.FatalError)
AnimatedIcon.FS()
}
}
}
@Suppress("RemoveExplicitTypeArguments")
CompletableFuture.allOf(registerRegistryAndInitStoreFuture, StartupUtil.getServerFuture())
initStoreFuture
.thenCompose {
// `invokeLater()` is needed to place the app starting code on a freshly minted `IdeEventQueue` instance
val placeOnEventQueueActivity = initAppActivity.startChild(Activities.PLACE_ON_EVENT_QUEUE)
val loadComponentInEdtFuture = CompletableFuture.runAsync({
placeOnEventQueueActivity.end()
placeOnEventQueueActivity.end()
val indicator = if (SplashManager.SPLASH_WINDOW == null) {
null
}
else object : EmptyProgressIndicator() {
override fun setFraction(fraction: Double) {
SplashManager.SPLASH_WINDOW.showProgress(fraction)
}
}
app.loadComponents(indicator)
}, Executor { ApplicationManager.getApplication().invokeLater(it) })
CompletableFuture.allOf(loadComponentInEdtFuture, preloadSyncServiceFuture)
}
.thenRunAsync({
val activity = initAppActivity.startChild("app initialized callback")
val tasks = callAppInitialized(app)
// should be after scheduling all app initialized listeners (because this activity is not important)
if (!Main.isLightEdit()) {
ForkJoinPool.commonPool().execute {
// execute in parallel to component loading - this functionality should be used only by plugin functionality that is used after start-up
runActivity("system properties setting") {
SystemPropertyBean.initSystemProperties()
val indicator = if (SplashManager.SPLASH_WINDOW == null) {
null
}
else object : EmptyProgressIndicator() {
override fun setFraction(fraction: Double) {
SplashManager.SPLASH_WINDOW.showProgress(fraction)
}
}
app.loadComponents(indicator)
}, Executor { ApplicationManager.getApplication().invokeLater(it) })
CompletableFuture.allOf(loadComponentInEdtFuture, preloadSyncServiceFuture, StartupUtil.getServerFuture())
}
.thenRunAsync({
initAppActivity.runChild("app initialized callback") {
ForkJoinTask.invokeAll(callAppInitialized(app))
}
ForkJoinTask.invokeAll(tasks)
activity.end()
if (!headless) {
if (!app.isHeadlessEnvironment) {
addActivateAndWindowsCliListeners()
}
initAppActivity.end()
}, nonEdtExecutor /* if `loadComponentInEdtFuture` is completed after `preloadSyncServiceFuture`,
then this task will be executed in EDT, so force execution out of EDT */)
}, Executor {
// if `loadComponentInEdtFuture` is completed after `preloadSyncServiceFuture`,
// then this task will be executed in EDT, so force execution out of EDT
if (app.isDispatchThread) {
ForkJoinPool.commonPool().execute(it)
}
else {
it.run()
}
})
.thenRun {
if (starter.requiredModality == ApplicationStarter.NOT_IN_EDT) {
starter.main(args)
@@ -251,7 +244,6 @@ private fun startApp(app: ApplicationImpl,
}
}
@ApiStatus.Internal
@JvmOverloads
fun preloadServices(plugins: List<IdeaPluginDescriptorImpl>,
container: ComponentManagerImpl,
@@ -272,27 +264,6 @@ fun preloadServices(plugins: List<IdeaPluginDescriptorImpl>,
return logError(result.syncPreloadedServices)
}
@ApiStatus.Internal
fun registerRegistryAndInitStore(registerFuture: CompletableFuture<List<IdeaPluginDescriptorImpl>>,
app: ApplicationImpl): CompletableFuture<List<IdeaPluginDescriptorImpl>> {
// async because register task is executed in EDT - force execution in a pooled thread
return registerFuture.thenComposeAsync({ plugins ->
val future = CompletableFuture.runAsync({
runActivity("add registry keys") {
RegistryKeyBean.addKeysFromPlugins()
}
}, ForkJoinPool.commonPool())
// initSystemProperties or RegistryKeyBean.addKeysFromPlugins maybe not yet performed,
// but it is ok because registry is not and should be not used
initConfigurationStore(app)
future.thenApply {
plugins
}
}, ForkJoinPool.commonPool())
}
private fun addActivateAndWindowsCliListeners() {
StartupUtil.addExternalInstanceListener { rawArgs ->
LOG.info("External instance command received")
@@ -395,10 +366,8 @@ private fun loadSystemFonts() {
GraphicsEnvironment.getLocalGraphicsEnvironment().availableFontFamilyNames
}
@ApiStatus.Internal
fun findStarter(key: String) = ApplicationStarter.EP_NAME.iterable.find { it == null || it.commandName == key }
@ApiStatus.Internal
fun initConfigurationStore(app: ApplicationImpl) {
var activity = StartUpMeasurer.startMainActivity("beforeApplicationLoaded")
val configPath = PathManager.getConfigDir()
@@ -450,7 +419,6 @@ private fun processProgramArguments(args: List<String>): List<String> {
return arguments
}
@ApiStatus.Internal
fun callAppInitialized(app: Application): List<RecursiveAction> {
val extensionArea = app.extensionArea as ExtensionsAreaImpl
val extensionPoint = extensionArea.getExtensionPoint<ApplicationInitializedListener>("com.intellij.applicationInitializedListener")
@@ -471,18 +439,33 @@ fun callAppInitialized(app: Application): List<RecursiveAction> {
}
extensionPoint.reset()
ForkJoinPool.commonPool().execute {
runActivity("create locator file") {
val locatorFile = Path.of(PathManager.getSystemPath(), ApplicationEx.LOCATOR_FILE_NAME)
try {
locatorFile.parent?.createDirectories()
Files.writeString(locatorFile, PathManager.getHomePath(), Charsets.UTF_8)
// should be after scheduling all app initialized listeners (because this activity is not important)
result.add(object : RecursiveAction() {
override fun compute() {
val pool = ForkJoinPool.commonPool()
pool.execute {
runActivity("create locator file") {
val locatorFile = Path.of(PathManager.getSystemPath(), ApplicationEx.LOCATOR_FILE_NAME)
try {
locatorFile.parent?.createDirectories()
Files.writeString(locatorFile, PathManager.getHomePath(), StandardCharsets.UTF_8)
}
catch (e: IOException) {
LOG.warn("Can't store a location in '$locatorFile'", e)
}
}
}
catch (e: IOException) {
LOG.warn("Can't store a location in '$locatorFile'", e)
if (!Main.isLightEdit()) {
// this functionality should be used only by plugin functionality that is used after start-up
pool.execute {
runActivity("system properties setting") {
SystemPropertyBean.initSystemProperties()
}
}
}
}
}
})
return result
}
@@ -29,12 +29,12 @@ import com.intellij.openapi.application.ConfigImportHelper;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.openapi.util.SystemInfoRt;
import com.intellij.openapi.util.io.win32.IdeaWin32;
import com.intellij.openapi.wm.impl.X11UiUtil;
import com.intellij.ui.AppUIUtil;
import com.intellij.ui.CoreIconManager;
import com.intellij.ui.IconManager;
import com.intellij.ui.scale.JBUIScale;
import com.intellij.util.EnvironmentUtil;
@@ -187,14 +187,17 @@ public final class StartupUtil {
private static void runPreAppClass(@NotNull Logger log) {
String classBeforeAppProperty = System.getProperty(IDEA_CLASS_BEFORE_APPLICATION_PROPERTY);
if (classBeforeAppProperty != null) {
Activity activity = StartUpMeasurer.startActivity("pre app class running", ActivityCategory.APP_INIT);
try {
Class<?> clazz = Class.forName(classBeforeAppProperty);
Method invokeMethod = clazz.getDeclaredMethod("invoke");
invokeMethod.setAccessible(true);
invokeMethod.invoke(null);
}
catch (Exception e) {
log.error("Failed pre-app class init for class " + classBeforeAppProperty, e);
}
activity.end();
}
}
@@ -770,6 +773,10 @@ public final class StartupUtil {
"\n " + PathManager.PROPERTY_LOG_PATH + '=' + logPath(PathManager.getLogPath())
);
log.info("CPU cores: " + Runtime.getRuntime().availableProcessors() +
"; ForkJoinPool.commonPool: " + ForkJoinPool.commonPool() +
"; factory: " + ForkJoinPool.commonPool().getFactory());
activity.end();
}
@@ -814,11 +821,13 @@ public final class StartupUtil {
Class<?> dialogClass = Class.forName(stepsDialogName);
Constructor<?> constr = dialogClass.getConstructor(AppStarter.class);
((CommonCustomizeIDEWizardDialog) constr.newInstance(appStarter)).showIfNeeded();
} catch (Throwable e) {
}
catch (Throwable e) {
Main.showMessage(BootstrapBundle.message("bootstrap.error.title.configuration.wizard.failed"), e);
return;
}
} else if (Boolean.parseBoolean(System.getProperty("idea.show.customize.ide.wizard"))) {
}
else if (Boolean.parseBoolean(System.getProperty("idea.show.customize.ide.wizard"))) {
new CustomizeIDEWizardDialog(provider, appStarter, true, false).showIfNeeded();
}
@@ -827,47 +836,38 @@ public final class StartupUtil {
}
// must be called from EDT
public static boolean patchSystem(@NotNull Logger log) {
public static boolean patchSystem(@NotNull Logger log) throws Throwable {
if (!ourSystemPatched.compareAndSet(false, true)) {
return false;
}
Activity activity = StartUpMeasurer.startActivity("event queue replacing", ActivityCategory.APP_INIT);
replaceSystemEventQueue(log);
// replace system event queue
//noinspection ResultOfMethodCallIgnored
IdeEventQueue.getInstance();
if (!Main.isHeadless()) {
patchSystemForUi(log);
if ("true".equals(System.getProperty("idea.check.swing.threading"))) {
activity = activity.endAndStart("repaint manager set");
RepaintManager.setCurrentManager(new AssertiveRepaintManager());
}
if (SystemInfoRt.isXWindow) {
activity = activity.endAndStart("linux wm set");
String wmName = X11UiUtil.getWmName();
log.info("WM detected: " + wmName);
if (wmName != null) {
X11UiUtil.patchDetectedWm(wmName);
}
}
activity = activity.endAndStart("icon manager activation");
IconManager.activate(new CoreIconManager());
}
activity.end();
return true;
}
@ApiStatus.Internal
public static void replaceSystemEventQueue(@NotNull Logger log) {
log.info("CPU cores: " + Runtime.getRuntime().availableProcessors() +
"; ForkJoinPool.commonPool: " + ForkJoinPool.commonPool() +
"; factory: " + ForkJoinPool.commonPool().getFactory());
// replaces system event queue
//noinspection ResultOfMethodCallIgnored
IdeEventQueue.getInstance();
}
private static void patchSystemForUi(@NotNull Logger log) {
if ("true".equals(System.getProperty("idea.check.swing.threading"))) {
RepaintManager.setCurrentManager(new AssertiveRepaintManager());
}
if (SystemInfoRt.isXWindow) {
String wmName = X11UiUtil.getWmName();
log.info("WM detected: " + wmName);
if (wmName != null) {
X11UiUtil.patchDetectedWm(wmName);
}
}
IconManager.activate();
}
private static boolean showUserAgreementAndConsentsIfNeeded(@NotNull Logger log,
@NotNull CompletableFuture<?> initUiTask,
@NotNull EndUserAgreement.Document agreement) {
@@ -889,18 +889,17 @@ public final class StartupUtil {
try {
if (!ourSystemPatched.get()) {
EventQueue.invokeAndWait(() -> {
if (!patchSystem(log)) {
return;
}
try {
if (!patchSystem(log)) {
return;
}
UIManager.setLookAndFeel(IntelliJLaf.class.getName());
IconManager.activate();
// todo investigate why in test mode dummy icon manager is not suitable
IconLoader.activate();
// we don't set AppUIUtil.updateForDarcula(false) because light is default
}
catch (Exception ignore) { }
catch (Throwable e) {
log.warn(e);
}
});
}
@@ -59,6 +59,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
@ApiStatus.Internal
public class ApplicationImpl extends ComponentManagerImpl implements ApplicationEx {
// do not use PluginManager.processException() because it can force app to exit, but we want just log error and continue
private static final Logger LOG = Logger.getInstance(ApplicationImpl.class);
@@ -110,6 +111,10 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
}
public ApplicationImpl(boolean isInternal, boolean isUnitTestMode, boolean isHeadless, boolean isCommandLine) {
this(isInternal, isUnitTestMode, isHeadless, isCommandLine, null);
}
public ApplicationImpl(boolean isInternal, boolean isUnitTestMode, boolean isHeadless, boolean isCommandLine, Consumer<ApplicationImpl> initTask) {
super(null);
// reset back to null only when all components already disposed
@@ -119,8 +124,14 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
registerServiceInstance(ApplicationInfo.class, ApplicationInfoImpl.getShadowInstance(), ComponentManagerImpl.getFakeCorePluginDescriptor());
registerServiceInstance(Application.class, this, ComponentManagerImpl.getFakeCorePluginDescriptor());
boolean strictMode = isUnitTestMode || isInternal;
BundleBase.assertOnMissedKeys(strictMode);
if (initTask != null) {
// myLock is a final field, we cannot do init in EDT and set it later
initTask.accept(this);
}
if (isUnitTestMode || isInternal) {
BundleBase.assertOnMissedKeys(true);
}
// do not crash AWT on exceptions
AWTExceptionHandler.register();
@@ -141,18 +152,16 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
Activity activity = StartUpMeasurer.startActivity("AppDelayQueue instantiation", ActivityCategory.APP_INIT);
AtomicReference<Thread> edtThread = new AtomicReference<>();
Runnable runnable = () -> {
EdtInvocationManager.invokeAndWaitIfNeeded(() -> {
// instantiate AppDelayQueue which starts "Periodic task thread" which we'll mark busy to prevent this EDT to die
// that thread was chosen because we know for sure it's running
AppScheduledExecutorService service = (AppScheduledExecutorService)AppExecutorUtil.getAppScheduledExecutorService();
Thread thread = service.getPeriodicTasksThread();
Thread thread = ((AppScheduledExecutorService)AppExecutorUtil.getAppScheduledExecutorService()).getPeriodicTasksThread();
AWTAutoShutdown.getInstance().notifyThreadBusy(thread); // needed for EDT not to exit suddenly
Disposer.register(this, () -> {
AWTAutoShutdown.getInstance().notifyThreadFree(thread); // allow for EDT to exit - needed for Upsource
});
edtThread.set(Thread.currentThread());
};
EdtInvocationManager.invokeAndWaitIfNeeded(runnable);
});
myLock = new ReadMostlyRWLock(edtThread.get());
// Acquire IW lock on EDT indefinitely in legacy mode
if (!USE_SEPARATE_WRITE_THREAD || isUnitTestMode) {
@@ -348,14 +357,13 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
@Override
public final void load() {
List<IdeaPluginDescriptorImpl> plugins = PluginManagerCore.getLoadedPlugins(null);
registerComponents(plugins, null);
registerComponents(plugins, this, null);
ApplicationLoader.initConfigurationStore(this);
preloadServices(plugins, "", false).getSyncPreloadedServices().join();
loadComponents(null);
ForkJoinTask.invokeAll(ApplicationLoader.callAppInitialized(this));
}
@ApiStatus.Internal
public final void loadComponents(@Nullable ProgressIndicator indicator) {
if (indicator == null) {
// no splash, no need to to use progress manager
@@ -632,7 +640,6 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
return !ProgressManager.getInstance().hasProgressIndicator();
}
@ApiStatus.Internal
public final @NotNull CompletableFuture<@NotNull ProgressWindow> createProgressWindowAsyncIfNeeded(@NotNull @NlsContexts.ProgressTitle String progressTitle,
boolean canBeCanceled,
boolean shouldShowModalWindow,
@@ -1300,7 +1307,6 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
* so that background threads with read actions don't see half-baked PSI/VFS/etc. The runnable may perform write actions itself,
* callers should be ready for those.
*/
@ApiStatus.Internal
public void executeSuspendingWriteAction(@Nullable Project project, @NotNull @NlsContexts.DialogTitle String title, @NotNull Runnable runnable) {
assertIsWriteThread();
if (!myLock.isWriteLocked()) {
@@ -1393,7 +1399,6 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
(isCommandLine() ? " (Command line)" : "");
}
@ApiStatus.Internal
@Override
public @NotNull String activityNamePrefix() {
return "app ";
@@ -1425,7 +1430,6 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
myDispatcher.neuterMultiCasterWhilePerformanceTestIsRunningUntil(disposable);
}
@ApiStatus.Internal
public boolean getComponentCreated() {
return getContainerState().get().compareTo(ContainerState.COMPONENT_CREATED) >= 0;
}
@@ -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-2021 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.application.impl;
import com.intellij.openapi.application.AccessToken;
@@ -43,7 +29,7 @@ import java.util.concurrent.locks.LockSupport;
* Read lock: flips {@link Reader#readRequested} bit in its own thread local {@link Reader} structure and waits for writer to release its lock by checking {@link #writeRequested}.<br>
* Write lock: sets global {@link #writeRequested} bit and waits for all readers (in global {@link #readers} list) to release their locks by checking {@link Reader#readRequested} for all readers.
*/
class ReadMostlyRWLock {
final class ReadMostlyRWLock {
final Thread writeThread;
@VisibleForTesting
volatile boolean writeRequested; // this writer is requesting or obtained the write access
@@ -313,7 +313,7 @@ final class DefaultProjectImpl extends ComponentManagerImpl implements Project {
registerServiceInstance(Project.class, actualContainerInstance, ComponentManagerImpl.getFakeCorePluginDescriptor());
//noinspection unchecked
registerComponents((List<IdeaPluginDescriptorImpl>)PluginManagerCore.getLoadedPlugins(), null);
registerComponents((List<IdeaPluginDescriptorImpl>)PluginManagerCore.getLoadedPlugins(), ApplicationManager.getApplication(), null);
createComponents(null);
Disposer.register(actualContainerInstance, this);
}
@@ -1,4 +1,5 @@
// Copyright 2000-2021 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.
@file:Suppress("ReplaceNegatedIsEmptyWithIsNotEmpty")
package com.intellij.openapi.project.impl
import com.intellij.conversion.ConversionResult
@@ -85,7 +86,7 @@ open class ProjectManagerExImpl : ProjectManagerImpl() {
val activity = StartUpMeasurer.startMainActivity("project opening preparation")
if (!options.forceOpenInNewFrame) {
val openProjects = openProjects
if (!openProjects.isNullOrEmpty()) {
if (!openProjects.isEmpty()) {
var projectToClose = options.projectToClose
if (projectToClose == null) {
// if several projects are opened, ask to reuse not last opened project frame, but last focused (to avoid focus switching)
@@ -9,7 +9,6 @@ import com.intellij.diagnostic.PluginException
import com.intellij.diagnostic.StartUpMeasurer
import com.intellij.diagnostic.StartUpMeasurer.Activities
import com.intellij.diagnostic.StartUpMeasurer.startActivity
import com.intellij.ide.plugins.IdeaPluginDescriptorImpl
import com.intellij.ide.plugins.PluginManagerCore
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.logger
@@ -23,8 +22,7 @@ import org.jetbrains.annotations.ApiStatus
internal fun registerComponents(project: ProjectImpl) {
var activity = createActivity(project) { "project ${Activities.REGISTER_COMPONENTS_SUFFIX}" }
// at this point of time plugins are already loaded by application - no need to pass indicator to getLoadedPlugins call
@Suppress("UNCHECKED_CAST")
project.registerComponents(PluginManagerCore.getLoadedPlugins() as List<IdeaPluginDescriptorImpl>, null)
project.registerComponents(PluginManagerCore.getLoadedPlugins(null), ApplicationManager.getApplication(), null)
activity = activity?.endAndStart("projectComponentRegistered")
runOnlyCorePluginExtensions(
@@ -13,12 +13,10 @@ import org.jetbrains.annotations.Nullable;
* @author gregsh
*/
public final class SystemPropertyBean implements PluginAware {
private static final ExtensionPointName<SystemPropertyBean> EP_NAME = new ExtensionPointName<>("com.intellij.systemProperty");
private PluginDescriptor myPluginDescriptor;
public static void initSystemProperties() {
EP_NAME.forEachExtensionSafe(bean -> {
new ExtensionPointName<SystemPropertyBean>("com.intellij.systemProperty").forEachExtensionSafe(bean -> {
if (System.getProperty(bean.name) == null) {
System.setProperty(bean.name, bean.value);
}
@@ -8,6 +8,7 @@ import com.intellij.openapi.extensions.*
import com.intellij.openapi.util.text.StringUtil
import com.intellij.util.xmlb.annotations.Attribute
import com.intellij.util.xmlb.annotations.Transient
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.Nls
import org.jetbrains.annotations.NonNls
@@ -26,14 +27,14 @@ class RegistryKeyBean : PluginAware {
private val pendingRemovalKeys = HashSet<String>()
@JvmStatic
internal fun addKeysFromPlugins() {
@ApiStatus.Internal
fun addKeysFromPlugins() {
val epName = ExtensionPointName<RegistryKeyBean>("com.intellij.registryKey")
Registry.addKeys(epName.iterable.map { createRegistryKeyDescriptor(it) })
Registry.addKeys(epName.iterable.asSequence().map { createRegistryKeyDescriptor(it) }.iterator())
epName.addExtensionPointListener(object : ExtensionPointListener<RegistryKeyBean>, ExtensionPointPriorityListener {
override fun extensionAdded(extension: RegistryKeyBean, pluginDescriptor: PluginDescriptor) {
Registry.addKeys(listOf(createRegistryKeyDescriptor(extension)))
Registry.addKeys(listOf(createRegistryKeyDescriptor(extension)).iterator())
}
}, null)
@@ -1,39 +1,43 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.util.LastComputedIconCache;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.HeavyPlatformTestCase;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.util.FileContentUtilCore;
import com.intellij.util.IconUtil;
import com.intellij.util.PlatformIcons;
import com.intellij.util.TimeoutUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class IconUtilTest extends HeavyPlatformTestCase {
@Override
protected boolean isIconRequired() {
return false;
return true;
}
@Override
protected void setUp() throws Exception {
super.setUp();
while (DumbService.isDumb(getProject())) {
UIUtil.dispatchAllInvocationEvents();
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue();
}
}
@@ -65,26 +69,32 @@ public class IconUtilTest extends HeavyPlatformTestCase {
assertJustOneLockedIcon(file);
}
private void assertJustOneLockedIcon(VirtualFile file) throws IOException {
WriteCommandAction.runWriteCommandAction(getProject(),
(ThrowableComputable<Void,IOException>)() -> {
file.setBinaryContent("class X {}".getBytes(StandardCharsets.UTF_8));
file.setWritable(false);
return null;
});
UIUtil.dispatchAllInvocationEvents(); // write actions
UIUtil.dispatchAllInvocationEvents();
private void assertJustOneLockedIcon(@NotNull VirtualFile file) throws IOException {
LastComputedIconCache.clear(file);
WriteCommandAction.runWriteCommandAction(getProject(), (ThrowableComputable<Void, IOException>)() -> {
file.setBinaryContent("class X {}".getBytes(StandardCharsets.UTF_8));
file.setWritable(false);
return null;
});
// write actions
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue();
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue();
try {
Icon icon = IconUtil.getIcon(file, -1, getProject());
List<Icon> icons = IconTestUtil.renderDeferredIcon(icon);
assertOneElement(ContainerUtil.filter(icons, ic -> ic == IconTestUtil.unwrapRetrievableIcon(PlatformIcons.LOCKED_ICON)));
List<Icon> icons = IconTestUtil.renderDeferredIcon(IconUtil.getIcon(file, -1, getProject()));
List<Icon> result = new ArrayList<>();
for (Icon icon : icons) {
if (IconTestUtil.unwrapIcon(icon) == PlatformIcons.LOCKED_ICON) {
result.add(icon);
}
}
assertThat(result).hasSize(1);
}
finally {
WriteCommandAction.runWriteCommandAction(getProject(),
(ThrowableComputable<Void,IOException>)() -> {
file.setWritable(true);
return null;
});
WriteCommandAction.runWriteCommandAction(getProject(), (ThrowableComputable<Void, IOException>)() -> {
file.setWritable(true);
return null;
});
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.openapi.util.IconLoader
@@ -22,7 +22,7 @@ class UiTestRule(private val testDataRoot: Path) : RequireHeadlessMode() {
override fun before() {
super.before()
IconManager.activate()
IconManager.activate(null)
IconLoader.activate()
}
@@ -1,8 +1,7 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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 org.jetbrains.io;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.containers.ContainerUtil;
import io.netty.channel.*;
import io.netty.util.concurrent.GenericFutureListener;
import org.jetbrains.annotations.NotNull;
@@ -20,7 +19,9 @@ public final class ChannelRegistrar extends ChannelInboundHandlerAdapter {
private static final Logger LOG = Logger.getInstance(ChannelRegistrar.class);
private final AtomicReference<ServerChannel> serverChannel = new AtomicReference<>();
private final Set<Channel> clientChannels = ContainerUtil.newConcurrentSet();
// don't use ContainerUtil here!
@SuppressWarnings("SSBasedInspection")
private final Set<Channel> clientChannels = Collections.newSetFromMap(new ConcurrentHashMap<>());
private boolean isEventLoopGroupOwner;
@@ -173,14 +173,4 @@ internal abstract class BaseComponentAdapter(internal val componentManager: Comp
@Suppress("UNCHECKED_CAST")
return old as T?
}
// used in LinkedHashSetWrapper
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
return other is ComponentAdapter && componentKey == other.componentKey
}
override fun hashCode() = componentKey.hashCode()
}
@@ -234,15 +234,15 @@ abstract class ComponentManagerImpl @JvmOverloads constructor(internal val paren
final override fun getExtensionArea() = extensionArea
@Internal
open fun registerComponents(plugins: List<IdeaPluginDescriptorImpl>, listenerCallbacks: MutableList<Runnable>?) {
open fun registerComponents(plugins: List<IdeaPluginDescriptorImpl>,
app: Application?,
listenerCallbacks: MutableList<Runnable>?) {
val activityNamePrefix = activityNamePrefix()
val app = getApplication()
val headless = app == null || app.isHeadlessEnvironment
var newComponentConfigCount = 0
var map: ConcurrentMap<String, MutableList<ListenerDescriptor>>? = null
val isHeadlessMode = app?.isHeadlessEnvironment == true
val isUnitTestMode = app?.isUnitTestMode == true
val isHeadless = app == null || app.isHeadlessEnvironment
val isUnitTestMode = app?.isUnitTestMode ?: false
val clonePoint = parent != null
@@ -257,7 +257,7 @@ abstract class ComponentManagerImpl @JvmOverloads constructor(internal val paren
}
executeRegisterTask(mainPlugin, mainContainerDescriptor, this) { pluginDescriptor, containerDescriptor ->
newComponentConfigCount += registerComponents(pluginDescriptor, containerDescriptor, headless)
newComponentConfigCount += registerComponents(pluginDescriptor, containerDescriptor, isHeadless)
}
executeRegisterTask(mainPlugin, mainContainerDescriptor, this) { _, containerDescriptor ->
@@ -268,7 +268,7 @@ abstract class ComponentManagerImpl @JvmOverloads constructor(internal val paren
map = m
}
for (listener in listeners) {
if ((isUnitTestMode && !listener.activeInTestMode) || (isHeadlessMode && !listener.activeInHeadlessMode)) {
if ((isUnitTestMode && !listener.activeInTestMode) || (isHeadless && !listener.activeInHeadlessMode)) {
continue
}
@@ -535,10 +535,10 @@ abstract class ComponentManagerImpl @JvmOverloads constructor(internal val paren
val result = getComponent(serviceClass) ?: return null
PluginException.logPluginError(LOG,
"$key requested as a service, but it is a component - " +
"convert it to a service or change call to " +
if (parent == null) "ApplicationManager.getApplication().getComponent()" else "project.getComponent()",
null, serviceClass)
"$key requested as a service, but it is a component - " +
"convert it to a service or change call to " +
if (parent == null) "ApplicationManager.getApplication().getComponent()" else "project.getComponent()",
null, serviceClass)
return result
}
@@ -668,12 +668,11 @@ abstract class ComponentManagerImpl @JvmOverloads constructor(internal val paren
fun <T : Any> registerServiceInstance(serviceInterface: Class<T>, instance: T, pluginDescriptor: PluginDescriptor) {
val serviceKey = serviceInterface.name
checkState()
componentKeyToAdapter.remove(serviceKey)
val descriptor = ServiceDescriptor()
descriptor.serviceInterface = serviceKey
descriptor.serviceImplementation = instance.javaClass.name
registerAdapter(ServiceComponentAdapter(descriptor, pluginDescriptor, this, instance.javaClass, instance), pluginDescriptor)
componentKeyToAdapter.put(serviceKey, ServiceComponentAdapter(descriptor, pluginDescriptor, this, instance.javaClass, instance))
}
@TestOnly
@@ -937,15 +936,15 @@ abstract class ComponentManagerImpl @JvmOverloads constructor(internal val paren
return ServicePreloadingResult(
asyncPreloadedServices = CompletableFuture.runAsync({
runActivity("${activityPrefix}service async preloading") {
ForkJoinTask.invokeAll(asyncPreloadedServices)
}
}, ForkJoinPool.commonPool()),
runActivity("${activityPrefix}service async preloading") {
ForkJoinTask.invokeAll(asyncPreloadedServices)
}
}, ForkJoinPool.commonPool()),
syncPreloadedServices = CompletableFuture.runAsync({
runActivity("${activityPrefix}service sync preloading") {
ForkJoinTask.invokeAll(syncPreloadedServices)
}
}, ForkJoinPool.commonPool())
runActivity("${activityPrefix}service sync preloading") {
ForkJoinTask.invokeAll(syncPreloadedServices)
}
}, ForkJoinPool.commonPool())
)
}
@@ -6,6 +6,7 @@ import com.intellij.openapi.Disposable
import com.intellij.openapi.extensions.PluginDescriptor
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.util.Disposer
import org.picocontainer.ComponentAdapter
internal class MyComponentAdapter(private val componentKey: Class<*>,
override val implementationClassName: String,
@@ -62,4 +63,14 @@ internal class MyComponentAdapter(private val componentKey: Class<*>,
}
override fun toString() = "ComponentAdapter(key=${getComponentKey()}, implementation=${componentImplementation}, plugin=$pluginId)"
// used in LinkedHashSetWrapper
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
return other is ComponentAdapter && componentKey == other.componentKey
}
override fun hashCode() = componentKey.hashCode()
}
@@ -6,16 +6,18 @@ import com.intellij.diagnostic.ThreadDumper
import com.intellij.ide.IdeEventQueue
import com.intellij.ide.plugins.IdeaPluginDescriptorImpl
import com.intellij.ide.plugins.PluginManagerCore
import com.intellij.idea.*
import com.intellij.idea.Main
import com.intellij.idea.callAppInitialized
import com.intellij.idea.initConfigurationStore
import com.intellij.idea.preloadServices
import com.intellij.openapi.application.PathManager
import com.intellij.openapi.application.impl.ApplicationImpl
import com.intellij.openapi.util.RecursionManager
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.util.registry.RegistryKeyBean
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFSImpl
import com.intellij.ui.IconManager
import com.intellij.util.SystemProperties
import com.intellij.util.concurrency.AppExecutorUtil
import java.awt.EventQueue
import java.util.concurrent.*
import java.util.function.Supplier
@@ -43,7 +45,7 @@ internal fun doLoadApp(setupEventQueue: () -> Unit) {
val loadedPluginFuture = CompletableFuture.supplyAsync(Supplier {
PluginManagerCore.getLoadedPlugins(PathManager::class.java.classLoader)
}, AppExecutorUtil.getAppExecutorService())
}, ForkJoinPool.commonPool())
setupEventQueue()
@@ -53,13 +55,13 @@ internal fun doLoadApp(setupEventQueue: () -> Unit) {
RecursionManager.assertOnMissedCache(app)
}
IconManager.activate()
val plugins: List<IdeaPluginDescriptorImpl>
try {
// 40 seconds - tests maybe executed on cloud agents where IO speed is a very slow
plugins = registerRegistryAndInitStore(registerAppComponents(loadedPluginFuture, app), app)
.get(40, TimeUnit.SECONDS)
plugins = loadedPluginFuture.get(40, TimeUnit.SECONDS)
app.registerComponents(plugins, app, null)
initConfigurationStore(app)
RegistryKeyBean.addKeysFromPlugins()
Registry.getInstance().markAsLoaded()
val preloadServiceFuture = preloadServices(plugins, app, activityPrefix = "")
app.loadComponents(null)
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.
@file:Suppress("JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE")
package com.intellij.testFramework
@@ -17,10 +17,8 @@ import com.intellij.ide.impl.HeadlessDataManager
import com.intellij.ide.startup.impl.StartupManagerImpl
import com.intellij.ide.structureView.StructureViewFactory
import com.intellij.ide.structureView.impl.StructureViewFactoryImpl
import com.intellij.idea.StartupUtil
import com.intellij.openapi.Disposable
import com.intellij.openapi.actionSystem.DataProvider
import com.intellij.openapi.actionSystem.ex.ActionUtil
import com.intellij.openapi.application.Application
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.impl.ApplicationImpl
@@ -31,7 +29,6 @@ import com.intellij.openapi.command.impl.UndoManagerImpl
import com.intellij.openapi.command.undo.DocumentReferenceManager
import com.intellij.openapi.command.undo.UndoManager
import com.intellij.openapi.components.serviceIfCreated
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.fileEditor.impl.EditorHistoryManager
import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl
@@ -119,7 +116,8 @@ class TestApplicationManager private constructor() {
HeavyPlatformTestCase.doAutodetectPlatformPrefix()
doLoadApp {
if (EventQueue.isDispatchThread()) {
StartupUtil.replaceSystemEventQueue(logger<TestApplicationManager>())
// replaces system event queue
IdeEventQueue.getInstance()
}
else {
replaceIdeEventQueueSafely()
@@ -29,6 +29,8 @@ import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.rt.execution.junit.FileComparisonFailure;
import com.intellij.testFramework.exceptionCases.AbstractExceptionCase;
import com.intellij.testFramework.fixtures.IdeaTestExecutionPolicy;
import com.intellij.ui.CoreIconManager;
import com.intellij.ui.IconManager;
import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.PeekableIterator;
@@ -226,7 +228,7 @@ public abstract class UsefulTestCase extends TestCase {
setupTempDir();
boolean isStressTest = isStressTest();
ApplicationManagerEx.setInStressTest(isStressTest);;
ApplicationManagerEx.setInStressTest(isStressTest);
if (isPerformanceTest()) {
Timings.getStatistics();
}
@@ -236,8 +238,15 @@ public abstract class UsefulTestCase extends TestCase {
if (isIconRequired()) {
// ensure that IconLoader will use dummy empty icon
IconLoader.deactivate();
//IconManager.activate();
try {
IconManager.activate(new CoreIconManager());
}
catch (Exception e) {
throw e;
}
catch (Throwable e) {
throw new RuntimeException(e);
}
}
}
@@ -293,6 +302,12 @@ public abstract class UsefulTestCase extends TestCase {
// don't use method references here to make stack trace reading easier
//noinspection Convert2MethodRef
new RunAll(
() -> {
if (isIconRequired()) {
IconManager.deactivate();
IconLoader.clearCacheInTests();
}
},
() -> disposeRootDisposable(),
() -> cleanupSwingDataStructures(),
() -> cleanupDeleteOnExitHookList(),
@@ -466,7 +481,7 @@ public abstract class UsefulTestCase extends TestCase {
}
}
protected void invokeSetUp() throws Exception {
protected final void invokeSetUp() throws Exception {
long setupStart = System.nanoTime();
setUp();
long setupCost = (System.nanoTime() - setupStart) / 1000000;
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.fixtures;
import com.intellij.lang.Language;
@@ -18,8 +18,6 @@ import com.intellij.testFramework.UsefulTestCase;
import com.intellij.testFramework.fixtures.impl.LightTempDirTestFixtureImpl;
import com.intellij.util.ThrowableRunnable;
import org.jetbrains.annotations.NotNull;
import org.junit.Rule;
import org.junit.rules.TestRule;
/**
* Base class for light tests.
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.fixtures;
import com.intellij.codeInsight.lookup.LookupElement;
@@ -6,6 +6,7 @@ import com.intellij.codeInsight.lookup.LookupElementPresentation;
import com.intellij.codeInsight.lookup.LookupElementRenderer;
import com.intellij.ui.DeferredIcon;
import com.intellij.ui.LayeredIcon;
import com.intellij.ui.icons.CompositeIcon;
import com.intellij.ui.icons.RowIcon;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -16,8 +17,7 @@ import javax.swing.*;
* @author peter
*/
public final class TestLookupElementPresentation extends LookupElementPresentation {
@NotNull
public static TestLookupElementPresentation renderReal(@NotNull LookupElement e) {
public static @NotNull TestLookupElementPresentation renderReal(@NotNull LookupElement e) {
TestLookupElementPresentation p = new TestLookupElementPresentation();
//noinspection rawtypes
LookupElementRenderer renderer = e.getExpensiveRenderer();
@@ -30,13 +30,25 @@ public final class TestLookupElementPresentation extends LookupElementPresentati
return p;
}
@Nullable
public static Icon unwrapIcon(@Nullable Icon icon) {
public static @Nullable Icon unwrapIcon(@Nullable Icon icon) {
while (true) {
if (icon instanceof RowIcon) icon = ((RowIcon)icon).getIcon(0);
else if (icon instanceof DeferredIcon) icon = ((DeferredIcon)icon).evaluate();
else if (icon instanceof LayeredIcon) icon = ((LayeredIcon)icon).getIcon(0);
else return icon;
if (icon instanceof RowIcon) {
if (((CompositeIcon)icon).getIconCount() == 0) {
return icon;
}
else {
icon = ((RowIcon)icon).getIcon(0);
}
}
else if (icon instanceof DeferredIcon) {
icon = ((DeferredIcon)icon).evaluate();
}
else if (icon instanceof LayeredIcon) {
icon = ((LayeredIcon)icon).getIcon(0);
}
else {
return icon;
}
}
}
}
@@ -1,7 +1,8 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.openapi.util.IconLoader;
import com.intellij.ui.icons.CompositeIcon;
import com.intellij.util.TimeoutUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
@@ -16,19 +17,37 @@ import java.util.Collections;
import java.util.List;
public final class IconTestUtil {
@Nullable
public static String getIconPath(Icon icon) {
public static @Nullable String getIconPath(@NotNull Icon icon) {
icon = unwrapRetrievableIcon(icon);
return ((IconLoader.CachedImageIcon)icon).getOriginalPath();
if (icon instanceof IconLoader.CachedImageIcon) {
return ((IconLoader.CachedImageIcon)icon).getOriginalPath();
}
else {
// DummyIcon
return icon.toString();
}
}
public static Icon unwrapRetrievableIcon(Icon icon) {
public static @NotNull Icon unwrapRetrievableIcon(@NotNull Icon icon) {
while (icon instanceof RetrievableIcon) {
icon = ((RetrievableIcon)icon).retrieveIcon();
}
return icon;
}
public static @NotNull Icon unwrapIcon(@NotNull Icon icon) {
while (icon instanceof CompositeIcon) {
CompositeIcon compositeIcon = (CompositeIcon)icon;
if (compositeIcon.getIconCount() == 0) {
break;
}
icon = compositeIcon.getIcon(0);
}
assert icon != null;
return unwrapRetrievableIcon(icon);
}
@NotNull
static List<Icon> autopsyIconsFrom(@NotNull Icon icon) {
if (icon instanceof RetrievableIcon) {
@@ -18,7 +18,7 @@ fun <K, V> MutableMap<K, MutableList<V>>.remove(key: K, value: V) {
fun <K, V> MutableMap<K, MutableList<V>>.putValue(key: K, value: V) {
val list = get(key)
if (list == null) {
put(key, SmartList<V>(value))
put(key, SmartList(value))
}
else {
list.add(value)
@@ -88,11 +88,7 @@ inline fun <T> Iterator<T>.forEachGuaranteed(operation: (T) -> Unit) {
}
inline fun <T> Collection<T>.forEachLoggingErrors(logger: Logger, operation: (T) -> Unit) {
return asSequence().forEachLoggingErrors(logger, operation)
}
inline fun <T> Sequence<T>.forEachLoggingErrors(logger: Logger, operation: (T) -> Unit) {
forEach {
asSequence().forEach {
try {
operation(it)
}
@@ -100,6 +96,7 @@ inline fun <T> Sequence<T>.forEachLoggingErrors(logger: Logger, operation: (T) -
logger.error(e)
}
}
return
}
inline fun <T, R : Any> Collection<T>.mapNotNullLoggingErrors(logger: Logger, operation: (T) -> R?): List<R> {
@@ -190,7 +187,7 @@ inline fun <T, R> Collection<T>.mapSmartSet(transform: (T) -> R): Set<R> {
inline fun <T, R : Any> Collection<T>.mapSmartNotNull(transform: (T) -> R?): List<R> {
val size = size
return if (size == 1) {
transform(first())?.let { SmartList<R>(it) } ?: SmartList<R>()
transform(first())?.let { SmartList(it) } ?: SmartList()
}
else {
mapNotNullTo(ArrayList(size), transform)
@@ -219,7 +216,7 @@ inline fun <T> Collection<T>.filterSmartMutable(predicate: (T) -> Boolean): Muta
return filterTo(if (size <= 1) SmartList() else ArrayList(), predicate)
}
inline fun <reified E : Enum<E>, V> enumMapOf(): MutableMap<E, V> = EnumMap<E, V>(E::class.java)
inline fun <reified E : Enum<E>, V> enumMapOf(): MutableMap<E, V> = EnumMap(E::class.java)
fun <E> Collection<E>.toArray(empty: Array<E>): Array<E> {
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
@@ -2,7 +2,6 @@
package com.intellij.openapi.application;
import com.intellij.diagnostic.StartUpMeasurer;
import com.intellij.openapi.util.PropertiesUtil;
import com.intellij.openapi.util.SystemInfoRt;
import com.intellij.openapi.util.text.StringUtilRt;
import com.intellij.openapi.util.text.Strings;
@@ -56,7 +55,7 @@ public final class PathManager {
private static final String SYSTEM_DIRECTORY = "system";
private static final String PATHS_SELECTOR = System.getProperty(PROPERTY_PATHS_SELECTOR);
private static class Lazy {
private static final class Lazy {
private static final Pattern PROPERTY_REF = Pattern.compile("\\$\\{(.+?)}");
}
@@ -550,16 +549,19 @@ public final class PathManager {
Path file = path == null ? null : Paths.get(path);
if (file != null) {
try (Reader reader = Files.newBufferedReader(file)) {
Map<String, String> properties = PropertiesUtil.loadProperties(reader);
for (Map.Entry<String, String> entry : properties.entrySet()) {
String key = entry.getKey();
if (PROPERTY_HOME_PATH.equals(key) || PROPERTY_HOME.equals(key)) {
log(path + ": '" + key + "' cannot be redefined");
//noinspection NonSynchronizedMethodOverridesSynchronizedMethod
new Properties() {
@Override
public Object put(Object key, Object value) {
if (PROPERTY_HOME_PATH.equals(key) || PROPERTY_HOME.equals(key)) {
log(path + ": '" + key + "' cannot be redefined");
}
else if (!sysProperties.containsKey(key)) {
sysProperties.setProperty(String.valueOf(key), substituteVars(String.valueOf(value)));
}
return null;
}
else if (!sysProperties.containsKey(key)) {
sysProperties.setProperty(key, substituteVars(entry.getValue()));
}
}
}.load(reader);
}
catch (NoSuchFileException | AccessDeniedException ignore) { }
catch (IOException e) {
@@ -1,9 +1,8 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.util;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.util.text.Strings;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.util.io.URLUtil;
@@ -76,9 +75,11 @@ public final class JDOMUtil {
}
}
// avoid loading of SystemInfo class
if (Strings.indexOfIgnoreCase(System.getProperty("java.vm.vendor", ""), "IBM", 0) < 0) {
// avoid loading of SystemInfo and Strings classes
String jvmVendor = System.getProperty("java.vm.vendor", "");
if (!jvmVendor.contains("IBM") && !jvmVendor.contains("ibm")) {
try {
//noinspection HttpUrlsUsage
factory.setProperty("http://java.sun.com/xml/stream/properties/report-cdata-event", true);
}
catch (Exception e) {
@@ -184,7 +185,7 @@ public final class JDOMUtil {
sb.append(each == '<' ? "&lt;" : "&gt;");
}
else if (!Verifier.isXMLCharacter(each)) {
sb.append("0x").append(StringUtil.toUpperCase(Long.toHexString(each)));
sb.append("0x").append(Strings.toUpperCase(Long.toHexString(each)));
}
else {
sb.append(each);
@@ -410,14 +411,14 @@ public final class JDOMUtil {
write(document, file, lineSeparator);
}
/**
* Use {@link #write(Element, Path)}
*/
@Deprecated
public static void write(@NotNull Element element, @NotNull File file) throws IOException {
write(element, file, "\n");
}
public static void write(@NotNull Element element, @NotNull File file, @Nullable String lineSeparator) throws IOException {
FileUtil.createParentDirs(file);
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
writeElement(element, writer, createOutputter(lineSeparator));
writeElement(element, writer, createOutputter("\n"));
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.util;
import com.intellij.reference.SoftReference;
@@ -7,6 +7,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
import java.lang.ref.Reference;
@@ -16,10 +17,7 @@ public final class LastComputedIconCache {
public static @Nullable Icon get(@NotNull UserDataHolder holder, int flags) {
Int2ObjectMap<Icon> map = SoftReference.dereference(holder.getUserData(LAST_COMPUTED_ICON));
if (map == null) {
return null;
}
return map.get(flags);
return map == null ? null : map.get(flags);
}
public static void put(@NotNull UserDataHolder holder, Icon icon, int flags) {
@@ -48,4 +46,9 @@ public final class LastComputedIconCache {
map.put(flags, icon);
}
}
@TestOnly
public static void clear(@NotNull UserDataHolder holder) {
holder.putUserData(LAST_COMPUTED_ICON, null);
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.util.registry;
import com.intellij.diagnostic.LoadingState;
@@ -54,7 +54,7 @@ public final class Registry {
}
public static boolean is(@NonNls @NotNull String key, boolean defaultValue) {
if (!LoadingState.COMPONENTS_REGISTERED.isOccurred()) {
if (!LoadingState.CONFIGURATION_STORE_INITIALIZED.isOccurred()) {
LoadingState.LAF_INITIALIZED.checkOccurred();
return defaultValue;
}
@@ -72,7 +72,7 @@ public final class Registry {
}
public static int intValue(@NonNls @NotNull String key, int defaultValue) {
if (!LoadingState.COMPONENTS_REGISTERED.isOccurred()) {
if (!LoadingState.CONFIGURATION_STORE_INITIALIZED.isOccurred()) {
LoadingState.LAF_INITIALIZED.checkOccurred();
return defaultValue;
}
@@ -124,7 +124,7 @@ public final class Registry {
}
public static @NotNull Registry getInstance() {
LoadingState.COMPONENTS_REGISTERED.checkOccurred();
LoadingState.CONFIGURATION_STORE_INITIALIZED.checkOccurred();
return ourInstance;
}
@@ -176,15 +176,18 @@ public final class Registry {
List<RegistryValue> result = new ArrayList<>();
Map<String, RegistryKeyDescriptor> contributedKeys = getInstance().myContributedKeys;
Registry instance = getInstance();
Map<String, RegistryKeyDescriptor> contributedKeys = instance.myContributedKeys;
while (keys.hasMoreElements()) {
@NonNls final String each = keys.nextElement();
if (each.endsWith(".description") || each.endsWith(".restartRequired") || contributedKeys.containsKey(each)) continue;
result.add(get(each));
if (each.endsWith(".description") || each.endsWith(".restartRequired") || contributedKeys.containsKey(each)) {
continue;
}
result.add(instance.doGet(each));
}
for (String key : contributedKeys.keySet()) {
result.add(get(key));
result.add(instance.doGet(key));
}
return result;
@@ -192,9 +195,10 @@ public final class Registry {
void restoreDefaults() {
Map<String, String> old = new HashMap<>(myUserProperties);
Registry instance = getInstance();
for (String each : old.keySet()) {
try {
get(each).resetToDefault();
instance.doGet(each).resetToDefault();
}
catch (MissingResourceException e) {
// outdated property that is not declared in registry.properties anymore
@@ -212,17 +216,21 @@ public final class Registry {
}
private static boolean isRestartNeeded(@NotNull Map<String, String> map) {
Registry instance = getInstance();
for (String s : map.keySet()) {
final RegistryValue eachValue = get(s);
if (eachValue.isRestartRequired() && eachValue.isChangedSinceAppStart()) return true;
RegistryValue eachValue = instance.doGet(s);
if (eachValue.isRestartRequired() && eachValue.isChangedSinceAppStart()) {
return true;
}
}
return false;
}
public static synchronized void addKeys(@NotNull List<RegistryKeyDescriptor> descriptors) {
public static synchronized void addKeys(@NotNull Iterator<RegistryKeyDescriptor> descriptors) {
// getInstance must be not used here - phase COMPONENT_REGISTERED is not yet completed
for (RegistryKeyDescriptor descriptor : descriptors) {
while (descriptors.hasNext()) {
RegistryKeyDescriptor descriptor = descriptors.next();
ourInstance.myContributedKeys.put(descriptor.getName(), descriptor);
}
}
@@ -9,7 +9,6 @@ import com.intellij.openapi.util.NlsSafe;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.text.CharArrayUtil;
import com.intellij.util.text.CharSequenceSubSequence;
import com.intellij.util.text.MergingCharSequence;
@@ -106,9 +105,9 @@ public class StringUtil extends StringUtilRt {
}
}
public static final NotNullFunction<String, String> QUOTER = s -> "\"" + s + "\"";
public static final java.util.function.Function<String, String> QUOTER = s -> "\"" + s + "\"";
public static final NotNullFunction<String, String> SINGLE_QUOTER = s -> "'" + s + "'";
public static final java.util.function.Function<String, String> SINGLE_QUOTER = s -> "'" + s + "'";
@Contract(pure = true)
public static @NotNull List<String> getWordsInStringLongestFirst(@NotNull String find) {
@@ -133,7 +132,7 @@ public class StringUtil extends StringUtilRt {
return Object::toString;
}
public static final @NotNull Function<String, String> TRIMMER = StringUtil::trim;
public static final @NotNull java.util.function.Function<String, String> TRIMMER = StringUtil::trim;
// Unlike String.replace(CharSequence,CharSequence) does not allocate intermediate objects on non-match
// TODO revise when JDK9 arrives - its String.replace(CharSequence, CharSequence) is more optimized
@@ -1211,7 +1210,7 @@ public class StringUtil extends StringUtilRt {
}
/**
* @return list containing all words in {@code text}, or {@link ContainerUtil#emptyList()} if there are none.
* @return list containing all words in {@code text}, or {@link Collections#emptyList()} if there are none.
* The <b>word</b> here means the maximum sub-string consisting entirely of characters which are {@code Character.isJavaIdentifierPart(c)}.
*/
@Contract(pure = true)
@@ -1239,7 +1238,7 @@ public class StringUtil extends StringUtilRt {
}
}
if (result == null) {
return ContainerUtil.emptyList();
return Collections.emptyList();
}
return result;
}
@@ -1369,7 +1368,7 @@ public class StringUtil extends StringUtilRt {
@Contract(pure = true)
public static @NotNull String join(@NotNull Collection<String> strings, @NotNull String separator) {
if (strings.size() <= 1) {
return notNullize(ContainerUtil.getFirstItem(strings));
return notNullize(strings.isEmpty() ? null : strings.iterator().next());
}
StringBuilder result = new StringBuilder();
join(strings, separator, result);
@@ -1468,7 +1467,7 @@ public class StringUtil extends StringUtilRt {
return Formats.formatDuration(duration);
}
/**
/**
* Formats duration given in milliseconds as a sum of time units (example: {@code formatDuration(123456, "") = "2m 3s 456ms"}).
* @deprecated use NlsMessages#formatDurationApproximateNarrow for localized output
*/
@@ -2749,6 +2748,7 @@ public class StringUtil extends StringUtilRt {
@Contract(pure = true)
public static @NotNull String formatLinks(@NotNull String message) {
@SuppressWarnings("HttpUrlsUsage")
Pattern linkPattern = Pattern.compile("http://[a-zA-Z0-9./\\-+]+");
StringBuffer result = new StringBuffer();
Matcher m = linkPattern.matcher(message);
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.openapi.util.Iconable;
@@ -11,20 +11,20 @@ import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
import java.awt.*;
import java.util.Iterator;
import java.util.ServiceLoader;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
public interface IconManager {
@NotNull
static IconManager getInstance() {
static @NotNull IconManager getInstance() {
return IconManagerHelper.instance;
}
// Icon Loader is quite heavy, better to not instantiate class unless required
static void activate() {
IconManagerHelper.activate();
static void activate(@Nullable IconManager impl) throws Throwable {
IconManagerHelper.activate(impl);
}
@TestOnly
@@ -52,39 +52,31 @@ public interface IconManager {
return loadRasterizedIcon(path.startsWith("/") ? path.substring(1) : path, aClass.getClassLoader(), cacheKey, flags);
}
@NotNull
default Icon createEmptyIcon(@NotNull Icon icon) {
default @NotNull Icon createEmptyIcon(@NotNull Icon icon) {
return icon;
}
@NotNull
default Icon createOffsetIcon(@NotNull Icon icon) {
default @NotNull Icon createOffsetIcon(@NotNull Icon icon) {
return icon;
}
@NotNull
Icon createLayered(Icon @NotNull ... icons);
@NotNull Icon createLayered(Icon @NotNull ... icons);
@NotNull
default Icon colorize(Graphics2D g, @NotNull Icon source, @NotNull Color color) {
default @NotNull Icon colorize(Graphics2D g, @NotNull Icon source, @NotNull Color color) {
return source;
}
@NotNull <T> Icon createDeferredIcon(@Nullable Icon base, T param, @NotNull Function<? super T, ? extends Icon> f);
@NotNull <T> Icon createDeferredIcon(@Nullable Icon base, T param, @NotNull Function<? super T, ? extends Icon> iconProducer);
@NotNull
RowIcon createLayeredIcon(@NotNull Iconable instance, Icon icon, int flags);
@NotNull RowIcon createLayeredIcon(@NotNull Iconable instance, Icon icon, int flags);
@NotNull
default RowIcon createRowIcon(int iconCount) {
default @NotNull RowIcon createRowIcon(int iconCount) {
return createRowIcon(iconCount, RowIcon.Alignment.TOP);
}
@NotNull
RowIcon createRowIcon(int iconCount, RowIcon.Alignment alignment);
@NotNull RowIcon createRowIcon(int iconCount, RowIcon.Alignment alignment);
@NotNull
RowIcon createRowIcon(Icon @NotNull ... icons);
@NotNull RowIcon createRowIcon(Icon @NotNull ... icons);
void registerIconLayer(int flagMask, @NotNull Icon icon);
@@ -95,14 +87,17 @@ final class IconManagerHelper {
private static final AtomicBoolean isActivated = new AtomicBoolean();
static volatile IconManager instance = DummyIconManager.INSTANCE;
static void activate() {
static void activate(@Nullable IconManager impl) throws Throwable {
if (!isActivated.compareAndSet(false, true)) {
return;
}
Iterator<IconManager> iterator = ServiceLoader.load(IconManager.class, IconManager.class.getClassLoader()).iterator();
if (iterator.hasNext()) {
instance = iterator.next();
if (impl == null) {
Class<?> implClass = IconManagerHelper.class.getClassLoader().loadClass("com.intellij.ui.CoreIconManager");
instance = (IconManager)MethodHandles.lookup().findConstructor(implClass, MethodType.methodType(void.class)).invoke();
}
else {
instance = impl;
}
}
@@ -124,21 +119,21 @@ final class DummyIconManager implements IconManager {
return DummyIcon.INSTANCE;
}
@NotNull
@Override
public Icon getIcon(@NotNull String path, @NotNull Class<?> aClass) {
return DummyIcon.INSTANCE;
public @NotNull Icon getIcon(@NotNull String path, @NotNull Class<?> aClass) {
return new DummyIcon(path);
}
@Override
public @NotNull Icon loadRasterizedIcon(@NotNull String path, @NotNull ClassLoader classLoader, long cacheKey, int flags) {
return DummyIcon.INSTANCE;
return new DummyIcon(path);
}
@NotNull
@Override
public RowIcon createLayeredIcon(@NotNull Iconable instance, Icon icon, int flags) {
return new DummyRowIcon();
public @NotNull RowIcon createLayeredIcon(@NotNull Iconable instance, Icon icon, int flags) {
Icon[] icons = new Icon[2];
icons[0] = icon;
return new DummyRowIcon(icons);
}
@Override
@@ -147,34 +142,36 @@ final class DummyIconManager implements IconManager {
@Override
public @NotNull Icon tooltipOnlyIfComposite(@NotNull Icon icon) {
return new DummyIcon();
return icon;
}
@Override
public @NotNull <T> Icon createDeferredIcon(@Nullable Icon base, T param, @NotNull Function<? super T, ? extends Icon> f) {
public @NotNull <T> Icon createDeferredIcon(@Nullable Icon base, T param, @NotNull Function<? super T, ? extends Icon> iconProducer) {
return base;
}
@NotNull
@Override
public RowIcon createRowIcon(int iconCount, RowIcon.Alignment alignment) {
public @NotNull RowIcon createRowIcon(int iconCount, RowIcon.Alignment alignment) {
return new DummyRowIcon(iconCount);
}
@NotNull
@Override
public Icon createLayered(Icon @NotNull ... icons) {
public @NotNull Icon createLayered(Icon @NotNull ... icons) {
return new DummyRowIcon(icons);
}
@NotNull
@Override
public RowIcon createRowIcon(Icon @NotNull ... icons) {
public @NotNull RowIcon createRowIcon(Icon @NotNull ... icons) {
return new DummyRowIcon(icons);
}
private static class DummyIcon implements Icon {
static final DummyIcon INSTANCE = new DummyIcon();
static final DummyIcon INSTANCE = new DummyIcon("<DummyIcon>");
private final String path;
private DummyIcon(@NotNull String path) {
this.path = path;
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
@@ -192,29 +189,33 @@ final class DummyIconManager implements IconManager {
@Override
public int hashCode() {
return 0;
return path.hashCode();
}
@Override
public boolean equals(Object obj) {
return obj instanceof DummyIcon;
return this == obj || (obj instanceof DummyIcon && ((DummyIcon)obj).path == path);
}
@Override
public String toString() {
return path;
}
}
private static class DummyRowIcon extends DummyIcon implements RowIcon {
private static final class DummyRowIcon extends DummyIcon implements RowIcon {
private Icon[] icons;
DummyRowIcon(int iconCount) {
super("<DummyRowIcon>");
icons = new Icon[iconCount];
}
DummyRowIcon(Icon[] icons) {
super("<DummyRowIcon>");
this.icons = icons;
}
DummyRowIcon() {
}
@Override
public int getIconCount() {
return icons == null ? 0 : icons.length;
@@ -233,9 +234,8 @@ final class DummyIconManager implements IconManager {
icons[i] = icon;
}
@NotNull
@Override
public Icon getDarkIcon(boolean isDark) {
public @NotNull Icon getDarkIcon(boolean isDark) {
return this;
}
@@ -243,5 +243,23 @@ final class DummyIconManager implements IconManager {
public Icon @NotNull [] getAllIcons() {
return icons == null ? new Icon[0] : ContainerUtil.packNullables(icons).toArray(new Icon[0]);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
return o instanceof DummyRowIcon && Arrays.equals(icons, ((DummyRowIcon)o).icons);
}
@Override
public int hashCode() {
return icons.length > 0 ? icons[0].hashCode() : 0;
}
@Override
public String toString() {
return "Row icon. myIcons=" + Arrays.asList(icons);
}
}
}
@@ -39,16 +39,6 @@ public final class ContainerUtil {
return new HashMap<>();
}
/**
* @deprecated Use {@link HashMap#HashMap(Map)}
*/
@Contract(pure = true)
@ApiStatus.ScheduledForRemoval(inVersion = "2021.2")
@Deprecated
public static @NotNull <K, V> HashMap<K, V> newHashMap(@NotNull Map<? extends K, ? extends V> map) {
return new HashMap<>(map);
}
@SafeVarargs
@Contract(pure = true)
public static @NotNull <K, V> Map<K, V> newHashMap(@NotNull Pair<? extends K, ? extends V> first, Pair<? extends K,? extends V> @NotNull ... entries) {
@@ -93,16 +83,6 @@ public final class ContainerUtil {
return map;
}
/**
* @deprecated Use {@link THashMap#THashMap(Map)}
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2021.1")
@Contract(pure = true)
public static @NotNull <K, V> THashMap<K, V> newTroveMap() {
return new THashMap<>();
}
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2021.1")
public static @NotNull <T> TObjectHashingStrategy<T> canonicalStrategy() {
@@ -117,15 +97,6 @@ public final class ContainerUtil {
return TObjectHashingStrategy.IDENTITY;
}
/**
* @deprecated Use {@link IdentityHashMap#IdentityHashMap()}
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2021.2")
public static @NotNull <K, V> IdentityHashMap<K, V> newIdentityHashMap() {
return new IdentityHashMap<>();
}
/**
* @deprecated Use {@link LinkedList#LinkedList()}
*/
@@ -2384,7 +2355,7 @@ public final class ContainerUtil {
}
return true;
}
@Contract(pure = true)
public static <T> boolean isSameElements(@NotNull Collection<? extends T> list1, @NotNull Collection<? extends T> list2) {
return list1.size() == list2.size() && list1.containsAll(list2);
@@ -53,10 +53,10 @@ public final class IconLoader {
private static final Logger LOG = Logger.getInstance(IconLoader.class);
// the key: URL or Pair(path, classLoader)
private static final ConcurrentMap<Object, CachedImageIcon> iconCache = new ConcurrentHashMap<>(100, 0.9f, 2);
private static final ConcurrentMap<@NotNull Object, @NotNull CachedImageIcon> iconCache = new ConcurrentHashMap<>(100, 0.9f, 2);
// contains mapping between icons and disabled icons.
private static final Cache<Icon, Icon> iconToDisabledIcon = Caffeine.newBuilder().weakKeys().build();
private static final Cache<@NotNull Icon, @NotNull Icon> iconToDisabledIcon = Caffeine.newBuilder().weakKeys().build();
private static volatile boolean STRICT_GLOBAL;
@@ -86,9 +86,9 @@ public final class IconLoader {
}
};
private static boolean ourIsActivated;
private static boolean isActivated = !GraphicsEnvironment.isHeadless();
private IconLoader() { }
private IconLoader() {}
public static <T> T performStrictly(@NotNull Supplier<? extends T> computable) {
STRICT_LOCAL.set(true);
@@ -116,8 +116,9 @@ public final class IconLoader {
if (prev != next) {
iconToDisabledIcon.invalidateAll();
//clears svg cache
// clear svg cache
ImageLoader.ImageCache.INSTANCE.clearCache();
// iconCache is not cleared because it contain original icon (instance that will delegate to)
}
}
@@ -147,10 +148,18 @@ public final class IconLoader {
}
public static void clearCache() {
// Copy the transform to trigger update of cached icons
// copy the transform to trigger update of cached icons
updateTransform(IconTransform::copy);
}
@TestOnly
public static void clearCacheInTests() {
iconCache.clear();
iconToDisabledIcon.invalidateAll();
ImageLoader.ImageCache.INSTANCE.clearCache();
pathTransformGlobalModCount.incrementAndGet();
}
/**
* @deprecated Use {@link #getIcon(String, Class)}
*/
@@ -290,12 +299,12 @@ public final class IconLoader {
}
public static void activate() {
ourIsActivated = true;
isActivated = true;
}
@TestOnly
public static void deactivate() {
ourIsActivated = false;
isActivated = false;
}
@Nullable
@@ -518,7 +527,7 @@ public final class IconLoader {
* Same as {@link #getDisabledIcon(Icon)} with an ancestor component for HiDPI-awareness.
*/
public static @NotNull Icon getDisabledIcon(@NotNull Icon icon, @Nullable Component ancestor) {
if (!ourIsActivated) {
if (!isActivated) {
return icon;
}
@@ -778,7 +787,7 @@ public final class IconLoader {
private @NotNull ImageIcon getRealIcon(@Nullable ScaleContext context) {
ImageDataLoader resolver = this.resolver;
if (resolver == null || !ourIsActivated) {
if (resolver == null || !isActivated) {
return EMPTY_ICON;
}
@@ -1389,7 +1398,7 @@ public final class IconLoader {
return null;
}
private static class LabelHolder {
private static final class LabelHolder {
/**
* To get disabled icon with paint it into the image. Some icons require
* not null component to paint.
@@ -43,9 +43,6 @@
<applicationService serviceInterface="com.intellij.stats.completion.tracker.InstallationIdProvider"
serviceImplementation="com.intellij.stats.completion.tracker.PermanentInstallationIdProvider"/>
<registryKey key="completion.stats.send.logs" defaultValue="true"
description="Send anonymous logs about completion usage in EAP builds"/>
<registryKey key="completion.stats.analytics.platform.send" defaultValue="true"
description="Send completion logs to Analytics Platform"/>
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.stats.completion.sender
import com.intellij.internal.statistic.utils.StatisticsUploadAssistant
@@ -9,7 +9,6 @@ import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.util.registry.Registry
import com.intellij.stats.completion.network.status.WebServiceStatusManager
import com.intellij.util.Alarm
import com.intellij.util.Time
@@ -20,7 +19,7 @@ private fun isSendAllowed(): Boolean {
}
internal fun isCompletionLogsSendAllowed(): Boolean {
return ApplicationManager.getApplication().isEAP && Registry.`is`("completion.stats.send.logs")
return ApplicationManager.getApplication().isEAP && java.lang.Boolean.parseBoolean(System.getProperty("completion.stats.send.logs", "true"))
}
private val LOG = logger<SenderPreloadingActivity>()
@@ -1,11 +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.
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.jetbrains.python;
import com.intellij.application.options.RegistryManager;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiManager;
import com.intellij.util.PlatformIcons;
import com.intellij.ui.IconTestUtil;
import com.intellij.util.PsiIconUtil;
import com.jetbrains.python.fixtures.PyTestCase;
import com.jetbrains.python.namespacePackages.PyNamespacePackagesService;
@@ -16,7 +17,6 @@ import java.util.Collections;
import java.util.List;
public class PyPackageIconTest extends PyTestCase {
@Override
public void setUp() throws Exception {
super.setUp();
@@ -114,12 +114,12 @@ public class PyPackageIconTest extends PyTestCase {
}
private void checkPackageIcon(@NotNull String path, boolean has) {
final VirtualFile found = myFixture.findFileInTempDir(path);
VirtualFile found = myFixture.findFileInTempDir(path);
assertNotNull(found);
final PsiDirectory dir = PsiManager.getInstance(myFixture.getProject()).findDirectory(found);
PsiDirectory dir = PsiManager.getInstance(myFixture.getProject()).findDirectory(found);
assertNotNull(dir);
final Icon icon = PsiIconUtil.getProvidersIcon(dir, 0);
assertEquals(PlatformIcons.PACKAGE_ICON.equals(icon), has);
Icon icon = PsiIconUtil.getProvidersIcon(dir, 0);
assertEquals(AllIcons.Nodes.Package.equals(IconTestUtil.unwrapIcon(icon)), has);
}
private void toggleNamespacePackageDirectory(@NotNull String directory) {
@@ -13,9 +13,7 @@
serviceImplementation="com.intellij.spellchecker.ui.SpellCheckingEditorCustomizationProviderImpl"
overrides="true"/>
<fileType name="Dictionary" implementationClass="com.intellij.spellchecker.DictionaryFileType" extensions="dic"/>
<projectService serviceImplementation="com.intellij.spellchecker.settings.SpellCheckerSettings"/>
<postStartupActivity implementation="com.intellij.spellchecker.settings.SettingsTransferActivity"/>
<projectService serviceImplementation="com.intellij.spellchecker.SpellCheckerManager"/>
<projectConfigurable parentId="proofread" instance="com.intellij.spellchecker.settings.SpellCheckerSettingsManager" id="reference.settings.ide.settings.spelling" key="spelling" bundle="messages.SpellCheckerBundle" />
<localInspection shortName="SpellCheckingInspection" bundle="messages.SpellCheckerBundle"
@@ -24,14 +22,13 @@
<nameSuggestionProvider id="DictionarySuggestionProvider" implementation="com.intellij.spellchecker.quickfixes.DictionarySuggestionProvider" order="first"/>
<severitiesProvider implementation="com.intellij.spellchecker.SpellCheckerSeveritiesProvider"/>
<spellchecker.support language="TEXT" implementationClass="com.intellij.spellchecker.tokenizer.SpellcheckingStrategy"/>
<spellchecker.bundledDictionaryProvider implementation="com.intellij.spellchecker.DefaultBundledDictionariesProvider"/>
<registryKey key="spellchecker.corrections.limit" defaultValue="3" description="Spellchecker corrections limit" restartRequired="false"/>
<projectService serviceImplementation="com.intellij.spellchecker.state.ProjectDictionaryState"/>
<applicationService serviceImplementation="com.intellij.spellchecker.state.CachedDictionaryState"/>
<statistics.projectUsagesCollector implementation="com.intellij.spellchecker.statistics.SpellcheckerConfigCollector"/>
<lookup.usageDetails implementation="com.intellij.spellchecker.statistics.SpellcheckerLookupUsageDescriptor"/>
<statistics.counterUsagesCollector groupId="spellchecker.events" version="1"/>
@@ -9,6 +9,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.command.undo.BasicUndoableAction;
import com.intellij.openapi.command.undo.UndoManager;
import com.intellij.openapi.components.Service;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
@@ -47,7 +48,8 @@ import static com.intellij.openapi.util.io.FileUtilRt.toSystemDependentName;
import static com.intellij.openapi.vfs.VfsUtilCore.visitChildrenRecursively;
import static com.intellij.project.ProjectKt.getProjectStoreDirectory;
public class SpellCheckerManager implements Disposable {
@Service(Service.Level.PROJECT)
public final class SpellCheckerManager implements Disposable {
private static final Logger LOG = Logger.getInstance(SpellCheckerManager.class);
private static final int MAX_METRICS = 1;
@@ -70,7 +72,6 @@ public class SpellCheckerManager implements Disposable {
private SpellCheckerEngine mySpellChecker;
private SuggestionProvider mySuggestionProvider;
public static SpellCheckerManager getInstance(Project project) {
return project.getService(SpellCheckerManager.class);
}
@@ -412,10 +413,12 @@ public class SpellCheckerManager implements Disposable {
}
}
private class CustomDictFileListener implements VirtualFileListener {
private final class CustomDictFileListener implements VirtualFileListener {
private final SpellCheckerSettings mySettings;
CustomDictFileListener(@NotNull SpellCheckerSettings settings) {mySettings = settings;}
CustomDictFileListener(@NotNull SpellCheckerSettings settings) {
mySettings = settings;
}
@Override
public void fileDeleted(@NotNull VirtualFileEvent event) {
@@ -9,18 +9,19 @@ import org.jetbrains.annotations.NotNull;
import static com.intellij.spellchecker.SpellCheckerManager.DictionaryLevel.APP;
import static com.intellij.spellchecker.SpellCheckerManager.DictionaryLevel.PROJECT;
public class SettingsTransferActivity implements StartupActivity {
final class SettingsTransferActivity implements StartupActivity.DumbAware {
@Override
public void runActivity(@NotNull Project project) {
final SpellCheckerSettings settings = SpellCheckerSettings.getInstance(project);
if (!settings.isSettingsTransferred()) {
if (settings.isUseSingleDictionaryToSave() &&
PROJECT.getName().equals(settings.getDictionaryToSave()) &&
project.getService(ProjectDictionaryState.class).getProjectDictionary().getWords().isEmpty()) {
settings.setDictionaryToSave(APP.getName());
}
settings.setSettingsTransferred(true);
SpellCheckerSettings settings = SpellCheckerSettings.getInstance(project);
if (settings.isSettingsTransferred()) {
return;
}
if (settings.isUseSingleDictionaryToSave() &&
PROJECT.getName().equals(settings.getDictionaryToSave()) &&
project.getService(ProjectDictionaryState.class).getProjectDictionary().getWords().isEmpty()) {
settings.setDictionaryToSave(APP.getName());
}
settings.setSettingsTransferred(true);
}
}
@@ -1,10 +1,7 @@
// Copyright 2000-2021 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.spellchecker.settings;
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.components.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.spellchecker.SpellCheckerManager;
@@ -20,7 +17,8 @@ import static com.intellij.openapi.util.text.StringUtil.notNullize;
import static com.intellij.openapi.util.text.StringUtil.parseInt;
@State(name = "SpellCheckerSettings", storages = @Storage(StoragePathMacros.WORKSPACE_FILE))
public class SpellCheckerSettings implements PersistentStateComponent<Element> {
@Service(Service.Level.PROJECT)
public final class SpellCheckerSettings implements PersistentStateComponent<Element> {
// For xml serialization
private static final String SPELLCHECKER_MANAGER_SETTINGS_TAG = "SpellCheckerSettings";
@@ -46,7 +44,7 @@ public class SpellCheckerSettings implements PersistentStateComponent<Element> {
private Set<String> myRuntimeDisabledDictionariesNames = new HashSet<>();
private String myDictionaryToSave = DEFAULT_DICTIONARY_TO_SAVE;
private boolean myUseSingleDictionaryToSave = DEFAULT_USE_SINGLE_DICT;
private boolean mySettingsTransferred = false;
private boolean mySettingsTransferred;
@NlsSafe
public String getDictionaryToSave() {
@@ -1,8 +1,7 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 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.spellchecker.state;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.*;
import com.intellij.serviceContainer.NonInjectable;
@@ -16,7 +15,8 @@ import org.jetbrains.annotations.NotNull;
storages = @Storage(value = "cachedDictionary.xml", roamingType = RoamingType.DISABLED),
reportStatistic = false
)
public class CachedDictionaryState extends DictionaryState implements PersistentStateComponent<DictionaryState> {
@Service(Service.Level.APP)
public final class CachedDictionaryState extends DictionaryState implements PersistentStateComponent<DictionaryState> {
public static final String DEFAULT_NAME = "cached";
private final EventDispatcher<DictionaryStateListener> myDictListenerEventDispatcher =
EventDispatcher.create(DictionaryStateListener.class);
@@ -1,24 +1,10 @@
/*
* 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-2021 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.xml.ui;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.NlsContexts;
import com.intellij.util.PlatformIcons;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -36,7 +22,7 @@ public class BigStringComponent extends TextFieldWithBrowseButton {
public BigStringComponent(boolean hasBorder, @NlsContexts.DialogTitle String windowTitle) {
super();
myWindowTitle = windowTitle;
setButtonIcon(PlatformIcons.OPEN_EDIT_DIALOG_ICON);
setButtonIcon(AllIcons.Actions.ShowViewer);
addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {