From 9ad2d140d1a64414b125c1dce8d8ee02c83fddc5 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Dec 2017 15:16:55 +0100 Subject: [PATCH 01/18] [platform] migrates JdkVersionDetector service to new Java version parser --- .../jps/model/java/JdkVersionDetector.java | 59 ++++---- .../java/impl/JdkVersionDetectorImpl.java | 127 +++++++----------- .../jps/model/JdkVersionDetectorTest.kt | 12 +- .../com/intellij/util/lang/JavaVersion.java | 17 ++- 4 files changed, 95 insertions(+), 120 deletions(-) diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JdkVersionDetector.java b/jps/model-api/src/org/jetbrains/jps/model/java/JdkVersionDetector.java index 64f60bd390df..8fa6d7c869b4 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/java/JdkVersionDetector.java +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JdkVersionDetector.java @@ -1,21 +1,10 @@ /* - * 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-2017 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.jps.model.java; import com.intellij.openapi.util.Bitness; +import com.intellij.util.lang.JavaVersion; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.service.JpsServiceManager; @@ -30,18 +19,21 @@ public abstract class JdkVersionDetector { return JpsServiceManager.getInstance().getService(JdkVersionDetector.class); } - /** - * Returns java version for JDK located at {@code homePath} in format like
- * java version "1.8.0_40"
- * by running 'java -version' command - * @param homePath path to JDK home directory - * @return version string of {@code null} if version cannot be determined - */ + /** @deprecated use {@link #detectJdkVersionInfo(String)} (to be removed in IDEA 2019) */ @Nullable - public abstract String detectJdkVersion(@NotNull String homePath); + @SuppressWarnings("deprecation") + public String detectJdkVersion(@NotNull String homePath) { + JdkVersionInfo info = detectJdkVersionInfo(homePath); + return info != null ? info.getVersion() : null; + } + /** @deprecated use {@link #detectJdkVersionInfo(String, ActionRunner)} (to be removed in IDEA 2019) */ @Nullable - public abstract String detectJdkVersion(@NotNull String homePath, @NotNull ActionRunner actionRunner); + @SuppressWarnings("deprecation") + public String detectJdkVersion(@NotNull String homePath, @NotNull ActionRunner runner) { + JdkVersionInfo info = detectJdkVersionInfo(homePath, runner); + return info != null ? info.getVersion() : null; + } @Nullable public abstract JdkVersionInfo detectJdkVersionInfo(@NotNull String homePath); @@ -55,22 +47,27 @@ public abstract class JdkVersionDetector { } public static final class JdkVersionInfo { - private final String myVersion; - private final Bitness myBitness; + public final JavaVersion version; + public final Bitness bitness; - public JdkVersionInfo(@NotNull String version, @NotNull Bitness bitness) { - myVersion = version; - myBitness = bitness; + public JdkVersionInfo(@NotNull JavaVersion version, @NotNull Bitness bitness) { + this.version = version; + this.bitness = bitness; } - @NotNull + @Override + public String toString() { + return version + " " + bitness; + } + + /** @deprecated use {@link #version} (to be removed in IDEA 2019) */ public String getVersion() { - return myVersion; + return "java version \"" + version + '"'; } - @NotNull + /** @deprecated use {@link #bitness} (to be removed in IDEA 2019) */ public Bitness getBitness() { - return myBitness; + return bitness; } } } \ No newline at end of file diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JdkVersionDetectorImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JdkVersionDetectorImpl.java index ce9ccde97c06..ce0da9bc9a65 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JdkVersionDetectorImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JdkVersionDetectorImpl.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 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.jps.model.java.impl; @@ -21,6 +9,7 @@ import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.util.io.BaseOutputReader; +import com.intellij.util.lang.JavaVersion; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.java.JdkVersionDetector; @@ -44,67 +33,58 @@ public class JdkVersionDetectorImpl extends JdkVersionDetector { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.projectRoots.impl.SdkVersionUtil"); private static final ActionRunner ACTION_RUNNER = r -> SharedThreadPool.getInstance().executeOnPooledThread(r); - @Override @Nullable - public String detectJdkVersion(@NotNull String homePath) { - return detectJdkVersion(homePath, ACTION_RUNNER); - } - - @Nullable - public String detectJdkVersion(@NotNull String homePath, @NotNull ActionRunner runner) { - File rtFile = new File(homePath, "jre/lib/rt.jar"); - if (rtFile.isFile()) { - try (JarFile rtJar = new JarFile(rtFile, false)) { - Manifest manifest = rtJar.getManifest(); - if (manifest != null) { - String version = manifest.getMainAttributes().getValue("Implementation-Version"); - if (version != null) { - return "java version \"" + version + "\""; - } - } - } - catch (IOException e) { - LOG.info(e); - } - } - - JdkVersionInfo info = detectJdkVersionInfo(homePath, runner); - return info != null ? info.getVersion() : null; - } - @Override public JdkVersionInfo detectJdkVersionInfo(@NotNull String homePath) { return detectJdkVersionInfo(homePath, ACTION_RUNNER); } + @Nullable @Override public JdkVersionInfo detectJdkVersionInfo(@NotNull String homePath, @NotNull ActionRunner runner) { + // Java 1.7+ File releaseFile = new File(homePath, "release"); if (releaseFile.isFile()) { - try { - Properties p = new Properties(); - p.load(new FileInputStream(releaseFile)); - String version = p.getProperty("JAVA_FULL_VERSION", p.getProperty("JAVA_VERSION")); - if (version != null) { - version = StringUtil.unquoteString(version); - int i = version.indexOf('+'); - if (i > 0) { - version = version.substring(0, i); - } + Properties p = new Properties(); + try (FileInputStream stream = new FileInputStream(releaseFile)) { + p.load(stream); + String versionString = p.getProperty("JAVA_FULL_VERSION", p.getProperty("JAVA_VERSION")); + if (versionString != null) { + JavaVersion version = JavaVersion.parse(versionString); String arch = StringUtil.unquoteString(p.getProperty("OS_ARCH", "")); boolean x64 = "x86_64".equals(arch) || "amd64".equals(arch); - return new JdkVersionInfo("java version \"" + version + "\"", x64 ? Bitness.x64 : Bitness.x32); + return new JdkVersionInfo(version, x64 ? Bitness.x64 : Bitness.x32); } } - catch (IOException e) { - LOG.info(e); + catch (IOException | IllegalArgumentException e) { + LOG.info(releaseFile.getPath(), e); } } - String javaExe = homePath + File.separator + "bin" + File.separator + (SystemInfo.isWindows ? "java.exe" : "java"); - if (new File(javaExe).canExecute()) { + // Java 1.2 - 1.8 + File rtFile = new File(homePath, "jre/lib/rt.jar"); + if (rtFile.isFile()) { + try (JarFile rtJar = new JarFile(rtFile, false)) { + Manifest manifest = rtJar.getManifest(); + if (manifest != null) { + String versionString = manifest.getMainAttributes().getValue("Implementation-Version"); + if (versionString != null) { + JavaVersion version = JavaVersion.parse(versionString); + boolean x64 = new File(rtFile.getParent(), "amd64").isDirectory(); + return new JdkVersionInfo(version, x64 ? Bitness.x64 : Bitness.x32); + } + } + } + catch (IOException | IllegalArgumentException e) { + LOG.info(rtFile.getPath(), e); + } + } + + // last resort + File javaExe = new File(homePath, "bin/" + (SystemInfo.isWindows ? "java.exe" : "java")); + if (javaExe.canExecute()) { try { - Process process = new ProcessBuilder(javaExe, "-version").redirectErrorStream(true).start(); + Process process = new ProcessBuilder(javaExe.getPath(), "-version").redirectErrorStream(true).start(); VersionOutputReader reader = new VersionOutputReader(process.getInputStream(), runner); try { reader.waitFor(); @@ -113,10 +93,17 @@ public class JdkVersionDetectorImpl extends JdkVersionDetector { LOG.info(e); process.destroy(); } - return reader.getVersionInfo(); + + if (!reader.myLines.isEmpty()) { + JavaVersion base = JavaVersion.parse(reader.myLines.get(0)); + JavaVersion rt = JavaVersion.tryParse(reader.myLines.size() > 2 ? reader.myLines.get(1) : null); + JavaVersion version = rt != null && rt.feature == base.feature && rt.minor == base.minor ? rt : base; + boolean x64 = reader.myLines.stream().anyMatch(s -> s.contains("64-Bit") || s.contains("x86_64") || s.contains("amd64")); + return new JdkVersionInfo(version, x64 ? Bitness.x64 : Bitness.x32); + } } - catch (IOException e) { - LOG.info(e); + catch (IOException | IllegalArgumentException e) { + LOG.info(javaExe.getPath(), e); } } @@ -150,27 +137,7 @@ public class JdkVersionDetectorImpl extends JdkVersionDetector { @Override protected void onTextAvailable(@NotNull String text) { myLines.add(text); - LOG.debug("text: " + text); - } - - @Nullable - public JdkVersionInfo getVersionInfo() { - String version = null; - Bitness arch = Bitness.x32; - - for (String line : myLines) { - if (line.contains("version")) { - if (version == null) { - version = line; - } - } - else if (line.contains("64-Bit") || line.contains("x86_64") || line.contains("amd64")) { - arch = Bitness.x64; - } - } - - LOG.debug("Returning " + version + " " + arch); - return version != null ? new JdkVersionInfo(version, arch) : null; + LOG.trace("text: " + text); } } } \ No newline at end of file diff --git a/jps/model-impl/testSrc/org/jetbrains/jps/model/JdkVersionDetectorTest.kt b/jps/model-impl/testSrc/org/jetbrains/jps/model/JdkVersionDetectorTest.kt index a1e6bca8420b..614dacab18e3 100644 --- a/jps/model-impl/testSrc/org/jetbrains/jps/model/JdkVersionDetectorTest.kt +++ b/jps/model-impl/testSrc/org/jetbrains/jps/model/JdkVersionDetectorTest.kt @@ -1,4 +1,6 @@ -// Copyright 2000-2017 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-2017 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.jps.model import com.intellij.openapi.util.Bitness @@ -9,15 +11,9 @@ import org.junit.Test class JdkVersionDetectorTest { @Test fun detectJdkVersion() { - val jdkHome = System.getProperty("java.home") - val jdkVersion = JdkVersionDetector.getInstance().detectJdkVersion(jdkHome) - assertThat(jdkVersion).contains("\"${SystemInfo.JAVA_VERSION.removeSuffix("-ea")}\"") - } - - @Test fun detectJdkVersionInfo() { val jdkHome = System.getProperty("java.home") val jdkVersion = JdkVersionDetector.getInstance().detectJdkVersionInfo(jdkHome) - assertThat(jdkVersion?.version).contains("\"${SystemInfo.JAVA_VERSION.removeSuffix("-ea")}\"") + assertThat(jdkVersion?.version.toString()).startsWith(SystemInfo.JAVA_VERSION) assertThat(jdkVersion?.bitness).isEqualTo(if (SystemInfo.is64Bit) Bitness.x64 else Bitness.x32) } } \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/lang/JavaVersion.java b/platform/util/src/com/intellij/util/lang/JavaVersion.java index 05e5bc568048..76d70e2ba3c4 100644 --- a/platform/util/src/com/intellij/util/lang/JavaVersion.java +++ b/platform/util/src/com/intellij/util/lang/JavaVersion.java @@ -5,6 +5,7 @@ package com.intellij.util.lang; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -144,7 +145,7 @@ public final class JavaVersion { */ public static @NotNull JavaVersion parse(@NotNull String versionString) throws IllegalArgumentException { // trimming - String str = versionString; + String str = versionString.trim(); if (str.contains("Runtime Environment")) { int p = str.indexOf("(build "); if (p > 0) str = str.substring(p); @@ -226,4 +227,18 @@ public final class JavaVersion { private static boolean startsWithWord(String s, String word) { return s.startsWith(word) && (s.length() == word.length() || !Character.isLetterOrDigit(s.charAt(word.length()))); } + + /** + * A safe version of {@link #parse(String)} - returns {@code null} if can't parse a version string. + */ + public static @Nullable JavaVersion tryParse(String versionString) { + if (versionString != null) { + try { + return parse(versionString); + } + catch (IllegalArgumentException ignored) { } + } + + return null; + } } \ No newline at end of file From cc63a5504be33671cadddb46f3595222ec0602d5 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Dec 2017 15:25:28 +0100 Subject: [PATCH 02/18] Cleanup (migrates deprecated JdkVersionDetector usages) --- build/scripts/utils.gant | 23 +++++-------------- .../jps/model/java/JdkVersionDetector.java | 6 ++++- .../impl/JpsJavaExtensionServiceImpl.java | 8 +++++-- .../intellij/build/impl/JdkUtils.groovy | 21 ++++------------- .../projectRoots/impl/SdkVersionUtil.java | 22 ++---------------- 5 files changed, 24 insertions(+), 56 deletions(-) diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant index bbb1cbb98088..527d55f6ec5e 100644 --- a/build/scripts/utils.gant +++ b/build/scripts/utils.gant @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 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. */ @@ -103,7 +91,7 @@ binding.setVariable("guessHome", { binding.setVariable("loadProject", { defineJdk("IDEA jdk", setupJdkPath("jdkHome", "$home/build/jdk/1.6", "JDK_16_x64")) defineJdk("1.8", setupJdkPath("jdk8Home", "$home/build/jdk/1.8", "JDK_18_x64")) - + setupKotlin() def bundledKotlinPath = "$home/build/dependencies/build/kotlin/Kotlin/kotlinc" if (!new File(bundledKotlinPath, "lib/kotlin-runtime.jar").exists()) { @@ -195,9 +183,10 @@ private String setupJdkPath(String propertyName, String defaultDir, String envVa } else { jdk = guessJdk() - def version = JdkVersionDetector.instance.detectJdkVersion(jdk) - if (propertyName.contains("8") && !version.contains("1.8.")) { - projectBuilder.error("JDK 1.8 is required to compile the project, but '$propertyName' property and '$envVarName' environment variable aren't defined and default JDK $jdk ($version) cannot be used as JDK 1.8") + def jdkInfo = JdkVersionDetector.instance.detectJdkVersionInfo(jdk) + if (propertyName.contains("8") && jdkInfo.@version.feature != 8) { + projectBuilder.error("JDK 1.8 is required to compile the project, but '$propertyName' property and '$envVarName' environment variable" + + " aren't defined and default JDK $jdk ($jdkInfo) cannot be used as JDK 1.8") return null } projectBuilder.info("'$envVarName' isn't defined and '$defaultDir' doesn't exist, $propertyName set to $jdk") diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JdkVersionDetector.java b/jps/model-api/src/org/jetbrains/jps/model/java/JdkVersionDetector.java index 8fa6d7c869b4..c3e8aa52b683 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/java/JdkVersionDetector.java +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JdkVersionDetector.java @@ -62,7 +62,7 @@ public abstract class JdkVersionDetector { /** @deprecated use {@link #version} (to be removed in IDEA 2019) */ public String getVersion() { - return "java version \"" + version + '"'; + return formatVersionString(version); } /** @deprecated use {@link #bitness} (to be removed in IDEA 2019) */ @@ -70,4 +70,8 @@ public abstract class JdkVersionDetector { return bitness; } } + + public static String formatVersionString(@NotNull JavaVersion version) { + return "java version \"" + version + '"'; + } } \ No newline at end of file diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaExtensionServiceImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaExtensionServiceImpl.java index 2296ace2dde1..ba9e20de5b20 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaExtensionServiceImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaExtensionServiceImpl.java @@ -1,4 +1,6 @@ -// Copyright 2000-2017 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-2017 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.jps.model.java.impl; import com.intellij.openapi.util.io.FileUtil; @@ -128,7 +130,9 @@ public class JpsJavaExtensionServiceImpl extends JpsJavaExtensionService { @Override public JpsTypedLibrary> addJavaSdk(@NotNull JpsGlobal global, @NotNull String name, @NotNull String homePath) { - String version = JdkVersionDetector.getInstance().detectJdkVersion(homePath); + JdkVersionDetector.JdkVersionInfo jdkInfo = JdkVersionDetector.getInstance().detectJdkVersionInfo(homePath); + assert jdkInfo != null : homePath; + String version = JdkVersionDetector.formatVersionString(jdkInfo.version); JpsTypedLibrary> sdk = global.addSdk(name, homePath, version, JpsJavaSdkType.INSTANCE); File homeDir = new File(FileUtil.toSystemDependentName(homePath)); List roots = JavaSdkUtil.getJdkClassesRoots(homeDir, false); diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/JdkUtils.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/JdkUtils.groovy index 865f74d90ab1..5639f78cd23f 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/JdkUtils.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/JdkUtils.groovy @@ -1,17 +1,5 @@ /* - * 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-2017 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.intellij.build.impl @@ -54,9 +42,10 @@ class JdkUtils { } else { jdkDir = getCurrentJdk() - def version = JdkVersionDetector.instance.detectJdkVersion(jdkDir) - if (propertyName.contains("8") && !version.contains("1.8.")) { - messages.error("JDK 1.8 is required to compile the project, but '$propertyName' property and '$envVarName' environment variable aren't defined and default JDK $jdkDir ($version) cannot be used as JDK 1.8") + def jdkInfo = JdkVersionDetector.instance.detectJdkVersionInfo(jdkDir) + if (propertyName.contains("8") && jdkInfo.@version.feature != 8) { + messages.error("JDK 1.8 is required to compile the project, but '$propertyName' property and '$envVarName' environment variable" + + " aren't defined and default JDK $jdkDir ($jdkInfo) cannot be used as JDK 1.8") return null } messages.info("'$envVarName' isn't defined and '$defaultDir' doesn't exist, $propertyName set to $jdkDir") diff --git a/platform/lang-api/src/com/intellij/openapi/projectRoots/impl/SdkVersionUtil.java b/platform/lang-api/src/com/intellij/openapi/projectRoots/impl/SdkVersionUtil.java index 8c38f0717fb9..90ce8e3cd34b 100644 --- a/platform/lang-api/src/com/intellij/openapi/projectRoots/impl/SdkVersionUtil.java +++ b/platform/lang-api/src/com/intellij/openapi/projectRoots/impl/SdkVersionUtil.java @@ -1,17 +1,5 @@ /* - * 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-2017 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.projectRoots.impl; @@ -29,13 +17,7 @@ public class SdkVersionUtil { private SdkVersionUtil() { } - /** @deprecated use {@link #detectJdkVersion(String)} to be removed in IDEA 2018 */ - @Nullable - @SuppressWarnings("unused") - public static String readVersionFromProcessOutput(@NotNull String homePath, @NotNull String[] command, String versionLineMarker) { - return JdkVersionDetector.getInstance().detectJdkVersion(homePath, ACTION_RUNNER); - } - + /** @deprecated use {@link #getJdkVersionInfo(String)} (to be removed in IDEA 2019) */ @Nullable public static String detectJdkVersion(@NotNull String homePath) { return JdkVersionDetector.getInstance().detectJdkVersion(homePath, ACTION_RUNNER); From 7dbff7345412b8be19dbabb0bd9279541c2788ec Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 21 Dec 2017 15:48:52 +0100 Subject: [PATCH 03/18] GDPR support: SentUsageStatistics.isAllowed flag is now part of ConsentOptions; bundled default consents.json --- .../com/intellij/ide/gdpr/ConsentOptions.java | 9 +++ .../src/com/intellij/idea/StartupUtil.java | 2 +- .../actions/SendStatisticsAction.java | 16 ++-- .../configurable/StatisticsConfigurable.java | 76 ------------------- .../StatisticsConfigurationComponent.form | 74 ------------------ .../StatisticsConfigurationComponent.java | 71 ----------------- .../UsageStatisticsPersistenceComponent.java | 17 +++-- .../StatisticsNotificationManager.java | 16 ++-- .../src/com/intellij/ui/AppUIUtil.java | 2 +- .../src/META-INF/PlatformExtensions.xml | 3 - .../platform-resources/src/PrivacyPolicy.html | 7 +- platform/platform-resources/src/consents.json | 9 +++ 12 files changed, 50 insertions(+), 252 deletions(-) delete mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java delete mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form delete mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java create mode 100644 platform/platform-resources/src/consents.json diff --git a/platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java b/platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java index f9a2e498a4c7..0f3636ac7d37 100644 --- a/platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java +++ b/platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java @@ -98,6 +98,15 @@ public final class ConsentOptions { return confirmedConsent == null? Permission.UNDEFINED : confirmedConsent.isAccepted()? Permission.YES : Permission.NO; } + public boolean setSendingUsageStatsAllowed(boolean allowed) { + final Consent defConsent = loadDefaultConsents().get(STATISTICS_OPTION_ID); + if (defConsent != null && !defConsent.isDeleted()) { + saveConfirmedConsents(Collections.singleton(new ConfirmedConsent(defConsent.getId(), defConsent.getVersion(), allowed, 0L))); + return true; + } + return false; + } + @Nullable public String getConfirmedConsentsString() { final Map defaults = loadDefaultConsents(); diff --git a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java index 51ee6a849f8f..91e55a82e0bf 100644 --- a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java +++ b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java @@ -130,7 +130,7 @@ public class StartupUtil { if (!Main.isHeadless()) { AppUIUtil.updateWindowIcon(JOptionPane.getRootFrame()); AppUIUtil.registerBundledFonts(); - AppUIUtil.showEndUserAgreement(); + AppUIUtil.showUserAgreementAndConsentsIfNeeded(); } appStarter.start(newConfigFolder); diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/actions/SendStatisticsAction.java b/platform/platform-impl/src/com/intellij/internal/statistic/actions/SendStatisticsAction.java index 3e49fe81134d..05a4ddf2ae85 100755 --- a/platform/platform-impl/src/com/intellij/internal/statistic/actions/SendStatisticsAction.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/actions/SendStatisticsAction.java @@ -15,11 +15,11 @@ */ package com.intellij.internal.statistic.actions; -import com.intellij.internal.statistic.utils.StatisticsUploadAssistant; +import com.intellij.internal.statistic.ApplicationStatisticsPersistenceComponent; import com.intellij.internal.statistic.connect.StatisticsResult; import com.intellij.internal.statistic.connect.StatisticsService; -import com.intellij.internal.statistic.ApplicationStatisticsPersistenceComponent; import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; +import com.intellij.internal.statistic.utils.StatisticsUploadAssistant; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.ApplicationManager; @@ -45,10 +45,14 @@ public class SendStatisticsAction extends AnAction { @Override public void run(@NotNull ProgressIndicator indicator) { UsageStatisticsPersistenceComponent statisticsPersistenceComponent = UsageStatisticsPersistenceComponent.getInstance(); - boolean sendAllowed = statisticsPersistenceComponent.isAllowed(); - statisticsPersistenceComponent.setAllowed(true); - ApplicationStatisticsPersistenceComponent.persistOpenedProjects(); - statisticsPersistenceComponent.setAllowed(sendAllowed); + final boolean sendAllowed = statisticsPersistenceComponent.isAllowed(); + try { + statisticsPersistenceComponent.setAllowed(true); + ApplicationStatisticsPersistenceComponent.persistOpenedProjects(); + } + finally { + statisticsPersistenceComponent.setAllowed(sendAllowed); + } StatisticsService service = StatisticsUploadAssistant.getStatisticsService(); final StatisticsResult result = service.send(); diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java deleted file mode 100644 index 3ec9f7cf6d97..000000000000 --- a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package com.intellij.internal.statistic.configurable; - -import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; -import com.intellij.openapi.options.Configurable; -import com.intellij.openapi.options.ConfigurationException; -import com.intellij.openapi.options.SearchableConfigurable; -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; - -public class StatisticsConfigurable implements SearchableConfigurable, Configurable.NoScroll { - - private boolean modifiedByDefault; - - public StatisticsConfigurable() { - this(false); - } - - public StatisticsConfigurable(boolean isModifiedByDefault) { - modifiedByDefault = isModifiedByDefault; - } - - - private StatisticsConfigurationComponent myConfig; - - @Nls - public String getDisplayName() { - return "Usage Statistics"; - } - - @Override - @Nullable - @NonNls - public String getHelpTopic() { - return "preferences.usage.statictics"; - } - - public JComponent createComponent() { - myConfig = new StatisticsConfigurationComponent(); - return myConfig.getJComponent(); - } - - public boolean isModified() { - final UsageStatisticsPersistenceComponent persistenceComponent = UsageStatisticsPersistenceComponent.getInstance(); - return myConfig.isAllowed() != persistenceComponent.isAllowed() || - myConfig.getPeriod() != persistenceComponent.getPeriod() || - modifiedByDefault; - } - - public void apply() throws ConfigurationException { - final UsageStatisticsPersistenceComponent persistenceComponent = UsageStatisticsPersistenceComponent.getInstance(); - - //persistenceComponent.setPeriod(myConfig.getPeriod()); - persistenceComponent.setAllowed(myConfig.isAllowed()); - persistenceComponent.setShowNotification(false); - modifiedByDefault = false; - } - - public void reset() { - myConfig.reset(); - } - - public void disposeUIResources() { - myConfig = null; - } - - @NotNull - @Override - public String getId() { - return "usage.statistics"; - } -} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form deleted file mode 100644 index fc64eadf51ec..000000000000 --- a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form +++ /dev/null @@ -1,74 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java deleted file mode 100644 index 3c87c7215cf6..000000000000 --- a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package com.intellij.internal.statistic.configurable; - -import com.intellij.internal.statistic.StatisticsBundle; -import com.intellij.internal.statistic.connect.StatisticsService; -import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; -import com.intellij.internal.statistic.utils.StatisticsUploadAssistant; -import com.intellij.openapi.application.ApplicationInfo; -import com.intellij.openapi.application.ApplicationNamesInfo; -import com.intellij.ui.RelativeFont; - -import javax.swing.*; -import java.util.Map; - -public class StatisticsConfigurationComponent { - - private JPanel myMainPanel; - private JLabel myTitle; - private JCheckBox myAllowToSendUsagesCheckBox; - private JLabel myLabel; - - public StatisticsConfigurationComponent() { - String product = ApplicationNamesInfo.getInstance().getFullProductName(); - String company = ApplicationInfo.getInstance().getCompanyName(); - myTitle.setText(StatisticsBundle.message("stats.title", product, company)); - myLabel.setText(StatisticsBundle.message("stats.config.details", company)); - RelativeFont.SMALL.install(myLabel); - - myAllowToSendUsagesCheckBox.setText(StatisticsBundle.message("stats.config.allow.send.stats.text", company)); - - // Let current statistics service override labels - StatisticsService service = StatisticsUploadAssistant.getStatisticsService(); - if (service != null) { - Map overrides = service.getStatisticsConfigurationLabels(); - if (overrides != null) { - String s = overrides.get(StatisticsService.TITLE); - if (s != null) { - myTitle.setText(s); - } - s = overrides.get(StatisticsService.DETAILS); - if (s != null) { - myLabel.setText(s); - } - s = overrides.get(StatisticsService.ALLOW_CHECKBOX); - if (s != null) { - myAllowToSendUsagesCheckBox.setText(s); - } - } - } - - myTitle.setText(myTitle.getText().replace("%company%", company)); - myLabel.setText(myLabel.getText().replace("%company%", company)); - myAllowToSendUsagesCheckBox.setText(myAllowToSendUsagesCheckBox.getText().replace("%company%", company)); - } - - public JPanel getJComponent() { - return myMainPanel; - } - - public boolean isAllowed() { - return myAllowToSendUsagesCheckBox.isSelected(); - } - - public void reset() { - myAllowToSendUsagesCheckBox.setSelected(UsageStatisticsPersistenceComponent.getInstance().isAllowed()); - } - - public SendPeriod getPeriod() { - return SendPeriod.DAILY; - } -} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java index 113a24249b0a..451ab4946533 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java @@ -2,6 +2,7 @@ package com.intellij.internal.statistic.persistence; +import com.intellij.ide.gdpr.ConsentOptions; import com.intellij.internal.statistic.beans.ConvertUsagesUtil; import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; @@ -25,7 +26,6 @@ import java.util.Set; public class UsageStatisticsPersistenceComponent extends BasicSentUsagesPersistenceComponent implements NamedComponent, PersistentStateComponent { - @NonNls private boolean isAllowed = false; @NonNls private boolean isShowNotification = true; @NotNull private SendPeriod myPeriod = SendPeriod.DAILY; @@ -73,8 +73,11 @@ public class UsageStatisticsPersistenceComponent extends BasicSentUsagesPersiste setSentTime(0); } + // compatibility: if was previously allowed, transfer the setting to the new place final String isAllowedValue = element.getAttributeValue(IS_ALLOWED_ATTR); - setAllowed(!StringUtil.isEmptyOrSpaces(isAllowedValue) && Boolean.parseBoolean(isAllowedValue)); + if (!StringUtil.isEmptyOrSpaces(isAllowedValue) && Boolean.parseBoolean(isAllowedValue)) { + setAllowed(true); + } final String isShowNotificationValue = element.getAttributeValue(SHOW_NOTIFICATION_ATTR); setShowNotification(StringUtil.isEmptyOrSpaces(isShowNotificationValue) || Boolean.parseBoolean(isShowNotificationValue)); @@ -100,9 +103,9 @@ public class UsageStatisticsPersistenceComponent extends BasicSentUsagesPersiste element.setAttribute(LAST_TIME_ATTR, String.valueOf(lastTimeSent)); } - if (isAllowed()) { - element.setAttribute(IS_ALLOWED_ATTR, "true"); - } + //if (isAllowed()) { + // element.setAttribute(IS_ALLOWED_ATTR, "true"); + //} if (!isShowNotification()) { element.setAttribute(SHOW_NOTIFICATION_ATTR, "false"); } @@ -131,12 +134,12 @@ public class UsageStatisticsPersistenceComponent extends BasicSentUsagesPersiste } public void setAllowed(boolean allowed) { - isAllowed = allowed; + ConsentOptions.getInstance().setSendingUsageStatsAllowed(allowed); } @Override public boolean isAllowed() { - return isAllowed; + return ConsentOptions.getInstance().isSendingUsageStatsAllowed() == ConsentOptions.Permission.YES; } public void setShowNotification(boolean showNotification) { diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java b/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java index 327cbc773727..4293d84393c8 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java @@ -1,19 +1,18 @@ package com.intellij.internal.statistic.updater; -import com.intellij.internal.statistic.configurable.StatisticsConfigurable; +import com.intellij.ide.gdpr.Consent; +import com.intellij.ide.gdpr.ConsentOptions; import com.intellij.internal.statistic.connect.StatisticsService; import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; import com.intellij.notification.Notifications; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.options.ShowSettingsUtil; -import com.intellij.openapi.wm.IdeFrame; -import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.ui.AppUIUtil; import org.jetbrains.annotations.NotNull; -import javax.swing.*; import javax.swing.event.HyperlinkEvent; +import java.util.Collection; public class StatisticsNotificationManager { @@ -56,9 +55,10 @@ public class StatisticsNotificationManager { notification.expire(); } else if ("settings".equals(description)) { - final ShowSettingsUtil util = ShowSettingsUtil.getInstance(); - IdeFrame ideFrame = WindowManagerEx.getInstanceEx().findFrameFor(null); - util.editConfigurable((JFrame)ideFrame, new StatisticsConfigurable(true)); + final Collection result = AppUIUtil.confirmConsentOptions(ConsentOptions.getInstance().getConsents().first); + if (result != null) { + ConsentOptions.getInstance().setConsents(result); + } notification.expire(); } } diff --git a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java index c9d827d3c0be..0893de4ea8b1 100644 --- a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java +++ b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java @@ -253,7 +253,7 @@ public class AppUIUtil { return iconPath; } - public static void showEndUserAgreement() { + public static void showUserAgreementAndConsentsIfNeeded() { if (ApplicationInfoImpl.getShadowInstance().isVendorJetBrains()) { EndUserAgreement.Document agreement = EndUserAgreement.getLatestDocument(); if (!agreement.isAccepted()) { diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index 64f5bdbaed2b..ae273649247b 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -415,9 +415,6 @@ - - diff --git a/platform/platform-resources/src/PrivacyPolicy.html b/platform/platform-resources/src/PrivacyPolicy.html index c3fc6051e6fc..f89b18f35323 100644 --- a/platform/platform-resources/src/PrivacyPolicy.html +++ b/platform/platform-resources/src/PrivacyPolicy.html @@ -1,4 +1,4 @@ - + @@ -12,7 +12,7 @@

This Policy may be amended from time to time. The respective latest version of the policy at the point of time of the purchase/registration of a JetBrains Software Product (whichever occurs later) shall apply. The data controller is JetBrains s.r.o., Praha 4, Na hřebenech - II 1718/10, PSČ 147 00, Česká republika + II 1718/10, PSČ 140 00, Česká republika

In this Privacy Policy, we describe the type of data, including personal data (collectively, “data”), @@ -297,9 +297,6 @@ Website works

  • For security purposes
  • -
  • Make sure you connect to the right service on our Website when we make any changes to the way the - Website works -
  • Accepting these cookies is a condition of using the Website, so if you prevent these cookies we can't diff --git a/platform/platform-resources/src/consents.json b/platform/platform-resources/src/consents.json new file mode 100644 index 000000000000..a44ef27787b9 --- /dev/null +++ b/platform/platform-resources/src/consents.json @@ -0,0 +1,9 @@ +[ + { + "consentId": "rsch.send.usage.stat", + "version": "1.0", + "text": "I consent to submit anonymous usage statistics to help JetBrains improve their products. I agree that the following information will be sent to JetBrains and processed in accordance with JetBrains Privacy Policy https://www.jetbrains.com/company/privacy.html\n * Information about which product features are used\n * General statistics (number of files, file types) of the solutions I am working on\n * General information about my hardware configuration (for example, amount of RAM, CPU speed and number of cores)\n * General information about my software configuration (for example, OS version)\nI can revoke my consent at any time in this Data Sharing Options dialog available at Help | Data Sharing Options", + "printableName": "Send anonymous usage statistics to JetBrains", + "accepted": "false" + } +] \ No newline at end of file From 777e4da5dc9d12d92060acb87320bedbe1f6be76 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Dec 2017 15:39:28 +0100 Subject: [PATCH 04/18] Cleanup (migrates deprecated SdkVersionUtil usages) --- .../execution/util/JreVersionDetector.java | 38 ++++--------------- .../openapi/projectRoots/JavaSdk.java | 16 +------- .../projectRoots/SimpleJavaSdkType.java | 21 +++------- 3 files changed, 15 insertions(+), 60 deletions(-) diff --git a/java/execution/impl/src/com/intellij/execution/util/JreVersionDetector.java b/java/execution/impl/src/com/intellij/execution/util/JreVersionDetector.java index ed0636697b26..f465f01080e3 100644 --- a/java/execution/impl/src/com/intellij/execution/util/JreVersionDetector.java +++ b/java/execution/impl/src/com/intellij/execution/util/JreVersionDetector.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 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.execution.util; @@ -26,17 +14,17 @@ import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.jps.model.java.JdkVersionDetector; public class JreVersionDetector { private String myLastAlternativeJrePath ; //awful hack private boolean myLastIsJre50; public boolean isModuleJre50Configured(final ModuleBasedConfiguration configuration) { - final Module module = configuration.getConfigurationModule().getModule(); - if (module != null && !module.isDisposed()) { - return isJre50(ModuleRootManager.getInstance(module).getSdk()); - } - return isJre50(ProjectRootManager.getInstance(configuration.getProject()).getProjectSdk()); + Module module = configuration.getConfigurationModule().getModule(); + Sdk sdk = module != null && !module.isDisposed() ? ModuleRootManager.getInstance(module).getSdk() + : ProjectRootManager.getInstance(configuration.getProject()).getProjectSdk(); + return JavaSdkUtil.isJdkAtLeast(sdk, JavaSdkVersion.JDK_1_5); } public boolean isJre50Configured(final CommonJavaRunConfigurationParameters configuration) { @@ -48,22 +36,12 @@ public class JreVersionDetector { } myLastAlternativeJrePath = alternativeJrePath; - String versionString = SdkVersionUtil.detectJdkVersion(myLastAlternativeJrePath); - myLastIsJre50 = versionString != null && isJre50(versionString); + JdkVersionDetector.JdkVersionInfo jdkInfo = SdkVersionUtil.getJdkVersionInfo(myLastAlternativeJrePath); + myLastIsJre50 = jdkInfo != null && jdkInfo.version.feature >= 5; return myLastIsJre50; } } return false; } - - private static boolean isJre50(Sdk jdk) { - return JavaSdkUtil.isJdkAtLeast(jdk, JavaSdkVersion.JDK_1_5); - } - - private static boolean isJre50(String versionString) { - if (versionString == null) return false; - JavaSdkVersion version = JavaSdkVersion.fromVersionString(versionString); - return version != null && version.isAtLeast(JavaSdkVersion.JDK_1_5); - } } \ No newline at end of file diff --git a/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdk.java b/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdk.java index 9a807c28c0ac..83d4f8e320dd 100644 --- a/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdk.java +++ b/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdk.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 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.projectRoots; @@ -57,7 +45,7 @@ public abstract class JavaSdk extends SdkType implements JavaSdkType { return JdkUtil.checkForJre(file); } - /** @deprecated use {@link SdkVersionUtil#detectJdkVersion} (to be removed in IDEA 2019) */ + /** @deprecated use {@link SdkVersionUtil#getJdkVersionInfo} (to be removed in IDEA 2019) */ public static String getJdkVersion(@NotNull String sdkHome) { return SdkVersionUtil.detectJdkVersion(sdkHome); } diff --git a/platform/lang-api/src/com/intellij/openapi/projectRoots/SimpleJavaSdkType.java b/platform/lang-api/src/com/intellij/openapi/projectRoots/SimpleJavaSdkType.java index a7a298e17b9f..2dc435c6be8d 100644 --- a/platform/lang-api/src/com/intellij/openapi/projectRoots/SimpleJavaSdkType.java +++ b/platform/lang-api/src/com/intellij/openapi/projectRoots/SimpleJavaSdkType.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 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.projectRoots; @@ -20,6 +8,7 @@ import com.intellij.openapi.projectRoots.impl.SdkVersionUtil; import com.intellij.openapi.util.io.FileUtil; import org.jdom.Element; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.java.JdkVersionDetector; import java.io.File; @@ -52,8 +41,7 @@ public class SimpleJavaSdkType extends SdkType implements JavaSdkType { } @Override - public void saveAdditionalData(@NotNull SdkAdditionalData additionalData, @NotNull Element additional) { - } + public void saveAdditionalData(@NotNull SdkAdditionalData additionalData, @NotNull Element additional) { } @Override public String getBinPath(@NotNull Sdk sdk) { @@ -87,6 +75,7 @@ public class SimpleJavaSdkType extends SdkType implements JavaSdkType { @Override public final String getVersionString(final String sdkHome) { - return SdkVersionUtil.detectJdkVersion(sdkHome); + JdkVersionDetector.JdkVersionInfo jdkInfo = SdkVersionUtil.getJdkVersionInfo(sdkHome); + return jdkInfo != null ? JdkVersionDetector.formatVersionString(jdkInfo.version) : null; } } \ No newline at end of file From 9988cfe65cd1324e92915ad8a362f3b1bde6bc0d Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Dec 2017 16:59:49 +0100 Subject: [PATCH 05/18] [java] migrates Java SDK classes to new version parser --- .../projectRoots/impl/JavaSdkImpl.java | 95 ++++++------------- .../openapi/projectRoots/JavaSdkVersion.java | 78 +++++---------- 2 files changed, 49 insertions(+), 124 deletions(-) diff --git a/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java b/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java index f73ceae8acd3..9da10b39e6d4 100644 --- a/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java +++ b/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java @@ -1,4 +1,6 @@ -// Copyright 2000-2017 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-2017 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.projectRoots.impl; import com.intellij.icons.AllIcons; @@ -16,24 +18,23 @@ import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.jrt.JrtFileSystem; import com.intellij.util.PathUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; +import com.intellij.util.lang.JavaVersion; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; +import org.jetbrains.jps.model.java.JdkVersionDetector; import org.jetbrains.jps.model.java.impl.JavaSdkUtil; import javax.swing.*; import java.io.File; import java.util.*; import java.util.concurrent.ConcurrentHashMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Stream; /** @@ -46,12 +47,8 @@ public class JavaSdkImpl extends JavaSdk { public static final DataKey KEY = DataKey.create("JavaSdk"); private static final String VM_EXE_NAME = "java"; // do not use JavaW.exe for Windows because of issues with encoding - private static final Pattern VERSION_STRING_PATTERN = Pattern.compile("^(.*)java version \"([1234567890_.]*)\"(.*)$"); - private static final String JAVA_VERSION_PREFIX = "java version "; - private static final String OPENJDK_VERSION_PREFIX = "openjdk version "; - private final Map myCachedSdkHomeToVersionString = new ConcurrentHashMap<>(); - private final Map myCachedVersionStringToJavaVersion = new ConcurrentHashMap<>(); + private final Map myCachedSdkHomeToVersion = new ConcurrentHashMap<>(); public JavaSdkImpl(final VirtualFileManager fileManager, final FileTypeManager fileTypeManager) { super("JavaSDK"); @@ -73,12 +70,9 @@ public class JavaSdkImpl extends JavaSdk { } private void updateCache(VirtualFileEvent event) { - final VirtualFile file = event.getFile(); if (FileTypes.ARCHIVE.equals(fileTypeManager.getFileTypeByFileName(event.getFileName()))) { - final String filePath = file.getPath(); - if (myCachedSdkHomeToVersionString.keySet().removeIf(sdkHome -> FileUtil.isAncestor(sdkHome, filePath, false))) { - myCachedVersionStringToJavaVersion.clear(); - } + String filePath = event.getFile().getPath(); + myCachedSdkHomeToVersion.keySet().removeIf(sdkHome -> FileUtil.isAncestor(sdkHome, filePath, false)); } } }); @@ -201,50 +195,14 @@ public class JavaSdkImpl extends JavaSdk { @Override public String suggestSdkName(String currentSdkName, String sdkHome) { - final String suggestedName; - if (currentSdkName != null && !currentSdkName.isEmpty()) { - final Matcher matcher = VERSION_STRING_PATTERN.matcher(currentSdkName); - final boolean replaceNameWithVersion = matcher.matches(); - if (replaceNameWithVersion){ - // user did not change name -> set it automatically - final String versionString = getVersionString(sdkHome); - suggestedName = versionString == null ? currentSdkName : matcher.replaceFirst("$1" + versionString + "$3"); - } - else { - suggestedName = currentSdkName; - } - } - else { - String versionString = getVersionString(sdkHome); - suggestedName = versionString == null ? ProjectBundle.message("sdk.java.unknown.name") : getVersionNumber(versionString); - } - return suggestedName; - } + JavaVersion version = getJavaVersion(sdkHome); + if (version == null) return currentSdkName; - @NotNull - private static String getVersionNumber(@NotNull String versionString) { - if (versionString.startsWith(JAVA_VERSION_PREFIX) || versionString.startsWith(OPENJDK_VERSION_PREFIX)) { - boolean openJdk = versionString.startsWith(OPENJDK_VERSION_PREFIX); - versionString = versionString.substring(openJdk ? OPENJDK_VERSION_PREFIX.length() : JAVA_VERSION_PREFIX.length()); - if (versionString.startsWith("\"") && versionString.endsWith("\"")) { - versionString = versionString.substring(1, versionString.length() - 1); - } - int dotIdx = versionString.indexOf('.'); - if (dotIdx > 0) { - try { - int major = Integer.parseInt(versionString.substring(0, dotIdx)); - int minorDot = versionString.indexOf('.', dotIdx + 1); - if (minorDot > 0) { - int minor = Integer.parseInt(versionString.substring(dotIdx + 1, minorDot)); - versionString = major + "." + minor; - } - } - catch (NumberFormatException e) { - // Do nothing. Use original version string if failed to parse according to major.minor pattern. - } - } - } - return versionString; + StringBuilder suggested = new StringBuilder(); + if (version.feature < 9) suggested.append("1."); + suggested.append(version.feature); + if (version.ea) suggested.append("-ea"); + return suggested.toString(); } @Override @@ -322,23 +280,24 @@ public class JavaSdkImpl extends JavaSdk { modificator.addRoot(root, annoType); } + @Nullable + private JavaVersion getJavaVersion(String sdkHome) { + return myCachedSdkHomeToVersion.computeIfAbsent(sdkHome, k -> { + JdkVersionDetector.JdkVersionInfo jdkInfo = SdkVersionUtil.getJdkVersionInfo(k); + return jdkInfo != null ? jdkInfo.version : null; + }); + } + @Override public final String getVersionString(String sdkHome) { - String versionString = myCachedSdkHomeToVersionString.get(sdkHome); - if (versionString == null) { - versionString = SdkVersionUtil.detectJdkVersion(sdkHome); - if (!StringUtil.isEmpty(versionString)) { - myCachedSdkHomeToVersionString.put(sdkHome, versionString); - } - } - return versionString; + JavaVersion version = getJavaVersion(sdkHome); + return version != null ? JdkVersionDetector.formatVersionString(version) : null; } @Override public JavaSdkVersion getVersion(@NotNull Sdk sdk) { - String versionString = sdk.getVersionString(); - return versionString == null ? null : - myCachedVersionStringToJavaVersion.computeIfAbsent(versionString, JavaSdkVersion::fromVersionString); + JavaVersion version = getJavaVersion(sdk.getHomePath()); + return version != null ? JavaSdkVersion.fromJavaVersion(version) : null; } @Override diff --git a/java/java-psi-api/src/com/intellij/openapi/projectRoots/JavaSdkVersion.java b/java/java-psi-api/src/com/intellij/openapi/projectRoots/JavaSdkVersion.java index 93aa6056361f..bbecf1620ecd 100644 --- a/java/java-psi-api/src/com/intellij/openapi/projectRoots/JavaSdkVersion.java +++ b/java/java-psi-api/src/com/intellij/openapi/projectRoots/JavaSdkVersion.java @@ -1,29 +1,14 @@ /* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 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.projectRoots; -import com.intellij.openapi.util.Version; import com.intellij.pom.java.LanguageLevel; -import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.lang.JavaVersion; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Arrays; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * Represents version of Java SDK. Use {@code JavaSdk#getVersion(Sdk)} method to obtain version of an {@code Sdk}. @@ -32,29 +17,25 @@ import java.util.regex.Pattern; * @see LanguageLevel */ public enum JavaSdkVersion { - JDK_1_0(LanguageLevel.JDK_1_3, 0, new String[]{"1.0"}), - JDK_1_1(LanguageLevel.JDK_1_3, 1, new String[]{"1.1"}), - JDK_1_2(LanguageLevel.JDK_1_3, 2, new String[]{"1.2"}), - JDK_1_3(LanguageLevel.JDK_1_3, 3, new String[]{"1.3"}), - JDK_1_4(LanguageLevel.JDK_1_4, 4, new String[]{"1.4"}), - JDK_1_5(LanguageLevel.JDK_1_5, 5, new String[]{"1.5", "5.0"}), - JDK_1_6(LanguageLevel.JDK_1_6, 6, new String[]{"1.6", "6.0"}), - JDK_1_7(LanguageLevel.JDK_1_7, 7, new String[]{"1.7", "7.0"}), - JDK_1_8(LanguageLevel.JDK_1_8, 8, new String[]{"1.8", "8.0"}), - JDK_1_9(LanguageLevel.JDK_1_9, 9, new String[]{"1.9", "9.0", "9-ea"}), - JDK_10(LanguageLevel.JDK_1_9, 10, new String[]{"10.0", "10-ea"}); + JDK_1_0(LanguageLevel.JDK_1_3, new String[]{"1.0"}), + JDK_1_1(LanguageLevel.JDK_1_3, new String[]{"1.1"}), + JDK_1_2(LanguageLevel.JDK_1_3, new String[]{"1.2"}), + JDK_1_3(LanguageLevel.JDK_1_3, new String[]{"1.3"}), + JDK_1_4(LanguageLevel.JDK_1_4, new String[]{"1.4"}), + JDK_1_5(LanguageLevel.JDK_1_5, new String[]{"1.5", "5.0"}), + JDK_1_6(LanguageLevel.JDK_1_6, new String[]{"1.6", "6.0"}), + JDK_1_7(LanguageLevel.JDK_1_7, new String[]{"1.7", "7.0"}), + JDK_1_8(LanguageLevel.JDK_1_8, new String[]{"1.8", "8.0"}), + JDK_1_9(LanguageLevel.JDK_1_9, new String[]{"1.9", "9.0", "9-ea"}), + JDK_10(LanguageLevel.JDK_1_9, new String[]{"10.0", "10-ea"}); private static final JavaSdkVersion MAX_JDK = JDK_1_9; - private static final Pattern JAVA_VERSION = Pattern.compile("java version \"(\\d.*)\""); - private final LanguageLevel myMaxLanguageLevel; - private final int myRelease; private final String[] myVersionStrings; - JavaSdkVersion(@NotNull LanguageLevel maxLanguageLevel, int release, @NotNull String[] description) { + JavaSdkVersion(@NotNull LanguageLevel maxLanguageLevel, @NotNull String[] description) { myMaxLanguageLevel = maxLanguageLevel; - myRelease = release; myVersionStrings = description; } @@ -93,31 +74,16 @@ public enum JavaSdkVersion { throw new IllegalArgumentException("Can't map " + languageLevel + " to any of " + Arrays.toString(values())); } - /** - * Version string could be an actual version (like {@code "1.8.0_131"}), - * or a string returned by "java -version" command (like {@code "java version \"9-ea\""}). - */ + /** See {@link JavaVersion#parse(String)} for supported formats. */ @Nullable public static JavaSdkVersion fromVersionString(@NotNull String versionString) { - Matcher matcher = JAVA_VERSION.matcher(versionString.trim()); - if (matcher.matches()) { - versionString = matcher.group(1); - } + JavaVersion version = JavaVersion.tryParse(versionString); + return version != null ? fromJavaVersion(version) : null; + } - Version parsed = Version.parseVersion(versionString); - if (parsed != null && parsed.major > 0) { - int release = parsed.major == 1 ? parsed.minor : parsed.major; - return ContainerUtil.find(values(), v -> v.myRelease == release); - } - - for (JavaSdkVersion version : values()) { - for (String pattern : version.myVersionStrings) { - if (versionString.contains(pattern)) { - return version; - } - } - } - - return null; + @Nullable + public static JavaSdkVersion fromJavaVersion(@NotNull JavaVersion version) { + JavaSdkVersion[] values = values(); + return version.feature < values.length ? values[version.feature] : null; } } \ No newline at end of file From ff1842bfdaefa26717d7a0d78a4831ac218fd9b3 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Thu, 21 Dec 2017 17:29:18 +0100 Subject: [PATCH 06/18] API PlatformTestUtil.waitUntilBusy -> waitWhileBusy --- .../projectView/NavigateFromSourceTest.java | 16 ++---------- .../projectView/ProjectTreeSortingTest.java | 16 ++---------- .../projectView/ProjectViewUpdatingTest.java | 26 +++++-------------- .../StructureViewUpdatingTest.java | 16 ++---------- .../projectView/TestProjectTreeStructure.java | 18 +++---------- .../testFramework/PlatformTestUtil.java | 18 +++---------- .../properties/PropertiesProjectViewTest.java | 16 ++---------- 7 files changed, 21 insertions(+), 105 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/projectView/NavigateFromSourceTest.java b/java/java-tests/testSrc/com/intellij/projectView/NavigateFromSourceTest.java index c49dfff32bd0..3bf910b757d5 100644 --- a/java/java-tests/testSrc/com/intellij/projectView/NavigateFromSourceTest.java +++ b/java/java-tests/testSrc/com/intellij/projectView/NavigateFromSourceTest.java @@ -1,17 +1,5 @@ /* - * 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-2017 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; @@ -132,7 +120,7 @@ public class NavigateFromSourceTest extends BaseProjectViewTestCase { psiClass = psiFile.getClasses()[0]; pane.select(psiClass, virtualFile, true); - PlatformTestUtil.waitUntilBusy(tree); + PlatformTestUtil.waitWhileBusy(tree); PlatformTestUtil.assertTreeEqual(tree, expected, true); } } diff --git a/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeSortingTest.java b/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeSortingTest.java index a819c4b52c17..c2da56aa3162 100644 --- a/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeSortingTest.java +++ b/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeSortingTest.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 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; @@ -249,7 +237,7 @@ public class ProjectTreeSortingTest extends BaseProjectViewTestCase { private void assertTree(String expected) { TreePath path = PlatformTestUtil.waitForPromise(myPane.promisePathToElement(getContentDirectory())); - PlatformTestUtil.waitUntilBusy(myPane.getTree()); + PlatformTestUtil.waitWhileBusy(myPane.getTree()); Object element = path.getLastPathComponent(); assertNotNull("Element for " + getContentDirectory() + " not found", element); assertEquals(expected, PlatformTestUtil.print(myPane.getTree(), element, new Queryable.PrintInfo(), false)); diff --git a/java/java-tests/testSrc/com/intellij/projectView/ProjectViewUpdatingTest.java b/java/java-tests/testSrc/com/intellij/projectView/ProjectViewUpdatingTest.java index f3bcc99f8b8a..5ff8d4ca4a5d 100644 --- a/java/java-tests/testSrc/com/intellij/projectView/ProjectViewUpdatingTest.java +++ b/java/java-tests/testSrc/com/intellij/projectView/ProjectViewUpdatingTest.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 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; @@ -50,7 +38,7 @@ public class ProjectViewUpdatingTest extends BaseProjectViewTestCase { final AbstractProjectViewPSIPane pane = myStructure.createPane(); getProjectTreeStructure().setProviders(); pane.select(element, element.getContainingFile().getVirtualFile(), true); - PlatformTestUtil.waitUntilBusy(pane.getTree()); + PlatformTestUtil.waitWhileBusy(pane.getTree()); PlatformTestUtil.assertTreeEqual(pane.getTree(), "-Project\n" + " -PsiDirectory: standardProviders\n" + " -PsiDirectory: src\n" + @@ -102,7 +90,7 @@ public class ProjectViewUpdatingTest extends BaseProjectViewTestCase { final PsiClass aClass = classFile.getClasses()[0]; final PsiFile containingFile = aClass.getContainingFile(); pane.select(aClass, containingFile.getVirtualFile(), true); - PlatformTestUtil.waitUntilBusy(pane.getTree()); + PlatformTestUtil.waitWhileBusy(pane.getTree()); PlatformTestUtil.assertTreeEqual(pane.getTree(), "-Project\n" + " -PsiDirectory: updateProjectView\n" + " -PsiDirectory: src\n" + @@ -148,7 +136,7 @@ public class ProjectViewUpdatingTest extends BaseProjectViewTestCase { PlatformTestUtil.waitForAlarm(600); final PsiFile containingFile2 = aClass2.getContainingFile(); pane.select(aClass2, containingFile2.getVirtualFile(), true); - PlatformTestUtil.waitUntilBusy(pane.getTree()); + PlatformTestUtil.waitWhileBusy(pane.getTree()); PlatformTestUtil.assertTreeEqual(pane.getTree(), "-Project\n" + " -PsiDirectory: updateProjectView\n" + " -PsiDirectory: src\n" + @@ -181,7 +169,7 @@ public class ProjectViewUpdatingTest extends BaseProjectViewTestCase { PsiClass aClass = classFile.getClasses()[0]; PsiFile containingFile = aClass.getContainingFile(); pane.select(aClass, containingFile.getVirtualFile(), true); - PlatformTestUtil.waitUntilBusy(pane.getTree()); + PlatformTestUtil.waitWhileBusy(pane.getTree()); PlatformTestUtil.assertTreeEqual(pane.getTree(), "-Project\n" + " -PsiDirectory: showClassMembers\n" + " -PsiDirectory: src\n" + @@ -228,7 +216,7 @@ public class ProjectViewUpdatingTest extends BaseProjectViewTestCase { final PsiField lastField = aClass.getFields()[1]; pane.select(lastField, containingFile.getVirtualFile(), true); - PlatformTestUtil.waitUntilBusy(pane.getTree()); + PlatformTestUtil.waitWhileBusy(pane.getTree()); PlatformTestUtil.assertTreeEqual(pane.getTree(), "-Project\n" + " -PsiDirectory: showClassMembers\n" + " -PsiDirectory: src\n" + @@ -395,7 +383,7 @@ public class ProjectViewUpdatingTest extends BaseProjectViewTestCase { AbstractTreeBuilder builder = pane.getTreeBuilder(); if (builder == null) { pane.updateFromRoot(false); - PlatformTestUtil.waitUntilBusy(tree); + PlatformTestUtil.waitWhileBusy(tree); PlatformTestUtil.assertTreeEqual(tree, "-Project\n" + " -1\n" + " +01.2\n" + diff --git a/java/java-tests/testSrc/com/intellij/projectView/StructureViewUpdatingTest.java b/java/java-tests/testSrc/com/intellij/projectView/StructureViewUpdatingTest.java index 1ce282558ad9..d216f41f090c 100644 --- a/java/java-tests/testSrc/com/intellij/projectView/StructureViewUpdatingTest.java +++ b/java/java-tests/testSrc/com/intellij/projectView/StructureViewUpdatingTest.java @@ -1,17 +1,5 @@ /* - * 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-2017 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; @@ -137,7 +125,7 @@ public class StructureViewUpdatingTest extends TestSourceBasedTestCase { svc.select(innerClassField, true); - PlatformTestUtil.waitUntilBusy(svc.getTree()); + PlatformTestUtil.waitWhileBusy(svc.getTree()); PlatformTestUtil.assertTreeEqual( svc.getTree(), "-Class2.java\n" + diff --git a/platform/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java b/platform/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java index ffa7871b5507..4b309ed7a14d 100644 --- a/platform/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java +++ b/platform/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java @@ -1,17 +1,5 @@ /* - * 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-2017 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; @@ -42,7 +30,7 @@ public class TestProjectTreeStructure extends AbstractProjectTreeStructure imple public void checkNavigateFromSourceBehaviour(PsiElement element, VirtualFile virtualFile, AbstractProjectViewPSIPane pane) { Assert.assertNull(ProjectViewTestUtil.getNodeForElement(element, pane)); pane.select(element, virtualFile, true); - PlatformTestUtil.waitUntilBusy(pane.getTree()); + PlatformTestUtil.waitWhileBusy(pane.getTree()); Assert.assertTrue(ProjectViewTestUtil.isExpanded(element, pane)); } @@ -50,7 +38,7 @@ public class TestProjectTreeStructure extends AbstractProjectTreeStructure imple final AbstractProjectViewPSIPane pane = new TestProjectViewPSIPane(myProject, this, 9); pane.createComponent(); Disposer.register(this, pane); - PlatformTestUtil.waitUntilBusy(pane.getTree()); + PlatformTestUtil.waitWhileBusy(pane.getTree()); return pane; } diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java index 148f35de710b..aba490efa046 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 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; @@ -258,7 +246,7 @@ public class PlatformTestUtil { public static void expand(JTree tree, int... rows) { for (int row : rows) { tree.expandRow(row); - waitUntilBusy(tree); + waitWhileBusy(tree); } } @@ -284,7 +272,7 @@ public class PlatformTestUtil { } @TestOnly - public static void waitUntilBusy(JTree tree) { + public static void waitWhileBusy(JTree tree) { assert EventQueue.isDispatchThread(); long millis = 10000L + System.currentTimeMillis(); while (isBusy(tree)) { diff --git a/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesProjectViewTest.java b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesProjectViewTest.java index 826499dc6634..bf626ae80ba5 100644 --- a/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesProjectViewTest.java +++ b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesProjectViewTest.java @@ -1,17 +1,5 @@ /* - * 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-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.lang.properties; @@ -115,7 +103,7 @@ public class PropertiesProjectViewTest extends LightPlatformCodeInsightFixtureTe PsiFile psiFile = getPsiManager().findFile(myFixture.findFileInTempDir(getTestName(true) + "/xxx.properties")); assert psiFile != null; pane.select(psiFile, psiFile.getVirtualFile(), sortByType); - PlatformTestUtil.waitUntilBusy(pane.getTree()); + PlatformTestUtil.waitWhileBusy(pane.getTree()); return pane; } } From ec5440bbdd32068b6874d3aa47fbf62a114664b1 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Dec 2017 17:34:15 +0100 Subject: [PATCH 07/18] [build] reverts premature migration to new API --- build/scripts/utils.gant | 2 +- .../groovy/org/jetbrains/intellij/build/impl/JdkUtils.groovy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant index 527d55f6ec5e..723410b95e79 100644 --- a/build/scripts/utils.gant +++ b/build/scripts/utils.gant @@ -184,7 +184,7 @@ private String setupJdkPath(String propertyName, String defaultDir, String envVa else { jdk = guessJdk() def jdkInfo = JdkVersionDetector.instance.detectJdkVersionInfo(jdk) - if (propertyName.contains("8") && jdkInfo.@version.feature != 8) { + if (propertyName.contains("8") && jdkInfo.version.contains("1.8.")) { projectBuilder.error("JDK 1.8 is required to compile the project, but '$propertyName' property and '$envVarName' environment variable" + " aren't defined and default JDK $jdk ($jdkInfo) cannot be used as JDK 1.8") return null diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/JdkUtils.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/JdkUtils.groovy index 5639f78cd23f..727ef7f5314f 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/JdkUtils.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/JdkUtils.groovy @@ -43,7 +43,7 @@ class JdkUtils { else { jdkDir = getCurrentJdk() def jdkInfo = JdkVersionDetector.instance.detectJdkVersionInfo(jdkDir) - if (propertyName.contains("8") && jdkInfo.@version.feature != 8) { + if (propertyName.contains("8") && !jdkInfo.version.contains("1.8.")) { messages.error("JDK 1.8 is required to compile the project, but '$propertyName' property and '$envVarName' environment variable" + " aren't defined and default JDK $jdkDir ($jdkInfo) cannot be used as JDK 1.8") return null From 0babfe26af1eaaac2825ca7207ad1b57e065ae72 Mon Sep 17 00:00:00 2001 From: Artem Gainanov Date: Thu, 21 Dec 2017 23:44:14 +0700 Subject: [PATCH 08/18] [gui-test] plugin path selection fix --- .../src/com/intellij/testGuiFramework/impl/GuiTestCase.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt b/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt index 2c7f77a9da9b..f6ab12f7914f 100644 --- a/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt +++ b/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt @@ -148,8 +148,8 @@ open class GuiTestCase { * is a Mac native. */ fun chooseFileInFileChooser(path: String, timeout: Long = defaultTimeout) { - val macNativeFileChooser = SystemInfo.isMac() && (System.getProperty("ide.mac.file.chooser.native", "true").toLowerCase() == "true") - if (!macNativeFileChooser) { + val macNativeFileChooser = SystemInfo.isMac() && (System.getProperty("ide.mac.file.chooser.native", "true").toLowerCase() == "false") + if (macNativeFileChooser) { MacFileChooserDialogFixture(robot()).selectByPath(path) } else { From eea03864da29e20dc15dbd4c1c65cd24cfd7c63c Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 21 Dec 2017 12:36:07 +0100 Subject: [PATCH 09/18] IG: add option to ignore accesses from inner classes (IDEA-184055) --- ...therObjectsPrivateFieldInspectionBase.java | 46 +++++++++++-------- .../UseOfAnotherObjectsPrivateField.html | 1 + ...fAnotherObjectsPrivateFieldInspection.java | 16 ------- .../UseOfAnotherObjectsPrivateField.java | 33 +++++++++++++ ...therObjectsPrivateFieldInspectionTest.java | 27 +++++++++++ 5 files changed, 87 insertions(+), 36 deletions(-) delete mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/encapsulation/UseOfAnotherObjectsPrivateFieldInspection.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/encapsulation/use_of_another_objects_private_field/UseOfAnotherObjectsPrivateField.java create mode 100644 plugins/InspectionGadgets/testsrc/com/siyeh/ig/encapsulation/UseOfAnotherObjectsPrivateFieldInspectionTest.java diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/encapsulation/UseOfAnotherObjectsPrivateFieldInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/encapsulation/UseOfAnotherObjectsPrivateFieldInspectionBase.java index 62e57feacb00..9efd2dcd79d1 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/encapsulation/UseOfAnotherObjectsPrivateFieldInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/encapsulation/UseOfAnotherObjectsPrivateFieldInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2017 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,21 +16,26 @@ package com.siyeh.ig.encapsulation; import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; +import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.psiutils.MethodUtils; +import org.jdom.Element; import org.jetbrains.annotations.NotNull; import javax.swing.*; -public class UseOfAnotherObjectsPrivateFieldInspectionBase - extends BaseInspection { +public class UseOfAnotherObjectsPrivateFieldInspectionBase extends BaseInspection { @SuppressWarnings({"PublicField"}) public boolean ignoreSameClass = false; + + @SuppressWarnings({"PublicField"}) + public boolean ignoreInnerClasses = false; + @SuppressWarnings({"PublicField"}) public boolean ignoreEquals = false; @@ -56,34 +61,36 @@ public class UseOfAnotherObjectsPrivateFieldInspectionBase @Override public JComponent createOptionsPanel() { - final MultipleCheckboxOptionsPanel panel = - new MultipleCheckboxOptionsPanel(this); - panel.addCheckbox(InspectionGadgetsBundle.message( - "ignore.accesses.from.the.same.class"), "ignoreSameClass"); - panel.addCheckbox(InspectionGadgetsBundle.message( - "ignore.accesses.from.equals.method"), "ignoreEquals"); + final MultipleCheckboxOptionsPanel panel = new MultipleCheckboxOptionsPanel(this); + final JCheckBox box = panel.addCheckboxEx(InspectionGadgetsBundle.message("ignore.accesses.from.the.same.class"), "ignoreSameClass"); + panel.addDependentCheckBox("Ignore accesses from inner classes", "ignoreInnerClasses", box); + panel.addCheckbox(InspectionGadgetsBundle.message("ignore.accesses.from.equals.method"), "ignoreEquals"); return panel; } + @Override + public void writeSettings(@NotNull Element node) throws WriteExternalException { + // this inspection uses old style serialization, make sure newly introduced setting field does not change profile. + defaultWriteSettings(node, "ignoreInnerClasses"); + writeBooleanOption(node, "ignoreInnerClasses", false); + } + @Override public BaseInspectionVisitor buildVisitor() { return new UseOfAnotherObjectsPrivateFieldVisitor(); } - private class UseOfAnotherObjectsPrivateFieldVisitor - extends BaseInspectionVisitor { + private class UseOfAnotherObjectsPrivateFieldVisitor extends BaseInspectionVisitor { @Override - public void visitReferenceExpression( - @NotNull PsiReferenceExpression expression) { + public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) { super.visitReferenceExpression(expression); final PsiExpression qualifier = expression.getQualifierExpression(); if (qualifier == null || qualifier instanceof PsiThisExpression) { return; } if (ignoreEquals) { - final PsiMethod method = - PsiTreeUtil.getParentOfType(expression, PsiMethod.class); + final PsiMethod method = PsiTreeUtil.getParentOfType(expression, PsiMethod.class); if (MethodUtils.isEquals(method)) { return; } @@ -94,10 +101,10 @@ public class UseOfAnotherObjectsPrivateFieldInspectionBase } final PsiField field = (PsiField)referent; if (ignoreSameClass) { - final PsiClass parent = - PsiTreeUtil.getParentOfType(expression, PsiClass.class); + final PsiClass parent = PsiTreeUtil.getParentOfType(expression, PsiClass.class); final PsiClass containingClass = field.getContainingClass(); - if (parent != null && parent.equals(containingClass)) { + if (parent != null && (parent.equals(containingClass) || + ignoreInnerClasses && PsiTreeUtil.isAncestor(containingClass, parent, true))) { return; } } @@ -108,8 +115,7 @@ public class UseOfAnotherObjectsPrivateFieldInspectionBase if (field.hasModifierProperty(PsiModifier.STATIC)) { return; } - final PsiElement fieldNameElement = - expression.getReferenceNameElement(); + final PsiElement fieldNameElement = expression.getReferenceNameElement(); if (fieldNameElement == null) { return; } diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfAnotherObjectsPrivateField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfAnotherObjectsPrivateField.html index 6e532ba64010..4b721669eab7 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfAnotherObjectsPrivateField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfAnotherObjectsPrivateField.html @@ -10,6 +10,7 @@ using proxies.

    Use the first checkbox below to ignore accesses from the same class and only report accesses from inner or outer classes. + To ignore accesses from inner classes also, use the nested checkbox.

    Use the second checkbox below to ignore accesses from an equals() method.

    diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/encapsulation/UseOfAnotherObjectsPrivateFieldInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/encapsulation/UseOfAnotherObjectsPrivateFieldInspection.java deleted file mode 100644 index fa2ef949c267..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/encapsulation/UseOfAnotherObjectsPrivateFieldInspection.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.siyeh.igtest.encapsulation; - -public class UseOfAnotherObjectsPrivateFieldInspection { - public int foo; - protected int bar; - private int baz; - - public void fooBar(UseOfAnotherObjectsPrivateFieldInspection copy) - { - foo = copy.foo; - bar = copy.bar; - baz = copy.baz; - foo = this.baz; - foo = baz; - } -} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/encapsulation/use_of_another_objects_private_field/UseOfAnotherObjectsPrivateField.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/encapsulation/use_of_another_objects_private_field/UseOfAnotherObjectsPrivateField.java new file mode 100644 index 000000000000..5c0f02e005a3 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/encapsulation/use_of_another_objects_private_field/UseOfAnotherObjectsPrivateField.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2017 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.siyeh.igtest.encapsulation; + +public class UseOfAnotherObjectsPrivateField { + public int foo; + protected int bar; + private int baz; + + public void fooBar(UseOfAnotherObjectsPrivateField copy) + { + foo = copy.foo; + bar = copy.bar; + baz = copy.baz; + foo = this.baz; + foo = baz; + } + + class Inside { + + int f(UseOfAnotherObjectsPrivateField pugnacious) { + return pugnacious.baz; + } + } +} +class SomewhereElse { + + void m(UseOfAnotherObjectsPrivateField tenacious) { + tenacious.bar = 1; + tenacious.foo = 2; + } +} diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/encapsulation/UseOfAnotherObjectsPrivateFieldInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/encapsulation/UseOfAnotherObjectsPrivateFieldInspectionTest.java new file mode 100644 index 000000000000..7e74532e3b37 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/encapsulation/UseOfAnotherObjectsPrivateFieldInspectionTest.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2017 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.siyeh.ig.encapsulation; + +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightInspectionTestCase; +import org.jetbrains.annotations.Nullable; + +/** + * @author Bas Leijdekkers + */ +public class UseOfAnotherObjectsPrivateFieldInspectionTest extends LightInspectionTestCase { + + public void testUseOfAnotherObjectsPrivateField() { + doTest(); + } + + @Nullable + @Override + protected InspectionProfileEntry getInspection() { + final UseOfAnotherObjectsPrivateFieldInspection inspection = new UseOfAnotherObjectsPrivateFieldInspection(); + inspection.ignoreSameClass = true; + inspection.ignoreInnerClasses = true; + return inspection; + } +} From 99a8d2235109a02a4f61cdc488a18558907db4ff Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 21 Dec 2017 16:28:54 +0100 Subject: [PATCH 10/18] test written defaults of inspections using old serialization --- .../com/intellij/codeInspection/inspection-black-list.txt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/inspection-black-list.txt b/platform/analysis-impl/src/com/intellij/codeInspection/inspection-black-list.txt index 1b5fa78a2466..04453ff9e1a7 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/inspection-black-list.txt +++ b/platform/analysis-impl/src/com/intellij/codeInspection/inspection-black-list.txt @@ -17,7 +17,6 @@ com.intellij.codeInspection.miscGenerics.SuspiciousCollectionsMethodCallsInspect com.intellij.codeInspection.nullable.NullableStuffInspection com.intellij.codeInspection.suspiciousNameCombination.SuspiciousNameCombinationInspection com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection -com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection com.intellij.codeInspection.varScopeCanBeNarrowed.FieldCanBeLocalInspection com.intellij.codeInspection.visibility.VisibilityInspection com.intellij.lang.javascript.inspections.JSMismatchedCollectionQueryUpdateInspection @@ -116,11 +115,8 @@ com.siyeh.ig.encapsulation.UseOfAnotherObjectsPrivateFieldInspection com.siyeh.ig.errorhandling.BadExceptionCaughtInspection com.siyeh.ig.errorhandling.BadExceptionDeclaredInspection com.siyeh.ig.errorhandling.BadExceptionThrownInspection -com.siyeh.ig.errorhandling.EmptyCatchBlockInspection com.siyeh.ig.errorhandling.ExceptionFromCatchWhichDoesntWrapInspection com.siyeh.ig.errorhandling.ThrowCaughtLocallyInspection -com.siyeh.ig.errorhandling.UnusedCatchParameterInspection -com.siyeh.ig.finalization.FinalizeCallsSuperFinalizeInspection com.siyeh.ig.finalization.FinalizeInspection com.siyeh.ig.inheritance.InterfaceNeverImplementedInspection com.siyeh.ig.inheritance.NonProtectedConstructorInAbstractClassInspection @@ -165,8 +161,6 @@ com.siyeh.ig.naming.PackageNamingConventionInspection com.siyeh.ig.naming.ParameterNameDiffersFromOverriddenParameterInspection com.siyeh.ig.naming.ParameterNamingConventionInspection com.siyeh.ig.naming.QuestionableNameInspection -com.siyeh.ig.naming.StaticMethodNamingConventionInspection -com.siyeh.ig.naming.StaticVariableNamingConventionInspection com.siyeh.ig.numeric.CastThatLosesPrecisionInspection com.siyeh.ig.numeric.ImplicitNumericConversionInspection com.siyeh.ig.numeric.IntegerMultiplicationImplicitCastToLongInspection @@ -178,7 +172,6 @@ com.siyeh.ig.packaging.PackageWithTooManyClassesInspection com.siyeh.ig.performance.CallToSimpleGetterInClassInspection com.siyeh.ig.performance.CallToSimpleSetterInClassInspection com.siyeh.ig.performance.MethodMayBeStaticInspection -com.siyeh.ig.performance.SizeReplaceableByIsEmptyInspection com.siyeh.ig.performance.StringConcatenationInLoopsInspection com.siyeh.ig.performance.StringConstructorInspection com.siyeh.ig.performance.StringReplaceableByStringBufferInspection @@ -203,7 +196,6 @@ com.siyeh.ig.style.RedundantImplementsInspection com.siyeh.ig.style.UnnecessarilyQualifiedInnerClassAccessInspection com.siyeh.ig.style.UnnecessarilyQualifiedStaticUsageInspection com.siyeh.ig.style.UnnecessaryBlockStatementInspection -com.siyeh.ig.style.UnnecessaryFinalOnParameterInspection com.siyeh.ig.style.UnnecessaryFullyQualifiedNameInspection com.siyeh.ig.style.UnnecessaryParenthesesInspection com.siyeh.ig.style.UnqualifiedInnerClassAccessInspection From d6fc5cd95bfc71ec4db7ca7743a640c1548761c2 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 21 Dec 2017 19:54:20 +0300 Subject: [PATCH 11/18] cleanup: mark read/writeExternal in FacetConfiguration as default And remove empty implementations. --- .../com/intellij/facet/FacetConfiguration.java | 6 ++++-- .../impl/invalid/InvalidFacetConfiguration.java | 15 ++------------- .../facet/AppEngineFacetConfiguration.java | 9 --------- 3 files changed, 6 insertions(+), 24 deletions(-) diff --git a/platform/lang-api/src/com/intellij/facet/FacetConfiguration.java b/platform/lang-api/src/com/intellij/facet/FacetConfiguration.java index c84c64880e13..84c0461df707 100644 --- a/platform/lang-api/src/com/intellij/facet/FacetConfiguration.java +++ b/platform/lang-api/src/com/intellij/facet/FacetConfiguration.java @@ -48,12 +48,14 @@ public interface FacetConfiguration extends JDOMExternalizable { */ @Override @Deprecated - void readExternal(final Element element) throws InvalidDataException; + default void readExternal(final Element element) throws InvalidDataException { + } /** * @deprecated implement {@link com.intellij.openapi.components.PersistentStateComponent#getState()} instead */ @Override @Deprecated - void writeExternal(final Element element) throws WriteExternalException; + default void writeExternal(final Element element) throws WriteExternalException { + } } diff --git a/platform/lang-impl/src/com/intellij/facet/impl/invalid/InvalidFacetConfiguration.java b/platform/lang-impl/src/com/intellij/facet/impl/invalid/InvalidFacetConfiguration.java index a88e760f3718..1708c5b25ec4 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/invalid/InvalidFacetConfiguration.java +++ b/platform/lang-impl/src/com/intellij/facet/impl/invalid/InvalidFacetConfiguration.java @@ -16,14 +16,11 @@ package com.intellij.facet.impl.invalid; import com.intellij.facet.FacetConfiguration; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.serialization.facet.FacetState; import com.intellij.facet.ui.FacetEditorContext; import com.intellij.facet.ui.FacetEditorTab; import com.intellij.facet.ui.FacetValidatorsManager; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.WriteExternalException; -import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.serialization.facet.FacetState; /** * @author nik @@ -49,14 +46,6 @@ public class InvalidFacetConfiguration implements FacetConfiguration { }; } - @Override - public void readExternal(Element element) throws InvalidDataException { - } - - @Override - public void writeExternal(Element element) throws WriteExternalException { - } - public String getErrorMessage() { return myErrorMessage; } diff --git a/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineFacetConfiguration.java b/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineFacetConfiguration.java index b9e149840ffc..5d25f1a25d10 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineFacetConfiguration.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineFacetConfiguration.java @@ -20,9 +20,6 @@ import com.intellij.facet.ui.FacetEditorContext; import com.intellij.facet.ui.FacetEditorTab; import com.intellij.facet.ui.FacetValidatorsManager; import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.WriteExternalException; -import org.jdom.Element; import org.jetbrains.jps.appengine.model.PersistenceApi; import org.jetbrains.jps.appengine.model.impl.AppEngineModuleExtensionProperties; @@ -40,12 +37,6 @@ public class AppEngineFacetConfiguration implements FacetConfiguration, Persiste }; } - public void readExternal(Element element) throws InvalidDataException { - } - - public void writeExternal(Element element) throws WriteExternalException { - } - public AppEngineModuleExtensionProperties getState() { return myProperties; } From cbc090b64ab4816a711564f87f003544bbd328d0 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 21 Dec 2017 20:02:11 +0300 Subject: [PATCH 12/18] cleanup: FacetConfiguration don't extend JDOMExternalizable anymore --- .../com/intellij/facet/FacetConfiguration.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/platform/lang-api/src/com/intellij/facet/FacetConfiguration.java b/platform/lang-api/src/com/intellij/facet/FacetConfiguration.java index 84c0461df707..3ec5a1732de0 100644 --- a/platform/lang-api/src/com/intellij/facet/FacetConfiguration.java +++ b/platform/lang-api/src/com/intellij/facet/FacetConfiguration.java @@ -16,24 +16,23 @@ package com.intellij.facet; -import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.facet.ui.FacetEditorContext; +import com.intellij.facet.ui.FacetEditorTab; +import com.intellij.facet.ui.FacetValidatorsManager; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; -import com.intellij.facet.ui.FacetEditorTab; -import com.intellij.facet.ui.FacetEditorContext; -import com.intellij.facet.ui.FacetValidatorsManager; import org.jdom.Element; /** * Implementations of this interface contain settings of a specific facet. * *

    - * Implement {@link com.intellij.openapi.components.PersistentStateComponent} instead of {@link com.intellij.openapi.util.JDOMExternalizable} - * in your implementation of {@link com.intellij.facet.FacetConfiguration} + * Implement {@link com.intellij.openapi.components.PersistentStateComponent} instead of overriding {@link #readExternal(Element)} and + * {@link #writeExternal(Element)} methods in your implementation of {@link com.intellij.facet.FacetConfiguration} * * @author nik */ -public interface FacetConfiguration extends JDOMExternalizable { +public interface FacetConfiguration { /** * Creates editor which will be used to edit this facet configuration @@ -46,7 +45,6 @@ public interface FacetConfiguration extends JDOMExternalizable { /** * @deprecated implement {@link com.intellij.openapi.components.PersistentStateComponent#loadState(Object)} instead */ - @Override @Deprecated default void readExternal(final Element element) throws InvalidDataException { } @@ -54,7 +52,6 @@ public interface FacetConfiguration extends JDOMExternalizable { /** * @deprecated implement {@link com.intellij.openapi.components.PersistentStateComponent#getState()} instead */ - @Override @Deprecated default void writeExternal(final Element element) throws WriteExternalException { } From 0734a3bc1ae8f4d31d6f4aafc8fab5ce3723a2fd Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Dec 2017 18:02:06 +0100 Subject: [PATCH 13/18] [testFramework] temporary disables overly cautious assertion --- .../com/intellij/testFramework/IdeaTestUtil.java | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java b/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java index 2fdde81df019..e6d1a6094d20 100644 --- a/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java +++ b/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 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; @@ -177,7 +165,7 @@ public class IdeaTestUtil extends PlatformTestUtil { // hack ((SdkModificator)sdk).setVersionString(testVersion.getDescription()); - assert JavaSdk.getInstance().getVersion(sdk) == testVersion; + //assert JavaSdk.getInstance().getVersion(sdk) == testVersion; Disposer.register(parentDisposable, () -> ((SdkModificator)sdk).setVersionString(oldVersionString)); } From a74f71c3c53c6eb24695611fda50928a71c1bbfc Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 21 Dec 2017 19:59:15 +0300 Subject: [PATCH 14/18] fix async tree test --- python/testSrc/com/jetbrains/python/PyStructureViewTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/testSrc/com/jetbrains/python/PyStructureViewTest.java b/python/testSrc/com/jetbrains/python/PyStructureViewTest.java index 351902759de3..059c014d5377 100644 --- a/python/testSrc/com/jetbrains/python/PyStructureViewTest.java +++ b/python/testSrc/com/jetbrains/python/PyStructureViewTest.java @@ -3,6 +3,7 @@ package com.jetbrains.python; import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.testFramework.PlatformTestUtil; import com.jetbrains.python.fixtures.PyTestCase; import com.jetbrains.python.psi.PyFunction; import com.jetbrains.python.structureView.PyStructureViewElement; @@ -134,6 +135,7 @@ public class PyStructureViewTest extends PyTestCase { private void doTest(final String expected, final boolean inherited) { myFixture.testStructureView(component -> { component.setActionActive("SHOW_INHERITED", !inherited); + PlatformTestUtil.waitWhileBusy(component.getTree()); assertTreeEqual(component.getTree(), expected); }); } From 758e004a5df8fecdfd79bdca60aad549505a876e Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 21 Dec 2017 20:15:29 +0300 Subject: [PATCH 15/18] project view: improved fix for duplicating module and group names Treat all modules which names has prefix equal to another module's name as direct children of the parent group to avoid nodes with duplicated names in Project View (IDEA-183205). --- .../ide/projectView/impl/ModuleGroup.java | 17 +++++++---------- .../module/GroupModulesByQualifiedNamesTest.kt | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ModuleGroup.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ModuleGroup.java index 6867611e86bf..783e26d07d06 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ModuleGroup.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ModuleGroup.java @@ -68,20 +68,15 @@ public class ModuleGroup { Set> moduleAsGroupsPaths = ContainerUtil.map2Set(grouper.getAllModules(), module -> grouper.getModuleAsGroupPath(module)); for (final Module module : grouper.getAllModules()) { List group = grouper.getGroupPath(module); - if (myGroupPath.equals(group) || isChild(myGroupPath, group) && (recursively || allIntermediatePathsAreFromSet(myGroupPath, group, moduleAsGroupsPaths))) { + if (myGroupPath.equals(group) || isChild(myGroupPath, group) && (recursively || isUnderGroupWithSameNameAsSomeModule(myGroupPath, group, moduleAsGroupsPaths))) { result.add(module); } } return result; } - private static boolean allIntermediatePathsAreFromSet(List parent, List descendant, Set> set) { - for (int i = parent.size() + 1; i < descendant.size() - 1; i++) { - if (!set.contains(descendant.subList(0, i))) { - return false; - } - } - return true; + private static boolean isUnderGroupWithSameNameAsSomeModule(List parent, List descendant, Set> moduleNamesAsGroups) { + return descendant.size() > parent.size() && moduleNamesAsGroups.contains(descendant.subList(0, parent.size() + 1)); } @NotNull @@ -90,9 +85,11 @@ public class ModuleGroup { Set> moduleAsGroupsPaths = ContainerUtil.map2Set(grouper.getAllModules(), module -> grouper.getModuleAsGroupPath(module)); for (Module module : grouper.getAllModules()) { List group = grouper.getGroupPath(module); - if (!moduleAsGroupsPaths.contains(group) && isChild(myGroupPath, group)) { + if (isChild(myGroupPath, group)) { final List directChild = ContainerUtil.append(myGroupPath, group.get(myGroupPath.size())); - result.add(new ModuleGroup(directChild)); + if (!moduleAsGroupsPaths.contains(directChild)) { + result.add(new ModuleGroup(directChild)); + } } } diff --git a/platform/platform-tests/testSrc/com/intellij/module/GroupModulesByQualifiedNamesTest.kt b/platform/platform-tests/testSrc/com/intellij/module/GroupModulesByQualifiedNamesTest.kt index 6b4ed28aed56..d785e23d7db2 100644 --- a/platform/platform-tests/testSrc/com/intellij/module/GroupModulesByQualifiedNamesTest.kt +++ b/platform/platform-tests/testSrc/com/intellij/module/GroupModulesByQualifiedNamesTest.kt @@ -60,9 +60,25 @@ class GroupModulesByQualifiedNamesTest : PlatformTestCase() { fun `test module as a group`() { val module1 = createModule("a.foo") val module2 = createModule("a.foo.bar") + val module3 = createModule("a.foo.bar.baz") assertEquals("foo", grouper.getShortenedName(module1)) assertEquals("bar", grouper.getShortenedName(module2)) + assertEquals("baz", grouper.getShortenedName(module3)) + + val parentGroup = ModuleGroup(listOf("a")) + assertSameElements(parentGroup.modulesInGroup(grouper, false), module1, module2, module3) + assertSameElements(parentGroup.modulesInGroup(grouper, true), module1, module2, module3) + + assertEmpty(parentGroup.childGroups(grouper)) + } + + fun `test module as a group with deep ancestor`() { + val module1 = createModule("a.foo") + val module2 = createModule("a.foo.bar.baz") + + assertEquals("foo", grouper.getShortenedName(module1)) + assertEquals("baz", grouper.getShortenedName(module2)) val parentGroup = ModuleGroup(listOf("a")) assertSameElements(parentGroup.modulesInGroup(grouper, false), module1, module2) From 2ef60a41f92c51f3323468c6fcd2717b958a6641 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Dec 2017 18:37:59 +0100 Subject: [PATCH 16/18] [java] restores JDK version deduction from a string; restores assertion --- .../projectRoots/impl/JavaSdkImpl.java | 28 +++++++++---------- .../intellij/testFramework/IdeaTestUtil.java | 15 +++++----- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java b/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java index 9da10b39e6d4..ec1e3817ad70 100644 --- a/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java +++ b/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java @@ -48,7 +48,8 @@ public class JavaSdkImpl extends JavaSdk { private static final String VM_EXE_NAME = "java"; // do not use JavaW.exe for Windows because of issues with encoding - private final Map myCachedSdkHomeToVersion = new ConcurrentHashMap<>(); + private final Map myCachedSdkHomeToVersionString = new ConcurrentHashMap<>(); + private final Map myCachedVersionStringToJdkVersion = new ConcurrentHashMap<>(); public JavaSdkImpl(final VirtualFileManager fileManager, final FileTypeManager fileTypeManager) { super("JavaSDK"); @@ -72,7 +73,9 @@ public class JavaSdkImpl extends JavaSdk { private void updateCache(VirtualFileEvent event) { if (FileTypes.ARCHIVE.equals(fileTypeManager.getFileTypeByFileName(event.getFileName()))) { String filePath = event.getFile().getPath(); - myCachedSdkHomeToVersion.keySet().removeIf(sdkHome -> FileUtil.isAncestor(sdkHome, filePath, false)); + if (myCachedSdkHomeToVersionString.keySet().removeIf(sdkHome -> FileUtil.isAncestor(sdkHome, filePath, false))) { + myCachedVersionStringToJdkVersion.clear(); + } } } }); @@ -195,7 +198,7 @@ public class JavaSdkImpl extends JavaSdk { @Override public String suggestSdkName(String currentSdkName, String sdkHome) { - JavaVersion version = getJavaVersion(sdkHome); + JavaVersion version = JavaVersion.tryParse(getVersionString(sdkHome)); if (version == null) return currentSdkName; StringBuilder suggested = new StringBuilder(); @@ -280,24 +283,19 @@ public class JavaSdkImpl extends JavaSdk { modificator.addRoot(root, annoType); } - @Nullable - private JavaVersion getJavaVersion(String sdkHome) { - return myCachedSdkHomeToVersion.computeIfAbsent(sdkHome, k -> { + @Override + public final String getVersionString(String sdkHome) { + return myCachedSdkHomeToVersionString.computeIfAbsent(sdkHome, k -> { JdkVersionDetector.JdkVersionInfo jdkInfo = SdkVersionUtil.getJdkVersionInfo(k); - return jdkInfo != null ? jdkInfo.version : null; + return jdkInfo != null ? JdkVersionDetector.formatVersionString(jdkInfo.version) : null; }); } - @Override - public final String getVersionString(String sdkHome) { - JavaVersion version = getJavaVersion(sdkHome); - return version != null ? JdkVersionDetector.formatVersionString(version) : null; - } - @Override public JavaSdkVersion getVersion(@NotNull Sdk sdk) { - JavaVersion version = getJavaVersion(sdk.getHomePath()); - return version != null ? JavaSdkVersion.fromJavaVersion(version) : null; + String versionString = sdk.getVersionString(); + return versionString == null ? null : + myCachedVersionStringToJdkVersion.computeIfAbsent(versionString, JavaSdkVersion::fromVersionString); } @Override diff --git a/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java b/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java index e6d1a6094d20..19c81eca7224 100644 --- a/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java +++ b/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java @@ -23,6 +23,7 @@ import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.TestOnly; +import org.junit.Assert; import org.junit.Assume; import java.io.File; @@ -157,19 +158,18 @@ public class IdeaTestUtil extends PlatformTestUtil { } @TestOnly - public static void setTestVersion(@NotNull final JavaSdkVersion testVersion, @NotNull Module module, @NotNull Disposable parentDisposable) { - ModuleRootManager rootManager = ModuleRootManager.getInstance(module); - final Sdk sdk = rootManager.getSdk(); - final String oldVersionString = sdk.getVersionString(); + public static void setTestVersion(@NotNull JavaSdkVersion testVersion, @NotNull Module module, @NotNull Disposable parentDisposable) { + Sdk sdk = ModuleRootManager.getInstance(module).getSdk(); + Assert.assertNotNull(sdk); + String oldVersionString = sdk.getVersionString(); // hack ((SdkModificator)sdk).setVersionString(testVersion.getDescription()); - //assert JavaSdk.getInstance().getVersion(sdk) == testVersion; + Assert.assertSame(testVersion, JavaSdk.getInstance().getVersion(sdk)); Disposer.register(parentDisposable, () -> ((SdkModificator)sdk).setVersionString(oldVersionString)); } - @NotNull public static String requireRealJdkHome() { String javaHome = SystemProperties.getJavaHome(); @@ -180,7 +180,8 @@ public class IdeaTestUtil extends PlatformTestUtil { return path; } } + //noinspection ConstantConditions Assume.assumeTrue("Cannot find JDK, checked paths: " + paths, false); return null; } -} +} \ No newline at end of file From f2fe14d146cf6d3feb0f57a4f75c9036583788cb Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Dec 2017 18:58:20 +0100 Subject: [PATCH 17/18] [platform] accepts post-8 numbers in old Java version format (e.g. "1.10" is a valid Javac target) --- platform/util/src/com/intellij/util/lang/JavaVersion.java | 6 ++++-- .../util/testSrc/com/intellij/util/lang/JavaVersionTest.kt | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/platform/util/src/com/intellij/util/lang/JavaVersion.java b/platform/util/src/com/intellij/util/lang/JavaVersion.java index 76d70e2ba3c4..dc93a570ffe7 100644 --- a/platform/util/src/com/intellij/util/lang/JavaVersion.java +++ b/platform/util/src/com/intellij/util/lang/JavaVersion.java @@ -130,6 +130,8 @@ public final class JavaVersion { return current; } + private static final int MAX_ACCEPTED_VERSION = 25; // sanity check + /** *

    Parses a Java version string.

    * @@ -170,7 +172,7 @@ public final class JavaVersion { int feature = Integer.parseInt(numbers.get(0)), minor = 0, update = 0, build = 0; boolean ea = false; - if (feature > 8 && feature < 50 /*sanity check*/) { + if (feature > 8 && feature < MAX_ACCEPTED_VERSION) { // Java 9+ p = 1; while (p < separators.size() && ".".equals(separators.get(p))) p++; @@ -196,7 +198,7 @@ public final class JavaVersion { else if (feature == 1 && numbers.size() > 1 && separators.size() > 1 && ".".equals(separators.get(1))) { // Java 1.0 .. 1.8 feature = Integer.parseInt(numbers.get(1)); - if (feature <= 8) { + if (feature <= MAX_ACCEPTED_VERSION) { if (numbers.size() > 2 && separators.size() > 2 && ".".equals(separators.get(2))) { minor = Integer.parseInt(numbers.get(2)); if (numbers.size() > 3 && separators.size() > 3 && "_".equals(separators.get(3))) { diff --git a/platform/util/testSrc/com/intellij/util/lang/JavaVersionTest.kt b/platform/util/testSrc/com/intellij/util/lang/JavaVersionTest.kt index 5ac0cee7cc50..b0a9193c3561 100644 --- a/platform/util/testSrc/com/intellij/util/lang/JavaVersionTest.kt +++ b/platform/util/testSrc/com/intellij/util/lang/JavaVersionTest.kt @@ -23,6 +23,7 @@ class JavaVersionTest { @Test fun `1_8_0_45-internal`() = doTest("1.8.0_45-internal", 8, 0, 45, 0, true) @Test fun `1_8_0_121-2-whatever-b11`() = doTest("1.8.0_121-2-whatever-b11", 8, 0, 121, 11) @Test fun `1_8_0_121-(big-number)-b11`() = doTest("1.8.0_121-99${Long.MAX_VALUE}-b11", 8, 0, 121, 11) + @Test fun `1_10`() = doTest("1.10", 10) @Test fun `9`() = doTest("9", 9) @Test fun `9-ea`() = doTest("9-ea", 9, 0, 0, 0, true) From e8eabac4e13a52e76b46bba00c8e9f04dabd0b75 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Dec 2017 20:45:49 +0100 Subject: [PATCH 18/18] [tests] corrects JDK version detector test expectations A version obtained from JDK metadata (release file or rt.jar) has less details than "java.runtime.version" system property (notably, it misses a build number and EA flag). --- .../org/jetbrains/jps/model/JdkVersionDetectorTest.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jps/model-impl/testSrc/org/jetbrains/jps/model/JdkVersionDetectorTest.kt b/jps/model-impl/testSrc/org/jetbrains/jps/model/JdkVersionDetectorTest.kt index 614dacab18e3..443c0f07c43f 100644 --- a/jps/model-impl/testSrc/org/jetbrains/jps/model/JdkVersionDetectorTest.kt +++ b/jps/model-impl/testSrc/org/jetbrains/jps/model/JdkVersionDetectorTest.kt @@ -5,6 +5,7 @@ package org.jetbrains.jps.model import com.intellij.openapi.util.Bitness import com.intellij.openapi.util.SystemInfo +import com.intellij.util.lang.JavaVersion import org.assertj.core.api.Assertions.assertThat import org.jetbrains.jps.model.java.JdkVersionDetector import org.junit.Test @@ -13,7 +14,9 @@ class JdkVersionDetectorTest { @Test fun detectJdkVersion() { val jdkHome = System.getProperty("java.home") val jdkVersion = JdkVersionDetector.getInstance().detectJdkVersionInfo(jdkHome) - assertThat(jdkVersion?.version.toString()).startsWith(SystemInfo.JAVA_VERSION) + assertThat(jdkVersion?.version?.feature).isEqualTo(JavaVersion.current().feature) + assertThat(jdkVersion?.version?.minor).isEqualTo(JavaVersion.current().minor) + assertThat(jdkVersion?.version?.update).isEqualTo(JavaVersion.current().update) assertThat(jdkVersion?.bitness).isEqualTo(if (SystemInfo.is64Bit) Bitness.x64 else Bitness.x32) } } \ No newline at end of file