reduce classloading

GitOrigin-RevId: c479437368496c31b0b9a2d7fca2bf2e2dba34b1
This commit is contained in:
Vladimir Krivosheev
2021-04-05 09:30:17 +00:00
committed by intellij-monorepo-bot
parent 2287719686
commit 3946308293
23 changed files with 227 additions and 251 deletions
@@ -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.openapi.components;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.xmlb.annotations.MapAnnotation;
import com.intellij.util.xmlb.annotations.Property;
import org.jetbrains.annotations.Nullable;
@@ -46,10 +45,12 @@ public class ComponentConfig {
*/
public boolean prepareClasses(boolean headless) {
if (headless && headlessImplementationClass != null) {
if (StringUtil.isEmpty(headlessImplementationClass)) return false;
if (headlessImplementationClass.isEmpty()) {
return false;
}
setImplementationClass(headlessImplementationClass);
}
if (StringUtil.isEmpty(interfaceClass)) {
if (interfaceClass == null || interfaceClass.isEmpty()) {
setInterfaceClass(implementationClass);
}
return true;
@@ -64,8 +65,7 @@ public class ComponentConfig {
}
public void setHeadlessImplementationClass(String headlessImplementationClass) {
headlessImplementationClass = headlessImplementationClass == null ? null : headlessImplementationClass.trim();
this.headlessImplementationClass = headlessImplementationClass == null ? null : StringUtil.isEmpty(headlessImplementationClass) ? "" : headlessImplementationClass;
this.headlessImplementationClass = headlessImplementationClass == null ? null : headlessImplementationClass.trim();
}
public void setLoadForDefaultProject(boolean loadForDefaultProject) {
@@ -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.components;
import com.intellij.openapi.application.ApplicationManager;
@@ -50,11 +50,10 @@ public final class ServiceDescriptor {
public PreloadMode preload = ServiceDescriptor.PreloadMode.FALSE;
public String getInterface() {
return serviceInterface != null ? serviceInterface : getImplementation();
return serviceInterface == null ? getImplementation() : serviceInterface;
}
@Nullable
public String getImplementation() {
public @Nullable String getImplementation() {
if (testServiceImplementation != null && ApplicationManager.getApplication().isUnitTestMode()) {
return testServiceImplementation;
}
@@ -7,13 +7,15 @@ import com.intellij.openapi.util.SafeJdomFactory
import org.jdom.Element
import java.io.IOException
import java.nio.file.Path
import java.util.*
import java.util.zip.ZipFile
@Suppress("ReplaceNegatedIsEmptyWithIsNotEmpty")
class PluginXmlPathResolver(private val pluginJarFiles: List<Path>) : PathResolver {
companion object {
@JvmField
val DEFAULT_PATH_RESOLVER: PathResolver = PluginXmlPathResolver(emptyList())
// don't use Kotlin emptyList here
val DEFAULT_PATH_RESOLVER: PathResolver = PluginXmlPathResolver(Collections.emptyList())
@JvmStatic
private fun loadUsingZipFile(jarFile: Path, relativePath: String, jdomFactory: SafeJdomFactory): Element? {
@@ -1,13 +1,12 @@
// 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.extensions;
import com.intellij.util.containers.CollectionFactory;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
@@ -17,7 +16,7 @@ import java.util.Map;
public final class PluginId implements Comparable<PluginId> {
public static final PluginId[] EMPTY_ARRAY = new PluginId[0];
private static final Map<String, PluginId> ourRegisteredIds = CollectionFactory.createSmallMemoryFootprintMap();
private static final Map<String, PluginId> ourRegisteredIds = new HashMap<>();
public static synchronized @NotNull PluginId getId(@NotNull String idString) {
return ourRegisteredIds.computeIfAbsent(idString, PluginId::new);
@@ -33,13 +32,6 @@ public final class PluginId implements Comparable<PluginId> {
return null;
}
/** @deprecated Use {@link #getRegisteredIdList} */
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2021.3")
public static synchronized @NotNull Map<String, PluginId> getRegisteredIds() {
return CollectionFactory.createSmallMemoryFootprintMap(ourRegisteredIds);
}
public static synchronized @NotNull Collection<PluginId> getRegisteredIdList() {
return new ArrayList<>(ourRegisteredIds.values());
}
@@ -2,9 +2,10 @@
package com.intellij.ide;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.Strings;
import com.intellij.util.text.StringTokenizer;
import java.util.Locale;
import java.util.Objects;
import java.util.StringTokenizer;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
@@ -93,17 +94,18 @@ public final class Prefs {
}
private static String getNodeKey(String key) {
final int dotIndex = key.lastIndexOf('.');
return Strings.toLowerCase((dotIndex >= 0 ? key.substring(dotIndex + 1) : key));
int dotIndex = key.lastIndexOf('.');
return (dotIndex >= 0 ? key.substring(dotIndex + 1) : key).toLowerCase(Locale.ENGLISH);
}
private static Preferences getPreferences(String key) {
Preferences prefs = Preferences.userRoot();
final int dotIndex = key.lastIndexOf('.');
if (dotIndex > 0) {
final StringTokenizer tokenizer = new StringTokenizer(key.substring(0, dotIndex), ".", false);
StringTokenizer tokenizer = new StringTokenizer(key.substring(0, dotIndex), ".", false);
while (tokenizer.hasMoreElements()) {
prefs = prefs.node(Strings.toLowerCase(tokenizer.nextElement()));
String str = tokenizer.nextToken();
prefs = prefs.node(str == null ? null : str.toLowerCase(Locale.ENGLISH));
}
}
return prefs;
@@ -121,10 +123,10 @@ public final class Prefs {
// rewrite from old location into the new one
final Preferences prefs = Preferences.userRoot();
final T val = getter.get(prefs, key, def);
if (!Comparing.equal(val, def)) {
// first use Objects.equals to avoid loading Comparing class
if (!Objects.equals(val, def) && !Comparing.equal(val, def)) {
setter.set(getPreferences(key), getNodeKey(key), val);
prefs.remove(key);
}
}
}
@@ -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.ide.gdpr
import com.intellij.idea.Main
@@ -12,7 +12,6 @@ import com.intellij.ui.AppUIUtil
import java.util.*
object Agreements {
private val bundle
get() = ResourceBundle.getBundle("messages.AgreementsBundle")
@@ -76,7 +75,7 @@ object Agreements {
}
private fun AgreementUi.applyDataSharing(): AgreementUi {
val dataSharingConsent = ConsentOptions.getInstance().consents.first[0]
val dataSharingConsent = ConsentOptions.getInstance().consents.key[0]
this.setText(prepareConsentsHtmlText(dataSharingConsent))
.setTitle(bundle.getString("dataSharing.dialog.title"))
.clearBottomPanel()
@@ -10,9 +10,6 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtilRt;
import com.intellij.openapi.vfs.CharsetToolkit;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -57,7 +54,16 @@ public final class ConsentOptions {
@Override
public @NotNull String readBundledConsents() {
return loadText(ConsentOptions.class.getClassLoader().getResourceAsStream(BUNDLED_CONSENTS_PATH));
InputStream stream = ConsentOptions.class.getClassLoader().getResourceAsStream(BUNDLED_CONSENTS_PATH);
if (stream != null) {
try (InputStream inputStream = stream) {
return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
}
catch (IOException e) {
LOG.info(e);
}
}
return "";
}
@Override
@@ -70,18 +76,6 @@ public final class ConsentOptions {
public @NotNull String readConfirmedConsents() throws IOException {
return Files.readString(CONFIRMED_CONSENTS_FILE);
}
private @NotNull String loadText(InputStream stream) {
if (stream != null) {
try (InputStream inputStream = CharsetToolkit.inputStreamSkippingBOM(stream)) {
return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
}
catch (IOException e) {
LOG.info(e);
}
}
return "";
}
}, appInfo.isEAP() && appInfo.isVendorJetBrains());
}
@@ -140,19 +134,19 @@ public final class ConsentOptions {
public @Nullable String getConfirmedConsentsString() {
final Map<String, Consent> defaults = loadDefaultConsents();
if (!defaults.isEmpty()) {
final String str = confirmedConsentToExternalString(
String str = confirmedConsentToExternalString(
loadConfirmedConsents().values().stream().filter(c -> {
final Consent def = defaults.get(c.getId());
return def != null && !def.isDeleted();
})
);
return StringUtilRt.isEmptyOrSpaces(str)? null : str;
return str.isBlank() ? null : str;
}
return null;
}
public void applyServerUpdates(@Nullable String json) {
if (StringUtilRt.isEmptyOrSpaces(json)) {
if (json == null || json.isBlank()) {
return;
}
@@ -174,14 +168,14 @@ public final class ConsentOptions {
}
}
public @NotNull Pair<List<Consent>, Boolean> getConsents() {
public @NotNull Map.Entry<List<Consent>, Boolean> getConsents() {
final Map<String, Consent> allDefaults = loadDefaultConsents();
if (myIsEAP) {
// for EA builds there is a different option for statistics sending management
allDefaults.remove(STATISTICS_OPTION_ID);
}
if (allDefaults.isEmpty()) {
return new Pair<>(Collections.emptyList(), Boolean.FALSE);
return new AbstractMap.SimpleImmutableEntry<>(Collections.emptyList(), Boolean.FALSE);
}
final Map<String, ConfirmedConsent> allConfirmed = loadConfirmedConsents();
final List<Consent> result = new ArrayList<>();
@@ -194,7 +188,7 @@ public final class ConsentOptions {
}
result.sort(Comparator.comparing(ConsentBase::getId));
boolean confirmationEnabled = Boolean.parseBoolean(System.getProperty(CONSENTS_CONFIRMATION_PROPERTY, "true"));
return new Pair<>(result, confirmationEnabled && needReconfirm(allDefaults, allConfirmed));
return new AbstractMap.SimpleImmutableEntry<>(result, confirmationEnabled && needReconfirm(allDefaults, allConfirmed));
}
public void setConsents(@NotNull Collection<Consent> confirmedByUser) {
@@ -285,7 +279,7 @@ public final class ConsentOptions {
}
private static @NotNull Collection<ConsentAttributes> fromJson(@Nullable String json) {
if (StringUtilRt.isEmptyOrSpaces(json)) {
if (json == null || json.isBlank()) {
return Collections.emptyList();
}
@@ -878,7 +878,7 @@ public final class StartupUtil {
runInEdtAndWait(log, () -> Agreements.INSTANCE.showEndUserAndDataSharingAgreements(agreement), initUiTask);
dialogWasShown = true;
}
else if (ConsentOptions.getInstance().getConsents().second) {
else if (ConsentOptions.getInstance().getConsents().getValue()) {
runInEdtAndWait(log, Agreements.INSTANCE::showDataSharingAgreement, initUiTask);
}
return dialogWasShown;
@@ -1,32 +1,18 @@
/*
* 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.actionSystem.impl;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.WeakList;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Map;
import java.util.WeakHashMap;
public class PresentationFactory {
private final Map<AnAction, Presentation> myAction2Presentation = ContainerUtil.createWeakMap();
private final Map<AnAction, Presentation> actionToPresentation = new WeakHashMap<>();
private boolean myNeedRebuild;
private static final Collection<PresentationFactory> ourAllFactories = new WeakList<>();
@@ -35,15 +21,14 @@ public class PresentationFactory {
ourAllFactories.add(this);
}
@NotNull
public final Presentation getPresentation(@NotNull AnAction action) {
public final @NotNull Presentation getPresentation(@NotNull AnAction action) {
ApplicationManager.getApplication().assertIsDispatchThread();
Presentation presentation = myAction2Presentation.get(action);
Presentation presentation = actionToPresentation.get(action);
if (presentation == null || !action.isDefaultIcon()) {
Presentation templatePresentation = action.getTemplatePresentation();
if (presentation == null) {
presentation = templatePresentation.clone();
myAction2Presentation.put(action, presentation);
actionToPresentation.put(action, presentation);
}
if (!action.isDefaultIcon()) {
presentation.setIcon(templatePresentation.getIcon());
@@ -59,7 +44,7 @@ public class PresentationFactory {
public void reset() {
ApplicationManager.getApplication().assertIsDispatchThread();
myAction2Presentation.clear();
actionToPresentation.clear();
myNeedRebuild = true;
}
@@ -1,13 +1,13 @@
// 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.remote;
import com.intellij.execution.CommandLineUtil;
import com.intellij.execution.process.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.util.concurrency.AppExecutorUtil;
import com.intellij.util.io.BaseOutputReader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -112,7 +112,7 @@ public class BaseRemoteProcessHandler<T extends RemoteProcess> extends BaseProce
@NotNull
@Override
public Future<?> executeTask(@NotNull Runnable task) {
return ApplicationManager.getApplication().executeOnPooledThread(task);
return AppExecutorUtil.getAppExecutorService().submit(task);
}
private abstract static class RemoteOutputReader extends BaseOutputReader {
@@ -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.ide.IdeBundle;
@@ -8,7 +8,10 @@ import com.intellij.ide.gdpr.ConsentSettingsUi;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.*;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
@@ -40,6 +43,7 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
public final class AppUIUtil {
@@ -310,14 +314,14 @@ public final class AppUIUtil {
}
public static boolean needToShowConsentsAgreement() {
return ConsentOptions.getInstance().getConsents().second;
return ConsentOptions.getInstance().getConsents().getValue();
}
public static boolean showConsentsAgreementIfNeeded(@NotNull Executor edtExecutor) {
final Pair<List<Consent>, Boolean> consentsToShow = ConsentOptions.getInstance().getConsents();
final Map.Entry<List<Consent>, Boolean> consentsToShow = ConsentOptions.getInstance().getConsents();
final Ref<Boolean> result = new Ref<>(Boolean.FALSE);
if (consentsToShow.second) {
edtExecutor.execute(() -> result.set(confirmConsentOptions(consentsToShow.first)));
if (consentsToShow.getValue()) {
edtExecutor.execute(() -> result.set(confirmConsentOptions(consentsToShow.getKey())));
}
return result.get();
}
@@ -406,7 +410,7 @@ public final class AppUIUtil {
public static List<Consent> loadConsentsForEditing() {
final ConsentOptions options = ConsentOptions.getInstance();
List<Consent> result = options.getConsents().first;
List<Consent> result = options.getConsents().getKey();
if (options.isEAP()) {
final Consent statConsent = options.getUsageStatsConsent();
if (statConsent != null) {
@@ -8,6 +8,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author Eugene Zhuravlev
@@ -33,24 +34,24 @@ public class ConsentsTest extends TestCase{
final ConsentOptions options = data.first;
final MemoryIOBackend storage = data.second;
final Pair<List<Consent>, Boolean> beforeConfirm = options.getConsents();
assertTrue("Consents should require confirmation", beforeConfirm.second);
assertEquals(2, beforeConfirm.first.size());
final Map.Entry<List<Consent>, Boolean> beforeConfirm = options.getConsents();
assertTrue("Consents should require confirmation", beforeConfirm.getValue());
assertEquals(2, beforeConfirm.getKey().size());
checkStorage(storage, JSON_CONSENTS_DATA, "", "");
final Consent consentBeforeUpgrade = lookupConsent(CONSENT_ID_1, beforeConfirm.first);
final Consent consentBeforeUpgrade = lookupConsent(CONSENT_ID_1, beforeConfirm.getKey());
assertNotNull(consentBeforeUpgrade);
assertEquals(Version.fromString("1.0"), consentBeforeUpgrade.getVersion());
final boolean initialAcceptedState = consentBeforeUpgrade.isAccepted();
// confirm
options.setConsents(beforeConfirm.first);
options.setConsents(beforeConfirm.getKey());
{
final Pair<List<Consent>, Boolean> afterConfirm = options.getConsents();
assertFalse("Consents should NOT require confirmation", afterConfirm.second);
final Consent consentAfterCorfirm = lookupConsent(CONSENT_ID_1, afterConfirm.first);
final Map.Entry<List<Consent>, Boolean> afterConfirm = options.getConsents();
assertFalse("Consents should NOT require confirmation", afterConfirm.getValue());
final Consent consentAfterCorfirm = lookupConsent(CONSENT_ID_1, afterConfirm.getKey());
assertNotNull(consentAfterCorfirm);
assertEquals(Version.fromString("1.0"), consentAfterCorfirm.getVersion());
assertEquals(initialAcceptedState, consentAfterCorfirm.isAccepted());
@@ -61,9 +62,9 @@ public class ConsentsTest extends TestCase{
Thread.sleep(1L);// ensure timestamp changes
options.applyServerUpdates(createUpgradeJson(CONSENT_ID_1, newAcceptedState));
{
final Pair<List<Consent>, Boolean> afterUpgrade = options.getConsents();
assertFalse("Consents should NOT require confirmation", afterUpgrade.second); // no confirmation on minor updates required
final Consent consentAfterUpgrade = lookupConsent(CONSENT_ID_1, afterUpgrade.first);
final Map.Entry<List<Consent>, Boolean> afterUpgrade = options.getConsents();
assertFalse("Consents should NOT require confirmation", afterUpgrade.getValue()); // no confirmation on minor updates required
final Consent consentAfterUpgrade = lookupConsent(CONSENT_ID_1, afterUpgrade.getKey());
assertNotNull(consentAfterUpgrade);
assertEquals(Version.fromString("1.5"), consentAfterUpgrade.getVersion());
assertEquals(newAcceptedState, consentAfterUpgrade.isAccepted());
@@ -75,31 +76,31 @@ public class ConsentsTest extends TestCase{
final ConsentOptions options = data.first;
final MemoryIOBackend storage = data.second;
final Pair<List<Consent>, Boolean> beforeConfirm = options.getConsents();
assertTrue("Consents should require confirmation", beforeConfirm.second);
assertEquals(2, beforeConfirm.first.size());
final Map.Entry<List<Consent>, Boolean> beforeConfirm = options.getConsents();
assertTrue("Consents should require confirmation", beforeConfirm.getValue());
assertEquals(2, beforeConfirm.getKey().size());
checkStorage(storage, JSON_CONSENTS_DATA, "", "");
final Consent consentBeforeUpgrade = lookupConsent(CONSENT_ID_1, beforeConfirm.first);
final Consent consentBeforeUpgrade = lookupConsent(CONSENT_ID_1, beforeConfirm.getKey());
assertNotNull(consentBeforeUpgrade);
assertEquals(Version.fromString("1.0"), consentBeforeUpgrade.getVersion());
options.setConsents(beforeConfirm.first);
final Pair<List<Consent>, Boolean> afterConfirm = options.getConsents();
assertFalse("Consents should NOT require confirmation", afterConfirm.second);
assertEquals(2, afterConfirm.first.size());
options.setConsents(beforeConfirm.getKey());
final Map.Entry<List<Consent>, Boolean> afterConfirm = options.getConsents();
assertFalse("Consents should NOT require confirmation", afterConfirm.getValue());
assertEquals(2, afterConfirm.getKey().size());
assertEquals(JSON_CONSENTS_DATA, storage.myBundled);
assertEquals("", storage.myDefaults);
assertFalse("The storage should contain non-empty confirmed consents", StringUtil.isEmpty(storage.myConfirmed));
options.applyServerUpdates(JSON_MINOR_UPGRADE_CONSENTS_DATA);
final Pair<List<Consent>, Boolean> afterUpdate = options.getConsents();
assertFalse("Consents should NOT require confirmation", afterUpdate.second);
assertEquals(2, afterUpdate.first.size());
final Map.Entry<List<Consent>, Boolean> afterUpdate = options.getConsents();
assertFalse("Consents should NOT require confirmation", afterUpdate.getValue());
assertEquals(2, afterUpdate.getKey().size());
assertEquals(JSON_CONSENTS_DATA, storage.myBundled);
assertFalse("The storage should contain non-empty default consents", StringUtil.isEmpty(storage.myDefaults));
assertFalse("The storage should contain non-empty confirmed consents", StringUtil.isEmpty(storage.myConfirmed));
final Consent consentAfterUpgrade = lookupConsent(CONSENT_ID_1, afterUpdate.first);
final Consent consentAfterUpgrade = lookupConsent(CONSENT_ID_1, afterUpdate.getKey());
assertNotNull(consentAfterUpgrade);
assertEquals(Version.fromString("1.5"), consentAfterUpgrade.getVersion());
}
@@ -110,25 +111,25 @@ public class ConsentsTest extends TestCase{
final MemoryIOBackend storage = data.second;
{
final Pair<List<Consent>, Boolean> beforeConfirm = options.getConsents();
assertTrue("Consents should require confirmation", beforeConfirm.second);
assertEquals(2, beforeConfirm.first.size());
final Map.Entry<List<Consent>, Boolean> beforeConfirm = options.getConsents();
assertTrue("Consents should require confirmation", beforeConfirm.getValue());
assertEquals(2, beforeConfirm.getKey().size());
checkStorage(storage, JSON_CONSENTS_DATA, "", "");
final Consent consentBeforeUpgrade = lookupConsent(CONSENT_ID_USAGE_STATS, beforeConfirm.first);
final Consent consentBeforeUpgrade = lookupConsent(CONSENT_ID_USAGE_STATS, beforeConfirm.getKey());
assertNotNull(consentBeforeUpgrade);
assertEquals(Version.fromString("1.0"), consentBeforeUpgrade.getVersion());
assertFalse(consentBeforeUpgrade.isAccepted());
assertEquals(ConsentOptions.Permission.UNDEFINED, options.isSendingUsageStatsAllowed());
// confirm
options.setConsents(beforeConfirm.first);
options.setConsents(beforeConfirm.getKey());
}
// after-confirmation state
{
final Pair<List<Consent>, Boolean> afterConfirm = options.getConsents();
assertFalse("Consents should NOT require confirmation", afterConfirm.second);
assertEquals(2, afterConfirm.first.size());
final Map.Entry<List<Consent>, Boolean> afterConfirm = options.getConsents();
assertFalse("Consents should NOT require confirmation", afterConfirm.getValue());
assertEquals(2, afterConfirm.getKey().size());
assertEquals(JSON_CONSENTS_DATA, storage.myBundled);
assertEquals("", storage.myDefaults);
assertFalse("The storage should contain non-empty confirmed consents", StringUtil.isEmpty(storage.myConfirmed));
@@ -138,13 +139,13 @@ public class ConsentsTest extends TestCase{
// updates from server
{
options.applyServerUpdates(JSON_MAJOR_UPGRADE_CONSENTS_DATA);
final Pair<List<Consent>, Boolean> afterUpdate = options.getConsents();
assertTrue("Consents should require confirmation", afterUpdate.second);
assertEquals(2, afterUpdate.first.size());
final Map.Entry<List<Consent>, Boolean> afterUpdate = options.getConsents();
assertTrue("Consents should require confirmation", afterUpdate.getValue());
assertEquals(2, afterUpdate.getKey().size());
assertEquals(JSON_CONSENTS_DATA, storage.myBundled);
assertFalse("The storage should contain non-empty default consents", StringUtil.isEmpty(storage.myDefaults));
assertFalse("The storage should contain non-empty confirmed consents", StringUtil.isEmpty(storage.myConfirmed));
final Consent consentAfterUpgrade = lookupConsent(CONSENT_ID_USAGE_STATS, afterUpdate.first);
final Consent consentAfterUpgrade = lookupConsent(CONSENT_ID_USAGE_STATS, afterUpdate.getKey());
assertNotNull(consentAfterUpgrade);
assertEquals(Version.fromString("2.0"), consentAfterUpgrade.getVersion());
assertFalse(consentAfterUpgrade.isAccepted()); // although default value is now 'true', the last accepted value should be returned
@@ -152,7 +153,7 @@ public class ConsentsTest extends TestCase{
// second confirmation
final List<Consent> toAccept = new ArrayList<>();
for (Consent consent : afterUpdate.first) {
for (Consent consent : afterUpdate.getKey()) {
if (CONSENT_ID_USAGE_STATS.equals(consent.getId())) {
toAccept.add(consent.derive(true));
}
@@ -164,13 +165,13 @@ public class ConsentsTest extends TestCase{
}
{
final Pair<List<Consent>, Boolean> afterSecondConfirm = options.getConsents();
assertFalse("Consents should NOT require confirmation", afterSecondConfirm.second);
assertEquals(2, afterSecondConfirm.first.size());
final Map.Entry<List<Consent>, Boolean> afterSecondConfirm = options.getConsents();
assertFalse("Consents should NOT require confirmation", afterSecondConfirm.getValue());
assertEquals(2, afterSecondConfirm.getKey().size());
assertEquals(JSON_CONSENTS_DATA, storage.myBundled);
assertFalse("The storage should contain non-empty default consents", StringUtil.isEmpty(storage.myDefaults));
assertFalse("The storage should contain non-empty confirmed consents", StringUtil.isEmpty(storage.myConfirmed));
final Consent consentAfterSecondConfirm = lookupConsent(CONSENT_ID_USAGE_STATS, afterSecondConfirm.first);
final Consent consentAfterSecondConfirm = lookupConsent(CONSENT_ID_USAGE_STATS, afterSecondConfirm.getKey());
assertNotNull(consentAfterSecondConfirm);
assertEquals(Version.fromString("2.0"), consentAfterSecondConfirm.getVersion());
assertTrue(consentAfterSecondConfirm.isAccepted());
@@ -183,19 +184,19 @@ public class ConsentsTest extends TestCase{
final ConsentOptions options = data.first;
final MemoryIOBackend storage = data.second;
final Pair<List<Consent>, Boolean> beforeConfirm = options.getConsents();
assertTrue("Consents should require confirmation", beforeConfirm.second);
assertEquals(2, beforeConfirm.first.size());
final Map.Entry<List<Consent>, Boolean> beforeConfirm = options.getConsents();
assertTrue("Consents should require confirmation", beforeConfirm.getValue());
assertEquals(2, beforeConfirm.getKey().size());
assertEquals(JSON_CONSENTS_DATA, storage.myDefaults);
assertEquals("", storage.myConfirmed);
assertNotNull(lookupConsent(CONSENT_ID_USAGE_STATS, beforeConfirm.first));
assertNotNull(lookupConsent(CONSENT_ID_USAGE_STATS, beforeConfirm.getKey()));
assertEquals(ConsentOptions.Permission.UNDEFINED, options.isSendingUsageStatsAllowed());
options.setConsents(beforeConfirm.first);
final Pair<List<Consent>, Boolean> afterConfirm = options.getConsents();
assertFalse("Consents should NOT require confirmation", afterConfirm.second);
assertEquals(2, afterConfirm.first.size());
options.setConsents(beforeConfirm.getKey());
final Map.Entry<List<Consent>, Boolean> afterConfirm = options.getConsents();
assertFalse("Consents should NOT require confirmation", afterConfirm.getValue());
assertEquals(2, afterConfirm.getKey().size());
assertEquals(JSON_CONSENTS_DATA, storage.myBundled);
assertEquals(JSON_CONSENTS_DATA, storage.myDefaults);
assertFalse("The storage should contain non-empty confirmed consents", StringUtil.isEmpty(storage.myConfirmed));
@@ -207,28 +208,28 @@ public class ConsentsTest extends TestCase{
final ConsentOptions options = data.first;
final MemoryIOBackend storage = data.second;
final Pair<List<Consent>, Boolean> beforeConfirm = options.getConsents();
assertTrue("Consents should require confirmation", beforeConfirm.second);
assertEquals(2, beforeConfirm.first.size());
final Map.Entry<List<Consent>, Boolean> beforeConfirm = options.getConsents();
assertTrue("Consents should require confirmation", beforeConfirm.getValue());
assertEquals(2, beforeConfirm.getKey().size());
assertEquals(JSON_CONSENTS_DATA, storage.myBundled);
assertEquals(JSON_CONSENTS_DATA, storage.myDefaults);
assertEquals("", storage.myConfirmed);
final List<Consent> changedByUser = new ArrayList<>();
for (Consent consent : beforeConfirm.first) {
for (Consent consent : beforeConfirm.getKey()) {
changedByUser.add(consent.derive(!consent.isAccepted()));
}
options.setConsents(changedByUser);
final Pair<List<Consent>, Boolean> afterConfirm = options.getConsents();
assertFalse("Consents should NOT require confirmation", afterConfirm.second);
assertEquals(2, afterConfirm.first.size());
final Map.Entry<List<Consent>, Boolean> afterConfirm = options.getConsents();
assertFalse("Consents should NOT require confirmation", afterConfirm.getValue());
assertEquals(2, afterConfirm.getKey().size());
assertEquals(JSON_CONSENTS_DATA, storage.myBundled);
assertEquals(JSON_CONSENTS_DATA, storage.myDefaults);
assertFalse("The storage should contain non-empty confirmed consents", StringUtil.isEmpty(storage.myConfirmed));
for (Consent userConsent : changedByUser) {
final Consent loaded = lookupConsent(userConsent, afterConfirm.first);
final Consent loaded = lookupConsent(userConsent, afterConfirm.getKey());
assertEquals(userConsent, loaded);
assertEquals(userConsent.isAccepted(), loaded.isAccepted());
}
@@ -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.execution.CommandLineUtil;
@@ -99,15 +99,17 @@ public class EnvReader extends EnvironmentUtil.ShellEnvReader {
cl.add(cmdExePath);
cl.add("/c");
cl.add(prepareCallArgs(callArgs));
return runProcessAndReadOutputAndEnvs(cl, batchFile != null ? batchFile.getParent() : null, scriptEnvironmentProcessor, envFile);
Map.Entry<String, Map<String, String>> entry =
runProcessAndReadOutputAndEnvs(cl, batchFile != null ? batchFile.getParent() : null, scriptEnvironmentProcessor, envFile);
return new Pair<>(entry.getKey(), entry.getValue());
}
finally {
try {
Files.delete(envFile);
}
catch (final NoSuchFileException ignore) {
catch (NoSuchFileException ignore) {
}
catch (final IOException e) {
catch (IOException e) {
Logger.getInstance(EnvironmentUtil.class).warn("Cannot delete temporary file", e);
}
}
@@ -29,7 +29,7 @@ class BuiltInServer private constructor(val eventLoopGroup: EventLoopGroup,
companion object {
init {
// IDEA-120811
if (System.getProperty("io.netty.random.id", "true")!!.toBoolean()) {
if (java.lang.Boolean.parseBoolean(System.getProperty("io.netty.random.id", "true"))) {
System.setProperty("io.netty.machineId", "28:f0:76:ff:fe:16:65:0e")
System.setProperty("io.netty.processId", Random().nextInt(65535).toString())
}
@@ -1,8 +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.jna;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.SystemInfoRt;
import com.intellij.util.system.CpuArch;
import com.sun.jna.Native;
import org.jetbrains.annotations.NotNull;
@@ -21,7 +21,7 @@ public final class JnaLoader {
ourJnaLoaded = Boolean.TRUE;
}
catch (Throwable t) {
logger.warn("Unable to load JNA library (OS: " + SystemInfo.OS_NAME + " " + SystemInfo.OS_VERSION + ")", t);
logger.warn("Unable to load JNA library (OS: " + SystemInfoRt.OS_NAME + " " + SystemInfoRt.OS_VERSION + ")", t);
}
}
}
@@ -42,5 +42,7 @@ public final class JnaLoader {
* @see Native#register
* @see Native#load
*/
public static final boolean supportsDirectMapping = !(SystemInfo.isMac && CpuArch.isArm64());
public static boolean isSupportsDirectMapping() {
return !(SystemInfoRt.isMac && CpuArch.isArm64());
}
}
@@ -6,7 +6,6 @@ import com.intellij.openapi.util.SystemInfoRt;
import com.intellij.openapi.util.text.StringUtilRt;
import com.intellij.openapi.util.text.Strings;
import com.intellij.psi.codeStyle.MinusculeMatcher;
import com.intellij.util.SystemProperties;
import com.intellij.util.containers.FList;
import com.intellij.util.io.URLUtil;
import kotlin.Pair;
@@ -539,7 +538,8 @@ public final class PathManager {
Set<String> paths = new LinkedHashSet<>();
paths.add(System.getProperty(PROPERTIES_FILE));
paths.add(getCustomPropertiesFile());
paths.add(SystemProperties.getUserHome() + '/' + PROPERTIES_FILE_NAME);
// Don't use here SystemProperties.getUserHome(). Called too early to load extra class.
paths.add(System.getProperty("user.home") + '/' + PROPERTIES_FILE_NAME);
for (Path binDir : getBinDirectories()) {
paths.add(binDir.resolve(PROPERTIES_FILE_NAME).toString());
}
@@ -547,26 +547,29 @@ public final class PathManager {
Properties sysProperties = System.getProperties();
for (String path : paths) {
Path file = path == null ? null : Paths.get(path);
if (file != null) {
try (Reader reader = Files.newBufferedReader(file)) {
//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;
if (file == null) {
continue;
}
try (Reader reader = Files.newBufferedReader(file)) {
//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");
}
}.load(reader);
}
catch (NoSuchFileException | AccessDeniedException ignore) { }
catch (IOException e) {
log("Can't read property file '" + path + "': " + e.getMessage());
}
else if (!sysProperties.containsKey(key)) {
sysProperties.setProperty(String.valueOf(key), substituteVars(String.valueOf(value)));
}
return null;
}
}.load(reader);
}
catch (NoSuchFileException | AccessDeniedException ignore) {
}
catch (IOException e) {
log("Can't read property file '" + path + "': " + e.getMessage());
}
}
}
@@ -743,21 +746,27 @@ public final class PathManager {
public static @NotNull String getAbsolutePath(@NotNull String path) {
if (path.startsWith("~/") || path.startsWith("~\\")) {
path = SystemProperties.getUserHome() + path.substring(1);
path = System.getProperty("user.home") + path.substring(1);
}
return Paths.get(path).toAbsolutePath().normalize().toString();
}
private static @Nullable String getExplicitPath(String property) {
private static @Nullable String getExplicitPath(@NotNull String property) {
String path = System.getProperty(property);
return path != null ? getAbsolutePath(StringUtilRt.unquoteString(path, '"')) : null;
if (path == null) {
return null;
}
boolean quoted = path.length() > 1 && '"' == path.charAt(0) && '"' == path.charAt(path.length() - 1);
return getAbsolutePath(quoted ? path.substring(1, path.length() - 1) : path);
}
private static String platformPath(String selector,
String macDir, String macSub,
String winVar, String winSub,
String xdgVar, String xdgDfl, String xdgSub) {
String userHome = SystemProperties.getUserHome(), vendorName = vendorName();
String userHome = System.getProperty("user.home");
String vendorName = vendorName();
if (SystemInfoRt.isMac) {
String dir = userHome + "/Library/" + macDir + '/' + vendorName;
@@ -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.io;
import com.intellij.jna.JnaLoader;
@@ -59,7 +59,7 @@ public final class FileSystemUtil {
return check(new IdeaWin32MediatorImpl());
}
else if ((SystemInfo.isLinux || SystemInfo.isMac && CpuArch.isIntel64() || SystemInfo.isSolaris || SystemInfo.isFreeBSD) &&
JnaLoader.isLoaded() && JnaLoader.supportsDirectMapping) {
JnaLoader.isLoaded() && JnaLoader.isSupportsDirectMapping()) {
return check(new JnaUnixMediatorImpl());
}
}
@@ -277,7 +277,7 @@ public final class FileSystemUtil {
private final LimitedPool<Memory> myMemoryPool = new LimitedPool.Sync<>(10, () -> new Memory(256));
JnaUnixMediatorImpl() {
assert JnaLoader.supportsDirectMapping : "Direct mapping not available on " + Platform.RESOURCE_PREFIX;
assert JnaLoader.isSupportsDirectMapping() : "Direct mapping not available on " + Platform.RESOURCE_PREFIX;
if ("linux-x86".equals(Platform.RESOURCE_PREFIX)) myOffsets = LINUX_32;
else if ("linux-x86-64".equals(Platform.RESOURCE_PREFIX)) myOffsets = LINUX_64;
@@ -3,7 +3,6 @@ package com.intellij.ui;
import com.intellij.openapi.util.Iconable;
import com.intellij.ui.icons.RowIcon;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -13,7 +12,9 @@ import javax.swing.*;
import java.awt.*;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
@@ -241,7 +242,13 @@ final class DummyIconManager implements IconManager {
@Override
public Icon @NotNull [] getAllIcons() {
return icons == null ? new Icon[0] : ContainerUtil.packNullables(icons).toArray(new Icon[0]);
List<Icon> list = new ArrayList<>();
for (Icon element : icons) {
if (element != null) {
list.add(element);
}
}
return list.toArray(new Icon[0]);
}
@Override
@@ -5,7 +5,6 @@ import com.intellij.diagnostic.Activity;
import com.intellij.execution.process.UnixProcessManager;
import com.intellij.execution.process.WinProcessManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfoRt;
import com.intellij.openapi.util.text.StringUtilRt;
import com.intellij.util.containers.CollectionFactory;
@@ -263,7 +262,7 @@ public final class EnvironmentUtil {
}
LOG.info("loading shell env: " + String.join(" ", command));
return runProcessAndReadOutputAndEnvs(command, null, additionalEnvironment, envFile).second;
return runProcessAndReadOutputAndEnvs(command, null, additionalEnvironment, envFile).getValue();
}
finally {
try {
@@ -284,7 +283,7 @@ public final class EnvironmentUtil {
* @see #runProcessAndReadOutputAndEnvs(List, Path, Map, Path)
* @see #runProcessAndReadOutputAndEnvs(List, Path, Consumer, Path)
*/
protected final @NotNull Pair<String, Map<String, String>> runProcessAndReadOutputAndEnvs(@NotNull List<String> command,
protected final @NotNull Map.Entry<String, Map<String, String>> runProcessAndReadOutputAndEnvs(@NotNull List<String> command,
@Nullable Path workingDir,
@NotNull Path envFile) throws IOException {
return runProcessAndReadOutputAndEnvs(command, workingDir, emptyMap(), envFile);
@@ -300,10 +299,11 @@ public final class EnvironmentUtil {
* @see #runProcessAndReadOutputAndEnvs(List, Path, Path)
* @see #runProcessAndReadOutputAndEnvs(List, Path, Consumer, Path)
*/
protected final @NotNull Pair<String, Map<String, String>> runProcessAndReadOutputAndEnvs(@NotNull List<String> command,
@Nullable Path workingDir,
@Nullable Map<String, String> scriptEnvironment,
@NotNull Path envFile) throws IOException {
protected final @NotNull Map.Entry<String, Map<String, String>> runProcessAndReadOutputAndEnvs(@NotNull List<String> command,
@Nullable Path workingDir,
@Nullable Map<String, String> scriptEnvironment,
@NotNull Path envFile)
throws IOException {
return runProcessAndReadOutputAndEnvs(command, workingDir, (it) -> {
if (scriptEnvironment != null) {
// we might need default environment for the process to launch correctly
@@ -322,7 +322,7 @@ public final class EnvironmentUtil {
* @see #runProcessAndReadOutputAndEnvs(List, Path, Path)
* @see #runProcessAndReadOutputAndEnvs(List, Path, Map, Path)
*/
protected final @NotNull Pair<String, Map<String, String>> runProcessAndReadOutputAndEnvs(@NotNull List<String> command,
protected final @NotNull Map.Entry<String, Map<String, String>> runProcessAndReadOutputAndEnvs(@NotNull List<String> command,
@Nullable Path workingDir,
@NotNull Consumer<@NotNull Map<String, String>> scriptEnvironmentProcessor,
@NotNull Path envFile) throws IOException {
@@ -347,7 +347,7 @@ public final class EnvironmentUtil {
if (exitCode != 0 || lines.isEmpty()) {
throw new IOException("command " + command + "\n\texit code:" + exitCode + " text:" + lines.length() + " out:" + gobbler.getText().trim());
}
return new Pair<>(gobbler.getText(), parseEnv(lines));
return new AbstractMap.SimpleImmutableEntry<>(gobbler.getText(), parseEnv(lines));
}
protected @NotNull List<String> getShellProcessCommand() {
@@ -564,7 +564,7 @@ public final class EnvironmentUtil {
StreamGobbler(@NotNull InputStream stream) {
super(stream, Charset.defaultCharset(), OPTIONS);
myBuffer = new StringBuffer();
start("stdout/stderr streams of shell env loading process");
startWithoutChangingThreadName();
}
@Override
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2013 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.containers;
import org.jetbrains.annotations.NotNull;
@@ -34,7 +20,7 @@ import java.util.List;
* or size-based methods (like size()) are dangerous, misleading, error-inducing and are not supported.
* Instead, please use {@link #add(T)} and {@link #iterator()}.
*/
public class WeakList<T> extends UnsafeWeakList<T> {
public final class WeakList<T> extends UnsafeWeakList<T> {
public WeakList() {
}
public WeakList(int initialCapacity) {
@@ -3,7 +3,7 @@ package com.intellij.util.io;
import com.intellij.ReviseWhenPortedToJDK;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.util.text.StringUtilRt;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.DeprecatedMethodException;
import org.jetbrains.annotations.ApiStatus;
@@ -39,12 +39,12 @@ public abstract class BaseDataReader {
}
protected void start(@NotNull @NonNls String presentableName) {
if (StringUtil.isEmptyOrSpaces(presentableName)) {
if (StringUtilRt.isEmptyOrSpaces(presentableName)) {
LOG.warn(new Throwable("Must provide not-empty presentable name"));
}
if (myFinishedFuture == null) {
myFinishedFuture = executeOnPooledThread(() -> {
if (StringUtil.isEmptyOrSpaces(presentableName)) {
if (StringUtilRt.isEmptyOrSpaces(presentableName)) {
doRun();
}
else {
@@ -54,6 +54,15 @@ public abstract class BaseDataReader {
}
}
@ApiStatus.Internal
protected void startWithoutChangingThreadName() {
if (myFinishedFuture == null) {
myFinishedFuture = executeOnPooledThread(() -> {
doRun();
});
}
}
/**
* Please don't override this method as the BaseOSProcessProcessHandler assumes that it can be two reading modes: blocking and non-blocking.
* Implement {@link #readAvailableBlocking} and {@link #readAvailableNonBlocking} instead.
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-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.text;
import org.jetbrains.annotations.NotNull;
@@ -23,7 +9,7 @@ import java.util.NoSuchElementException;
/**
* Copy of {@link java.util.StringTokenizer} with added {@link #getCurrentPosition()} and {@link #reset(String)} methods.
*/
public class StringTokenizer implements Enumeration<String> {
public final class StringTokenizer implements Enumeration<String> {
private int currentPosition;
private int newPosition;
private int maxPosition;
@@ -1,12 +1,10 @@
// 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.SystemInfo;
import com.intellij.openapi.util.SystemInfoRt;
import com.intellij.ui.scale.JBUIScale;
import com.intellij.ui.scale.ScaleType;
import com.intellij.util.SystemProperties;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
@@ -20,7 +18,7 @@ public final class JreHiDpiUtil {
/**
* Returns whether the JRE-managed HiDPI mode is enabled and the graphics configuration represents a HiDPI device.
* (analogue of {@link UIUtil#isRetina(Graphics2D)} on macOS)
* (analogue of {@link com.intellij.util.ui.UIUtil#isRetina(Graphics2D)} on macOS)
*/
public static boolean isJreHiDPI(@Nullable GraphicsConfiguration gc) {
return isJreHiDPIEnabled() && JBUIScale.isHiDPI(JBUIScale.sysScale(gc));
@@ -28,7 +26,7 @@ public final class JreHiDpiUtil {
/**
* Returns whether the JRE-managed HiDPI mode is enabled and the graphics represents a HiDPI device.
* (analogue of {@link UIUtil#isRetina(Graphics2D)} on macOS)
* (analogue of {@link com.intellij.util.ui.UIUtil#isRetina(Graphics2D)} on macOS)
*/
public static boolean isJreHiDPI(@Nullable Graphics2D g) {
return isJreHiDPIEnabled() && JBUIScale.isHiDPI(JBUIScale.sysScale(g));
@@ -41,6 +39,10 @@ public final class JreHiDpiUtil {
* @see ScaleType
*/
public static boolean isJreHiDPIEnabled() {
if (SystemInfoRt.isMac) {
return true;
}
Boolean value = jreHiDPI.get();
if (value != null) {
return value;
@@ -53,27 +55,22 @@ public final class JreHiDpiUtil {
}
value = false;
if (SystemProperties.getBooleanProperty("hidpi", true)) {
if (SystemInfo.isJetBrainsJvm) {
try {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
Class<?> sunGraphicsEnvironmentClass = Class.forName("sun.java2d.SunGraphicsEnvironment");
if (sunGraphicsEnvironmentClass.isInstance(ge)) {
try {
Method method = sunGraphicsEnvironmentClass.getDeclaredMethod("isUIScaleEnabled");
method.setAccessible(true);
value = (Boolean)method.invoke(ge);
}
catch (NoSuchMethodException e) {
value = false;
}
if (Boolean.parseBoolean(System.getProperty("hidpi", "true")) && SystemInfo.isJetBrainsJvm) {
try {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
Class<?> sunGraphicsEnvironmentClass = Class.forName("sun.java2d.SunGraphicsEnvironment");
if (sunGraphicsEnvironmentClass.isInstance(ge)) {
try {
Method method = sunGraphicsEnvironmentClass.getDeclaredMethod("isUIScaleEnabled");
method.setAccessible(true);
value = (Boolean)method.invoke(ge);
}
catch (NoSuchMethodException e) {
value = false;
}
}
catch (Throwable ignore) {
}
}
if (SystemInfoRt.isMac) {
value = true;
catch (Throwable ignore) {
}
}
jreHiDPI.set(value);