mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
more async start-up, do not activate icon loader explicitly
GitOrigin-RevId: dc43aca428d16c3a1b41b439a5f2f3be91a88743
This commit is contained in:
committed by
intellij-monorepo-bot
parent
32b9d6a38c
commit
a2ef29db78
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+52
-46
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+3
-2
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+17
-13
@@ -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;
|
||||
}
|
||||
|
||||
+2
-16
@@ -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);
|
||||
}
|
||||
|
||||
+2
-1
@@ -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);
|
||||
}
|
||||
|
||||
+5
-4
@@ -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()
|
||||
}
|
||||
+20
-21
@@ -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
-3
@@ -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.
|
||||
|
||||
+21
-9
@@ -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 == '<' ? "<" : ">");
|
||||
}
|
||||
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"/>
|
||||
|
||||
|
||||
+2
-3
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user